budibase/packages/builder/src/components/backend/DataTable/DataTable.svelte

245 lines
6.3 KiB
Svelte
Raw Normal View History

2020-03-10 14:53:23 +01:00
<script>
import { fade } from "svelte/transition"
import { tables } from "stores/backend"
import CreateRowButton from "./buttons/CreateRowButton.svelte"
import CreateColumnButton from "./buttons/CreateColumnButton.svelte"
import CreateViewButton from "./buttons/CreateViewButton.svelte"
import ExistingRelationshipButton from "./buttons/ExistingRelationshipButton.svelte"
import ExportButton from "./buttons/ExportButton.svelte"
import ImportButton from "./buttons/ImportButton.svelte"
2020-12-04 09:27:42 +01:00
import EditRolesButton from "./buttons/EditRolesButton.svelte"
2021-02-10 19:18:31 +01:00
import ManageAccessButton from "./buttons/ManageAccessButton.svelte"
2021-02-16 14:56:40 +01:00
import HideAutocolumnButton from "./buttons/HideAutocolumnButton.svelte"
import TableFilterButton from "./buttons/TableFilterButton.svelte"
import Table from "./Table.svelte"
2020-12-04 09:27:42 +01:00
import { TableNames } from "constants"
import CreateEditRow from "./modals/CreateEditRow.svelte"
import {
Pagination,
Heading,
Body,
Layout,
notifications,
} from "@budibase/bbui"
import { fetchData } from "@budibase/frontend-core"
import { API } from "api"
2020-03-10 17:06:30 +01:00
let hideAutocolumns = true
$: isUsersTable = $tables.selected?._id === TableNames.USERS
$: type = $tables.selected?.type
$: isInternal = type !== "external"
2021-10-18 17:03:13 +02:00
$: schema = $tables.selected?.schema
$: enrichedSchema = enrichSchema($tables.selected?.schema)
$: id = $tables.selected?._id
$: fetch = createFetch(id)
$: hasCols = checkHasCols(schema)
$: hasRows = !!$fetch.rows?.length
$: showError($fetch.error)
const showError = error => {
if (error) {
notifications.error(error?.message || "Unable to fetch data.")
}
}
2021-10-13 12:39:36 +02:00
2021-10-18 17:03:13 +02:00
const enrichSchema = schema => {
let tempSchema = { ...schema }
tempSchema._id = {
2021-10-13 12:39:36 +02:00
type: "internal",
editable: false,
displayName: "ID",
autocolumn: true,
}
if (isInternal) {
2021-10-18 17:03:13 +02:00
tempSchema._rev = {
2021-10-13 12:39:36 +02:00
type: "internal",
editable: false,
displayName: "Revision",
autocolumn: true,
}
}
2021-10-18 17:03:13 +02:00
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
const createFetch = tableId => {
return fetchData({
API,
datasource: {
tableId,
type: "table",
},
options: {
schema,
limit: 10,
paginate: true,
},
})
}
// Fetch data whenever sorting option changes
const onSort = e => {
fetch.update({
sortColumn: e.detail.column,
sortOrder: e.detail.order,
})
}
// Fetch data whenever filters change
const onFilter = e => {
fetch.update({
filter: e.detail,
})
}
// Fetch data whenever schema changes
const onUpdateColumns = () => {
fetch.refresh()
}
// Fetch data whenever rows are modified. Unfortunately we have to lose
// our pagination place, as our bookmarks will have shifted.
const onUpdateRows = () => {
fetch.refresh()
}
2020-03-10 14:53:23 +01:00
</script>
<div>
<Table
title={$tables.selected?.name}
2021-10-18 17:03:13 +02:00
schema={enrichedSchema}
{type}
tableId={id}
data={$fetch.rows}
bind:hideAutocolumns
loading={!$fetch.loaded}
on:sort={onSort}
allowEditing
disableSorting
on:updatecolumns={onUpdateColumns}
on:updaterows={onUpdateRows}
customPlaceholder
>
<div class="buttons">
<div class="left-buttons">
<CreateColumnButton
highlighted={$fetch.loaded && (!hasCols || !hasRows)}
on:updatecolumns={onUpdateColumns}
/>
{#if !isUsersTable}
<CreateRowButton
on:updaterows={onUpdateRows}
title={"Create row"}
modalContentComponent={CreateEditRow}
disabled={!hasCols}
highlighted={$fetch.loaded && hasCols && !hasRows}
/>
{/if}
{#if isInternal}
<CreateViewButton disabled={!hasCols || !hasRows} />
{/if}
</div>
<div class="right-buttons">
<ManageAccessButton resourceId={$tables.selected?._id} />
{#if isUsersTable}
<EditRolesButton />
{/if}
{#if !isInternal}
<ExistingRelationshipButton
table={$tables.selected}
on:updatecolumns={onUpdateColumns}
/>
{/if}
<HideAutocolumnButton bind:hideAutocolumns />
<ImportButton
disabled={$tables.selected?._id === "ta_users"}
tableId={$tables.selected?._id}
on:updaterows={onUpdateRows}
/>
<ExportButton
disabled={!hasRows || !hasCols}
view={$tables.selected?._id}
/>
{#key id}
<TableFilterButton
{schema}
on:change={onFilter}
disabled={!hasCols}
/>
{/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}
</Layout>
</div>
</Table>
{#key id}
<div in:fade={{ delay: 200, duration: 100 }}>
<div class="pagination">
<Pagination
page={$fetch.pageNumber + 1}
hasPrevPage={$fetch.hasPrevPage}
hasNextPage={$fetch.hasNextPage}
goToPrevPage={$fetch.loading ? null : fetch.prevPage}
goToNextPage={$fetch.loading ? null : fetch.nextPage}
/>
</div>
</div>
{/key}
</div>
<style>
.pagination {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
margin-top: var(--spacing-xl);
}
.buttons {
flex: 1 1 auto;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
2022-04-08 11:35:13 +02:00
flex-wrap: wrap;
}
.left-buttons,
.right-buttons {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
2022-04-08 11:37:45 +02:00
gap: var(--spacing-m);
}
</style>