Integrate sheet into data section better

This commit is contained in:
Andrew Kingston 2023-03-02 17:20:51 +00:00
parent 540906cf62
commit 5b590a5976
6 changed files with 178 additions and 198 deletions

View File

@ -18,142 +18,146 @@
Pagination, Pagination,
Heading, Heading,
Body, Body,
Modal,
Layout, Layout,
notifications, notifications,
} from "@budibase/bbui" } from "@budibase/bbui"
import { fetchData, Sheet } from "@budibase/frontend-core" import { fetchData, Sheet } from "@budibase/frontend-core"
import { API } from "api" import { API } from "api"
import CreateEditColumn from "components/backend/DataTable/modals/CreateEditColumn.svelte"
// let hideAutocolumns = true let createColumnModal
// let filters
// let hideAutocolumns = true
// $: isUsersTable = $tables.selected?._id === TableNames.USERS let filters
// $: type = $tables.selected?.type let hasRows = true
// $: isInternal = type !== "external"
// $: schema = $tables.selected?.schema $: isUsersTable = $tables.selected?._id === TableNames.USERS
// $: enrichedSchema = enrichSchema($tables.selected?.schema) $: type = $tables.selected?.type
// $: id = $tables.selected?._id $: isInternal = type !== "external"
// $: fetch = createFetch(id) $: schema = $tables.selected?.schema
// $: hasCols = checkHasCols(schema) $: enrichedSchema = enrichSchema($tables.selected?.schema)
// $: hasRows = !!$fetch.rows?.length $: id = $tables.selected?._id
// $: showError($fetch.error) $: hasCols = checkHasCols(schema)
// $: id, (filters = null) $: id, (filters = null)
//
// let appliedFilter let appliedFilter
// let rawFilter let rawFilter
// let appliedSort let appliedSort
// let selectedRows = [] let selectedRows = []
//
// $: enrichedSchema, $: enrichedSchema,
// () => { () => {
// appliedFilter = null appliedFilter = null
// rawFilter = null rawFilter = null
// appliedSort = null appliedSort = null
// selectedRows = [] selectedRows = []
// } }
//
// $: if (Number.isInteger($fetch.pageNumber)) { const enrichSchema = schema => {
// selectedRows = [] let tempSchema = { ...schema }
// } tempSchema._id = {
// type: "internal",
// const showError = error => { editable: false,
// if (error) { displayName: "ID",
// notifications.error(error?.message || "Unable to fetch data.") autocolumn: true,
// } }
// } if (isInternal) {
// tempSchema._rev = {
// const enrichSchema = schema => { type: "internal",
// let tempSchema = { ...schema } editable: false,
// tempSchema._id = { displayName: "Revision",
// type: "internal", autocolumn: true,
// editable: false, }
// displayName: "ID", }
// autocolumn: true,
// } return tempSchema
// if (isInternal) { }
// tempSchema._rev = {
// type: "internal", const checkHasCols = schema => {
// editable: false, if (!schema || Object.keys(schema).length === 0) {
// displayName: "Revision", return false
// autocolumn: true, }
// } let fields = Object.values(schema)
// } for (let field of fields) {
// if (!field.autocolumn) {
// return tempSchema return true
// } }
// }
// const checkHasCols = schema => { return false
// if (!schema || Object.keys(schema).length === 0) { }
// return false
// } // Fetch data whenever sorting option changes
// let fields = Object.values(schema) const onSort = async e => {
// for (let field of fields) { const sort = {
// if (!field.autocolumn) { sortColumn: e.detail.column,
// return true sortOrder: e.detail.order,
// } }
// } appliedSort = { ...sort }
// return false appliedSort.sortOrder = appliedSort.sortOrder.toLowerCase()
// } selectedRows = []
// }
// // Fetches new data whenever the table changes
// const createFetch = tableId => { // Fetch data whenever filters change
// return fetchData({ const onFilter = e => {
// API, filters = e.detail
// datasource: { appliedFilter = e.detail
// tableId, }
// type: "table",
// },
// options: {
// schema,
// limit: 10,
// paginate: true,
// },
// })
// }
//
// // Fetch data whenever sorting option changes
// const onSort = async e => {
// const sort = {
// sortColumn: e.detail.column,
// sortOrder: e.detail.order,
// }
// await fetch.update(sort)
// appliedSort = { ...sort }
// appliedSort.sortOrder = appliedSort.sortOrder.toLowerCase()
// selectedRows = []
// }
//
// // Fetch data whenever filters change
// const onFilter = e => {
// filters = e.detail
// fetch.update({
// filter: filters,
// })
// appliedFilter = e.detail
// }
//
// // Fetch data whenever schema changes
// const onUpdateColumns = () => {
// selectedRows = []
// fetch.refresh()
// }
//
// // Fetch data whenever rows are modified. Unfortunately we have to lose
// // our pagination place, as our bookmarks will have shifted.
// const onUpdateRows = () => {
// selectedRows = []
// fetch.refresh()
// }
//
// // When importing new rows it is better to reinitialise request/paging data.
// // Not doing so causes inconsistency in paging behaviour and content.
// const onImportData = () => {
// fetch.getInitialData()
// }
</script> </script>
<div> <div class="wrapper">
<Sheet tableId={$tables.selected?._id} {API} /> <div class="buttons">
<div class="left-buttons">
<CreateColumnButton
highlighted={!hasCols || !hasRows}
on:updatecolumns={null}
/>
{#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={null}
/>
{/if}
<ImportButton
disabled={$tables.selected?._id === "ta_users"}
tableId={$tables.selected?._id}
on:importrows={null}
/>
<ExportButton
disabled={!hasRows || !hasCols}
view={$tables.selected?._id}
filters={appliedFilter}
sorting={appliedSort}
{selectedRows}
/>
{#key id}
<TableFilterButton
{schema}
{filters}
on:change={onFilter}
disabled={!hasCols}
tableId={id}
/>
{/key}
</div>
</div>
<div class="sheet">
<Sheet
tableId={$tables.selected?._id}
{API}
filter={filters}
on:add-column={createColumnModal.show}
/>
</div>
</div> </div>
<!--<div>--> <!--<div>-->
@ -175,60 +179,6 @@
<!-- }}--> <!-- }}-->
<!-- customPlaceholder--> <!-- 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:importrows={onImportData}-->
<!-- />-->
<!-- <ExportButton-->
<!-- disabled={!hasRows || !hasCols}-->
<!-- view={$tables.selected?._id}-->
<!-- filters={appliedFilter}-->
<!-- sorting={appliedSort}-->
<!-- {selectedRows}-->
<!-- />-->
<!-- {#key id}-->
<!-- <TableFilterButton-->
<!-- {schema}-->
<!-- {filters}-->
<!-- on:change={onFilter}-->
<!-- disabled={!hasCols}-->
<!-- tableId={id}-->
<!-- />-->
<!-- {/key}-->
<!-- </div>-->
<!-- </div>-->
<!-- <div slot="placeholder">--> <!-- <div slot="placeholder">-->
<!-- <Layout gap="S">--> <!-- <Layout gap="S">-->
<!-- {#if !hasCols}--> <!-- {#if !hasCols}-->
@ -262,12 +212,23 @@
<!-- {/key}--> <!-- {/key}-->
<!--</div>--> <!--</div>-->
<Modal bind:this={createColumnModal}>
<CreateEditColumn on:updatecolumns />
</Modal>
<style> <style>
div { .wrapper {
flex: 1 1 auto; flex: 1 1 auto;
margin: -28px -40px -40px -40px; margin: -28px -40px -40px -40px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: var(--background);
}
.sheet {
flex: 1 1 auto;
display: flex;
flex-direction: column;
} }
.pagination { .pagination {
display: flex; display: flex;
@ -277,12 +238,14 @@
margin-top: var(--spacing-xl); margin-top: var(--spacing-xl);
} }
.buttons { .buttons {
flex: 1 1 auto; flex: 0 0 48px;
border-bottom: 2px solid var(--spectrum-global-color-gray-200);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
padding: 0 8px;
} }
.left-buttons, .left-buttons,
.right-buttons { .right-buttons {

View File

@ -5,7 +5,7 @@
import { getIconForField } from "./utils" import { getIconForField } from "./utils"
import SheetScrollWrapper from "./SheetScrollWrapper.svelte" import SheetScrollWrapper from "./SheetScrollWrapper.svelte"
const { visibleColumns, reorder } = getContext("spreadsheet") const { visibleColumns, reorder, dispatch } = getContext("spreadsheet")
</script> </script>
<div class="header"> <div class="header">
@ -32,6 +32,11 @@
{/each} {/each}
</div> </div>
</SheetScrollWrapper> </SheetScrollWrapper>
<div class="add-column" on:click={() => dispatch("add-column")}>
<SheetCell header width={40} center>
<Icon name="Add" size="S" />
</SheetCell>
</div>
</div> </div>
<style> <style>
@ -44,4 +49,13 @@
.row { .row {
display: flex; display: flex;
} }
.add-column {
width: 40px;
position: absolute;
right: 0;
top: 0;
display: flex;
justify-content: center;
border-left: 2px solid var(--spectrum-global-color-gray-200);
}
</style> </style>

View File

@ -1,5 +1,5 @@
<script> <script>
import { setContext } from "svelte" import { setContext, createEventDispatcher } from "svelte"
import { writable } from "svelte/store" import { writable } from "svelte/store"
import { createReorderStores } from "./stores/reorder" import { createReorderStores } from "./stores/reorder"
import { createViewportStores } from "./stores/viewport" import { createViewportStores } from "./stores/viewport"
@ -21,7 +21,7 @@
export let allowAddColumns = true export let allowAddColumns = true
export let allowAddRows = true export let allowAddRows = true
export let allowSelectRows = true export let allowSelectRows = true
// export let filter export let filter
// export let sortColumn // export let sortColumn
// export let sortOrder // export let sortOrder
@ -30,8 +30,10 @@
const rand = Math.random() const rand = Math.random()
// State stores // State stores
const dispatch = createEventDispatcher()
const config = writable({ const config = writable({
tableId, tableId,
filter,
allowAddRows, allowAddRows,
allowAddColumns, allowAddColumns,
allowSelectRows, allowSelectRows,
@ -61,6 +63,7 @@
scroll, scroll,
hoveredRowId, hoveredRowId,
config, config,
dispatch,
} }
const { rows, schema } = createRowsStore(context) const { rows, schema } = createRowsStore(context)
context = { ...context, rows, schema } context = { ...context, rows, schema }
@ -75,6 +78,7 @@
// Keep config store up to date // Keep config store up to date
$: config.set({ $: config.set({
tableId, tableId,
filter,
allowAddColumns, allowAddColumns,
allowAddRows, allowAddRows,
allowSelectRows, allowSelectRows,
@ -85,7 +89,7 @@
</script> </script>
<div class="sheet" style="--cell-height:{cellHeight}px;" id="sheet-{rand}"> <div class="sheet" style="--cell-height:{cellHeight}px;" id="sheet-{rand}">
<SheetControls /> <!--<SheetControls />-->
<div class="sheet-data"> <div class="sheet-data">
<StickyColumn /> <StickyColumn />
<div class="sheet-main"> <div class="sheet-main">

View File

@ -8,6 +8,7 @@
export let reorderSource = false export let reorderSource = false
export let reorderTarget = false export let reorderTarget = false
export let width = "" export let width = ""
export let center = false
</script> </script>
<div <div
@ -20,6 +21,7 @@
class:selected class:selected
class:reorder-source={reorderSource} class:reorder-source={reorderSource}
class:reorder-target={reorderTarget} class:reorder-target={reorderTarget}
class:center
on:focus on:focus
on:click on:click
on:mousedown on:mousedown
@ -61,6 +63,9 @@
.cell.row-hovered { .cell.row-hovered {
background: var(--cell-background-hover); background: var(--cell-background-hover);
} }
.cell.center {
justify-content: center;
}
/* Header cells */ /* Header cells */
.cell.header { .cell.header {

View File

@ -145,7 +145,7 @@
on:click={addRow} on:click={addRow}
width="40" width="40"
> >
<Icon hoverable name="Add" size="S" /> <Icon name="Add" size="S" />
</SheetCell> </SheetCell>
{#if $stickyColumn} {#if $stickyColumn}
<SheetCell <SheetCell

View File

@ -4,8 +4,9 @@ import { fetchData } from "../../../fetch/fetchData"
import { notifications } from "@budibase/bbui" import { notifications } from "@budibase/bbui"
export const createRowsStore = context => { export const createRowsStore = context => {
const { config, filter, API, scroll } = context const { config, API, scroll } = context
const tableId = derived(config, $config => $config.tableId) const tableId = derived(config, $config => $config.tableId)
const filter = derived(config, $config => $config.filter)
// Flag for whether this is the first time loading our fetch // Flag for whether this is the first time loading our fetch
let loaded = false let loaded = false
@ -19,7 +20,7 @@ export const createRowsStore = context => {
// Local stores for managing fetching data // Local stores for managing fetching data
const query = derived(filter, $filter => buildLuceneQuery($filter)) const query = derived(filter, $filter => buildLuceneQuery($filter))
const fetch = derived(tableId, $tableId => { const fetch = derived([tableId, filter], ([$tableId, $filter]) => {
if (!$tableId) { if (!$tableId) {
return null return null
} }
@ -43,13 +44,6 @@ export const createRowsStore = context => {
}) })
}) })
// Update fetch when query changes
query.subscribe($query => {
get(fetch)?.update({
query: $query,
})
})
// Observe each data fetch and extract some data // Observe each data fetch and extract some data
fetch.subscribe($fetch => { fetch.subscribe($fetch => {
if (!$fetch) { if (!$fetch) {