Refactor grid stores and how config is handled
This commit is contained in:
parent
c4e4b5c979
commit
deb4092cd3
|
@ -26,16 +26,14 @@
|
||||||
$: id = $tables.selected?._id
|
$: id = $tables.selected?._id
|
||||||
$: isUsersTable = id === TableNames.USERS
|
$: isUsersTable = id === TableNames.USERS
|
||||||
$: isInternal = $tables.selected?.type !== "external"
|
$: isInternal = $tables.selected?.type !== "external"
|
||||||
$: datasource = {
|
$: gridDatasource = {
|
||||||
type: "table",
|
type: "table",
|
||||||
tableId: id,
|
tableId: id,
|
||||||
}
|
}
|
||||||
|
$: tableDatasource = $datasources.list.find(datasource => {
|
||||||
$: datasource = $datasources.list.find(datasource => {
|
|
||||||
return datasource._id === $tables.selected?.sourceId
|
return datasource._id === $tables.selected?.sourceId
|
||||||
})
|
})
|
||||||
|
$: relationshipsEnabled = relationshipSupport(tableDatasource)
|
||||||
$: relationshipsEnabled = relationshipSupport(datasource)
|
|
||||||
|
|
||||||
const relationshipSupport = datasource => {
|
const relationshipSupport = datasource => {
|
||||||
const integration = $integrations[datasource?.source]
|
const integration = $integrations[datasource?.source]
|
||||||
|
@ -58,7 +56,7 @@
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<Grid
|
<Grid
|
||||||
{API}
|
{API}
|
||||||
{datasource}
|
datasource={gridDatasource}
|
||||||
allowAddRows={!isUsersTable}
|
allowAddRows={!isUsersTable}
|
||||||
allowDeleteRows={!isUsersTable}
|
allowDeleteRows={!isUsersTable}
|
||||||
schemaOverrides={isUsersTable ? userSchemaOverrides : null}
|
schemaOverrides={isUsersTable ? userSchemaOverrides : null}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
export const buildViewV2Endpoints = API => ({
|
export const buildViewV2Endpoints = API => ({
|
||||||
/**
|
/**
|
||||||
* Create a new view
|
* Create a new view
|
||||||
* @param tableId the id of the table where the view will be created
|
|
||||||
* @param view the view object
|
* @param view the view object
|
||||||
*/
|
*/
|
||||||
create: async view => {
|
create: async view => {
|
||||||
|
@ -10,9 +9,18 @@ export const buildViewV2Endpoints = API => ({
|
||||||
body: view,
|
body: view,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Updates a view
|
||||||
|
* @param view the view object
|
||||||
|
*/
|
||||||
|
update: async view => {
|
||||||
|
return await API.put({
|
||||||
|
url: `/api/v2/views/${view.id}`,
|
||||||
|
body: view,
|
||||||
|
})
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Fetches all rows in a view
|
* Fetches all rows in a view
|
||||||
* @param tableId the id of the table
|
|
||||||
* @param viewId the id of the view
|
* @param viewId the id of the view
|
||||||
*/
|
*/
|
||||||
fetch: async viewId => {
|
fetch: async viewId => {
|
||||||
|
@ -20,7 +28,6 @@ export const buildViewV2Endpoints = API => ({
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Delete a view
|
* Delete a view
|
||||||
* @param tableId the id of the table
|
|
||||||
* @param viewId the id of the view
|
* @param viewId the id of the view
|
||||||
*/
|
*/
|
||||||
delete: async viewId => {
|
delete: async viewId => {
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
column.schema.autocolumn ||
|
column.schema.autocolumn ||
|
||||||
column.schema.disabled ||
|
column.schema.disabled ||
|
||||||
column.schema.type === "formula" ||
|
column.schema.type === "formula" ||
|
||||||
(!$config.allowEditRows && row._id)
|
(!$config.canEditRows && row._id)
|
||||||
|
|
||||||
// Register this cell API if the row is focused
|
// Register this cell API if the row is focused
|
||||||
$: {
|
$: {
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<div
|
<div
|
||||||
on:click={select}
|
on:click={select}
|
||||||
class="checkbox"
|
class="checkbox"
|
||||||
class:visible={$config.allowDeleteRows &&
|
class:visible={$config.canDeleteRows &&
|
||||||
(disableNumber || rowSelected || rowHovered || rowFocused)}
|
(disableNumber || rowSelected || rowHovered || rowFocused)}
|
||||||
>
|
>
|
||||||
<Checkbox value={rowSelected} {disabled} />
|
<Checkbox value={rowSelected} {disabled} />
|
||||||
|
@ -48,14 +48,14 @@
|
||||||
{#if !disableNumber}
|
{#if !disableNumber}
|
||||||
<div
|
<div
|
||||||
class="number"
|
class="number"
|
||||||
class:visible={!$config.allowDeleteRows ||
|
class:visible={!$config.canDeleteRows ||
|
||||||
!(rowSelected || rowHovered || rowFocused)}
|
!(rowSelected || rowHovered || rowFocused)}
|
||||||
>
|
>
|
||||||
{row.__idx + 1}
|
{row.__idx + 1}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{#if rowSelected && $config.allowDeleteRows}
|
{#if rowSelected && $config.canDeleteRows}
|
||||||
<div class="delete" on:click={() => dispatch("request-bulk-delete")}>
|
<div class="delete" on:click={() => dispatch("request-bulk-delete")}>
|
||||||
<Icon
|
<Icon
|
||||||
name="Delete"
|
name="Delete"
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="expand" class:visible={$config.allowExpandRows && expandable}>
|
<div class="expand" class:visible={$config.canExpandRows && expandable}>
|
||||||
<Icon
|
<Icon
|
||||||
size="S"
|
size="S"
|
||||||
name="Maximize"
|
name="Maximize"
|
||||||
|
|
|
@ -167,7 +167,7 @@
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="Edit"
|
icon="Edit"
|
||||||
on:click={editColumn}
|
on:click={editColumn}
|
||||||
disabled={!$config.allowSchemaChanges || column.schema.disabled}
|
disabled={!$config.canEditColumns || column.schema.disabled}
|
||||||
>
|
>
|
||||||
Edit column
|
Edit column
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
icon="Label"
|
icon="Label"
|
||||||
on:click={makeDisplayColumn}
|
on:click={makeDisplayColumn}
|
||||||
disabled={idx === "sticky" ||
|
disabled={idx === "sticky" ||
|
||||||
!$config.allowSchemaChanges ||
|
!$config.canEditPrimaryDisplay ||
|
||||||
bannedDisplayColumnTypes.includes(column.schema.type)}
|
bannedDisplayColumnTypes.includes(column.schema.type)}
|
||||||
>
|
>
|
||||||
Use as display column
|
Use as display column
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { setContext, onMount } from "svelte"
|
import { setContext, onMount } from "svelte"
|
||||||
|
import { writable } from "svelte/store"
|
||||||
import { fade } from "svelte/transition"
|
import { fade } from "svelte/transition"
|
||||||
import { clickOutside, ProgressCircle } from "@budibase/bbui"
|
import { clickOutside, ProgressCircle } from "@budibase/bbui"
|
||||||
import { createEventManagers } from "../lib/events"
|
import { createEventManagers } from "../lib/events"
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
export let allowExpandRows = true
|
export let allowExpandRows = true
|
||||||
export let allowEditRows = true
|
export let allowEditRows = true
|
||||||
export let allowDeleteRows = true
|
export let allowDeleteRows = true
|
||||||
|
export let allowEditColumns = true
|
||||||
export let allowSchemaChanges = true
|
export let allowSchemaChanges = true
|
||||||
export let stripeRows = false
|
export let stripeRows = false
|
||||||
export let collaboration = true
|
export let collaboration = true
|
||||||
|
@ -50,11 +52,14 @@
|
||||||
// Unique identifier for DOM nodes inside this instance
|
// Unique identifier for DOM nodes inside this instance
|
||||||
const rand = Math.random()
|
const rand = Math.random()
|
||||||
|
|
||||||
|
// Store props in a store for reference in other stores
|
||||||
|
const props = writable($$props)
|
||||||
|
|
||||||
// Build up context
|
// Build up context
|
||||||
let context = {
|
let context = {
|
||||||
API: API || createAPIClient(),
|
API: API || createAPIClient(),
|
||||||
rand,
|
rand,
|
||||||
props: $$props,
|
props,
|
||||||
}
|
}
|
||||||
context = { ...context, ...createEventManagers() }
|
context = { ...context, ...createEventManagers() }
|
||||||
context = attachStores(context)
|
context = attachStores(context)
|
||||||
|
@ -71,11 +76,10 @@
|
||||||
contentLines,
|
contentLines,
|
||||||
gridFocused,
|
gridFocused,
|
||||||
error,
|
error,
|
||||||
canAddRows,
|
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
// Keep config store up to date with props
|
// Keep config store up to date with props
|
||||||
$: config.set({
|
$: props.set({
|
||||||
datasource,
|
datasource,
|
||||||
schemaOverrides,
|
schemaOverrides,
|
||||||
columnWhitelist,
|
columnWhitelist,
|
||||||
|
@ -83,6 +87,7 @@
|
||||||
allowExpandRows,
|
allowExpandRows,
|
||||||
allowEditRows,
|
allowEditRows,
|
||||||
allowDeleteRows,
|
allowDeleteRows,
|
||||||
|
allowEditColumns,
|
||||||
allowSchemaChanges,
|
allowSchemaChanges,
|
||||||
stripeRows,
|
stripeRows,
|
||||||
collaboration,
|
collaboration,
|
||||||
|
@ -144,7 +149,7 @@
|
||||||
<HeaderRow />
|
<HeaderRow />
|
||||||
<GridBody />
|
<GridBody />
|
||||||
</div>
|
</div>
|
||||||
{#if $canAddRows}
|
{#if $config.canAddRows}
|
||||||
<NewRow />
|
<NewRow />
|
||||||
{/if}
|
{/if}
|
||||||
<div class="overlays">
|
<div class="overlays">
|
||||||
|
@ -168,7 +173,7 @@
|
||||||
<ProgressCircle />
|
<ProgressCircle />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if allowDeleteRows}
|
{#if $config.canDeleteRows}
|
||||||
<BulkDeleteHandler />
|
<BulkDeleteHandler />
|
||||||
{/if}
|
{/if}
|
||||||
<KeyboardManager />
|
<KeyboardManager />
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
renderedRows,
|
renderedRows,
|
||||||
renderedColumns,
|
renderedColumns,
|
||||||
rowVerticalInversionIndex,
|
rowVerticalInversionIndex,
|
||||||
canAddRows,
|
|
||||||
hoveredRowId,
|
hoveredRowId,
|
||||||
dispatch,
|
dispatch,
|
||||||
isDragging,
|
isDragging,
|
||||||
|
config,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
let body
|
let body
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
invertY={idx >= $rowVerticalInversionIndex}
|
invertY={idx >= $rowVerticalInversionIndex}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
{#if $canAddRows}
|
{#if $config.canAddRows}
|
||||||
<div
|
<div
|
||||||
class="blank"
|
class="blank"
|
||||||
class:highlighted={$hoveredRowId === BlankRowID}
|
class:highlighted={$hoveredRowId === BlankRowID}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
</GridScrollWrapper>
|
</GridScrollWrapper>
|
||||||
{#if $config.allowSchemaChanges}
|
{#if $config.canEditColumns}
|
||||||
{#key $datasource}
|
{#key $datasource}
|
||||||
<TempTooltip
|
<TempTooltip
|
||||||
text="Click here to create your first column"
|
text="Click here to create your first column"
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
columnHorizontalInversionIndex,
|
columnHorizontalInversionIndex,
|
||||||
selectedRows,
|
selectedRows,
|
||||||
loading,
|
loading,
|
||||||
canAddRows,
|
config,
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
let visible = false
|
let visible = false
|
||||||
|
@ -154,7 +154,7 @@
|
||||||
condition={hasNoRows && !$loading}
|
condition={hasNoRows && !$loading}
|
||||||
type={TooltipType.Info}
|
type={TooltipType.Info}
|
||||||
>
|
>
|
||||||
{#if !visible && !selectedRowCount && $canAddRows}
|
{#if !visible && !selectedRowCount && $config.canAddRows}
|
||||||
<div
|
<div
|
||||||
class="new-row-fab"
|
class="new-row-fab"
|
||||||
on:click={() => dispatch("add-row-inline")}
|
on:click={() => dispatch("add-row-inline")}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
renderedRows,
|
renderedRows,
|
||||||
focusedCellId,
|
focusedCellId,
|
||||||
hoveredRowId,
|
hoveredRowId,
|
||||||
canAddRows,
|
config,
|
||||||
selectedCellMap,
|
selectedCellMap,
|
||||||
focusedRow,
|
focusedRow,
|
||||||
scrollLeft,
|
scrollLeft,
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{#if $canAddRows}
|
{#if $config.canAddRows}
|
||||||
<div
|
<div
|
||||||
class="row new"
|
class="row new"
|
||||||
on:mouseenter={$isDragging
|
on:mouseenter={$isDragging
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
config,
|
config,
|
||||||
menu,
|
menu,
|
||||||
gridFocused,
|
gridFocused,
|
||||||
canAddRows,
|
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
const ignoredOriginSelectors = [
|
const ignoredOriginSelectors = [
|
||||||
|
@ -46,12 +45,12 @@
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
focusFirstCell()
|
focusFirstCell()
|
||||||
} else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
} else if (e.key === "Enter" && (e.ctrlKey || e.metaKey)) {
|
||||||
if ($canAddRows) {
|
if ($config.canAddRows) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
dispatch("add-row-inline")
|
dispatch("add-row-inline")
|
||||||
}
|
}
|
||||||
} else if (e.key === "Delete" || e.key === "Backspace") {
|
} else if (e.key === "Delete" || e.key === "Backspace") {
|
||||||
if (Object.keys($selectedRows).length && $config.allowDeleteRows) {
|
if (Object.keys($selectedRows).length && $config.canDeleteRows) {
|
||||||
dispatch("request-bulk-delete")
|
dispatch("request-bulk-delete")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +99,7 @@
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "Enter":
|
case "Enter":
|
||||||
if ($canAddRows) {
|
if ($config.canAddRows) {
|
||||||
dispatch("add-row-inline")
|
dispatch("add-row-inline")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +119,7 @@
|
||||||
break
|
break
|
||||||
case "Delete":
|
case "Delete":
|
||||||
case "Backspace":
|
case "Backspace":
|
||||||
if (Object.keys($selectedRows).length && $config.allowDeleteRows) {
|
if (Object.keys($selectedRows).length && $config.canDeleteRows) {
|
||||||
dispatch("request-bulk-delete")
|
dispatch("request-bulk-delete")
|
||||||
} else {
|
} else {
|
||||||
deleteSelectedCell()
|
deleteSelectedCell()
|
||||||
|
@ -131,7 +130,7 @@
|
||||||
break
|
break
|
||||||
case " ":
|
case " ":
|
||||||
case "Space":
|
case "Space":
|
||||||
if ($config.allowDeleteRows) {
|
if ($config.canDeleteRows) {
|
||||||
toggleSelectRow()
|
toggleSelectRow()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
focusedCellAPI,
|
focusedCellAPI,
|
||||||
focusedRowId,
|
focusedRowId,
|
||||||
notifications,
|
notifications,
|
||||||
canAddRows,
|
|
||||||
} = getContext("grid")
|
} = getContext("grid")
|
||||||
|
|
||||||
$: style = makeStyle($menu)
|
$: style = makeStyle($menu)
|
||||||
|
@ -68,9 +67,7 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="Maximize"
|
icon="Maximize"
|
||||||
disabled={isNewRow ||
|
disabled={isNewRow || !$config.canEditRows || !$config.canExpandRows}
|
||||||
!$config.allowEditRows ||
|
|
||||||
!$config.allowExpandRows}
|
|
||||||
on:click={() => dispatch("edit-row", $focusedRow)}
|
on:click={() => dispatch("edit-row", $focusedRow)}
|
||||||
on:click={menu.actions.close}
|
on:click={menu.actions.close}
|
||||||
>
|
>
|
||||||
|
@ -94,14 +91,14 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="Duplicate"
|
icon="Duplicate"
|
||||||
disabled={isNewRow || !$canAddRows}
|
disabled={isNewRow || !$config.canAddRows}
|
||||||
on:click={duplicate}
|
on:click={duplicate}
|
||||||
>
|
>
|
||||||
Duplicate row
|
Duplicate row
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
icon="Delete"
|
icon="Delete"
|
||||||
disabled={isNewRow || !$config.allowDeleteRows}
|
disabled={isNewRow || !$config.canDeleteRows}
|
||||||
on:click={deleteRow}
|
on:click={deleteRow}
|
||||||
>
|
>
|
||||||
Delete row
|
Delete row
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const createActions = context => {
|
||||||
const { copiedCell, focusedCellAPI } = context
|
const { copiedCell, focusedCellAPI } = context
|
||||||
|
|
||||||
const copy = () => {
|
const copy = () => {
|
||||||
|
|
|
@ -35,20 +35,10 @@ export const createStores = () => {
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
// Checks if we have a certain column by name
|
|
||||||
const hasColumn = column => {
|
|
||||||
const $columns = get(columns)
|
|
||||||
const $sticky = get(stickyColumn)
|
|
||||||
return $columns.some(col => col.name === column) || $sticky?.name === column
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
columns: {
|
columns: {
|
||||||
...columns,
|
...columns,
|
||||||
subscribe: enrichedColumns.subscribe,
|
subscribe: enrichedColumns.subscribe,
|
||||||
actions: {
|
|
||||||
hasColumn,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
stickyColumn,
|
stickyColumn,
|
||||||
visibleColumns,
|
visibleColumns,
|
||||||
|
@ -56,10 +46,43 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const deriveStores = context => {
|
||||||
|
const { columns, stickyColumn } = context
|
||||||
|
|
||||||
|
// Derive if we have any normal columns
|
||||||
|
const hasNonAutoColumn = derived(
|
||||||
|
[columns, stickyColumn],
|
||||||
|
([$columns, $stickyColumn]) => {
|
||||||
|
let allCols = $columns || []
|
||||||
|
if ($stickyColumn) {
|
||||||
|
allCols = [...allCols, $stickyColumn]
|
||||||
|
}
|
||||||
|
const normalCols = allCols.filter(column => {
|
||||||
|
return !column.schema?.autocolumn
|
||||||
|
})
|
||||||
|
return normalCols.length > 0
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasNonAutoColumn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createActions = context => {
|
||||||
const { table, columns, stickyColumn, API, dispatch, config } = context
|
const { table, columns, stickyColumn, API, dispatch, config } = context
|
||||||
|
|
||||||
|
// Checks if we have a certain column by name
|
||||||
|
const hasColumn = column => {
|
||||||
|
const $columns = get(columns)
|
||||||
|
const $sticky = get(stickyColumn)
|
||||||
|
return $columns.some(col => col.name === column) || $sticky?.name === column
|
||||||
|
}
|
||||||
|
|
||||||
// Updates the tables primary display column
|
// Updates the tables primary display column
|
||||||
const changePrimaryDisplay = async column => {
|
const changePrimaryDisplay = async column => {
|
||||||
|
if (!get(config).canEditPrimaryDisplay) {
|
||||||
|
return
|
||||||
|
}
|
||||||
return await saveTable({
|
return await saveTable({
|
||||||
...get(table),
|
...get(table),
|
||||||
primaryDisplay: column,
|
primaryDisplay: column,
|
||||||
|
@ -83,21 +106,6 @@ export const deriveStores = context => {
|
||||||
await saveChanges()
|
await saveChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Derive if we have any normal columns
|
|
||||||
const hasNonAutoColumn = derived(
|
|
||||||
[columns, stickyColumn],
|
|
||||||
([$columns, $stickyColumn]) => {
|
|
||||||
let allCols = $columns || []
|
|
||||||
if ($stickyColumn) {
|
|
||||||
allCols = [...allCols, $stickyColumn]
|
|
||||||
}
|
|
||||||
const normalCols = allCols.filter(column => {
|
|
||||||
return !column.schema?.autocolumn
|
|
||||||
})
|
|
||||||
return normalCols.length > 0
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Persists column changes by saving metadata against table schema
|
// Persists column changes by saving metadata against table schema
|
||||||
const saveChanges = async () => {
|
const saveChanges = async () => {
|
||||||
const $columns = get(columns)
|
const $columns = get(columns)
|
||||||
|
@ -133,7 +141,7 @@ export const deriveStores = context => {
|
||||||
table.set(newTable)
|
table.set(newTable)
|
||||||
|
|
||||||
// Update server
|
// Update server
|
||||||
if (get(config).allowSchemaChanges) {
|
if (get(config).canSaveSchema) {
|
||||||
await API.saveTable(newTable)
|
await API.saveTable(newTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,11 +151,10 @@ export const deriveStores = context => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasNonAutoColumn,
|
|
||||||
columns: {
|
columns: {
|
||||||
...columns,
|
...columns,
|
||||||
actions: {
|
actions: {
|
||||||
...columns.actions,
|
hasColumn,
|
||||||
saveChanges,
|
saveChanges,
|
||||||
saveTable,
|
saveTable,
|
||||||
changePrimaryDisplay,
|
changePrimaryDisplay,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { writable } from "svelte/store"
|
|
||||||
import { derivedMemo } from "../../../utils"
|
import { derivedMemo } from "../../../utils"
|
||||||
|
import { derived } from "svelte/store"
|
||||||
|
|
||||||
export const createStores = context => {
|
export const deriveStores = context => {
|
||||||
const config = writable(context.props)
|
const { props, hasNonAutoColumn } = context
|
||||||
const getProp = prop => derivedMemo(config, $config => $config[prop])
|
const getProp = prop => derivedMemo(props, $props => $props[prop])
|
||||||
|
|
||||||
// Derive and memoize some props so that we can react to them in isolation
|
// Derive and memoize some props so that we can react to them in isolation
|
||||||
const datasource = getProp("datasource")
|
const datasource = getProp("datasource")
|
||||||
|
@ -16,6 +16,45 @@ export const createStores = context => {
|
||||||
const notifySuccess = getProp("notifySuccess")
|
const notifySuccess = getProp("notifySuccess")
|
||||||
const notifyError = getProp("notifyError")
|
const notifyError = getProp("notifyError")
|
||||||
|
|
||||||
|
// Derive features
|
||||||
|
const config = derived(
|
||||||
|
[props, hasNonAutoColumn],
|
||||||
|
([$props, $hasNonAutoColumn]) => {
|
||||||
|
let config = {
|
||||||
|
// Row features
|
||||||
|
canAddRows: $props.allowAddRows,
|
||||||
|
canExpandRows: $props.allowExpandRows,
|
||||||
|
canEditRows: $props.allowEditRows,
|
||||||
|
canDeleteRows: $props.allowDeleteRows,
|
||||||
|
|
||||||
|
// Column features
|
||||||
|
canEditColumns: $props.allowEditColumns,
|
||||||
|
canEditPrimaryDisplay: $props.allowEditColumns,
|
||||||
|
canSaveSchema: $props.allowSchemaChanges,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable some features if we're editing a view
|
||||||
|
if ($props.datasource?.type === "viewV2") {
|
||||||
|
config.canEditPrimaryDisplay = false
|
||||||
|
config.canEditColumns = false
|
||||||
|
config.canEditRows = false
|
||||||
|
config.canDeleteRows = false
|
||||||
|
config.canAddRows = false
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log($hasNonAutoColumn)
|
||||||
|
|
||||||
|
// Disable adding rows if we don't have any valid columns
|
||||||
|
if (!$hasNonAutoColumn) {
|
||||||
|
config.canAddRows = false
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(config)
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
config,
|
config,
|
||||||
datasource,
|
datasource,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable, get } from "svelte/store"
|
||||||
|
|
||||||
export const createStores = context => {
|
export const createStores = context => {
|
||||||
const { props } = context
|
const { props } = context
|
||||||
|
|
||||||
// Initialise to default props
|
// Initialise to default props
|
||||||
const filter = writable(props.initialFilter)
|
const filter = writable(get(props).initialFilter)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filter,
|
filter,
|
||||||
|
|
|
@ -17,7 +17,6 @@ import * as Filter from "./filter"
|
||||||
import * as Notifications from "./notifications"
|
import * as Notifications from "./notifications"
|
||||||
|
|
||||||
const DependencyOrderedStores = [
|
const DependencyOrderedStores = [
|
||||||
Config,
|
|
||||||
Notifications,
|
Notifications,
|
||||||
Sort,
|
Sort,
|
||||||
Filter,
|
Filter,
|
||||||
|
@ -34,6 +33,7 @@ const DependencyOrderedStores = [
|
||||||
Menu,
|
Menu,
|
||||||
Pagination,
|
Pagination,
|
||||||
Clipboard,
|
Clipboard,
|
||||||
|
Config,
|
||||||
]
|
]
|
||||||
|
|
||||||
export const attachStores = context => {
|
export const attachStores = context => {
|
||||||
|
@ -47,6 +47,11 @@ export const attachStores = context => {
|
||||||
context = { ...context, ...store.deriveStores?.(context) }
|
context = { ...context, ...store.deriveStores?.(context) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Action creation
|
||||||
|
for (let store of DependencyOrderedStores) {
|
||||||
|
context = { ...context, ...store.createActions?.(context) }
|
||||||
|
}
|
||||||
|
|
||||||
// Initialise any store logic
|
// Initialise any store logic
|
||||||
for (let store of DependencyOrderedStores) {
|
for (let store of DependencyOrderedStores) {
|
||||||
store.initialise?.(context)
|
store.initialise?.(context)
|
||||||
|
|
|
@ -12,7 +12,7 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const createActions = context => {
|
||||||
const { menu, focusedCellId, rand } = context
|
const { menu, focusedCellId, rand } = context
|
||||||
|
|
||||||
const open = (cellId, e) => {
|
const open = (cellId, e) => {
|
||||||
|
|
|
@ -23,7 +23,7 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const createActions = context => {
|
||||||
const {
|
const {
|
||||||
reorder,
|
reorder,
|
||||||
columns,
|
columns,
|
||||||
|
|
|
@ -19,7 +19,7 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const createActions = context => {
|
||||||
const { resize, columns, stickyColumn, ui } = context
|
const { resize, columns, stickyColumn, ui } = context
|
||||||
|
|
||||||
// Starts resizing a certain column
|
// Starts resizing a certain column
|
||||||
|
|
|
@ -38,8 +38,24 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Enrich rows with an index property and any pending changes
|
||||||
|
const enrichedRows = derived(
|
||||||
|
[rows, rowChangeCache],
|
||||||
|
([$rows, $rowChangeCache]) => {
|
||||||
|
return $rows.map((row, idx) => ({
|
||||||
|
...row,
|
||||||
|
...$rowChangeCache[row._id],
|
||||||
|
__idx: idx,
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rows,
|
rows: {
|
||||||
|
...rows,
|
||||||
|
subscribe: enrichedRows.subscribe,
|
||||||
|
},
|
||||||
rowLookupMap,
|
rowLookupMap,
|
||||||
table,
|
table,
|
||||||
loaded,
|
loaded,
|
||||||
|
@ -51,7 +67,7 @@ export const createStores = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const createActions = context => {
|
||||||
const {
|
const {
|
||||||
rows,
|
rows,
|
||||||
rowLookupMap,
|
rowLookupMap,
|
||||||
|
@ -71,27 +87,14 @@ export const deriveStores = context => {
|
||||||
hasNextPage,
|
hasNextPage,
|
||||||
error,
|
error,
|
||||||
notifications,
|
notifications,
|
||||||
config,
|
|
||||||
} = context
|
} = context
|
||||||
const instanceLoaded = writable(false)
|
const instanceLoaded = writable(false)
|
||||||
const fetch = writable(null)
|
const fetch = writable(null)
|
||||||
|
const tableId = writable(null)
|
||||||
|
|
||||||
// Local cache of row IDs to speed up checking if a row exists
|
// Local cache of row IDs to speed up checking if a row exists
|
||||||
let rowCacheMap = {}
|
let rowCacheMap = {}
|
||||||
|
|
||||||
// Enrich rows with an index property and any pending changes
|
|
||||||
const enrichedRows = derived(
|
|
||||||
[rows, rowChangeCache],
|
|
||||||
([$rows, $rowChangeCache]) => {
|
|
||||||
return $rows.map((row, idx) => ({
|
|
||||||
...row,
|
|
||||||
...$rowChangeCache[row._id],
|
|
||||||
__idx: idx,
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reset everything when table ID changes
|
// Reset everything when table ID changes
|
||||||
let unsubscribe = null
|
let unsubscribe = null
|
||||||
let lastResetKey = null
|
let lastResetKey = null
|
||||||
|
@ -102,6 +105,8 @@ export const deriveStores = context => {
|
||||||
instanceLoaded.set(false)
|
instanceLoaded.set(false)
|
||||||
loading.set(true)
|
loading.set(true)
|
||||||
|
|
||||||
|
console.log($datasource)
|
||||||
|
|
||||||
// Abandon if we don't have a valid datasource
|
// Abandon if we don't have a valid datasource
|
||||||
if (!$datasource?.tableId) {
|
if (!$datasource?.tableId) {
|
||||||
return
|
return
|
||||||
|
@ -501,7 +506,6 @@ export const deriveStores = context => {
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
enrichedRows,
|
|
||||||
rows: {
|
rows: {
|
||||||
...rows,
|
...rows,
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable, get } from "svelte/store"
|
||||||
|
|
||||||
export const createStores = context => {
|
export const createStores = context => {
|
||||||
const { props } = context
|
const { props } = context
|
||||||
|
const $props = get(props)
|
||||||
|
|
||||||
// Initialise to default props
|
// Initialise to default props
|
||||||
const sort = writable({
|
const sort = writable({
|
||||||
column: props.initialSortColumn,
|
column: $props.initialSortColumn,
|
||||||
order: props.initialSortOrder || "ascending",
|
order: $props.initialSortOrder || "ascending",
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -14,7 +14,7 @@ export const createStores = context => {
|
||||||
const focusedCellAPI = writable(null)
|
const focusedCellAPI = writable(null)
|
||||||
const selectedRows = writable({})
|
const selectedRows = writable({})
|
||||||
const hoveredRowId = writable(null)
|
const hoveredRowId = writable(null)
|
||||||
const rowHeight = writable(props.fixedRowHeight || DefaultRowHeight)
|
const rowHeight = writable(get(props).fixedRowHeight || DefaultRowHeight)
|
||||||
const previousFocusedRowId = writable(null)
|
const previousFocusedRowId = writable(null)
|
||||||
const gridFocused = writable(false)
|
const gridFocused = writable(false)
|
||||||
const isDragging = writable(false)
|
const isDragging = writable(false)
|
||||||
|
@ -61,23 +61,13 @@ export const createStores = context => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deriveStores = context => {
|
export const deriveStores = context => {
|
||||||
const {
|
const { focusedCellId, rows, rowLookupMap, rowHeight, stickyColumn, width } =
|
||||||
focusedCellId,
|
context
|
||||||
selectedRows,
|
|
||||||
hoveredRowId,
|
|
||||||
enrichedRows,
|
|
||||||
rowLookupMap,
|
|
||||||
rowHeight,
|
|
||||||
stickyColumn,
|
|
||||||
width,
|
|
||||||
hasNonAutoColumn,
|
|
||||||
config,
|
|
||||||
} = context
|
|
||||||
|
|
||||||
// Derive the row that contains the selected cell
|
// Derive the row that contains the selected cell
|
||||||
const focusedRow = derived(
|
const focusedRow = derived(
|
||||||
[focusedCellId, rowLookupMap, enrichedRows],
|
[focusedCellId, rowLookupMap, rows],
|
||||||
([$focusedCellId, $rowLookupMap, $enrichedRows]) => {
|
([$focusedCellId, $rowLookupMap, $rows]) => {
|
||||||
const rowId = $focusedCellId?.split("-")[0]
|
const rowId = $focusedCellId?.split("-")[0]
|
||||||
|
|
||||||
// Edge case for new rows
|
// Edge case for new rows
|
||||||
|
@ -87,18 +77,11 @@ export const deriveStores = context => {
|
||||||
|
|
||||||
// All normal rows
|
// All normal rows
|
||||||
const index = $rowLookupMap[rowId]
|
const index = $rowLookupMap[rowId]
|
||||||
return $enrichedRows[index]
|
return $rows[index]
|
||||||
},
|
},
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
|
|
||||||
// Callback when leaving the grid, deselecting all focussed or selected items
|
|
||||||
const blur = () => {
|
|
||||||
focusedCellId.set(null)
|
|
||||||
selectedRows.set({})
|
|
||||||
hoveredRowId.set(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derive the amount of content lines to show in cells depending on row height
|
// Derive the amount of content lines to show in cells depending on row height
|
||||||
const contentLines = derived(rowHeight, $rowHeight => {
|
const contentLines = derived(rowHeight, $rowHeight => {
|
||||||
if ($rowHeight >= LargeRowHeight) {
|
if ($rowHeight >= LargeRowHeight) {
|
||||||
|
@ -114,19 +97,24 @@ export const deriveStores = context => {
|
||||||
return ($stickyColumn?.width || 0) + $width + GutterWidth < 1100
|
return ($stickyColumn?.width || 0) + $width + GutterWidth < 1100
|
||||||
})
|
})
|
||||||
|
|
||||||
// Derive if we're able to add rows
|
|
||||||
const canAddRows = derived(
|
|
||||||
[config, hasNonAutoColumn],
|
|
||||||
([$config, $hasNonAutoColumn]) => {
|
|
||||||
return $config.allowAddRows && $hasNonAutoColumn
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canAddRows,
|
|
||||||
focusedRow,
|
focusedRow,
|
||||||
contentLines,
|
contentLines,
|
||||||
compact,
|
compact,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createActions = context => {
|
||||||
|
const { focusedCellId, selectedRows, hoveredRowId } = context
|
||||||
|
|
||||||
|
// Callback when leaving the grid, deselecting all focussed or selected items
|
||||||
|
const blur = () => {
|
||||||
|
focusedCellId.set(null)
|
||||||
|
selectedRows.set({})
|
||||||
|
hoveredRowId.set(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
ui: {
|
ui: {
|
||||||
actions: {
|
actions: {
|
||||||
blur,
|
blur,
|
||||||
|
|
|
@ -39,6 +39,14 @@ export const deriveStores = context => {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedCellMap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createActions = context => {
|
||||||
|
const { users } = context
|
||||||
|
|
||||||
const updateUser = user => {
|
const updateUser = user => {
|
||||||
const $users = get(users)
|
const $users = get(users)
|
||||||
if (!$users.some(x => x.sessionId === user.sessionId)) {
|
if (!$users.some(x => x.sessionId === user.sessionId)) {
|
||||||
|
@ -66,6 +74,5 @@ export const deriveStores = context => {
|
||||||
removeUser,
|
removeUser,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
selectedCellMap,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ export const deriveStores = context => {
|
||||||
const {
|
const {
|
||||||
rowHeight,
|
rowHeight,
|
||||||
visibleColumns,
|
visibleColumns,
|
||||||
enrichedRows,
|
rows,
|
||||||
scrollTop,
|
scrollTop,
|
||||||
scrollLeft,
|
scrollLeft,
|
||||||
width,
|
width,
|
||||||
|
@ -35,9 +35,9 @@ export const deriveStores = context => {
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
const renderedRows = derived(
|
const renderedRows = derived(
|
||||||
[enrichedRows, scrolledRowCount, visualRowCapacity],
|
[rows, scrolledRowCount, visualRowCapacity],
|
||||||
([$enrichedRows, $scrolledRowCount, $visualRowCapacity]) => {
|
([$rows, $scrolledRowCount, $visualRowCapacity]) => {
|
||||||
return $enrichedRows.slice(
|
return $rows.slice(
|
||||||
$scrolledRowCount,
|
$scrolledRowCount,
|
||||||
$scrolledRowCount + $visualRowCapacity
|
$scrolledRowCount + $visualRowCapacity
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue