Update some builder components to use new forms
This commit is contained in:
parent
3bdb484159
commit
387651213b
8 changed files with 73 additions and 102 deletions
|
@ -21,12 +21,11 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if type === 'options'}
|
{#if type === 'options'}
|
||||||
<Select thin secondary {label} data-cy="{meta.name}-select" bind:value>
|
<Select
|
||||||
<option value="">Choose an option</option>
|
{label}
|
||||||
{#each meta.constraints.inclusion as opt}
|
data-cy="{meta.name}-select"
|
||||||
<option value={opt}>{opt}</option>
|
bind:value
|
||||||
{/each}
|
options={meta.constraints.inclusion} />
|
||||||
</Select>
|
|
||||||
{:else if type === 'datetime'}
|
{:else if type === 'datetime'}
|
||||||
<DatePicker {label} bind:value />
|
<DatePicker {label} bind:value />
|
||||||
{:else if type === 'attachment'}
|
{:else if type === 'attachment'}
|
||||||
|
@ -47,7 +46,6 @@
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<Input
|
<Input
|
||||||
thin
|
|
||||||
{label}
|
{label}
|
||||||
data-cy="{meta.name}-input"
|
data-cy="{meta.name}-input"
|
||||||
{type}
|
{type}
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Button, Icon, Modal, ModalContent } from "@budibase/bbui"
|
||||||
Button,
|
|
||||||
Icon,
|
|
||||||
Modal,
|
|
||||||
ModalContent,
|
|
||||||
} from "@budibase/bbui"
|
|
||||||
import CreateEditColumn from "../modals/CreateEditColumn.svelte"
|
import CreateEditColumn from "../modals/CreateEditColumn.svelte"
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
|
@ -15,7 +10,7 @@
|
||||||
</Button>
|
</Button>
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={modal}>
|
||||||
<ModalContent
|
<ModalContent
|
||||||
size="large"
|
size="medium"
|
||||||
showCancelButton={false}
|
showCancelButton={false}
|
||||||
showConfirmButton={false}
|
showConfirmButton={false}
|
||||||
title={'Create Column'}>
|
title={'Create Column'}>
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { Input, Button, Label, Select, Toggle, Radio } from "@budibase/bbui"
|
||||||
Input,
|
|
||||||
Button,
|
|
||||||
Label,
|
|
||||||
Select,
|
|
||||||
Toggle,
|
|
||||||
Radio,
|
|
||||||
} from "@budibase/bbui"
|
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import { tables } from "stores/backend"
|
import { tables } from "stores/backend"
|
||||||
|
|
||||||
|
@ -54,8 +47,9 @@
|
||||||
$tables.selected?._id === TableNames.USERS &&
|
$tables.selected?._id === TableNames.USERS &&
|
||||||
UNEDITABLE_USER_FIELDS.includes(field.name)
|
UNEDITABLE_USER_FIELDS.includes(field.name)
|
||||||
$: invalid =
|
$: invalid =
|
||||||
|
!field.name ||
|
||||||
(field.type === LINK_TYPE && !field.tableId) ||
|
(field.type === LINK_TYPE && !field.tableId) ||
|
||||||
Object.keys($tables.draft.schema).some(key => key === field.name)
|
Object.keys($tables.draft?.schema ?? {}).some(key => key === field.name)
|
||||||
|
|
||||||
// used to select what different options can be displayed for column type
|
// used to select what different options can be displayed for column type
|
||||||
$: canBeSearched =
|
$: canBeSearched =
|
||||||
|
@ -91,19 +85,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTypeChange(event) {
|
function handleTypeChange(event) {
|
||||||
const definition = fieldDefinitions[event.target.value.toUpperCase()]
|
|
||||||
if (!definition) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// remove any extra fields that may not be related to this type
|
// remove any extra fields that may not be related to this type
|
||||||
delete field.autocolumn
|
delete field.autocolumn
|
||||||
delete field.subtype
|
delete field.subtype
|
||||||
delete field.tableId
|
delete field.tableId
|
||||||
delete field.relationshipType
|
delete field.relationshipType
|
||||||
// add in defaults and initial definition
|
|
||||||
field.type = definition.type
|
// Add in defaults and initial definition
|
||||||
field.constraints = definition.constraints
|
const definition = fieldDefinitions[event.detail?.toUpperCase()]
|
||||||
// default relationships many to many
|
if (definition?.constraints) {
|
||||||
|
field.constraints = definition.constraints
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default relationships many to many
|
||||||
if (field.type === LINK_TYPE) {
|
if (field.type === LINK_TYPE) {
|
||||||
field.relationshipType = RelationshipTypes.MANY_TO_MANY
|
field.relationshipType = RelationshipTypes.MANY_TO_MANY
|
||||||
}
|
}
|
||||||
|
@ -173,20 +167,15 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="actions" class:hidden={deletion}>
|
<div class="actions" class:hidden={deletion}>
|
||||||
<Input label="Name" thin bind:value={field.name} disabled={uneditable} />
|
<Input label="Name" bind:value={field.name} disabled={uneditable} />
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
disabled={originalName}
|
disabled={originalName}
|
||||||
secondary
|
|
||||||
thin
|
|
||||||
label="Type"
|
label="Type"
|
||||||
on:change={handleTypeChange}
|
bind:value={field.type}
|
||||||
bind:value={field.type}>
|
options={[...Object.values(fieldDefinitions), { name: 'Auto Column', type: AUTO_COL }]}
|
||||||
{#each Object.values(fieldDefinitions) as field}
|
getOptionLabel={field => field.name}
|
||||||
<option value={field.type}>{field.name}</option>
|
getOptionValue={field => field.type} />
|
||||||
{/each}
|
|
||||||
<option value={AUTO_COL}>Auto Column</option>
|
|
||||||
</Select>
|
|
||||||
|
|
||||||
{#if canBeRequired}
|
{#if canBeRequired}
|
||||||
<Toggle
|
<Toggle
|
||||||
|
@ -223,7 +212,6 @@
|
||||||
|
|
||||||
{#if field.type === 'string'}
|
{#if field.type === 'string'}
|
||||||
<Input
|
<Input
|
||||||
thin
|
|
||||||
type="number"
|
type="number"
|
||||||
label="Max Length"
|
label="Max Length"
|
||||||
bind:value={field.constraints.length.maximum} />
|
bind:value={field.constraints.length.maximum} />
|
||||||
|
@ -238,22 +226,20 @@
|
||||||
<DatePicker label="Latest" bind:value={field.constraints.datetime.latest} />
|
<DatePicker label="Latest" bind:value={field.constraints.datetime.latest} />
|
||||||
{:else if field.type === 'number'}
|
{:else if field.type === 'number'}
|
||||||
<Input
|
<Input
|
||||||
thin
|
|
||||||
type="number"
|
type="number"
|
||||||
label="Min Value"
|
label="Min Value"
|
||||||
bind:value={field.constraints.numericality.greaterThanOrEqualTo} />
|
bind:value={field.constraints.numericality.greaterThanOrEqualTo} />
|
||||||
<Input
|
<Input
|
||||||
thin
|
|
||||||
type="number"
|
type="number"
|
||||||
label="Max Value"
|
label="Max Value"
|
||||||
bind:value={field.constraints.numericality.lessThanOrEqualTo} />
|
bind:value={field.constraints.numericality.lessThanOrEqualTo} />
|
||||||
{:else if field.type === 'link'}
|
{:else if field.type === 'link'}
|
||||||
<Select label="Table" thin secondary bind:value={field.tableId}>
|
<Select
|
||||||
<option value="">Choose an option</option>
|
label="Table"
|
||||||
{#each tableOptions as table}
|
bind:value={field.tableId}
|
||||||
<option value={table._id}>{table.name}</option>
|
options={tableOptions}
|
||||||
{/each}
|
getOptionLabel={table => table.name}
|
||||||
</Select>
|
getOptionValue={table => table._id} />
|
||||||
{#if relationshipOptions && relationshipOptions.length > 0}
|
{#if relationshipOptions && relationshipOptions.length > 0}
|
||||||
<div>
|
<div>
|
||||||
<Label grey extraSmall>Define the relationship</Label>
|
<Label grey extraSmall>Define the relationship</Label>
|
||||||
|
@ -274,23 +260,24 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<Input
|
<Input label={`Column Name in Other Table`} bind:value={field.fieldName} />
|
||||||
label={`Column Name in Other Table`}
|
|
||||||
thin
|
|
||||||
bind:value={field.fieldName} />
|
|
||||||
{:else if field.type === AUTO_COL}
|
{:else if field.type === AUTO_COL}
|
||||||
<Select label="Auto Column Type" thin secondary bind:value={field.subtype}>
|
<Select
|
||||||
<option value="">Choose a subtype</option>
|
label="Auto Column Type"
|
||||||
{#each Object.entries(getAutoColumnInformation()) as [subtype, info]}
|
value={field.subtype}
|
||||||
<option value={subtype}>{info.name}</option>
|
on:change={e => (field.subtype = e.detail)}
|
||||||
{/each}
|
options={Object.entries(getAutoColumnInformation())}
|
||||||
</Select>
|
getOptionLabel={option => option[1].name}
|
||||||
|
getOptionValue={option => option[0]} />
|
||||||
{/if}
|
{/if}
|
||||||
<footer class="create-column-options">
|
<footer>
|
||||||
{#if !uneditable && originalName != null}
|
{#if !uneditable && originalName != null}
|
||||||
<Button warning size="S" text on:click={confirmDelete}>Delete Column</Button>
|
<Button warning size="S" text on:click={confirmDelete}>
|
||||||
|
Delete Column
|
||||||
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
<Button on:click={onClosed}>Cancel</Button>
|
<div class="spacer" />
|
||||||
|
<Button secondary on:click={onClosed}>Cancel</Button>
|
||||||
<Button cta on:click={saveColumn} bind:disabled={invalid}>
|
<Button cta on:click={saveColumn} bind:disabled={invalid}>
|
||||||
Save Column
|
Save Column
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -322,12 +309,13 @@
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: var(--spacing-m);
|
gap: var(--spacing-m);
|
||||||
}
|
}
|
||||||
|
.spacer {
|
||||||
:global(.create-column-options button:first-child) {
|
flex: 1 1 auto;
|
||||||
margin-right: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rel-type-center {
|
.rel-type-center {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
: $tables.selected
|
: $tables.selected
|
||||||
$: tableSchema = getUserSchema(table)
|
$: tableSchema = getUserSchema(table)
|
||||||
$: customSchemaKeys = getCustomSchemaKeys(tableSchema)
|
$: customSchemaKeys = getCustomSchemaKeys(tableSchema)
|
||||||
|
$: if (!row.status) row.status = "active"
|
||||||
|
|
||||||
const getUserSchema = table => {
|
const getUserSchema = table => {
|
||||||
let schema = table?.schema ?? {}
|
let schema = table?.schema ?? {}
|
||||||
|
@ -86,20 +87,18 @@
|
||||||
<!-- Defer rendering this select until roles load, otherwise the initial
|
<!-- Defer rendering this select until roles load, otherwise the initial
|
||||||
selection is always undefined -->
|
selection is always undefined -->
|
||||||
<Select
|
<Select
|
||||||
thin
|
|
||||||
secondary
|
|
||||||
label="Role"
|
label="Role"
|
||||||
data-cy="roleId-select"
|
data-cy="roleId-select"
|
||||||
bind:value={row.roleId}>
|
bind:value={row.roleId}
|
||||||
<option value="">Choose an option</option>
|
options={$roles}
|
||||||
{#each $roles as role}
|
getOptionLabel={role => role.name}
|
||||||
<option value={role._id}>{role.name}</option>
|
getOptionValue={role => role._id} />
|
||||||
{/each}
|
<Select
|
||||||
</Select>
|
label="Status"
|
||||||
<RowFieldControl
|
|
||||||
meta={{ name: 'status', type: 'options', constraints: { inclusion: ['active', 'inactive'] } }}
|
|
||||||
bind:value={row.status}
|
bind:value={row.status}
|
||||||
defaultValue={'active'} />
|
options={[{ label: 'Active', value: 'active' }, { label: 'Inactive', value: 'inactive' }]}
|
||||||
|
getOptionLabel={status => status.label}
|
||||||
|
getOptionValue={status => status.value} />
|
||||||
{#each customSchemaKeys as [key, meta]}
|
{#each customSchemaKeys as [key, meta]}
|
||||||
{#if !meta.autocolumn}
|
{#if !meta.autocolumn}
|
||||||
<RowFieldControl {meta} bind:value={row[key]} {creating} />
|
<RowFieldControl {meta} bind:value={row[key]} {creating} />
|
||||||
|
|
|
@ -201,7 +201,7 @@
|
||||||
|
|
||||||
.field {
|
.field {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: 2fr 4fr 1fr 1fr;
|
||||||
margin-top: var(--spacing-m);
|
margin-top: var(--spacing-m);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-gap: var(--spacing-m);
|
grid-gap: var(--spacing-m);
|
||||||
|
|
|
@ -92,6 +92,7 @@
|
||||||
<ModalContent
|
<ModalContent
|
||||||
title="Create Table"
|
title="Create Table"
|
||||||
confirmText="Create"
|
confirmText="Create"
|
||||||
|
size="large"
|
||||||
onConfirm={saveTable}
|
onConfirm={saveTable}
|
||||||
disabled={error || !name || (dataImport && !dataImport.valid)}>
|
disabled={error || !name || (dataImport && !dataImport.valid)}>
|
||||||
<Input
|
<Input
|
||||||
|
|
|
@ -42,27 +42,18 @@
|
||||||
{:else}
|
{:else}
|
||||||
{#if schema.relationshipType === 'one-to-many'}
|
{#if schema.relationshipType === 'one-to-many'}
|
||||||
<Select
|
<Select
|
||||||
thin
|
value={linkedIds?.[0]}
|
||||||
secondary
|
options={rows}
|
||||||
on:change={e => (linkedIds = e.target.value ? [e.target.value] : [])}
|
getOptionLabel={getPrettyName}
|
||||||
name={label}
|
getOptionValue={row => row._id}
|
||||||
{label}>
|
on:change={e => (linkedIds = e.detail ? [e.detail] : [])}
|
||||||
<option value="">Choose an option</option>
|
{label} />
|
||||||
{#each rows as row}
|
|
||||||
<option selected={row._id === linkedIds[0]} value={row._id}>
|
|
||||||
{getPrettyName(row)}
|
|
||||||
</option>
|
|
||||||
{/each}
|
|
||||||
</Select>
|
|
||||||
{:else}
|
{:else}
|
||||||
<Multiselect
|
<Multiselect
|
||||||
secondary
|
|
||||||
bind:value={linkedIds}
|
bind:value={linkedIds}
|
||||||
{label}
|
{label}
|
||||||
placeholder="Choose some options">
|
options={rows}
|
||||||
{#each rows as row}
|
getOptionLabel={getPrettyName}
|
||||||
<option value={row._id}>{getPrettyName(row)}</option>
|
getOptionValue={row => row._id} />
|
||||||
{/each}
|
|
||||||
</Multiselect>
|
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateAccessRole = event => {
|
const updateAccessRole = event => {
|
||||||
const role = event.target.value
|
const role = event.detail
|
||||||
|
|
||||||
// Select a valid screen with this new role - otherwise we'll not be
|
// Select a valid screen with this new role - otherwise we'll not be
|
||||||
// able to change role at all because ComponentNavigationTree will kick us
|
// able to change role at all because ComponentNavigationTree will kick us
|
||||||
|
@ -80,11 +80,10 @@
|
||||||
secondary
|
secondary
|
||||||
on:change={updateAccessRole}
|
on:change={updateAccessRole}
|
||||||
value={$selectedAccessRole}
|
value={$selectedAccessRole}
|
||||||
label="Filter by Access">
|
label="Filter by Access"
|
||||||
{#each $roles as role}
|
getOptionLabel={role => role.name}
|
||||||
<option value={role._id}>{role.name}</option>
|
getOptionValue={role => role._id}
|
||||||
{/each}
|
options={$roles} />
|
||||||
</Select>
|
|
||||||
<div class="search-screens">
|
<div class="search-screens">
|
||||||
<Input
|
<Input
|
||||||
extraThin
|
extraThin
|
||||||
|
|
Loading…
Reference in a new issue