mirror of https://github.com/Budibase/budibase.git
committed by
GitHub
27 changed files with 67 additions and 748 deletions
@ -1,62 +0,0 @@ |
|||
<script> |
|||
import { onMount } from "svelte" |
|||
import { buildStyle } from "../../helpers.js" |
|||
export let value = "" |
|||
export let name = "" |
|||
export let textAlign = "left" |
|||
export let width = "160px" |
|||
export let placeholder = "" |
|||
export let suffix = "" |
|||
export let onChange = val => {} |
|||
|
|||
let centerPlaceholder = textAlign === "center" |
|||
|
|||
let style = buildStyle({ width, textAlign }) |
|||
|
|||
function handleChange(val) { |
|||
value = val |
|||
let _value = value !== "auto" ? value + suffix : value |
|||
onChange(_value) |
|||
} |
|||
|
|||
$: displayValue = |
|||
suffix && value && value.endsWith(suffix) |
|||
? value.replace(new RegExp(`${suffix}$`), "") |
|||
: value || "" |
|||
</script> |
|||
|
|||
<input |
|||
{name} |
|||
class:centerPlaceholder |
|||
type="text" |
|||
value={displayValue} |
|||
{placeholder} |
|||
{style} |
|||
on:change={e => handleChange(e.target.value)} /> |
|||
|
|||
<style> |
|||
input { |
|||
/* width: 32px; */ |
|||
height: 36px; |
|||
font-size: 14px; |
|||
font-weight: 400; |
|||
margin: 0px 0px 0px 2px; |
|||
color: var(--ink); |
|||
padding: 0px 8px; |
|||
font-family: inter; |
|||
width: 164px; |
|||
box-sizing: border-box; |
|||
background-color: var(--grey-2); |
|||
border-radius: 4px; |
|||
border: 1px solid var(--grey-2); |
|||
outline: none; |
|||
} |
|||
|
|||
input::placeholder { |
|||
text-align: left; |
|||
} |
|||
|
|||
.centerPlaceholder::placeholder { |
|||
text-align: center; |
|||
} |
|||
</style> |
|||
@ -1,50 +0,0 @@ |
|||
<script> |
|||
import { onMount } from "svelte" |
|||
import Input from "../Input.svelte" |
|||
|
|||
export let meta = [] |
|||
export let label = "" |
|||
export let value = ["0", "0", "0", "0"] |
|||
export let suffix = "" |
|||
|
|||
export let onChange = () => {} |
|||
|
|||
function handleChange(val, idx) { |
|||
value.splice(idx, 1, val !== "auto" && suffix ? val + suffix : val) |
|||
|
|||
value = value |
|||
let _value = value.map(v => |
|||
suffix && !v.endsWith(suffix) && v !== "auto" ? v + suffix : v |
|||
) |
|||
onChange(_value) |
|||
} |
|||
|
|||
$: displayValues = |
|||
value && suffix |
|||
? value.map(v => v.replace(new RegExp(`${suffix}$`), "")) |
|||
: value || [] |
|||
</script> |
|||
|
|||
<div class="input-container"> |
|||
<div class="label">{label}</div> |
|||
<div class="inputs-group"> |
|||
{#each meta as m, i} |
|||
<Input |
|||
width="37px" |
|||
textAlign="center" |
|||
placeholder={m.placeholder || ''} |
|||
value={!displayValues || displayValues[i] === '0' ? '' : displayValues[i]} |
|||
onChange={value => handleChange(value || 0, i)} /> |
|||
{/each} |
|||
</div> |
|||
</div> |
|||
|
|||
<style> |
|||
.label { |
|||
flex: 0; |
|||
} |
|||
|
|||
.inputs-group { |
|||
flex: 1; |
|||
} |
|||
</style> |
|||
@ -1,65 +0,0 @@ |
|||
<script> |
|||
import getIcon from "./icon" |
|||
|
|||
export let icon |
|||
export let value |
|||
</script> |
|||
|
|||
<div class="select-container"> |
|||
{#if icon} |
|||
<i class={icon} /> |
|||
{/if} |
|||
<select class:adjusted={icon} on:change bind:value> |
|||
<slot /> |
|||
</select> |
|||
<span class="arrow"> |
|||
{@html getIcon('chevron-down', '24')} |
|||
</span> |
|||
</div> |
|||
|
|||
<style> |
|||
.select-container { |
|||
font-size: 14px; |
|||
position: relative; |
|||
border: var(--grey-4) 1px solid; |
|||
} |
|||
|
|||
.adjusted { |
|||
padding-left: 30px; |
|||
} |
|||
|
|||
i { |
|||
position: absolute; |
|||
left: 10px; |
|||
top: 10px; |
|||
} |
|||
|
|||
select { |
|||
height: 40px; |
|||
display: block; |
|||
font-family: sans-serif; |
|||
font-weight: 400; |
|||
font-size: 14px; |
|||
color: var(--ink); |
|||
padding: 0 40px 0px 20px; |
|||
width: 100%; |
|||
max-width: 100%; |
|||
box-sizing: border-box; |
|||
margin: 0; |
|||
-moz-appearance: none; |
|||
-webkit-appearance: none; |
|||
appearance: none; |
|||
background: var(--white); |
|||
} |
|||
|
|||
.arrow { |
|||
position: absolute; |
|||
right: 10px; |
|||
bottom: 0; |
|||
margin: auto; |
|||
width: 30px; |
|||
height: 30px; |
|||
pointer-events: none; |
|||
color: var(--ink); |
|||
} |
|||
</style> |
|||
@ -1,94 +0,0 @@ |
|||
<script> |
|||
import { store, backendUiStore } from "builderStore" |
|||
import ActionButton from "components/common/ActionButton.svelte" |
|||
import * as api from "../api" |
|||
|
|||
export let onClosed |
|||
|
|||
let username |
|||
let password |
|||
let accessLevelId |
|||
|
|||
$: valid = username && password && accessLevelId |
|||
$: appId = $store.appId |
|||
|
|||
async function createUser() { |
|||
const user = { name: username, username, password, accessLevelId } |
|||
const response = await api.createUser(user) |
|||
backendUiStore.actions.users.create(response) |
|||
onClosed() |
|||
} |
|||
</script> |
|||
|
|||
<form on:submit|preventDefault class="uk-form-stacked"> |
|||
<div class="main"> |
|||
<div class="heading"> |
|||
<i class="ri-list-settings-line button--toggled" /> |
|||
<div class="title">Create User</div> |
|||
</div> |
|||
<div class="uk-margin"> |
|||
<label class="uk-form-label" for="form-stacked-text">Username</label> |
|||
<input |
|||
data-cy="username" |
|||
class="uk-input" |
|||
type="text" |
|||
bind:value={username} /> |
|||
</div> |
|||
<div class="uk-margin"> |
|||
<label class="uk-form-label" for="form-stacked-text">Password</label> |
|||
<input |
|||
data-cy="password" |
|||
class="uk-input" |
|||
type="password" |
|||
bind:value={password} /> |
|||
</div> |
|||
<div class="uk-margin"> |
|||
<label class="uk-form-label" for="form-stacked-text">Access Level</label> |
|||
<select |
|||
data-cy="accessLevel" |
|||
class="uk-select" |
|||
bind:value={accessLevelId}> |
|||
<option value="" /> |
|||
<option value="POWER_USER">Power User</option> |
|||
<option value="ADMIN">Admin</option> |
|||
</select> |
|||
</div> |
|||
</div> |
|||
<footer> |
|||
<div class="button"> |
|||
<ActionButton secondary on:click={onClosed}>Cancel</ActionButton> |
|||
</div> |
|||
<ActionButton disabled={!valid} on:click={createUser}>Save</ActionButton> |
|||
</footer> |
|||
</form> |
|||
|
|||
<style> |
|||
.main { |
|||
padding: 40px 40px 20px 40px; |
|||
} |
|||
|
|||
.title { |
|||
font-size: 24px; |
|||
font-weight: 600; |
|||
color: var(--ink); |
|||
margin-left: 12px; |
|||
} |
|||
|
|||
.heading { |
|||
display: flex; |
|||
align-items: baseline; |
|||
} |
|||
|
|||
footer { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
padding: 20px; |
|||
background: var(--grey-1); |
|||
border-radius: 0 0 5px 5px; |
|||
} |
|||
|
|||
.button { |
|||
margin-right: 20px; |
|||
} |
|||
</style> |
|||
@ -1,170 +0,0 @@ |
|||
<script> |
|||
import InputGroup from "../common/Inputs/InputGroup.svelte" |
|||
import LayoutTemplateControls from "./LayoutTemplateControls.svelte" |
|||
|
|||
export let onStyleChanged = () => {} |
|||
export let component |
|||
|
|||
const tbrl = [ |
|||
{ placeholder: "T" }, |
|||
{ placeholder: "R" }, |
|||
{ placeholder: "B" }, |
|||
{ placeholder: "L" }, |
|||
] |
|||
|
|||
const se = [{ placeholder: "START" }, { placeholder: "END" }] |
|||
|
|||
const single = [{ placeholder: "" }] |
|||
|
|||
$: layout = { |
|||
...component._styles.position, |
|||
...component._styles.layout, |
|||
} |
|||
|
|||
$: layouts = { |
|||
templaterows: ["Grid Rows", single], |
|||
templatecolumns: ["Grid Columns", single], |
|||
} |
|||
|
|||
$: display = { |
|||
direction: ["Direction", single], |
|||
align: ["Align", single], |
|||
justify: ["Justify", single], |
|||
} |
|||
|
|||
$: positions = { |
|||
column: ["Column", se], |
|||
row: ["Row", se], |
|||
} |
|||
|
|||
$: spacing = { |
|||
margin: ["Margin", tbrl, "small"], |
|||
padding: ["Padding", tbrl, "small"], |
|||
} |
|||
|
|||
$: size = { |
|||
height: ["Height", single], |
|||
width: ["Width", single], |
|||
} |
|||
|
|||
$: zindex = { |
|||
zindex: ["Z-Index", single], |
|||
} |
|||
|
|||
const newValue = n => Array(n).fill("") |
|||
</script> |
|||
|
|||
<h3>Layout</h3> |
|||
<div class="layout-pos"> |
|||
{#each Object.entries(display) as [key, [name, meta, size]] (component._id + key)} |
|||
<div class="grid"> |
|||
<h5>{name}:</h5> |
|||
<LayoutTemplateControls |
|||
onStyleChanged={_value => onStyleChanged('layout', key, _value)} |
|||
values={layout[key] || newValue(meta.length)} |
|||
propertyName={name} |
|||
{meta} |
|||
{size} |
|||
type="text" /> |
|||
</div> |
|||
{/each} |
|||
</div> |
|||
|
|||
<!-- <h4>Positioning</h4> |
|||
<div class="layout-pos"> |
|||
{#each Object.entries(positions) as [key, [name, meta, size]] (component._id + key)} |
|||
<div class="grid"> |
|||
<h5>{name}:</h5> |
|||
<InputGroup |
|||
onStyleChanged={_value => onStyleChanged('position', key, _value)} |
|||
values={layout[key] || newValue(meta.length)} |
|||
{meta} |
|||
{size} /> |
|||
</div> |
|||
{/each} |
|||
</div> --> |
|||
|
|||
<h3>Spacing</h3> |
|||
<div class="layout-spacing"> |
|||
{#each Object.entries(spacing) as [key, [name, meta, size]] (component._id + key)} |
|||
<div class="grid"> |
|||
<h5>{name}:</h5> |
|||
<InputGroup |
|||
onStyleChanged={_value => onStyleChanged('position', key, _value)} |
|||
values={layout[key] || newValue(meta.length)} |
|||
{meta} |
|||
{size} |
|||
type="text" /> |
|||
</div> |
|||
{/each} |
|||
</div> |
|||
|
|||
<h3>Size</h3> |
|||
<div class="layout-layer"> |
|||
{#each Object.entries(size) as [key, [name, meta, size]] (component._id + key)} |
|||
<div class="grid"> |
|||
<h5>{name}:</h5> |
|||
<InputGroup |
|||
onStyleChanged={_value => onStyleChanged('position', key, _value)} |
|||
values={layout[key] || newValue(meta.length)} |
|||
type="text" |
|||
{meta} |
|||
{size} /> |
|||
</div> |
|||
{/each} |
|||
</div> |
|||
|
|||
<h3>Order</h3> |
|||
<div class="layout-layer"> |
|||
{#each Object.entries(zindex) as [key, [name, meta, size]] (component._id + key)} |
|||
<div class="grid"> |
|||
<h5>{name}:</h5> |
|||
<InputGroup |
|||
onStyleChanged={_value => onStyleChanged('position', key, _value)} |
|||
values={layout[key] || newValue(meta.length)} |
|||
{meta} |
|||
{size} /> |
|||
</div> |
|||
{/each} |
|||
</div> |
|||
|
|||
<style> |
|||
h3 { |
|||
text-transform: uppercase; |
|||
font-size: 13px; |
|||
font-weight: 600; |
|||
color: var(--ink); |
|||
opacity: 0.6; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
h4 { |
|||
text-transform: uppercase; |
|||
font-size: 10px; |
|||
font-weight: 600; |
|||
color: var(--ink); |
|||
opacity: 0.4; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
h5 { |
|||
font-size: 13px; |
|||
font-weight: 400; |
|||
color: var(--ink); |
|||
opacity: 0.8; |
|||
padding-top: 13px; |
|||
margin-bottom: 0; |
|||
} |
|||
|
|||
div > div { |
|||
display: grid; |
|||
grid-template-rows: 1fr; |
|||
grid-gap: 10px; |
|||
height: 40px; |
|||
margin-bottom: 15px; |
|||
} |
|||
|
|||
.grid { |
|||
grid-template-columns: 70px 2fr; |
|||
} |
|||
</style> |
|||
@ -1,44 +0,0 @@ |
|||
<script> |
|||
import { store } from "builderStore" |
|||
import Checkbox from "../common/Checkbox.svelte" |
|||
import StateBindingControl from "./StateBindingControl.svelte" |
|||
|
|||
export let index |
|||
export let prop_name |
|||
export let prop_value |
|||
export let prop_definition = {} |
|||
</script> |
|||
|
|||
<div class="root"> |
|||
{#if prop_definition.type !== 'event'} |
|||
<h5>{prop_name}</h5> |
|||
<StateBindingControl |
|||
value={prop_value} |
|||
type={prop_definition.type || prop_definition} |
|||
options={prop_definition.options} |
|||
styleBindingProperty={prop_definition.styleBindingProperty} |
|||
onChanged={v => store.setComponentProp(prop_name, v)} /> |
|||
{/if} |
|||
</div> |
|||
|
|||
<style> |
|||
.root { |
|||
height: 40px; |
|||
margin-bottom: 15px; |
|||
display: grid; |
|||
grid-template-rows: 1fr; |
|||
grid-template-columns: 70px 1fr; |
|||
grid-gap: 10px; |
|||
align-items: baseline; |
|||
} |
|||
|
|||
h5 { |
|||
word-wrap: break-word; |
|||
font-size: 13px; |
|||
font-weight: 400; |
|||
color: var(--ink); |
|||
opacity: 0.8; |
|||
padding-top: 13px; |
|||
margin-bottom: 0; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,11 @@ |
|||
<script> |
|||
/* |
|||
This file exists because of how we pass this control to the |
|||
properties panel - via a JS reference, not using svelte tags |
|||
... checkout the use of Input in propertyCategories to see what i mean |
|||
*/ |
|||
import { Input } from "@budibase/bbui" |
|||
export let name, value, placeholder, type |
|||
</script> |
|||
|
|||
<Input {name} {value} {placeholder} {type} thin on:change /> |
|||
@ -1,52 +0,0 @@ |
|||
<script> |
|||
import { some, includes, filter } from "lodash/fp" |
|||
import PropControl from "./PropControl.svelte" |
|||
import IconButton from "../common/IconButton.svelte" |
|||
|
|||
export let component |
|||
export let components |
|||
|
|||
let errors = [] |
|||
const props_to_ignore = ["_component", "_children", "_styles", "_code", "_id"] |
|||
|
|||
$: componentDef = components[component._component] |
|||
</script> |
|||
|
|||
<div class="root"> |
|||
|
|||
<form on:submit|preventDefault class="uk-form-stacked form-root"> |
|||
{#if componentDef} |
|||
{#each Object.entries(componentDef.props) as [prop_name, prop_def], index} |
|||
{#if prop_def !== 'event'} |
|||
<div class="prop-container"> |
|||
<PropControl |
|||
{prop_name} |
|||
prop_value={component[prop_name]} |
|||
prop_definition={prop_def} |
|||
{index} |
|||
disabled={false} /> |
|||
|
|||
</div> |
|||
{/if} |
|||
{/each} |
|||
{/if} |
|||
</form> |
|||
|
|||
</div> |
|||
|
|||
<style> |
|||
.root { |
|||
font-size: 10pt; |
|||
width: 100%; |
|||
} |
|||
|
|||
.form-root { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
} |
|||
|
|||
.prop-container { |
|||
flex: 1 1 auto; |
|||
min-width: 250px; |
|||
} |
|||
</style> |
|||
@ -1,63 +0,0 @@ |
|||
<script> |
|||
import { backendUiStore } from "builderStore" |
|||
import IconButton from "../common/IconButton.svelte" |
|||
import Input from "../common/Input.svelte" |
|||
|
|||
export let value = "" |
|||
export let onChanged = () => {} |
|||
export let type = "" |
|||
export let options = [] |
|||
export let styleBindingProperty = "" |
|||
|
|||
$: bindOptionToStyle = !!styleBindingProperty |
|||
</script> |
|||
|
|||
<div class="unbound-container"> |
|||
{#if type === 'bool'} |
|||
<div> |
|||
<IconButton |
|||
icon={value == true ? 'check-square' : 'square'} |
|||
size="19" |
|||
on:click={() => onChanged(!value)} /> |
|||
</div> |
|||
{:else if type === 'models'} |
|||
<select |
|||
class="uk-select uk-form-small" |
|||
bind:value |
|||
on:change={() => { |
|||
onChanged(value) |
|||
}}> |
|||
{#each $backendUiStore.models || [] as option} |
|||
<option value={option}>{option.name}</option> |
|||
{/each} |
|||
</select> |
|||
{:else if type === 'options' || type === 'models'} |
|||
<select |
|||
class="uk-select uk-form-small" |
|||
{value} |
|||
on:change={ev => onChanged(ev.target.value)}> |
|||
{#each options || [] as option} |
|||
{#if bindOptionToStyle} |
|||
<option style={`${styleBindingProperty}: ${option};`} value={option}> |
|||
{option} |
|||
</option> |
|||
{:else} |
|||
<option value={option}>{option}</option> |
|||
{/if} |
|||
{/each} |
|||
</select> |
|||
{/if} |
|||
</div> |
|||
|
|||
<style> |
|||
.unbound-container { |
|||
display: flex; |
|||
} |
|||
|
|||
.bound-header > div:nth-child(1) { |
|||
flex: 1 0 auto; |
|||
width: 30px; |
|||
color: var(--secondary50); |
|||
padding-left: 5px; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue