1
0
Fork 0
mirror of synced 2024-09-20 19:33:10 +12:00

Update table conditions to apply both row and cell conditions via same configuration

This commit is contained in:
Andrew Kingston 2024-07-16 14:01:50 +01:00
parent d2e292b4ff
commit ee984b6a19
No known key found for this signature in database
8 changed files with 71 additions and 115 deletions

View file

@ -62,7 +62,9 @@
return placeholder || "Choose an option" return placeholder || "Choose an option"
} }
return getFieldAttribute(getOptionLabel, value, options) return (
getFieldAttribute(getOptionLabel, value, options) || "Choose an option"
)
} }
const selectOption = value => { const selectOption = value => {

View file

@ -25,13 +25,23 @@
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const flipDuration = 130 const flipDuration = 130
const targetOptions = [
{
label: "Cell",
value: "cell",
},
{
label: "Row",
value: "row",
},
]
const conditionOptions = [ const conditionOptions = [
{ {
label: "Update background color", label: "Background color",
value: "backgroundColor", value: "backgroundColor",
}, },
{ {
label: "Update text color", label: "Text color",
value: "textColor", value: "textColor",
}, },
] ]
@ -68,6 +78,7 @@
const addCondition = () => { const addCondition = () => {
const condition = { const condition = {
id: generate(), id: generate(),
target: targetOptions[0].value,
metadataKey: conditionOptions[0].value, metadataKey: conditionOptions[0].value,
operator: Constants.OperatorOptions.Equals.value, operator: Constants.OperatorOptions.Equals.value,
valueType: FieldType.STRING, valueType: FieldType.STRING,
@ -123,7 +134,7 @@
<DrawerContent slot="body"> <DrawerContent slot="body">
<div class="container"> <div class="container">
<Layout noPadding> <Layout noPadding>
Update the appearance of cells based on their value. Update the appearance of cells and rows based on their value.
{#if tempValue.length} {#if tempValue.length}
<div <div
class="conditions" class="conditions"
@ -150,6 +161,12 @@
> >
<Icon name="DragHandle" size="XL" /> <Icon name="DragHandle" size="XL" />
</div> </div>
<span>Update</span>
<Select
placeholder={null}
options={targetOptions}
bind:value={condition.target}
/>
<Select <Select
placeholder={null} placeholder={null}
options={conditionOptions} options={conditionOptions}
@ -235,7 +252,7 @@
} }
.condition { .condition {
display: grid; display: grid;
grid-template-columns: auto 1fr auto auto auto 1fr 1fr 1fr auto auto; grid-template-columns: auto auto 1fr 1fr auto auto auto 1fr 1fr 1fr auto auto;
align-items: center; align-items: center;
grid-column-gap: var(--spacing-l); grid-column-gap: var(--spacing-l);
} }

View file

@ -7329,18 +7329,6 @@
] ]
} }
] ]
},
{
"section": true,
"tag": "condition",
"name": "Row conditions",
"settings": [
{
"type": "rowConditions",
"key": "rowConditions",
"nested": true
}
]
} }
], ],
"context": [ "context": [

View file

@ -19,7 +19,6 @@
export let columns = null export let columns = null
export let onRowClick = null export let onRowClick = null
export let buttons = null export let buttons = null
export let rowConditions = null
const context = getContext("context") const context = getContext("context")
const component = getContext("component") const component = getContext("component")
@ -173,7 +172,6 @@
{fixedRowHeight} {fixedRowHeight}
{columnWhitelist} {columnWhitelist}
{schemaOverrides} {schemaOverrides}
{rowConditions}
canAddRows={allowAddRows} canAddRows={allowAddRows}
canEditRows={allowEditRows} canEditRows={allowEditRows}
canDeleteRows={allowDeleteRows} canDeleteRows={allowDeleteRows}

View file

@ -131,8 +131,8 @@
on:click={handleClick} on:click={handleClick}
width={column.width} width={column.width}
metadata={{ metadata={{
...row.__metadata, ...row.__metadata?.row,
...row.__cellMetadata?.[column.name], ...row.__metadata?.cell[column.name],
}} }}
> >
<svelte:component <svelte:component

View file

@ -54,7 +54,7 @@
selected={rowSelected} selected={rowSelected}
{defaultHeight} {defaultHeight}
rowIdx={row?.__idx} rowIdx={row?.__idx}
metadata={row?.__metadata} metadata={row?.__metadata?.row}
> >
<div class="gutter"> <div class="gutter">
{#if $$slots.default} {#if $$slots.default}

View file

@ -1,15 +1,13 @@
import { writable, get } from "svelte/store" import { writable, get } from "svelte/store"
import { derivedMemo, QueryUtils } from "../../../utils" import { derivedMemo, QueryUtils } from "../../../utils"
import { OperatorOptions } from "@budibase/shared-core"
import { FieldType } from "@budibase/types"
import { processString, processStringSync } from "@budibase/string-templates"
export const createStores = () => { export const createStores = () => {
const cellMetadata = writable({}) const metadata = writable({})
const rowMetadata = writable({})
metadata.subscribe(console.log)
return { return {
cellMetadata, metadata,
rowMetadata,
} }
} }
@ -18,7 +16,7 @@ export const deriveStores = context => {
// Derive and memoize the cell conditions present in our columns so that we // Derive and memoize the cell conditions present in our columns so that we
// only recompute condition metadata when absolutely necessary // only recompute condition metadata when absolutely necessary
const cellConditions = derivedMemo(columns, $columns => { const conditions = derivedMemo(columns, $columns => {
let newConditions = [] let newConditions = []
for (let column of $columns) { for (let column of $columns) {
for (let condition of column.conditions || []) { for (let condition of column.conditions || []) {
@ -33,73 +31,43 @@ export const deriveStores = context => {
}) })
return { return {
cellConditions, conditions,
} }
} }
export const initialise = context => { export const initialise = context => {
const { cellMetadata, cellConditions, rowConditions, rowMetadata, rows } = const { metadata, conditions, rows } = context
context
// Recompute all cell metadata if cell conditions change // Recompute all cell metadata if cell conditions change
cellConditions.subscribe($conditions => { conditions.subscribe($conditions => {
let metadata = {} // Build new metadata
let newMetadata = {}
if ($conditions?.length) { if ($conditions?.length) {
for (let row of get(rows)) { for (let row of get(rows)) {
metadata[row._id] = evaluateCellConditions(row, $conditions) newMetadata[row._id] = evaluateConditions(row, $conditions)
} }
} }
cellMetadata.set(metadata) metadata.set(newMetadata)
})
// Recompute all row metadata if row conditions change
rowConditions.subscribe($conditions => {
let metadata = {}
if ($conditions?.length) {
for (let row of get(rows)) {
metadata[row._id] = evaluateRowConditions(row, $conditions)
}
}
rowMetadata.set(metadata)
}) })
// Recompute metadata for specific rows when they change // Recompute metadata for specific rows when they change
rows.subscribe($rows => { rows.subscribe($rows => {
const $cellConditions = get(cellConditions) const $conditions = get(conditions)
const $rowConditions = get(rowConditions) if (!$conditions?.length) {
const processCells = $cellConditions?.length > 0
const processRows = $rowConditions?.length > 0
if (!processCells && !processRows) {
return return
} }
const $cellMetadata = get(cellMetadata) const $metadata = get(metadata)
const $rowMetadata = get(rowMetadata) let metadataUpdates = {}
let cellUpdates = {}
let rowUpdates = {}
for (let row of $rows) { for (let row of $rows) {
// Process cell metadata if (!row._rev || $metadata[row._id]?.version !== row._rev) {
if (processCells) { console.log("reevalute", row._id)
if (!row._rev || $cellMetadata[row._id]?.version !== row._rev) { metadataUpdates[row._id] = evaluateConditions(row, $conditions)
cellUpdates[row._id] = evaluateCellConditions(row, $cellConditions)
} }
} }
// Process row metadata if (Object.keys(metadataUpdates).length) {
if (processRows) { metadata.update(state => ({
if (!row._rev || $rowMetadata[row._id]?.version !== row._rev) {
rowUpdates[row._id] = evaluateRowConditions(row, $rowConditions)
}
}
}
if (Object.keys(cellUpdates).length) {
cellMetadata.update(state => ({
...state, ...state,
...cellUpdates, ...metadataUpdates,
}))
}
if (Object.keys(rowUpdates).length) {
rowMetadata.update(state => ({
...state,
...rowUpdates,
})) }))
} }
}) })
@ -107,8 +75,12 @@ export const initialise = context => {
// Evaluates an array of cell conditions against a certain row and returns the // Evaluates an array of cell conditions against a certain row and returns the
// resultant metadata // resultant metadata
const evaluateCellConditions = (row, conditions) => { const evaluateConditions = (row, conditions) => {
let metadata = { version: row._rev } let metadata = {
version: row._rev,
row: {},
cell: {},
}
for (let condition of conditions) { for (let condition of conditions) {
try { try {
let { let {
@ -118,6 +90,7 @@ const evaluateCellConditions = (row, conditions) => {
operator, operator,
metadataKey, metadataKey,
metadataValue, metadataValue,
target,
} = condition } = condition
let value = row[column] let value = row[column]
@ -147,29 +120,17 @@ const evaluateCellConditions = (row, conditions) => {
const query = QueryUtils.buildQuery([luceneFilter]) const query = QueryUtils.buildQuery([luceneFilter])
const result = QueryUtils.runQuery([{ value }], query) const result = QueryUtils.runQuery([{ value }], query)
if (result.length > 0) { if (result.length > 0) {
if (!metadata[column]) { if (target === "row") {
metadata[column] = {} metadata.row = {
...metadata.row,
[metadataKey]: metadataValue,
}
} else {
metadata.cell[column] = {
...metadata.cell[column],
[metadataKey]: metadataValue,
}
} }
metadata[column][metadataKey] = metadataValue
}
} catch {
// Swallow
}
}
return metadata
}
// Evaluates an array of row conditions against a certain row and returns the
// resultant metadata
const evaluateRowConditions = (row, conditions) => {
let metadata = { version: row._rev }
for (let condition of conditions) {
try {
const { metadataKey, metadataValue, value } = condition
console.log("JS")
const result = processStringSync(value, { row })
if (result === true) {
metadata[metadataKey] = metadataValue
} }
} catch { } catch {
// Swallow // Swallow

View file

@ -11,8 +11,7 @@ export const deriveStores = context => {
width, width,
height, height,
rowChangeCache, rowChangeCache,
cellMetadata, metadata,
rowMetadata,
} = context } = context
// Derive visible rows // Derive visible rows
@ -31,29 +30,20 @@ export const deriveStores = context => {
} }
) )
const renderedRows = derived( const renderedRows = derived(
[ [rows, scrolledRowCount, visualRowCapacity, rowChangeCache, metadata],
rows,
scrolledRowCount,
visualRowCapacity,
rowChangeCache,
cellMetadata,
rowMetadata,
],
([ ([
$rows, $rows,
$scrolledRowCount, $scrolledRowCount,
$visualRowCapacity, $visualRowCapacity,
$rowChangeCache, $rowChangeCache,
$cellMetadata, $metadata,
$rowMetadata,
]) => { ]) => {
return $rows return $rows
.slice($scrolledRowCount, $scrolledRowCount + $visualRowCapacity) .slice($scrolledRowCount, $scrolledRowCount + $visualRowCapacity)
.map(row => ({ .map(row => ({
...row, ...row,
...$rowChangeCache[row._id], ...$rowChangeCache[row._id],
__metadata: $rowMetadata[row._id], __metadata: $metadata[row._id],
__cellMetadata: $cellMetadata[row._id],
})) }))
} }
) )