1
0
Fork 0
mirror of synced 2024-07-28 09:35:49 +12:00

Merge pull request #5315 from Budibase/data-ui-empty-states

Data UI empty states
This commit is contained in:
Andrew Kingston 2022-04-22 10:48:28 +01:00 committed by GitHub
commit 1614f88087
10 changed files with 186 additions and 54 deletions

View file

@ -80,8 +80,4 @@
.active svg { .active svg {
color: var(--spectrum-global-color-blue-600); color: var(--spectrum-global-color-blue-600);
} }
.spectrum-ActionButton-label {
padding-bottom: 2px;
}
</style> </style>

View file

@ -36,6 +36,7 @@
export let disableSorting = false export let disableSorting = false
export let autoSortColumns = true export let autoSortColumns = true
export let compact = false export let compact = false
export let customPlaceholder = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
@ -387,13 +388,24 @@
</div> </div>
{/each} {/each}
{:else} {:else}
<div class="placeholder" class:placeholder--no-fields={!fields?.length}> <div
class="placeholder"
class:placeholder--custom={customPlaceholder}
class:placeholder--no-fields={!fields?.length}
>
{#if customPlaceholder}
<slot name="placeholder" />
{:else}
<div class="placeholder-content"> <div class="placeholder-content">
<svg class="spectrum-Icon spectrum-Icon--sizeXXL" focusable="false"> <svg
class="spectrum-Icon spectrum-Icon--sizeXXL"
focusable="false"
>
<use xlink:href="#spectrum-icon-18-Table" /> <use xlink:href="#spectrum-icon-18-Table" />
</svg> </svg>
<div>No rows found</div> <div>No rows found</div>
</div> </div>
{/if}
</div> </div>
{/if} {/if}
</div> </div>
@ -458,6 +470,13 @@
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
user-select: none; user-select: none;
border-top: var(--table-border);
}
.spectrum-Table-headCell:first-of-type {
border-left: var(--table-border);
}
.spectrum-Table-headCell:last-of-type {
border-right: var(--table-border);
} }
.spectrum-Table-headCell--alignCenter { .spectrum-Table-headCell--alignCenter {
justify-content: center; justify-content: center;
@ -576,16 +595,19 @@
border-top: none; border-top: none;
grid-column: 1 / -1; grid-column: 1 / -1;
background-color: var(--table-bg); background-color: var(--table-bg);
padding: 40px;
} }
.placeholder--no-fields { .placeholder--no-fields {
border-top: var(--table-border); border-top: var(--table-border);
} }
.placeholder--custom {
justify-content: flex-start;
}
.wrapper--quiet .placeholder { .wrapper--quiet .placeholder {
border-left: none; border-left: none;
border-right: none; border-right: none;
} }
.placeholder-content { .placeholder-content {
padding: 40px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;

View file

@ -14,7 +14,7 @@
import Table from "./Table.svelte" import Table from "./Table.svelte"
import { TableNames } from "constants" import { TableNames } from "constants"
import CreateEditRow from "./modals/CreateEditRow.svelte" import CreateEditRow from "./modals/CreateEditRow.svelte"
import { Pagination } from "@budibase/bbui" import { Pagination, Heading, Body, Layout } from "@budibase/bbui"
import { fetchData } from "@budibase/frontend-core" import { fetchData } from "@budibase/frontend-core"
import { API } from "api" import { API } from "api"
@ -27,6 +27,8 @@
$: enrichedSchema = enrichSchema($tables.selected?.schema) $: enrichedSchema = enrichSchema($tables.selected?.schema)
$: id = $tables.selected?._id $: id = $tables.selected?._id
$: fetch = createFetch(id) $: fetch = createFetch(id)
$: hasCols = checkHasCols(schema)
$: hasRows = !!$fetch.rows?.length
const enrichSchema = schema => { const enrichSchema = schema => {
let tempSchema = { ...schema } let tempSchema = { ...schema }
@ -47,6 +49,20 @@
return tempSchema return tempSchema
} }
const checkHasCols = schema => {
if (!schema || Object.keys(schema).length === 0) {
return false
}
let fields = Object.values(schema)
for (let field of fields) {
if (!field.autocolumn) {
return true
}
}
return false
}
// Fetches new data whenever the table changes // Fetches new data whenever the table changes
const createFetch = tableId => { const createFetch = tableId => {
return fetchData({ return fetchData({
@ -104,19 +120,28 @@
disableSorting disableSorting
on:updatecolumns={onUpdateColumns} on:updatecolumns={onUpdateColumns}
on:updaterows={onUpdateRows} on:updaterows={onUpdateRows}
customPlaceholder
> >
<CreateColumnButton on:updatecolumns={onUpdateColumns} /> <div class="buttons">
{#if schema && Object.keys(schema).length > 0} <div class="left-buttons">
<CreateColumnButton
highlighted={$fetch.loaded && (!hasCols || !hasRows)}
on:updatecolumns={onUpdateColumns}
/>
{#if !isUsersTable} {#if !isUsersTable}
<CreateRowButton <CreateRowButton
on:updaterows={onUpdateRows} on:updaterows={onUpdateRows}
title={"Create row"} title={"Create row"}
modalContentComponent={CreateEditRow} modalContentComponent={CreateEditRow}
disabled={!hasCols}
highlighted={$fetch.loaded && hasCols && !hasRows}
/> />
{/if} {/if}
{#if isInternal} {#if isInternal}
<CreateViewButton /> <CreateViewButton disabled={!hasCols || !hasRows} />
{/if} {/if}
</div>
<div class="right-buttons">
<ManageAccessButton resourceId={$tables.selected?._id} /> <ManageAccessButton resourceId={$tables.selected?._id} />
{#if isUsersTable} {#if isUsersTable}
<EditRolesButton /> <EditRolesButton />
@ -128,16 +153,40 @@
/> />
{/if} {/if}
<HideAutocolumnButton bind:hideAutocolumns /> <HideAutocolumnButton bind:hideAutocolumns />
<!-- always have the export last -->
<ExportButton view={$tables.selected?._id} />
<ImportButton <ImportButton
tableId={$tables.selected?._id} tableId={$tables.selected?._id}
on:updaterows={onUpdateRows} on:updaterows={onUpdateRows}
/> />
<ExportButton
disabled={!hasRows || !hasCols}
view={$tables.selected?._id}
/>
{#key id} {#key id}
<TableFilterButton {schema} on:change={onFilter} /> <TableFilterButton
{schema}
on:change={onFilter}
disabled={!hasCols || !hasRows}
/>
{/key} {/key}
</div>
</div>
<div slot="placeholder">
<Layout gap="S">
{#if !hasCols}
<Heading>Let's create some columns</Heading>
<Body>
Start building out your table structure<br />
by adding some columns
</Body>
{:else}
<Heading>Now let's add a row</Heading>
<Body>
Add some data to your table<br />
by adding some rows
</Body>
{/if} {/if}
</Layout>
</div>
</Table> </Table>
{#key id} {#key id}
<div in:fade={{ delay: 200, duration: 100 }}> <div in:fade={{ delay: 200, duration: 100 }}>
@ -162,4 +211,20 @@
align-items: center; align-items: center;
margin-top: var(--spacing-xl); margin-top: var(--spacing-xl);
} }
.buttons {
flex: 1 1 auto;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
.left-buttons,
.right-buttons {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: var(--spacing-m);
}
</style> </style>

View file

@ -25,6 +25,7 @@
export let rowCount export let rowCount
export let type export let type
export let disableSorting = false export let disableSorting = false
export let customPlaceholder = false
let selectedRows = [] let selectedRows = []
let editableColumn let editableColumn
@ -117,10 +118,10 @@
</script> </script>
<Layout noPadding gap="S"> <Layout noPadding gap="S">
<div> <Layout noPadding gap="XS">
{#if title} {#if title}
<div class="table-title"> <div class="table-title">
<Heading size="S">{title}</Heading> <Heading size="M">{title}</Heading>
{#if loading} {#if loading}
<div transition:fade|local> <div transition:fade|local>
<Spinner size="10" /> <Spinner size="10" />
@ -134,7 +135,7 @@
<DeleteRowsButton on:updaterows {selectedRows} {deleteRows} /> <DeleteRowsButton on:updaterows {selectedRows} {deleteRows} />
{/if} {/if}
</div> </div>
</div> </Layout>
{#key tableId} {#key tableId}
<div class="table-wrapper"> <div class="table-wrapper">
<Table <Table
@ -144,6 +145,7 @@
{customRenderers} {customRenderers}
{rowCount} {rowCount}
{disableSorting} {disableSorting}
{customPlaceholder}
bind:selectedRows bind:selectedRows
allowSelectRows={allowEditing && !isUsersTable} allowSelectRows={allowEditing && !isUsersTable}
allowEditRows={allowEditing} allowEditRows={allowEditing}
@ -153,7 +155,9 @@
on:editrow={e => editRow(e.detail)} on:editrow={e => editRow(e.detail)}
on:clickrelationship={e => selectRelationship(e.detail)} on:clickrelationship={e => selectRelationship(e.detail)}
on:sort on:sort
/> >
<slot slot="placeholder" name="placeholder" />
</Table>
</div> </div>
{/key} {/key}
</Layout> </Layout>
@ -176,6 +180,7 @@
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
margin-top: var(--spacing-m);
} }
.table-title > div { .table-title > div {
margin-left: var(--spacing-xs); margin-left: var(--spacing-xs);

View file

@ -2,10 +2,21 @@
import { ActionButton, Modal } from "@budibase/bbui" import { ActionButton, Modal } from "@budibase/bbui"
import CreateEditColumn from "../modals/CreateEditColumn.svelte" import CreateEditColumn from "../modals/CreateEditColumn.svelte"
export let highlighted = false
export let disabled = false
let modal let modal
</script> </script>
<ActionButton icon="TableColumnAddRight" quiet size="S" on:click={modal.show}> <ActionButton
{disabled}
selected={highlighted}
emphasized={highlighted}
icon="TableColumnAddRight"
quiet
size="S"
on:click={modal.show}
>
Create column Create column
</ActionButton> </ActionButton>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View file

@ -4,11 +4,21 @@
export let modalContentComponent = CreateEditRow export let modalContentComponent = CreateEditRow
export let title = "Create row" export let title = "Create row"
export let disabled = false
export let highlighted = false
let modal let modal
</script> </script>
<ActionButton icon="TableRowAddBottom" size="S" quiet on:click={modal.show}> <ActionButton
{disabled}
emphasized={highlighted}
selected={highlighted}
icon="TableRowAddBottom"
size="S"
quiet
on:click={modal.show}
>
{title} {title}
</ActionButton> </ActionButton>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View file

@ -2,10 +2,18 @@
import { Modal, ActionButton } from "@budibase/bbui" import { Modal, ActionButton } from "@budibase/bbui"
import CreateViewModal from "../modals/CreateViewModal.svelte" import CreateViewModal from "../modals/CreateViewModal.svelte"
export let disabled = false
let modal let modal
</script> </script>
<ActionButton icon="CollectionAdd" size="S" quiet on:click={modal.show}> <ActionButton
{disabled}
icon="CollectionAdd"
size="S"
quiet
on:click={modal.show}
>
Create view Create view
</ActionButton> </ActionButton>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View file

@ -3,11 +3,18 @@
import ExportModal from "../modals/ExportModal.svelte" import ExportModal from "../modals/ExportModal.svelte"
export let view export let view
export let disabled = false
let modal let modal
</script> </script>
<ActionButton icon="DataDownload" size="S" quiet on:click={modal.show}> <ActionButton
{disabled}
icon="DataDownload"
size="S"
quiet
on:click={modal.show}
>
Export Export
</ActionButton> </ActionButton>
<Modal bind:this={modal}> <Modal bind:this={modal}>

View file

@ -8,6 +8,12 @@
} }
</script> </script>
<ActionButton icon="MagicWand" primary size="S" quiet on:click={hideOrUnhide}> <ActionButton
{#if hideAutocolumns}Show auto columns{:else}Hide auto columns{/if} icon={hideAutocolumns ? "VisibilityOff" : "Visibility"}
primary
size="S"
quiet
on:click={hideOrUnhide}
>
Auto columns
</ActionButton> </ActionButton>

View file

@ -5,6 +5,7 @@
export let schema export let schema
export let filters export let filters
export let disabled = false
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let modal let modal
@ -17,6 +18,7 @@
icon="Filter" icon="Filter"
size="S" size="S"
quiet quiet
{disabled}
on:click={modal.show} on:click={modal.show}
active={tempValue?.length > 0} active={tempValue?.length > 0}
> >