1
0
Fork 0
mirror of synced 2024-09-21 11:53:49 +12:00

Add view CRUD and table editing via new UI

This commit is contained in:
Andrew Kingston 2024-08-15 16:33:39 +01:00
parent fa80d99139
commit d313968eaa
No known key found for this signature in database
6 changed files with 66 additions and 46 deletions

View file

@ -9,7 +9,6 @@
import GridAddColumnModal from "components/backend/DataTable/modals/grid/GridCreateColumnModal.svelte" import GridAddColumnModal from "components/backend/DataTable/modals/grid/GridCreateColumnModal.svelte"
import GridCreateEditRowModal from "components/backend/DataTable/modals/grid/GridCreateEditRowModal.svelte" import GridCreateEditRowModal from "components/backend/DataTable/modals/grid/GridCreateEditRowModal.svelte"
import GridEditUserModal from "components/backend/DataTable/modals/grid/GridEditUserModal.svelte" import GridEditUserModal from "components/backend/DataTable/modals/grid/GridEditUserModal.svelte"
import GridCreateViewButton from "components/backend/DataTable/buttons/grid/GridCreateViewButton.svelte"
import GridImportButton from "components/backend/DataTable/buttons/grid/GridImportButton.svelte" import GridImportButton from "components/backend/DataTable/buttons/grid/GridImportButton.svelte"
import GridExportButton from "components/backend/DataTable/buttons/grid/GridExportButton.svelte" import GridExportButton from "components/backend/DataTable/buttons/grid/GridExportButton.svelte"
import GridFilterButton from "components/backend/DataTable/buttons/grid/GridFilterButton.svelte" import GridFilterButton from "components/backend/DataTable/buttons/grid/GridFilterButton.svelte"
@ -77,9 +76,6 @@
<GridFilterButton /> <GridFilterButton />
</svelte:fragment> </svelte:fragment>
<svelte:fragment slot="controls"> <svelte:fragment slot="controls">
{#if !isUsersTable}
<GridCreateViewButton />
{/if}
<GridManageAccessButton /> <GridManageAccessButton />
{#if !isUsersTable} {#if !isUsersTable}
<GridCreateAutomationButton /> <GridCreateAutomationButton />

View file

@ -39,10 +39,8 @@
const selectTable = tableId => { const selectTable = tableId => {
tables.select(tableId) tables.select(tableId)
if (!$isActive("./table/:tableId")) {
$goto(`./table/${tableId}`) $goto(`./table/${tableId}`)
} }
}
function openNode(datasource) { function openNode(datasource) {
toggledDatasources[datasource._id] = true toggledDatasources[datasource._id] = true

View file

@ -1,14 +1,11 @@
<script> <script>
import TableNavItem from "./TableNavItem/TableNavItem.svelte" import TableNavItem from "./TableNavItem/TableNavItem.svelte"
import { alphabetical } from "./utils"
export let tables export let tables
export let selectTable export let selectTable
$: sortedTables = tables.sort(alphabetical) $: sortedTables = tables.sort(alphabetical)
const alphabetical = (a, b) => {
return a.name?.toLowerCase() > b.name?.toLowerCase() ? 1 : -1
}
</script> </script>
<div class="hierarchy-items-container"> <div class="hierarchy-items-container">

View file

@ -66,3 +66,7 @@ export const parseFile = e => {
reader.readAsText(file) reader.readAsText(file)
}) })
} }
export const alphabetical = (a, b) => {
return a.name?.toLowerCase() > b.name?.toLowerCase() ? 1 : -1
}

View file

@ -1,16 +1,21 @@
<script> <script>
import { getContext } from "svelte" import { Modal, Input, notifications, ModalContent } from "@budibase/bbui"
import { Input, notifications, ModalContent } from "@budibase/bbui"
import { goto } from "@roxi/routify" import { goto } from "@roxi/routify"
import { viewsV2 } from "stores/builder" import { viewsV2 } from "stores/builder"
const { filter, sort, definition } = getContext("grid") export let table
let name let name
let modal
$: views = Object.keys($definition?.views || {}).map(x => x.toLowerCase()) $: views = Object.keys(table?.views || {}).map(x => x.toLowerCase())
$: nameExists = views.includes(name?.trim().toLowerCase()) $: nameExists = views.includes(name?.trim().toLowerCase())
export const show = () => {
name = null
modal?.show()
}
const enrichSchema = schema => { const enrichSchema = schema => {
// We need to sure that "visible" is set to true for any fields which have // We need to sure that "visible" is set to true for any fields which have
// not yet been saved with grid metadata attached // not yet been saved with grid metadata attached
@ -28,33 +33,30 @@
try { try {
const newView = await viewsV2.create({ const newView = await viewsV2.create({
name, name,
tableId: $definition._id, tableId: table._id,
query: $filter, schema: enrichSchema(table.schema),
sort: { primaryDisplay: table.primaryDisplay,
field: $sort.column,
order: $sort.order,
},
schema: enrichSchema($definition.schema),
primaryDisplay: $definition.primaryDisplay,
}) })
notifications.success(`View ${name} created`) notifications.success(`View ${name} created`)
$goto(`../../view/v2/${newView.id}`) $goto(`./${newView.id}`)
} catch (error) { } catch (error) {
notifications.error("Error creating view") notifications.error("Error creating view")
} }
} }
</script> </script>
<ModalContent <Modal bind:this={modal}>
<ModalContent
title="Create view" title="Create view"
confirmText="Create view" confirmText="Create view"
onConfirm={saveView} onConfirm={saveView}
disabled={nameExists} disabled={nameExists}
> >
<Input <Input
label="View name" label="View name"
thin thin
bind:value={name} bind:value={name}
error={nameExists ? "A view already exists with that name" : null} error={nameExists ? "A view already exists with that name" : null}
/> />
</ModalContent> </ModalContent>
</Modal>

View file

@ -6,7 +6,7 @@
contextMenuStore, contextMenuStore,
} from "stores/builder" } from "stores/builder"
import IntegrationIcon from "components/backend/DatasourceNavigator/IntegrationIcon.svelte" import IntegrationIcon from "components/backend/DatasourceNavigator/IntegrationIcon.svelte"
import { Icon } from "@budibase/bbui" import { Icon, Button } from "@budibase/bbui"
import { params, url } from "@roxi/routify" import { params, url } from "@roxi/routify"
import EditViewModal from "./EditViewModal.svelte" import EditViewModal from "./EditViewModal.svelte"
import DeleteViewModal from "./DeleteViewModal.svelte" import DeleteViewModal from "./DeleteViewModal.svelte"
@ -16,8 +16,11 @@
import { tick } from "svelte" import { tick } from "svelte"
import { DB_TYPE_EXTERNAL } from "constants/backend" import { DB_TYPE_EXTERNAL } from "constants/backend"
import { TableNames } from "constants" import { TableNames } from "constants"
import { alphabetical } from "components/backend/TableNavigator/utils"
import CreateViewModal from "./CreateViewModal.svelte"
// Editing table // Editing table
let createViewModal
let editTableModal let editTableModal
let deleteTableModal let deleteTableModal
@ -101,10 +104,6 @@
} }
) )
} }
const alphabetical = (a, b) => {
return a.name < b.name ? -1 : 1
}
</script> </script>
<div class="view-nav-bar"> <div class="view-nav-bar">
@ -126,7 +125,13 @@
<UserAvatars size="XS" users={tableSelectedBy} /> <UserAvatars size="XS" users={tableSelectedBy} />
{/if} {/if}
{#if tableEditable} {#if tableEditable}
<Icon on:click={openTableContextMenu} s hoverable name="MoreSmallList" /> <Icon
on:click={openTableContextMenu}
hoverable
name="MoreSmallList"
color="var(--spectrum-global-color-gray-600)"
hoverColor="var(--spectrum-global-color-gray-900)"
/>
{/if} {/if}
</a> </a>
{#each views as view (view.id)} {#each views as view (view.id)}
@ -145,15 +150,33 @@
{/if} {/if}
<Icon <Icon
on:click={e => openViewContextMenu(e, view)} on:click={e => openViewContextMenu(e, view)}
s
hoverable hoverable
name="MoreSmallList" name="MoreSmallList"
color="var(--spectrum-global-color-gray-600)"
hoverColor="var(--spectrum-global-color-gray-900)"
/> />
</a> </a>
{/each} {/each}
{#if !views.length && tableEditable}
<Button cta on:click={createViewModal?.show}>Create a view</Button>
<span>
To create subsets of data, control access and more, create a view.
</span>
{/if}
{#if views.length}
<Icon
name="Add"
size="L"
hoverable
color="var(--spectrum-global-color-gray-600)"
hoverColor="var(--spectrum-global-color-gray-900)"
on:click={createViewModal?.show}
/>
{/if}
</div> </div>
{#if table} {#if table && tableEditable}
<CreateViewModal {table} bind:this={createViewModal} />
<EditTableModal {table} bind:this={editTableModal} /> <EditTableModal {table} bind:this={editTableModal} />
<DeleteTableModal {table} bind:this={deleteTableModal} /> <DeleteTableModal {table} bind:this={deleteTableModal} />
{/if} {/if}
@ -183,7 +206,7 @@
align-items: center; align-items: center;
gap: var(--spacing-m); gap: var(--spacing-m);
transition: background 130ms ease-out, color 130ms ease-out; transition: background 130ms ease-out, color 130ms ease-out;
color: var(--spectrum-global-color-gray-700); color: var(--spectrum-global-color-gray-600);
} }
.title { .title {
font-size: 16px; font-size: 16px;