Refactor how grid settings are used and add option for row height
This commit is contained in:
parent
3f3e9fca56
commit
d77b2c6ab1
|
@ -5230,9 +5230,7 @@
|
||||||
"block": true,
|
"block": true,
|
||||||
"name": "Grid block",
|
"name": "Grid block",
|
||||||
"icon": "Table",
|
"icon": "Table",
|
||||||
"styles": [
|
"styles": ["size"],
|
||||||
"size"
|
|
||||||
],
|
|
||||||
"size": {
|
"size": {
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 400
|
"height": 400
|
||||||
|
@ -5245,23 +5243,49 @@
|
||||||
"key": "table",
|
"key": "table",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "columns",
|
||||||
|
"label": "Columns",
|
||||||
|
"key": "columns",
|
||||||
|
"dependsOn": "table"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "filter",
|
"type": "filter",
|
||||||
"label": "Filtering",
|
"label": "Filtering",
|
||||||
"key": "filter"
|
"key": "initialFilter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "field/sortable",
|
"type": "field/sortable",
|
||||||
"label": "Sort column",
|
"label": "Sort column",
|
||||||
"key": "sortColumn"
|
"key": "initialSortColumn"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "select",
|
"type": "select",
|
||||||
"label": "Sort order",
|
"label": "Sort order",
|
||||||
"key": "sortOrder",
|
"key": "initialSortOrder",
|
||||||
"options": ["Ascending", "Descending"],
|
"options": ["Ascending", "Descending"],
|
||||||
"defaultValue": "Ascending"
|
"defaultValue": "Ascending"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "select",
|
||||||
|
"label": "Row height",
|
||||||
|
"key": "initialRowHeight",
|
||||||
|
"placeholder": "Default",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"label": "Small",
|
||||||
|
"value": 36
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Medium",
|
||||||
|
"value": 64
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Large",
|
||||||
|
"value": 92
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"label": "Add rows",
|
"label": "Add rows",
|
||||||
|
|
|
@ -9,9 +9,10 @@
|
||||||
export let allowEditRows = true
|
export let allowEditRows = true
|
||||||
export let allowDeleteRows = true
|
export let allowDeleteRows = true
|
||||||
export let stripeRows = false
|
export let stripeRows = false
|
||||||
export let filter = null
|
export let initialFilter = null
|
||||||
export let sortColumn = null
|
export let initialSortColumn = null
|
||||||
export let sortOrder = null
|
export let initialSortOrder = null
|
||||||
|
export let initialRowHeight = null
|
||||||
|
|
||||||
const component = getContext("component")
|
const component = getContext("component")
|
||||||
const { styleable, API, builderStore } = getContext("sdk")
|
const { styleable, API, builderStore } = getContext("sdk")
|
||||||
|
@ -28,9 +29,10 @@
|
||||||
{allowEditRows}
|
{allowEditRows}
|
||||||
{allowDeleteRows}
|
{allowDeleteRows}
|
||||||
{stripeRows}
|
{stripeRows}
|
||||||
{filter}
|
{initialFilter}
|
||||||
{sortColumn}
|
{initialSortColumn}
|
||||||
{sortOrder}
|
{initialSortOrder}
|
||||||
|
{initialRowHeight}
|
||||||
showControls={false}
|
showControls={false}
|
||||||
allowExpandRows={false}
|
allowExpandRows={false}
|
||||||
allowSchemaChanges={false}
|
allowSchemaChanges={false}
|
||||||
|
|
|
@ -33,22 +33,6 @@
|
||||||
selected: allLarge,
|
selected: allLarge,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const changeColumnWidth = async width => {
|
|
||||||
columns.update(state => {
|
|
||||||
state.forEach(column => {
|
|
||||||
column.width = width
|
|
||||||
})
|
|
||||||
return state
|
|
||||||
})
|
|
||||||
if ($stickyColumn) {
|
|
||||||
stickyColumn.update(state => ({
|
|
||||||
...state,
|
|
||||||
width,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
await columns.actions.saveChanges()
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={anchor}>
|
<div bind:this={anchor}>
|
||||||
|
@ -70,7 +54,7 @@
|
||||||
{#each sizeOptions as option}
|
{#each sizeOptions as option}
|
||||||
<ActionButton
|
<ActionButton
|
||||||
quiet
|
quiet
|
||||||
on:click={() => changeColumnWidth(option.size)}
|
on:click={() => columns.actions.changeAllColumnWidths(option.size)}
|
||||||
selected={option.selected}
|
selected={option.selected}
|
||||||
>
|
>
|
||||||
{option.label}
|
{option.label}
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
GutterWidth,
|
GutterWidth,
|
||||||
DefaultRowHeight,
|
DefaultRowHeight,
|
||||||
} from "../lib/constants"
|
} from "../lib/constants"
|
||||||
import { memo } from "../../../utils"
|
|
||||||
|
|
||||||
export let API = null
|
export let API = null
|
||||||
export let tableId = null
|
export let tableId = null
|
||||||
|
@ -43,48 +42,26 @@
|
||||||
export let collaboration = true
|
export let collaboration = true
|
||||||
export let showAvatars = true
|
export let showAvatars = true
|
||||||
export let showControls = true
|
export let showControls = true
|
||||||
export let filter = null
|
export let initialFilter = null
|
||||||
export let sortColumn = null
|
export let initialSortColumn = null
|
||||||
export let sortOrder = null
|
export let initialSortOrder = null
|
||||||
|
export let initialRowHeight = null
|
||||||
|
|
||||||
// Unique identifier for DOM nodes inside this instance
|
// Unique identifier for DOM nodes inside this instance
|
||||||
const rand = Math.random()
|
const rand = Math.random()
|
||||||
|
|
||||||
// Stores derived from props.
|
|
||||||
// We use memo here to ensure redundant store reactions don't fire and cause
|
|
||||||
// wasted API calls.
|
|
||||||
const tableIdStore = memo(tableId)
|
|
||||||
const schemaOverridesStore = memo(schemaOverrides)
|
|
||||||
const filterStore = memo(filter)
|
|
||||||
const sortStore = memo({
|
|
||||||
column: sortColumn,
|
|
||||||
order: sortOrder,
|
|
||||||
})
|
|
||||||
const config = memo({
|
|
||||||
allowAddRows,
|
|
||||||
allowExpandRows,
|
|
||||||
allowEditRows,
|
|
||||||
allowDeleteRows,
|
|
||||||
allowSchemaChanges,
|
|
||||||
stripeRows,
|
|
||||||
showControls,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Build up context
|
// Build up context
|
||||||
let context = {
|
let context = {
|
||||||
API: API || createAPIClient(),
|
API: API || createAPIClient(),
|
||||||
rand,
|
rand,
|
||||||
config,
|
props: $$props,
|
||||||
tableId: tableIdStore,
|
|
||||||
schemaOverrides: schemaOverridesStore,
|
|
||||||
filter: filterStore,
|
|
||||||
sort: sortStore,
|
|
||||||
}
|
}
|
||||||
context = { ...context, ...createEventManagers() }
|
context = { ...context, ...createEventManagers() }
|
||||||
context = attachStores(context)
|
context = attachStores(context)
|
||||||
|
|
||||||
// Reference some stores for local use
|
// Reference some stores for local use
|
||||||
const {
|
const {
|
||||||
|
config,
|
||||||
isResizing,
|
isResizing,
|
||||||
isReordering,
|
isReordering,
|
||||||
ui,
|
ui,
|
||||||
|
@ -95,22 +72,23 @@
|
||||||
gridFocused,
|
gridFocused,
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
// Keep prop-derived stores up to date
|
// Keep config store up to date with props
|
||||||
$: tableIdStore.set(tableId)
|
|
||||||
$: schemaOverridesStore.set(schemaOverrides)
|
|
||||||
$: filterStore.set(filter)
|
|
||||||
$: sortStore.set({
|
|
||||||
column: sortColumn,
|
|
||||||
order: sortOrder,
|
|
||||||
})
|
|
||||||
$: config.set({
|
$: config.set({
|
||||||
|
tableId,
|
||||||
|
schemaOverrides,
|
||||||
allowAddRows,
|
allowAddRows,
|
||||||
allowSchemaChanges,
|
|
||||||
allowExpandRows,
|
allowExpandRows,
|
||||||
allowEditRows,
|
allowEditRows,
|
||||||
allowDeleteRows,
|
allowDeleteRows,
|
||||||
|
allowSchemaChanges,
|
||||||
stripeRows,
|
stripeRows,
|
||||||
|
collaboration,
|
||||||
|
showAvatars,
|
||||||
showControls,
|
showControls,
|
||||||
|
initialFilter,
|
||||||
|
initialSortColumn,
|
||||||
|
initialSortOrder,
|
||||||
|
initialRowHeight,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Set context for children to consume
|
// Set context for children to consume
|
||||||
|
|
|
@ -56,6 +56,23 @@ export const deriveStores = context => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updates the width of all columns
|
||||||
|
const changeAllColumnWidths = async width => {
|
||||||
|
columns.update(state => {
|
||||||
|
return state.map(col => ({
|
||||||
|
...col,
|
||||||
|
width,
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
if (get(stickyColumn)) {
|
||||||
|
stickyColumn.update(state => ({
|
||||||
|
...state,
|
||||||
|
width,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
await saveChanges()
|
||||||
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
|
@ -107,6 +124,7 @@ export const deriveStores = context => {
|
||||||
saveChanges,
|
saveChanges,
|
||||||
saveTable,
|
saveTable,
|
||||||
changePrimaryDisplay,
|
changePrimaryDisplay,
|
||||||
|
changeAllColumnWidths,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { writable } from "svelte/store"
|
||||||
|
import { derivedMemo } from "../../../utils"
|
||||||
|
|
||||||
|
export const createStores = context => {
|
||||||
|
const config = writable(context.props)
|
||||||
|
const getProp = prop => derivedMemo(config, $config => $config[prop])
|
||||||
|
|
||||||
|
// Derive and memoize some props so that we can react to them in isolation
|
||||||
|
const tableId = getProp("tableId")
|
||||||
|
const initialSortColumn = getProp("initialSortColumn")
|
||||||
|
const initialSortOrder = getProp("initialSortOrder")
|
||||||
|
const initialFilter = getProp("initialFilter")
|
||||||
|
const initialRowHeight = getProp("initialRowHeight")
|
||||||
|
|
||||||
|
return {
|
||||||
|
config,
|
||||||
|
tableId,
|
||||||
|
initialSortColumn,
|
||||||
|
initialSortOrder,
|
||||||
|
initialFilter,
|
||||||
|
initialRowHeight,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { writable } from "svelte/store"
|
||||||
|
import { derivedMemo } from "../../../utils"
|
||||||
|
|
||||||
|
export const createStores = context => {
|
||||||
|
const { props } = context
|
||||||
|
|
||||||
|
// Initialise to default props
|
||||||
|
const filter = writable(props.initialFilter)
|
||||||
|
|
||||||
|
return {
|
||||||
|
filter,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialise = context => {
|
||||||
|
const { filter, initialFilter } = context
|
||||||
|
|
||||||
|
// Reset filter when initial filter prop changes
|
||||||
|
initialFilter.subscribe(filter.set)
|
||||||
|
}
|
|
@ -11,8 +11,14 @@ import * as Users from "./users"
|
||||||
import * as Validation from "./validation"
|
import * as Validation from "./validation"
|
||||||
import * as Viewport from "./viewport"
|
import * as Viewport from "./viewport"
|
||||||
import * as Clipboard from "./clipboard"
|
import * as Clipboard from "./clipboard"
|
||||||
|
import * as Config from "./config"
|
||||||
|
import * as Sort from "./sort"
|
||||||
|
import * as Filter from "./filter"
|
||||||
|
|
||||||
const DependencyOrderedStores = [
|
const DependencyOrderedStores = [
|
||||||
|
Config,
|
||||||
|
Sort,
|
||||||
|
Filter,
|
||||||
Bounds,
|
Bounds,
|
||||||
Scroll,
|
Scroll,
|
||||||
Rows,
|
Rows,
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { writable } from "svelte/store"
|
||||||
|
|
||||||
|
export const createStores = context => {
|
||||||
|
const { props } = context
|
||||||
|
|
||||||
|
// Initialise to default props
|
||||||
|
const sort = writable({
|
||||||
|
column: props.initialSortColumn,
|
||||||
|
order: props.initialSortOrder || "ascending",
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
sort,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initialise = context => {
|
||||||
|
const { sort, initialSortColumn, initialSortOrder } = context
|
||||||
|
|
||||||
|
// Reset sort when initial sort props change
|
||||||
|
initialSortColumn.subscribe(newSortColumn => {
|
||||||
|
sort.update(state => ({ ...state, column: newSortColumn }))
|
||||||
|
})
|
||||||
|
initialSortOrder.subscribe(newSortOrder => {
|
||||||
|
sort.update(state => ({ ...state, order: newSortOrder }))
|
||||||
|
})
|
||||||
|
}
|
|
@ -8,12 +8,13 @@ import {
|
||||||
NewRowID,
|
NewRowID,
|
||||||
} from "../lib/constants"
|
} from "../lib/constants"
|
||||||
|
|
||||||
export const createStores = () => {
|
export const createStores = context => {
|
||||||
|
const { props } = context
|
||||||
const focusedCellId = writable(null)
|
const focusedCellId = writable(null)
|
||||||
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(DefaultRowHeight)
|
const rowHeight = writable(props.initialRowHeight || 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)
|
||||||
|
@ -98,9 +99,9 @@ export const deriveStores = context => {
|
||||||
|
|
||||||
// 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) {
|
||||||
return 3
|
return 3
|
||||||
} else if ($rowHeight === MediumRowHeight) {
|
} else if ($rowHeight >= MediumRowHeight) {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
|
@ -133,6 +134,7 @@ export const initialise = context => {
|
||||||
hoveredRowId,
|
hoveredRowId,
|
||||||
table,
|
table,
|
||||||
rowHeight,
|
rowHeight,
|
||||||
|
initialRowHeight,
|
||||||
} = context
|
} = context
|
||||||
|
|
||||||
// Ensure we clear invalid rows from state if they disappear
|
// Ensure we clear invalid rows from state if they disappear
|
||||||
|
@ -189,4 +191,7 @@ export const initialise = context => {
|
||||||
table.subscribe($table => {
|
table.subscribe($table => {
|
||||||
rowHeight.set($table?.rowHeight || DefaultRowHeight)
|
rowHeight.set($table?.rowHeight || DefaultRowHeight)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Reset row height when initial row height prop changes
|
||||||
|
initialRowHeight.subscribe(rowHeight.set)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,5 +3,5 @@ export * as JSONUtils from "./json"
|
||||||
export * as CookieUtils from "./cookies"
|
export * as CookieUtils from "./cookies"
|
||||||
export * as RoleUtils from "./roles"
|
export * as RoleUtils from "./roles"
|
||||||
export * as Utils from "./utils"
|
export * as Utils from "./utils"
|
||||||
export { memo } from "./memo"
|
export { memo, derivedMemo } from "./memo"
|
||||||
export { createWebsocket } from "./websocket"
|
export { createWebsocket } from "./websocket"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { writable, get } from "svelte/store"
|
import { writable, get, derived } from "svelte/store"
|
||||||
|
|
||||||
// A simple svelte store which deeply compares all changes and ensures that
|
// A simple svelte store which deeply compares all changes and ensures that
|
||||||
// subscribed children will only fire when a new value is actually set
|
// subscribed children will only fire when a new value is actually set
|
||||||
|
@ -33,3 +33,11 @@ export const memo = initialValue => {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enriched version of svelte's derived store which returns a memo
|
||||||
|
export const derivedMemo = (store, derivation) => {
|
||||||
|
const derivedStore = derived(store, derivation)
|
||||||
|
const memoStore = memo(get(derivedStore))
|
||||||
|
derivedStore.subscribe(memoStore.set)
|
||||||
|
return memoStore
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue