mirror of https://github.com/Budibase/budibase.git
6 changed files with 0 additions and 280 deletions
@ -1,118 +0,0 @@ |
|||
<script> |
|||
import { backendUiStore } from "builderStore" |
|||
import { Button } from "@budibase/bbui" |
|||
import ButtonGroup from "components/common/ButtonGroup.svelte" |
|||
import NumberBox from "components/common/NumberBox.svelte" |
|||
import ValuesList from "components/common/ValuesList.svelte" |
|||
import ErrorsBox from "components/common/ErrorsBox.svelte" |
|||
import Checkbox from "components/common/Checkbox.svelte" |
|||
import ActionButton from "components/common/ActionButton.svelte" |
|||
import DatePicker from "components/common/DatePicker.svelte" |
|||
import { keys, cloneDeep } from "lodash/fp" |
|||
|
|||
const FIELD_TYPES = ["string", "number", "boolean", "link"] |
|||
|
|||
let field = {} |
|||
|
|||
$: field = |
|||
$backendUiStore.draftModel.schema[$backendUiStore.selectedField] || {} |
|||
$: required = |
|||
field.constraints && |
|||
field.constraints.presence && |
|||
!field.constraints.presence.allowEmpty |
|||
</script> |
|||
|
|||
<div class="info"> |
|||
<div class="field-box"> |
|||
<header>Name</header> |
|||
<input class="budibase__input" type="text" bind:value={field.name} /> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="info"> |
|||
<div class="field-box"> |
|||
<header>Type</header> |
|||
<span>{field.type}</span> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="info"> |
|||
<div class="field"> |
|||
<label>Required</label> |
|||
<input |
|||
type="checkbox" |
|||
bind:checked={required} |
|||
on:change={() => (field.constraints.presence.allowEmpty = required)} /> |
|||
</div> |
|||
|
|||
{#if field.type === 'string'} |
|||
<NumberBox |
|||
label="Max Length" |
|||
bind:value={field.constraints.length.maximum} /> |
|||
<ValuesList label="Categories" bind:values={field.constraints.inclusion} /> |
|||
{:else if field.type === 'datetime'} |
|||
<DatePicker |
|||
label="Min Value" |
|||
bind:value={field.constraints.datetime.earliest} /> |
|||
<DatePicker |
|||
label="Max Value" |
|||
bind:value={field.constraints.datetime.latest} /> |
|||
{:else if field.type === 'number'} |
|||
<NumberBox |
|||
label="Min Value" |
|||
bind:value={field.constraints.numericality.greaterThanOrEqualTo} /> |
|||
<NumberBox |
|||
label="Max Value" |
|||
bind:value={field.constraints.numericality.lessThanOrEqualTo} /> |
|||
{:else if field.type === 'link'} |
|||
<div class="field"> |
|||
<label>Link</label> |
|||
<select class="budibase__input" bind:value={field.modelId}> |
|||
<option value={''} /> |
|||
{#each $backendUiStore.models as model} |
|||
{#if model._id !== $backendUiStore.draftModel._id} |
|||
<option value={model._id}>{model.name}</option> |
|||
{/if} |
|||
{/each} |
|||
</select> |
|||
</div> |
|||
{/if} |
|||
</div> |
|||
|
|||
<style> |
|||
.info { |
|||
margin-bottom: 16px; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
label { |
|||
font-size: 14px; |
|||
font-weight: 500; |
|||
margin-bottom: 8px; |
|||
} |
|||
|
|||
.field { |
|||
display: grid; |
|||
align-items: center; |
|||
margin-bottom: 16px; |
|||
} |
|||
|
|||
.field-box header { |
|||
font-size: 14px; |
|||
font-weight: 500; |
|||
margin-bottom: 8px; |
|||
} |
|||
|
|||
.field-box span { |
|||
background: var(--grey-2); |
|||
color: var(--grey-6); |
|||
font-weight: 400; |
|||
height: 36px; |
|||
display: grid; |
|||
align-items: center; |
|||
padding-left: 12px; |
|||
text-transform: capitalize; |
|||
border-radius: 5px; |
|||
cursor: not-allowed; |
|||
} |
|||
</style> |
|||
@ -1,156 +0,0 @@ |
|||
<script> |
|||
import { getContext, onMount } from "svelte" |
|||
import { Button, Switcher } from "@budibase/bbui" |
|||
import { notifier } from "builderStore/store/notifications" |
|||
import { store, backendUiStore } from "builderStore" |
|||
import api from "builderStore/api" |
|||
import ModelFieldEditor from "./ModelFieldEditor.svelte" |
|||
|
|||
const { open, close } = getContext("simple-modal") |
|||
|
|||
const ITEMS = [ |
|||
{ |
|||
title: "Setup", |
|||
key: "SETUP", |
|||
}, |
|||
{ |
|||
title: "Delete", |
|||
key: "DELETE", |
|||
}, |
|||
] |
|||
|
|||
let edited = false |
|||
|
|||
$: selectedTab = $backendUiStore.tabs.SETUP_PANEL |
|||
|
|||
$: edited = |
|||
$backendUiStore.selectedField || |
|||
($backendUiStore.draftModel && |
|||
$backendUiStore.draftModel.name !== $backendUiStore.selectedModel.name) |
|||
|
|||
async function deleteModel() { |
|||
const model = $backendUiStore.selectedModel |
|||
const field = $backendUiStore.selectedField |
|||
|
|||
if (field) { |
|||
const name = model.schema[field].name |
|||
delete model.schema[field] |
|||
backendUiStore.actions.models.save(model) |
|||
notifier.danger(`Field ${name} deleted.`) |
|||
return |
|||
} |
|||
|
|||
const DELETE_MODEL_URL = `/api/models/${model._id}/${model._rev}` |
|||
const response = await api.delete(DELETE_MODEL_URL) |
|||
backendUiStore.update(state => { |
|||
state.selectedView = null |
|||
state.selectedModel = {} |
|||
state.draftModel = {} |
|||
state.models = state.models.filter(({ _id }) => _id !== model._id) |
|||
notifier.danger(`${model.name} deleted successfully.`) |
|||
return state |
|||
}) |
|||
} |
|||
|
|||
function validate() { |
|||
let errors = [] |
|||
for (let field of Object.values($backendUiStore.draftModel.schema)) { |
|||
const restrictedFieldNames = ["type", "modelId"] |
|||
if (field.name.startsWith("_")) { |
|||
errors.push(`field '${field.name}' - name cannot begin with '_''`) |
|||
} else if (restrictedFieldNames.includes(field.name)) { |
|||
errors.push( |
|||
`field '${field.name}' - is a restricted name, please rename` |
|||
) |
|||
} else if (!field.name || !field.name.trim()) { |
|||
errors.push("field name cannot be blank") |
|||
} |
|||
} |
|||
|
|||
if (!$backendUiStore.draftModel.name) { |
|||
errors.push("Table name cannot be blank") |
|||
} |
|||
|
|||
return errors |
|||
} |
|||
|
|||
async function saveModel() { |
|||
const errors = validate() |
|||
if (errors.length > 0) { |
|||
notifier.danger(errors.join("/n")) |
|||
return |
|||
} |
|||
|
|||
await backendUiStore.actions.models.save($backendUiStore.draftModel) |
|||
notifier.success( |
|||
"Success! Your changes have been saved. Please continue on with your greatness." |
|||
) |
|||
} |
|||
</script> |
|||
|
|||
<div class="items-root"> |
|||
<Switcher headings={ITEMS} bind:value={$backendUiStore.tabs.SETUP_PANEL}> |
|||
{#if selectedTab === 'SETUP'} |
|||
{#if $backendUiStore.selectedField} |
|||
<ModelFieldEditor /> |
|||
{:else if $backendUiStore.draftModel.schema} |
|||
<div class="titled-input"> |
|||
<header>Name</header> |
|||
<input |
|||
data-cy="table-name-input" |
|||
type="text" |
|||
class="budibase__input" |
|||
bind:value={$backendUiStore.draftModel.name} /> |
|||
</div> |
|||
<!-- dont have this capability yet.. |
|||
<div class="titled-input"> |
|||
<header>Import Data</header> |
|||
<Button wide secondary>Import CSV</Button> |
|||
</div> |
|||
--> |
|||
{/if} |
|||
<footer> |
|||
<Button disabled={!edited} green={edited} wide on:click={saveModel}> |
|||
Save |
|||
</Button> |
|||
</footer> |
|||
{:else if selectedTab === 'DELETE'} |
|||
<div class="titled-input"> |
|||
<header>Danger Zone</header> |
|||
<Button red wide on:click={deleteModel}>Delete</Button> |
|||
</div> |
|||
{/if} |
|||
</Switcher> |
|||
</div> |
|||
|
|||
<style> |
|||
header { |
|||
font-weight: 500; |
|||
} |
|||
|
|||
footer { |
|||
width: 260px; |
|||
position: fixed; |
|||
bottom: 20px; |
|||
} |
|||
|
|||
.items-root { |
|||
padding: 20px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
max-height: 100%; |
|||
height: 100%; |
|||
background-color: var(--white); |
|||
} |
|||
|
|||
.titled-input { |
|||
margin-bottom: 16px; |
|||
display: grid; |
|||
} |
|||
|
|||
.titled-input header { |
|||
display: block; |
|||
font-size: 14px; |
|||
margin-bottom: 8px; |
|||
} |
|||
</style> |
|||
@ -1 +0,0 @@ |
|||
export { default as ModelSetupNav } from "./ModelSetupNav.svelte" |
|||
Loading…
Reference in new issue