creating rows and columns working
This commit is contained in:
parent
9e00550eda
commit
10d798fe62
|
@ -57,7 +57,7 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "^1.18.0",
|
||||
"@budibase/bbui": "^1.22.3",
|
||||
"@budibase/client": "^0.1.1",
|
||||
"@budibase/colorpicker": "^1.0.1",
|
||||
"@nx-js/compiler-util": "^2.0.0",
|
||||
|
@ -96,6 +96,7 @@
|
|||
"cypress-terminal-report": "^1.4.1",
|
||||
"eslint-plugin-cypress": "^2.11.1",
|
||||
"http-proxy-middleware": "^0.19.1",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^24.8.0",
|
||||
"ncp": "^2.0.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
|
|
|
@ -61,7 +61,6 @@ export const getBackendUiStore = () => {
|
|||
state.draftModel = cloneDeep(model)
|
||||
state.selectedField = ""
|
||||
state.selectedView = `all_${model._id}`
|
||||
state.tabs.SETUP_PANEL = "SETUP"
|
||||
return state
|
||||
}),
|
||||
save: async ({ model }) => {
|
||||
|
@ -95,7 +94,6 @@ export const getBackendUiStore = () => {
|
|||
[field.name]: cloneDeep(field),
|
||||
}
|
||||
state.selectedField = field.name
|
||||
state.tabs.NAVIGATION_PANEL = "NAVIGATE"
|
||||
|
||||
return state
|
||||
})
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
<script>
|
||||
import { onMount, getContext } from "svelte"
|
||||
import { store, backendUiStore } from "builderStore"
|
||||
import { Button } from "@budibase/bbui"
|
||||
import { Button, Icon } from "@budibase/bbui"
|
||||
import Select from "components/common/Select.svelte"
|
||||
import ActionButton from "components/common/ActionButton.svelte"
|
||||
import LinkedRecord from "./LinkedRecord.svelte"
|
||||
import TablePagination from "./TablePagination.svelte"
|
||||
import { DeleteRecordModal, CreateEditRecordModal } from "./modals"
|
||||
import RowPopover from "./popovers/Row.svelte"
|
||||
import ColumnPopover from "./popovers/Column.svelte"
|
||||
import ColumnHeaderPopover from "./popovers/ColumnHeader.svelte"
|
||||
import * as api from "./api"
|
||||
|
||||
const { open, close } = getContext("simple-modal")
|
||||
|
@ -43,6 +46,7 @@
|
|||
let views = []
|
||||
let currentPage = 0
|
||||
let search
|
||||
let dropdownLeft
|
||||
|
||||
$: {
|
||||
if ($backendUiStore.selectedView) {
|
||||
|
@ -85,16 +89,26 @@
|
|||
<section>
|
||||
<div class="table-controls">
|
||||
<h2 class="title">{$backendUiStore.selectedModel.name}</h2>
|
||||
<Button primary on:click={createNewRecord}>
|
||||
<span class="button-inner">Create New Record</span>
|
||||
</Button>
|
||||
<div class="popovers">
|
||||
<!-- <Button text small on:click={() => alert('Clicked!')}>
|
||||
<Icon name="view" />
|
||||
Create New View
|
||||
</Button> -->
|
||||
<ColumnPopover />
|
||||
<RowPopover />
|
||||
</div>
|
||||
</div>
|
||||
<table class="uk-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Edit</th>
|
||||
<th>
|
||||
<div>Edit</div>
|
||||
</th>
|
||||
{#each headers as header}
|
||||
<th>{$backendUiStore.selectedModel.schema[header].name}</th>
|
||||
<th>
|
||||
<ColumnHeaderPopover
|
||||
field={$backendUiStore.selectedModel.schema[header]} />
|
||||
</th>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -103,7 +117,7 @@
|
|||
<div class="no-data">No Data.</div>
|
||||
{/if}
|
||||
{#each paginatedData as row}
|
||||
<tr class="hoverable">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="uk-inline">
|
||||
<i class="ri-more-line" />
|
||||
|
@ -128,10 +142,10 @@
|
|||
</div>
|
||||
</td>
|
||||
{#each headers as header}
|
||||
<td>
|
||||
<td class="hoverable">
|
||||
{#if schema[header].type === 'link'}
|
||||
<LinkedRecord field={schema[header]} ids={row[header]} />
|
||||
{:else}{row[header]}{/if}
|
||||
{:else}{row[header] || ''}{/if}
|
||||
</td>
|
||||
{/each}
|
||||
</tr>
|
||||
|
@ -164,7 +178,8 @@
|
|||
}
|
||||
|
||||
thead {
|
||||
background: var(--blue-light);
|
||||
height: 40px;
|
||||
background: var(--grey-3);
|
||||
border: 1px solid var(--grey-4);
|
||||
}
|
||||
|
||||
|
@ -174,6 +189,23 @@
|
|||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
text-rendering: optimizeLegibility;
|
||||
transition: 0.5s all;
|
||||
}
|
||||
|
||||
/* thead th div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
} */
|
||||
|
||||
th:hover {
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
td {
|
||||
max-width: 200px;
|
||||
text-overflow: ellipsis;
|
||||
border: 1px solid var(--grey-4);
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
|
@ -188,10 +220,11 @@
|
|||
}
|
||||
|
||||
.table-controls {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.popovers {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.ri-more-line:hover,
|
||||
|
@ -203,11 +236,6 @@
|
|||
padding: 20px;
|
||||
}
|
||||
|
||||
.button-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -1,165 +0,0 @@
|
|||
<script>
|
||||
import { tick } from "svelte"
|
||||
import Textbox from "components/common/Textbox.svelte"
|
||||
import Button from "components/common/Button.svelte"
|
||||
import Select from "components/common/Select.svelte"
|
||||
import ActionButton from "components/common/ActionButton.svelte"
|
||||
import getIcon from "components/common/icon"
|
||||
import FieldView from "./FieldView.svelte"
|
||||
import api from "builderStore/api"
|
||||
import { store, backendUiStore } from "builderStore"
|
||||
import { pipe } from "components/common/core"
|
||||
import ErrorsBox from "components/common/ErrorsBox.svelte"
|
||||
|
||||
export let model = { schema: {} }
|
||||
export let onClosed
|
||||
|
||||
let showFieldView = false
|
||||
let fieldToEdit
|
||||
|
||||
$: modelFields = model.schema ? Object.entries(model.schema) : []
|
||||
|
||||
function editField() {}
|
||||
|
||||
function deleteField() {}
|
||||
|
||||
function onFinishedFieldEdit() {}
|
||||
|
||||
async function saveModel() {
|
||||
const SAVE_MODEL_URL = `/api/models`
|
||||
const response = await api.post(SAVE_MODEL_URL, model)
|
||||
const newModel = await response.json()
|
||||
backendUiStore.actions.models.create(newModel)
|
||||
onClosed()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="heading">
|
||||
{#if !showFieldView}
|
||||
<i class="ri-list-settings-line button--toggled" />
|
||||
<h3 class="budibase__title--3">Create / Edit Table</h3>
|
||||
{:else}
|
||||
<i class="ri-file-list-line button--toggled" />
|
||||
<h3 class="budibase__title--3">Create / Edit Field</h3>
|
||||
{/if}
|
||||
</div>
|
||||
{#if !showFieldView}
|
||||
<div class="padding">
|
||||
{#if $store.errors && $store.errors.length > 0}
|
||||
<ErrorsBox errors={$store.errors} />
|
||||
{/if}
|
||||
<div class="textbox">
|
||||
<Textbox label="Name" bind:text={model.name} />
|
||||
</div>
|
||||
<div class="table-controls">
|
||||
<span class="label">Fields</span>
|
||||
<div
|
||||
data-cy="add-new-model-field"
|
||||
class="hoverable new-field"
|
||||
on:click={() => (showFieldView = true)}>
|
||||
Add new field
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="uk-table fields-table budibase__table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Edit</th>
|
||||
<th>Name</th>
|
||||
<th>Type</th>
|
||||
<th />
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each modelFields as [key, meta]}
|
||||
<tr>
|
||||
<td>
|
||||
<i class="ri-more-line" on:click={() => editField(meta)} />
|
||||
</td>
|
||||
<td>
|
||||
<div>{key}</div>
|
||||
</td>
|
||||
<td>{meta.type}</td>
|
||||
<td>
|
||||
<i
|
||||
class="ri-delete-bin-6-line hoverable"
|
||||
on:click={() => deleteField(meta)} />
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<footer>
|
||||
<ActionButton color="secondary" on:click={saveModel}>Save</ActionButton>
|
||||
</footer>
|
||||
</div>
|
||||
{:else}
|
||||
<FieldView
|
||||
field={fieldToEdit}
|
||||
onFinished={onFinishedFieldEdit}
|
||||
schema={model.schema}
|
||||
goBack={() => (showFieldView = false)} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.padding {
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.textbox {
|
||||
margin: 0px 40px 0px 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.new-field {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
.fields-table {
|
||||
margin: 8px 40px 0px 40px;
|
||||
border-collapse: collapse;
|
||||
width: 88%;
|
||||
}
|
||||
|
||||
tbody > tr:hover {
|
||||
background-color: var(--grey-1);
|
||||
}
|
||||
|
||||
.table-controls {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 0px 40px;
|
||||
}
|
||||
|
||||
.ri-more-line:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.heading {
|
||||
padding: 40px 40px 0 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 0 0 10px;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: var(--grey-1);
|
||||
margin-top: 40px;
|
||||
padding: 20px 40px 20px 40px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
|
@ -68,10 +68,7 @@
|
|||
</script>
|
||||
|
||||
<div class="actions">
|
||||
<header>
|
||||
<i class="ri-file-user-fill" />
|
||||
<h4>Create / Edit Record</h4>
|
||||
</header>
|
||||
<h5>Add New Row</h5>
|
||||
<ErrorsBox {errors} />
|
||||
<form on:submit|preventDefault class="uk-form-stacked">
|
||||
{#each modelSchema as [key, meta]}
|
||||
|
@ -97,40 +94,11 @@
|
|||
<Button secondary on:click={onClosed}>Cancel</Button>
|
||||
</div>
|
||||
<div class="button-margin-4">
|
||||
<Button blue on:click={saveRecord}>Save</Button>
|
||||
<Button primary on:click={saveRecord}>Save</Button>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
header {
|
||||
margin-bottom: 40px;
|
||||
display: grid;
|
||||
grid-gap: 20px;
|
||||
grid-template-columns: 40px 1fr;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
i {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--blue-light);
|
||||
color: var(--grey-7);
|
||||
font-size: 20px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
display: inline-block;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
font-family: sans-serif;
|
||||
color: var(--ink);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.actions {
|
||||
padding: 30px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { Input, TextArea, Button, Select } from "@budibase/bbui"
|
||||
import { store, backendUiStore } from "builderStore"
|
||||
import { FIELDS } from "constants/backend"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import Dropdown from "components/common/Dropdown.svelte"
|
||||
import Textbox from "components/common/Textbox.svelte"
|
||||
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 LinkedRecordSelector from "components/common/LinkedRecordSelector.svelte"
|
||||
import * as api from "../api"
|
||||
|
||||
export let onClosed
|
||||
export let field = {}
|
||||
export let columnName
|
||||
|
||||
$: required =
|
||||
field.constraints &&
|
||||
field.constraints.presence &&
|
||||
!field.constraints.presence.allowEmpty
|
||||
$: if (field.type) {
|
||||
field.constraints = FIELDS[field.type.toUpperCase()].constraints
|
||||
}
|
||||
|
||||
function closed() {
|
||||
onClosed()
|
||||
}
|
||||
|
||||
async function saveColumn() {
|
||||
backendUiStore.actions.models.addField({
|
||||
name: columnName,
|
||||
field,
|
||||
})
|
||||
|
||||
backendUiStore.actions.models.save({
|
||||
model: $backendUiStore.draftModel,
|
||||
})
|
||||
onClosed()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="actions">
|
||||
<Input placeholder="Name" thin bind:value={columnName} />
|
||||
|
||||
<Select secondary thin bind:value={field.type}>
|
||||
{#each Object.values(FIELDS) as field}
|
||||
<option value={field.type}>{field.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
|
||||
<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>
|
||||
|
||||
</div>
|
||||
<footer>
|
||||
<div class="button-margin-3">
|
||||
<Button secondary on:click={onClosed}>Cancel</Button>
|
||||
</div>
|
||||
<div class="button-margin-4">
|
||||
<Button primary on:click={saveColumn}>Save Column</Button>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
.actions {
|
||||
padding: 20px;
|
||||
display: grid;
|
||||
grid-gap: var(--spacing-xl);
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 20px 30px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
gap: 20px;
|
||||
background: var(--grey-1);
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.field {
|
||||
margin-top: var(--spacing-xl);
|
||||
margin-bottom: var(--spacing-xl);
|
||||
}
|
||||
|
||||
.button-margin-3 {
|
||||
grid-column-start: 3;
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.button-margin-4 {
|
||||
grid-column-start: 4;
|
||||
display: grid;
|
||||
}
|
||||
</style>
|
|
@ -1,18 +1,13 @@
|
|||
<script>
|
||||
import { Input, Select } from "@budibase/bbui"
|
||||
|
||||
export let type = "text"
|
||||
export let value = ""
|
||||
export let label
|
||||
export let errors = []
|
||||
export let options = []
|
||||
|
||||
let checked = type === "checkbox" ? value : false
|
||||
|
||||
const determineClassName = type => {
|
||||
if (type === "checkbox") return "uk-checkbox"
|
||||
if (type === "select") return "uk-select"
|
||||
return "uk-input"
|
||||
}
|
||||
|
||||
const handleInput = event => {
|
||||
if (event.target.type === "checkbox") {
|
||||
value = event.target.checked
|
||||
|
@ -28,40 +23,21 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<label>{label}</label>
|
||||
|
||||
{#if type === 'select'}
|
||||
<select
|
||||
data-cy="{label}-select"
|
||||
class={determineClassName(type)}
|
||||
bind:value
|
||||
class:uk-form-danger={errors.length > 0}>
|
||||
<Select data-cy="{label}-select" bind:value>
|
||||
<option />
|
||||
{#each options as opt}
|
||||
<option value={opt}>{opt}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</Select>
|
||||
{:else}
|
||||
<input
|
||||
<Input
|
||||
thin
|
||||
placeholder={label}
|
||||
data-cy="{label}-input"
|
||||
class={determineClassName(type)}
|
||||
class:uk-form-danger={errors.length > 0}
|
||||
{checked}
|
||||
{type}
|
||||
{value}
|
||||
on:input={handleInput}
|
||||
on:change={handleInput} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
label {
|
||||
display: block;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
input {
|
||||
color: var(--dark-grey);
|
||||
}
|
||||
</style>
|
||||
{/if}
|
|
@ -0,0 +1,38 @@
|
|||
import "@testing-library/jest-dom/extend-expect"
|
||||
import { render, fireEvent } from "@testing-library/svelte"
|
||||
import CreateEditTable from "../CreateEditTable.svelte";
|
||||
|
||||
const testField = {
|
||||
field: {},
|
||||
name: "Yeet"
|
||||
};
|
||||
|
||||
describe("<CreateEditTable />", () => {
|
||||
|
||||
describe("New Column", () => {
|
||||
it("shows proper heading when rendered", () => {
|
||||
const { getByText } = render(CreateEditTable, { name: 'World' })
|
||||
|
||||
expect(getByText('Hello World!')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
describe("Edit Existing Column", () => {
|
||||
const { getByText } = render(CreateEditTable, testField)
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
|
||||
// // Note: This is as an async test as we are using `fireEvent`
|
||||
// test('changes button text on click', async () => {
|
||||
// const { getByText } = render(Comp, { name: 'World' })
|
||||
// const button = getByText('Button')
|
||||
|
||||
// // Using await when firing events is unique to the svelte testing library because
|
||||
// // we have to wait for the next `tick` so that Svelte flushes all pending state changes.
|
||||
// await fireEvent.click(button)
|
||||
|
||||
// expect(button).toHaveTextContent('Button Clicked')
|
||||
// })
|
|
@ -0,0 +1,25 @@
|
|||
<script>
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { DropdownMenu, Button, Icon, Input, Select } from "@budibase/bbui"
|
||||
import { FIELDS } from "constants/backend"
|
||||
import { ModelSetupNav } from "components/nav/ModelSetupNav"
|
||||
import ModelFieldEditor from "components/nav/ModelSetupNav/ModelFieldEditor.svelte"
|
||||
import CreateEditTable from "../modals/CreateEditTable.svelte"
|
||||
|
||||
let anchor
|
||||
let dropdown
|
||||
let fieldName
|
||||
</script>
|
||||
|
||||
<div bind:this={anchor}>
|
||||
<Button text small on:click={dropdown.show}>
|
||||
<Icon name="addcolumn" />
|
||||
Create New Column
|
||||
</Button>
|
||||
</div>
|
||||
<DropdownMenu bind:this={dropdown} {anchor} align="left">
|
||||
<CreateEditTable onClosed={dropdown.hide} />
|
||||
</DropdownMenu>
|
||||
|
||||
<style>
|
||||
</style>
|
|
@ -0,0 +1,114 @@
|
|||
<script>
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { DropdownMenu, Button, Icon, Input, Select } from "@budibase/bbui"
|
||||
import { FIELDS } from "constants/backend"
|
||||
import { ModelSetupNav } from "components/nav/ModelSetupNav"
|
||||
import ModelFieldEditor from "components/nav/ModelSetupNav/ModelFieldEditor.svelte"
|
||||
import CreateEditTable from "../modals/CreateEditTable.svelte"
|
||||
|
||||
export let field
|
||||
|
||||
let anchor
|
||||
let dropdown
|
||||
|
||||
let editing
|
||||
|
||||
function showEditor() {
|
||||
editing = true
|
||||
}
|
||||
|
||||
function hideEditor() {
|
||||
dropdown.hide()
|
||||
editing = false
|
||||
}
|
||||
|
||||
function deleteField() {
|
||||
alert("Delete Field Not Implemented")
|
||||
}
|
||||
|
||||
function save() {}
|
||||
</script>
|
||||
|
||||
<div bind:this={anchor} on:click={dropdown.show}>
|
||||
{field.name}
|
||||
<Icon name="arrowdown" />
|
||||
</div>
|
||||
<DropdownMenu bind:this={dropdown} {anchor} align="left">
|
||||
{#if editing}
|
||||
<h5>Edit Column</h5>
|
||||
<CreateEditTable
|
||||
onClosed={dropdown.hide}
|
||||
field={field.field}
|
||||
columnName={field.name} />
|
||||
{:else}
|
||||
<ul>
|
||||
<li on:click={showEditor}>
|
||||
<Icon name="edit" />
|
||||
Edit
|
||||
</li>
|
||||
<li on:click={deleteField}>
|
||||
<Icon name="delete" />
|
||||
Delete
|
||||
</li>
|
||||
<li>
|
||||
<Icon name="sortascending" />
|
||||
Sort A - Z
|
||||
</li>
|
||||
<li>
|
||||
<Icon name="sortdescending" />
|
||||
Sort Z - A
|
||||
</li>
|
||||
</ul>
|
||||
{/if}
|
||||
</DropdownMenu>
|
||||
|
||||
<style>
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
padding: var(--spacing-s) 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
font-family: var(--font-sans);
|
||||
font-size: var(--font-size-xs);
|
||||
color: var(--ink);
|
||||
padding: var(--spacing-s) var(--spacing-m);
|
||||
margin: auto 0px;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
li:hover {
|
||||
background-color: var(--grey-2);
|
||||
}
|
||||
|
||||
li:active {
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
.editor {
|
||||
padding: var(--spacing-xl);
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: var(--spacing-xl);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
gap: 20px;
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
}
|
||||
|
||||
.button-margin-3 {
|
||||
grid-column-start: 3;
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.button-margin-4 {
|
||||
grid-column-start: 4;
|
||||
display: grid;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,21 @@
|
|||
<script>
|
||||
import { DropdownMenu, Button, Icon } from "@budibase/bbui"
|
||||
import CreateEditRecord from "../modals/CreateEditRecord.svelte"
|
||||
|
||||
let anchor
|
||||
let dropdown
|
||||
</script>
|
||||
|
||||
<div bind:this={anchor}>
|
||||
<Button text small on:click={dropdown.show}>
|
||||
<Icon name="addrow" />
|
||||
Create New Row
|
||||
</Button>
|
||||
</div>
|
||||
<DropdownMenu bind:this={dropdown} anchor={anchor} align="left">
|
||||
<CreateEditRecord onClosed={dropdown.hide} />
|
||||
</DropdownMenu>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -3,7 +3,7 @@
|
|||
import { uuid } from "builderStore/uuid"
|
||||
import { fade } from "svelte/transition"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import { FIELDS, BLOCKS, MODELS } from "constants/backend"
|
||||
import { FIELDS, BLOCKS } from "constants/backend"
|
||||
import Block from "components/common/Block.svelte"
|
||||
|
||||
function addNewField(field) {
|
||||
|
@ -56,20 +56,6 @@
|
|||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="block-row">
|
||||
<span class="block-row-title">Tables</span>
|
||||
<p>Blocks are pre-made fields and help you build your table quicker.</p>
|
||||
<div class="blocks">
|
||||
{#each Object.values(MODELS) as model}
|
||||
<Block
|
||||
tertiary
|
||||
title={model.name}
|
||||
icon={model.icon}
|
||||
on:click={() => createModel(model)} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -12,7 +12,11 @@
|
|||
|
||||
let HEADINGS = [
|
||||
{
|
||||
title: "Navigate",
|
||||
title: "Tables",
|
||||
key: "TABLES",
|
||||
},
|
||||
{
|
||||
title: "Tables",
|
||||
key: "NAVIGATE",
|
||||
},
|
||||
{
|
||||
|
@ -38,7 +42,6 @@
|
|||
backendUiStore.update(state => {
|
||||
state.selectedModel = {}
|
||||
state.draftModel = { schema: {} }
|
||||
state.tabs.SETUP_PANEL = "SETUP"
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
@ -62,18 +65,6 @@
|
|||
title={model.name}
|
||||
icon="ri-table-fill"
|
||||
on:click={() => selectModel(model)} />
|
||||
{#if model._id === $backendUiStore.selectedModel._id}
|
||||
<div in:slide>
|
||||
{#each Object.keys(model.schema) as fieldName}
|
||||
<ListItem
|
||||
selected={model._id === $backendUiStore.selectedModel._id && fieldName === $backendUiStore.selectedField}
|
||||
indented
|
||||
icon="ri-layout-column-line"
|
||||
title={model.schema[fieldName].name}
|
||||
on:click={() => selectModel(model, fieldName)} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{:else if selectedTab === 'ADD'}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export const FIELDS = {
|
||||
PLAIN_TEXT: {
|
||||
STRING: {
|
||||
name: "Plain Text",
|
||||
icon: "ri-text",
|
||||
type: "string",
|
||||
|
@ -194,37 +194,4 @@ export const BLOCKS = {
|
|||
// presence: { allowEmpty: true },
|
||||
// },
|
||||
// },
|
||||
}
|
||||
|
||||
export const MODELS = {
|
||||
CONTACTS: {
|
||||
icon: "ri-contacts-book-line",
|
||||
name: "Contacts",
|
||||
schema: {
|
||||
Name: BLOCKS.NAME,
|
||||
"Phone Number": BLOCKS.PHONE_NUMBER,
|
||||
},
|
||||
},
|
||||
RECIPES: {
|
||||
icon: "ri-link",
|
||||
name: "Recipes",
|
||||
schema: {
|
||||
Name: BLOCKS.NAME,
|
||||
Cuisine: {
|
||||
...FIELDS.PLAIN_TEXT,
|
||||
name: "Cuisine",
|
||||
},
|
||||
},
|
||||
},
|
||||
SPORTS_TEAM: {
|
||||
icon: "ri-basketball-line",
|
||||
name: "Sports Team",
|
||||
schema: {
|
||||
Name: BLOCKS.NAME,
|
||||
Championships: {
|
||||
...FIELDS.NUMBER,
|
||||
name: "Championships",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
|
@ -14,16 +14,13 @@
|
|||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
<div class="nav">
|
||||
<ModelSetupNav />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 300px minmax(0, 1fr) 300px;
|
||||
grid-template-columns: 300px minmax(0, 1fr);
|
||||
background: var(--grey-1);
|
||||
line-height: 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue