1
0
Fork 0
mirror of synced 2024-09-20 11:27:56 +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 getFieldAttribute(getOptionLabel, value, options)
return (
getFieldAttribute(getOptionLabel, value, options) || "Choose an option"
)
}
const selectOption = value => {

View file

@ -25,13 +25,23 @@
const dispatch = createEventDispatcher()
const flipDuration = 130
const targetOptions = [
{
label: "Cell",
value: "cell",
},
{
label: "Row",
value: "row",
},
]
const conditionOptions = [
{
label: "Update background color",
label: "Background color",
value: "backgroundColor",
},
{
label: "Update text color",
label: "Text color",
value: "textColor",
},
]
@ -68,6 +78,7 @@
const addCondition = () => {
const condition = {
id: generate(),
target: targetOptions[0].value,
metadataKey: conditionOptions[0].value,
operator: Constants.OperatorOptions.Equals.value,
valueType: FieldType.STRING,
@ -123,7 +134,7 @@
<DrawerContent slot="body">
<div class="container">
<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}
<div
class="conditions"
@ -150,6 +161,12 @@
>
<Icon name="DragHandle" size="XL" />
</div>
<span>Update</span>
<Select
placeholder={null}
options={targetOptions}
bind:value={condition.target}
/>
<Select
placeholder={null}
options={conditionOptions}
@ -235,7 +252,7 @@
}
.condition {
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;
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": [

View file

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

View file

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

View file

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

View file

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

View file

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