forked from tsai/budibase
19 changed files with 255 additions and 314 deletions
@ -1,22 +0,0 @@ |
|||||
xcontext('Create a Model', () => { |
|
||||
|
|
||||
before(() => { |
|
||||
cy.visit('localhost:4001/_builder') |
|
||||
// https://on.cypress.io/type
|
|
||||
cy.createApp('Model App', 'Model App Description') |
|
||||
}) |
|
||||
|
|
||||
// https://on.cypress.io/interacting-with-elements
|
|
||||
it('should create a new model', () => { |
|
||||
|
|
||||
cy.createModel('dog', 'name', 'age') |
|
||||
|
|
||||
// Check if model exists
|
|
||||
cy.get('.title').should('have.text', 'dog') |
|
||||
}) |
|
||||
it('should add a record', () => { |
|
||||
cy.addRecord('bob', '15') |
|
||||
|
|
||||
cy.contains('bob').should('have.text', 'bob') |
|
||||
}) |
|
||||
}) |
|
||||
@ -0,0 +1,42 @@ |
|||||
|
xcontext('Create a Table', () => { |
||||
|
|
||||
|
before(() => { |
||||
|
cy.visit('localhost:4001/_builder') |
||||
|
// https://on.cypress.io/type
|
||||
|
cy.createApp('Table App', 'Table App Description') |
||||
|
}) |
||||
|
|
||||
|
// https://on.cypress.io/interacting-with-elements
|
||||
|
it('should create a new Table', () => { |
||||
|
|
||||
|
cy.createTable('dog', 'name', 'age') |
||||
|
|
||||
|
// Check if Table exists
|
||||
|
cy.get('.title').should('have.text', 'dog') |
||||
|
}) |
||||
|
|
||||
|
it('adds a new column to the table', () => { |
||||
|
cy.addRecord('bob', '15') |
||||
|
|
||||
|
cy.contains('bob').should('have.text', 'bob') |
||||
|
}) |
||||
|
|
||||
|
it('updates a column on the table', () => { |
||||
|
cy.addRecord('bob', '15') |
||||
|
|
||||
|
cy.contains('bob').should('have.text', 'bob') |
||||
|
}) |
||||
|
|
||||
|
it('edits a record', () => { |
||||
|
cy.addRecord('bob', '15') |
||||
|
|
||||
|
cy.contains('bob').should('have.text', 'bob') |
||||
|
}) |
||||
|
|
||||
|
it('deletes a record', () => { |
||||
|
cy.addRecord('bob', '15') |
||||
|
|
||||
|
cy.contains('bob').should('have.text', 'bob') |
||||
|
}) |
||||
|
|
||||
|
}) |
||||
@ -0,0 +1,94 @@ |
|||||
|
<script> |
||||
|
import { getContext } from "svelte" |
||||
|
import { backendUiStore } from "builderStore" |
||||
|
import { DropdownMenu, Button, Icon, Input, Select } from "@budibase/bbui" |
||||
|
import { FIELDS } from "constants/backend" |
||||
|
import CreateEditRecord from "../modals/CreateEditRecord.svelte" |
||||
|
import DeleteRecordModal from "../modals/DeleteRecord.svelte" |
||||
|
|
||||
|
const { open, close } = getContext("simple-modal") |
||||
|
|
||||
|
export let row |
||||
|
|
||||
|
let anchor |
||||
|
let dropdown |
||||
|
|
||||
|
let editing |
||||
|
|
||||
|
function showEditor() { |
||||
|
editing = true |
||||
|
} |
||||
|
|
||||
|
function hideEditor() { |
||||
|
dropdown.hide() |
||||
|
editing = false |
||||
|
close() |
||||
|
} |
||||
|
|
||||
|
const deleteRow = () => { |
||||
|
open( |
||||
|
DeleteRecordModal, |
||||
|
{ |
||||
|
onClosed: hideEditor, |
||||
|
record: row, |
||||
|
}, |
||||
|
{ styleContent: { padding: "0" } } |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
function save() {} |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={anchor} on:click={dropdown.show}> |
||||
|
<i class="ri-more-line" /> |
||||
|
</div> |
||||
|
<DropdownMenu bind:this={dropdown} {anchor} align="left"> |
||||
|
{#if editing} |
||||
|
<h4>Edit Row</h4> |
||||
|
<CreateEditRecord onClosed={hideEditor} record={row} /> |
||||
|
{:else} |
||||
|
<ul> |
||||
|
<li on:click={showEditor}> |
||||
|
<Icon name="edit" /> |
||||
|
Edit |
||||
|
</li> |
||||
|
<li on:click={deleteRow}> |
||||
|
<Icon name="delete" /> |
||||
|
Delete |
||||
|
</li> |
||||
|
</ul> |
||||
|
{/if} |
||||
|
</DropdownMenu> |
||||
|
|
||||
|
<style> |
||||
|
h4 { |
||||
|
padding: var(--spacing-l); |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
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); |
||||
|
} |
||||
|
</style> |
||||
@ -1,91 +0,0 @@ |
|||||
<script> |
|
||||
import * as blockDefinitions from "constants/backend" |
|
||||
import { backendUiStore } from "builderStore" |
|
||||
import Block from "components/common/Block.svelte" |
|
||||
|
|
||||
const HEADINGS = [ |
|
||||
{ |
|
||||
title: "Fields", |
|
||||
key: "FIELDS", |
|
||||
}, |
|
||||
{ |
|
||||
title: "Blocks", |
|
||||
key: "BLOCKS", |
|
||||
}, |
|
||||
] |
|
||||
|
|
||||
let selectedTab = "FIELDS" |
|
||||
|
|
||||
function addField(blockDefinition) { |
|
||||
backendUiStore.actions.models.addField(blockDefinition) |
|
||||
backendUiStore.actions.models.fetch() |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<section> |
|
||||
<header> |
|
||||
{#each HEADINGS as tab} |
|
||||
<span |
|
||||
class:selected={selectedTab === tab.key} |
|
||||
on:click={() => (selectedTab = tab.key)}> |
|
||||
{tab.title} |
|
||||
</span> |
|
||||
{/each} |
|
||||
</header> |
|
||||
|
|
||||
<div class="block-grid"> |
|
||||
{#each Object.values(blockDefinitions[selectedTab]) as blockDefinition} |
|
||||
<Block |
|
||||
on:click={() => addField(blockDefinition)} |
|
||||
title={blockDefinition.name} |
|
||||
icon={blockDefinition.icon} /> |
|
||||
{/each} |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<style> |
|
||||
header { |
|
||||
margin-top: 20px; |
|
||||
margin-bottom: 20px; |
|
||||
display: grid; |
|
||||
grid-template-columns: repeat(3, 1fr); |
|
||||
} |
|
||||
|
|
||||
span { |
|
||||
cursor: pointer; |
|
||||
display: grid; |
|
||||
justify-content: center; |
|
||||
align-content: center; |
|
||||
padding: 0px 16px; |
|
||||
height: 36px; |
|
||||
text-align: center; |
|
||||
background: #ffffff; |
|
||||
color: var(--grey-7); |
|
||||
border-radius: 5px; |
|
||||
font-family: inter; |
|
||||
font-size: 14px; |
|
||||
font-weight: 400; |
|
||||
transition: all 0.3s; |
|
||||
text-rendering: optimizeLegibility; |
|
||||
border: none !important; |
|
||||
transition: 0.2s; |
|
||||
outline: none; |
|
||||
} |
|
||||
|
|
||||
span:hover { |
|
||||
color: var(--ink); |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.selected { |
|
||||
background: var(--grey-3); |
|
||||
color: var(--ink); |
|
||||
} |
|
||||
|
|
||||
.block-grid { |
|
||||
margin-top: 20px; |
|
||||
display: grid; |
|
||||
grid-template-columns: 1fr 1fr; |
|
||||
grid-gap: 20px; |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,65 @@ |
|||||
|
<script> |
||||
|
import { backendUiStore } from "builderStore" |
||||
|
import { notifier } from "builderStore/store/notifications" |
||||
|
import { DropdownMenu, Button, Icon, Input, Select } from "@budibase/bbui" |
||||
|
|
||||
|
export let table |
||||
|
|
||||
|
let anchor |
||||
|
let dropdown |
||||
|
let name |
||||
|
|
||||
|
async function saveTable() { |
||||
|
await backendUiStore.actions.models.save({ |
||||
|
name, |
||||
|
schema: {}, |
||||
|
}) |
||||
|
notifier.success(`Table ${name} created successfully.`) |
||||
|
dropdown.hide() |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<div bind:this={anchor}> |
||||
|
<Button primary wide on:click={dropdown.show}>Create New Table</Button> |
||||
|
</div> |
||||
|
<DropdownMenu bind:this={dropdown} {anchor} align="left"> |
||||
|
<div class="container"> |
||||
|
<h4>Create Table</h4> |
||||
|
<Input placeholder="Table Name" thin bind:value={name} /> |
||||
|
</div> |
||||
|
<footer> |
||||
|
<div class="button-margin-3"> |
||||
|
<Button secondary on:click={dropdown.hide}>Cancel</Button> |
||||
|
</div> |
||||
|
<div class="button-margin-4"> |
||||
|
<Button primary on:click={saveTable}>Save</Button> |
||||
|
</div> |
||||
|
</footer> |
||||
|
</DropdownMenu> |
||||
|
|
||||
|
<style> |
||||
|
.container { |
||||
|
padding: var(--spacing-l); |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
footer { |
||||
|
padding: 20px; |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
.button-margin-3 { |
||||
|
grid-column-start: 3; |
||||
|
display: grid; |
||||
|
} |
||||
|
|
||||
|
.button-margin-4 { |
||||
|
grid-column-start: 4; |
||||
|
display: grid; |
||||
|
} |
||||
|
</style> |
||||
@ -1,93 +0,0 @@ |
|||||
<script> |
|
||||
import { backendUiStore } from "builderStore" |
|
||||
import { uuid } from "builderStore/uuid" |
|
||||
import { fade } from "svelte/transition" |
|
||||
import { notifier } from "builderStore/store/notifications" |
|
||||
import { FIELDS, BLOCKS } from "constants/backend" |
|
||||
import Block from "components/common/Block.svelte" |
|
||||
|
|
||||
function addNewField(field) { |
|
||||
backendUiStore.actions.models.addField(field) |
|
||||
} |
|
||||
|
|
||||
function createModel(model) { |
|
||||
const { schema, ...rest } = $backendUiStore.selectedModel |
|
||||
|
|
||||
backendUiStore.actions.models.save({ |
|
||||
model: { |
|
||||
...model, |
|
||||
...rest, |
|
||||
}, |
|
||||
}) |
|
||||
notifier.success(`${model.name} table created.`) |
|
||||
} |
|
||||
</script> |
|
||||
|
|
||||
<section transition:fade> |
|
||||
<header> |
|
||||
<h2>Create New Table</h2> |
|
||||
<p>Before you can view your table, you need to set it up.</p> |
|
||||
</header> |
|
||||
|
|
||||
<div class="block-row"> |
|
||||
<span class="block-row-title">Fields</span> |
|
||||
<p>Blocks are pre-made fields and help you build your table quicker.</p> |
|
||||
<div class="blocks"> |
|
||||
{#each Object.values(FIELDS) as field} |
|
||||
<Block |
|
||||
primary |
|
||||
title={field.name} |
|
||||
icon={field.icon} |
|
||||
on:click={() => addNewField(field)} /> |
|
||||
{/each} |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div class="block-row"> |
|
||||
<span class="block-row-title">Blocks</span> |
|
||||
<p>Blocks are pre-made fields and help you build your table quicker.</p> |
|
||||
<div class="blocks"> |
|
||||
{#each Object.values(BLOCKS) as field} |
|
||||
<Block |
|
||||
secondary |
|
||||
title={field.name} |
|
||||
icon={field.icon} |
|
||||
on:click={() => addNewField(field)} /> |
|
||||
{/each} |
|
||||
</div> |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<style> |
|
||||
section { |
|
||||
height: 100vh; |
|
||||
} |
|
||||
|
|
||||
h2 { |
|
||||
font-size: 20px; |
|
||||
font-weight: bold; |
|
||||
margin: 0; |
|
||||
} |
|
||||
|
|
||||
.block-row-title { |
|
||||
font-weight: 500; |
|
||||
font-size: 16px; |
|
||||
} |
|
||||
|
|
||||
p { |
|
||||
margin-top: 8px; |
|
||||
margin-bottom: 20px; |
|
||||
font-size: 14px; |
|
||||
} |
|
||||
|
|
||||
.block-row { |
|
||||
margin-top: 40px; |
|
||||
} |
|
||||
|
|
||||
.block-row .blocks { |
|
||||
display: grid; |
|
||||
grid-auto-flow: column; |
|
||||
grid-auto-columns: 110px; |
|
||||
grid-gap: 20px; |
|
||||
} |
|
||||
</style> |
|
||||
Loading…
Reference in new issue