@toclocoinc/lattice-grid 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -34
- package/docs/AI-SKILL.md +22 -22
- package/docs/API.html +3026 -233
- package/docs/CHART-CODES.md +60 -60
- package/docs/api-detail.html +365 -365
- package/lattice-grid.d.ts +390 -69
- package/lattice-grid.esm.min.js +952 -74
- package/lattice-grid.min.cjs +952 -74
- package/lattice-grid.min.css +1 -1
- package/lattice-grid.min.js +952 -74
- package/modules/charts.esm.min.js +308 -18
- package/modules/devtools.esm.min.js +8 -8
- package/modules/dhtmlx-compat.esm.min.js +958 -80
- package/modules/htmx.esm.min.js +919 -75
- package/modules/htmx.min.cjs +919 -75
- package/modules/htmx.min.js +919 -75
- package/modules/react.esm.min.js +2 -2
- package/modules/svelte.esm.min.js +2 -2
- package/modules/vue.esm.min.js +2 -2
- package/modules/webcomponent.esm.min.js +952 -74
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,24 +4,24 @@
|
|
|
4
4
|
dependencies, no build step required. Optional adapters for React, Vue, Svelte
|
|
5
5
|
and Web Components ship alongside it.
|
|
6
6
|
|
|
7
|
-
Version 1.
|
|
7
|
+
Version 1.12.0 · [latticegrid.dev](https://www.latticegrid.dev) · TOCLOCO Inc
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## What's here
|
|
12
12
|
|
|
13
13
|
This repository is the distribution: the built library, its type declarations
|
|
14
|
-
and the documentation. Everything is self-contained
|
|
14
|
+
and the documentation. Everything is self-contained: nothing is fetched at
|
|
15
15
|
runtime, not a CDN, not a font, not an icon sprite.
|
|
16
16
|
|
|
17
17
|
| File | What it is |
|
|
18
18
|
|---|---|
|
|
19
|
-
| `lattice-grid.min.js` | The library. UMD
|
|
19
|
+
| `lattice-grid.min.js` | The library. UMD: works with a `<script>` tag. |
|
|
20
20
|
| `lattice-grid.esm.min.js` | The same, as an ES module. |
|
|
21
21
|
| `lattice-grid.min.css` | The theme. Required. |
|
|
22
22
|
| `lattice-grid.d.ts` | TypeScript declarations. |
|
|
23
23
|
| `docs/API.html` | The complete API reference. |
|
|
24
|
-
| `docs/api-detail.html` | The developer guide
|
|
24
|
+
| `docs/api-detail.html` | The developer guide: what each part does, and why. |
|
|
25
25
|
|
|
26
26
|
Every module is optional and none of them is loaded unless you import it.
|
|
27
27
|
|
|
@@ -32,7 +32,7 @@ Every module is optional and none of them is loaded unless you import it.
|
|
|
32
32
|
| `modules/vue.esm.min.js` | Vue adapter. |
|
|
33
33
|
| `modules/svelte.esm.min.js` | Svelte adapter. |
|
|
34
34
|
| `modules/webcomponent.esm.min.js` | `<lattice-grid>` as a custom element. |
|
|
35
|
-
| `modules/htmx.esm.min.js` | htmx integration
|
|
35
|
+
| `modules/htmx.esm.min.js` | htmx integration: survives htmx's DOM swaps, hydrates from a server-rendered `<table>`, and drives sort, filter and infinite scroll over plain htmx requests. UMD and CJS builds sit beside it. |
|
|
36
36
|
| `modules/dhtmlx-compat.esm.min.js` | A compatibility wrapper for dhtmlx Grid, for moving an existing integration across without rewriting it. |
|
|
37
37
|
| `modules/devtools.esm.min.js` | The devtools panel, including the accessibility checks. |
|
|
38
38
|
|
|
@@ -55,20 +55,20 @@ enough to know whether the grid covers what you need.
|
|
|
55
55
|
- **Live data.** `rows.apply({add, update, remove})` patches in place: the grid
|
|
56
56
|
re-queries the stages a change actually touched and repaints the cells that
|
|
57
57
|
moved. A feed can be paused and resumed with the queue held.
|
|
58
|
-
- **Any source.** Rows in memory, or a source you write
|
|
58
|
+
- **Any source.** Rows in memory, or a source you write: server-side paging,
|
|
59
59
|
infinite scroll, streaming, or an async provider. Sorting and filtering can be
|
|
60
60
|
handed to the server or left to the grid.
|
|
61
61
|
|
|
62
62
|
### Working with the data
|
|
63
63
|
|
|
64
|
-
- **Editing.** Cell, row and form editing, with twenty-three editors
|
|
64
|
+
- **Editing.** Cell, row and form editing, with twenty-three editors: text,
|
|
65
65
|
number, date, time, select, multi-select, colour, rating, slider, segmented,
|
|
66
66
|
code, password, icon picker and more. Validation, async commits, optimistic
|
|
67
67
|
updates with rollback, and a full undo history.
|
|
68
68
|
- **Selection and ranges.** Cell, row, column and rectangular range selection,
|
|
69
69
|
with clipboard behaviour that round-trips through Excel.
|
|
70
70
|
- **Fill, copy and paste** across a range, including formulas.
|
|
71
|
-
- **Formulas.** A closed, safe expression language
|
|
71
|
+
- **Formulas.** A closed, safe expression language, no `eval`, no host access ,
|
|
72
72
|
with maths, text, logic, date and statistical functions, evaluated against
|
|
73
73
|
other columns.
|
|
74
74
|
- **Export.** CSV with fields sanitised against formula injection, real `.xlsx`
|
|
@@ -79,18 +79,18 @@ enough to know whether the grid covers what you need.
|
|
|
79
79
|
### Seeing the data
|
|
80
80
|
|
|
81
81
|
- **Charts.** `modules/charts` draws thirty-five chart types from the grid's own
|
|
82
|
-
data
|
|
82
|
+
data: line, bar, area, scatter, pie, donut, sunburst, treemap, radar, gauge,
|
|
83
83
|
funnel, heatmap, histogram, box plot, candlestick, combo, geomap, sankey,
|
|
84
84
|
chord, network, stream, violin, gantt and more. They follow the grid's
|
|
85
85
|
filters, and clicking a mark can filter it in turn.
|
|
86
|
-
- **Statistics.** `grid.statistics` profiles a column in one pass
|
|
86
|
+
- **Statistics.** `grid.statistics` profiles a column in one pass: count,
|
|
87
87
|
missing, distinct, five-number summary, standard deviation, outliers and a
|
|
88
|
-
histogram
|
|
88
|
+
histogram, and answers correlations and weighted averages. Thirty-eight
|
|
89
89
|
reduction kernels are available to the totals row, and you can register your
|
|
90
90
|
own.
|
|
91
91
|
- **Shadow columns.** Values the grid maintains about itself: how many times a
|
|
92
92
|
row has changed, what a value was when the page loaded, how fast it is moving,
|
|
93
|
-
its rank, percentile or share of the total. Real columns
|
|
93
|
+
its rank, percentile or share of the total. Real columns: sortable,
|
|
94
94
|
filterable, exportable, saved into a view.
|
|
95
95
|
- **Conditional formatting** as runtime state a user can change, with rules that
|
|
96
96
|
either name a threshold or describe the data: the top decile, the outliers,
|
|
@@ -102,14 +102,14 @@ enough to know whether the grid covers what you need.
|
|
|
102
102
|
|
|
103
103
|
- **Tool panels** for columns, filters, views, quick filter, formatting and
|
|
104
104
|
statistics, docked or as an icon rail.
|
|
105
|
-
- **Saved views
|
|
105
|
+
- **Saved views**, the whole grid state as a named, shareable object, stored
|
|
106
106
|
on your server or in the browser.
|
|
107
107
|
- **Column menu, context menu and status bar**, each extensible with your own
|
|
108
108
|
items.
|
|
109
109
|
- **Pinned columns and rows**, column groups, resize, reorder, autosize, and a
|
|
110
110
|
density control.
|
|
111
111
|
- **Master–detail rows**, tree data, and full-width rows.
|
|
112
|
-
- **Presence
|
|
112
|
+
- **Presence**: live cursors, selections and edit locks for collaborative use,
|
|
113
113
|
carrying intent and never values.
|
|
114
114
|
- **Comments** threaded on cells, and an annotation layer for presenting.
|
|
115
115
|
- **Full-screen mode**, print, and image capture.
|
|
@@ -126,7 +126,7 @@ enough to know whether the grid covers what you need.
|
|
|
126
126
|
a reset that keeps a host page's stylesheet out.
|
|
127
127
|
- **Typed.** Complete TypeScript declarations, checked against the runtime on
|
|
128
128
|
every build.
|
|
129
|
-
- **Zero runtime dependencies.** Nothing is fetched at runtime
|
|
129
|
+
- **Zero runtime dependencies.** Nothing is fetched at runtime, not a CDN, not
|
|
130
130
|
a font, not an icon sprite.
|
|
131
131
|
|
|
132
132
|
---
|
|
@@ -189,7 +189,7 @@ const LatticeGrid = createLatticeGrid({ React, createGrid });
|
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
The web component is the exception: it carries the grid inside it, so use it *or*
|
|
192
|
-
`createGrid` in a page, not both
|
|
192
|
+
`createGrid` in a page, not both, two copies keep separate registries, and a
|
|
193
193
|
renderer registered through one will not appear in the other.
|
|
194
194
|
|
|
195
195
|
The full setup for each framework is in the developer guide.
|
|
@@ -200,9 +200,9 @@ Two integrations that are not framework adapters.
|
|
|
200
200
|
|
|
201
201
|
**htmx.** `modules/htmx` lets a grid survive htmx's own DOM swaps, hydrate from
|
|
202
202
|
a server-rendered `<table>`, and drive sort, filter and infinite scroll over
|
|
203
|
-
plain htmx requests. It is a complete package rather than an add-on
|
|
203
|
+
plain htmx requests. It is a complete package rather than an add-on ,
|
|
204
204
|
`createGrid`, `autoInit`, `hydrateTable`, `readTable`, `serialiseState` and
|
|
205
|
-
`restoreState` are re-exported alongside its own functions
|
|
205
|
+
`restoreState` are re-exported alongside its own functions, so a page using it
|
|
206
206
|
imports this and never the base package as well.
|
|
207
207
|
|
|
208
208
|
**dhtmlx.** `modules/dhtmlx-compat` exposes a dhtmlx Grid-shaped API over
|
|
@@ -212,7 +212,7 @@ than rewriting it in one go.
|
|
|
212
212
|
### TypeScript
|
|
213
213
|
|
|
214
214
|
Declarations ship in the box and are wired up in `package.json`, so editors find
|
|
215
|
-
them without configuration
|
|
215
|
+
them without configuration: autocomplete, inline documentation and type
|
|
216
216
|
checking against the real API.
|
|
217
217
|
|
|
218
218
|
```ts
|
|
@@ -228,7 +228,7 @@ your editor tells you and what the grid does cannot drift apart.
|
|
|
228
228
|
|
|
229
229
|
A grid usually lives in whatever box the page layout gave it, and that box is
|
|
230
230
|
usually too small for the job. The left rail's last button fills the browser
|
|
231
|
-
window with the grid; clicking it again
|
|
231
|
+
window with the grid; clicking it again, or pressing <kbd>Esc</kbd>: puts it
|
|
232
232
|
back exactly where it was.
|
|
233
233
|
|
|
234
234
|
```js
|
|
@@ -248,8 +248,8 @@ it was found.
|
|
|
248
248
|
|
|
249
249
|
## Data types
|
|
250
250
|
|
|
251
|
-
Seven built-in types
|
|
252
|
-
`object` and `lookup
|
|
251
|
+
Seven built-in types: `text`, `number`, `boolean`, `date`, `dateString`,
|
|
252
|
+
`object` and `lookup`: cover ordinary business data and are inferred from your
|
|
253
253
|
rows automatically.
|
|
254
254
|
|
|
255
255
|
Beyond those, Lattice Grid ships **88 technical field types** for the data that
|
|
@@ -259,16 +259,16 @@ editor, filter, alignment, clipboard behaviour and Excel mapping.
|
|
|
259
259
|
|
|
260
260
|
| Group | Types |
|
|
261
261
|
|---|---|
|
|
262
|
-
| **Network** | `ipv4`, `ipv6`, `cidr
|
|
263
|
-
| **Time** | `time`, `datetime`, `duration
|
|
264
|
-
| **Radix** | `hex`, `hex8`, `hex16`, `hex32`, `binary`, `binary8`, `octal
|
|
265
|
-
| **Data** | `bytes`, `megabytes`, `gigabytes`, `bitrate`, `gigabits
|
|
262
|
+
| **Network** | `ipv4`, `ipv6`, `cidr`: sort in address order, not lexically, so `10.0.0.9` comes before `10.0.0.10`. |
|
|
263
|
+
| **Time** | `time`, `datetime`, `duration`: three things a single `date` type keeps being asked to be. |
|
|
264
|
+
| **Radix** | `hex`, `hex8`, `hex16`, `hex32`, `binary`, `binary8`, `octal`, the stored value stays a plain number; the base is presentation and input only. |
|
|
265
|
+
| **Data** | `bytes`, `megabytes`, `gigabytes`, `bitrate`, `gigabits`: shows `10 GB`, accepts `10,000M` typed in, stores `10`. Decimal and binary ladders are both first class, because `MB` and `MiB` are different quantities. |
|
|
266
266
|
| **Mechanical** | length, mass, duration, speed, acceleration, area, volume, force, pressure, torque, density, energy, power, angle, `rpm` and angular velocity. |
|
|
267
267
|
| **Fluid and thermal** | volumetric flow, mass flow, dynamic and kinematic viscosity, thermal conductivity, specific heat, and temperature in `celsius`, `fahrenheit` and `kelvin`. |
|
|
268
|
-
| **Electrical and SI** | voltage, current, resistance, capacitance, inductance, charge, conductance, frequency, flux density, luminous flux, luminous intensity, illuminance and substance
|
|
268
|
+
| **Electrical and SI** | voltage, current, resistance, capacitance, inductance, charge, conductance, frequency, flux density, luminous flux, luminous intensity, illuminance and substance: all auto-prefixed across the SI range. |
|
|
269
269
|
| **Chemistry and radiation** | `molarity`, `ppm`, `ppb`, absorbed dose, equivalent dose, radioactivity and dose rate. |
|
|
270
|
-
| **Finance and ratios** | `basisPoints`, `ratio`, `percentRate`, and decibels
|
|
271
|
-
| **Structured** | `json`, `secret
|
|
270
|
+
| **Finance and ratios** | `basisPoints`, `ratio`, `percentRate`, and decibels, which are reduced logarithmically, not averaged. |
|
|
271
|
+
| **Structured** | `json`, `secret`: `secret` is write-only: editable, never displayed, never exported. |
|
|
272
272
|
|
|
273
273
|
### Units of your own
|
|
274
274
|
|
|
@@ -297,7 +297,7 @@ createGrid(el, {
|
|
|
297
297
|
|
|
298
298
|
`display: 'auto'` walks the ladder and picks the most readable rung, so 1,500
|
|
299
299
|
tex renders as `1.5 ktex`. A unit given `{ auto: false }` stays off that ladder
|
|
300
|
-
while remaining accepted on input and available as an explicit `display
|
|
300
|
+
while remaining accepted on input and available as an explicit `display`: which
|
|
301
301
|
is how imperial units sit beside metric ones without an auto readout jumping
|
|
302
302
|
between the two.
|
|
303
303
|
|
|
@@ -313,15 +313,15 @@ createUnitType({ system: 'money', unit: '$', placement: 'prefix', decimals: 2 })
|
|
|
313
313
|
```
|
|
314
314
|
|
|
315
315
|
Whatever the display, **the stored value is always a plain number in the
|
|
316
|
-
column's base unit
|
|
316
|
+
column's base unit**, so sorting, filtering, grouping, totals and the pivot all
|
|
317
317
|
work on the number and never on the text.
|
|
318
318
|
|
|
319
319
|
---
|
|
320
320
|
|
|
321
321
|
## Documentation
|
|
322
322
|
|
|
323
|
-
- **[API reference](docs/API.html)
|
|
324
|
-
- **[Developer guide](docs/api-detail.html)
|
|
323
|
+
- **[API reference](docs/API.html)**: every namespace, method, config key and event.
|
|
324
|
+
- **[Developer guide](docs/api-detail.html)**: what each part does and why, with worked examples.
|
|
325
325
|
|
|
326
326
|
---
|
|
327
327
|
|
|
@@ -335,7 +335,7 @@ edition, no pro tier, no feature held back behind a key.
|
|
|
335
335
|
- **Licensed to deploy.** On any other host, an unlicensed grid renders
|
|
336
336
|
everything and carries a small trial watermark.
|
|
337
337
|
|
|
338
|
-
Nothing is ever disabled, degraded or withheld
|
|
338
|
+
Nothing is ever disabled, degraded or withheld, the failure to avoid is a
|
|
339
339
|
production screen breaking because a licence lapsed over a weekend. A key
|
|
340
340
|
removes the watermark; that is the whole of what it does.
|
|
341
341
|
|
package/docs/AI-SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# The AI skill layer
|
|
2
2
|
|
|
3
3
|
A prompt input above the grid that turns "EMEA deals over 50k, biggest first"
|
|
4
|
-
into a filter and a sort
|
|
4
|
+
into a filter and a sort: via whichever language model you choose.
|
|
5
5
|
|
|
6
6
|
This document has two halves. The first is for the developer wiring it up. The
|
|
7
7
|
second is written to be handed to a model, and describes the grid as a skill it
|
|
@@ -14,18 +14,18 @@ can drive.
|
|
|
14
14
|
**The grid never calls a language model. It makes no network request of any
|
|
15
15
|
kind.** It calls one async callback you supply, and whatever that callback
|
|
16
16
|
returns is validated and previewed. You own the model, the API key, the
|
|
17
|
-
request, and
|
|
17
|
+
request, and (the part that matters) the privacy decision.
|
|
18
18
|
|
|
19
19
|
By default the callback receives:
|
|
20
20
|
|
|
21
|
-
- `schema
|
|
21
|
+
- `schema`, the generated description of your columns: ids, titles, types,
|
|
22
22
|
which are filterable/sortable/groupable, and the declared option lists of
|
|
23
23
|
lookup columns.
|
|
24
|
-
- `context
|
|
24
|
+
- `context`: **empty**, unless you put something in it.
|
|
25
25
|
|
|
26
26
|
**No row values leave the grid.** Not a sample, not a summary, not the first
|
|
27
|
-
page. If you want the model to see data
|
|
28
|
-
helps
|
|
27
|
+
page. If you want the model to see data, and for some questions it genuinely
|
|
28
|
+
helps: you put it in `context` yourself, deliberately, having decided that
|
|
29
29
|
sending it to a third party is acceptable for that data, that tenant and that
|
|
30
30
|
jurisdiction. There is no flag that turns it on by accident.
|
|
31
31
|
|
|
@@ -43,7 +43,7 @@ Two things worth knowing before you do:
|
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
-
# Part one
|
|
46
|
+
# Part one: wiring it up
|
|
47
47
|
|
|
48
48
|
## Setup
|
|
49
49
|
|
|
@@ -68,7 +68,7 @@ gets a preview:
|
|
|
68
68
|
> **Filter Region is EMEA, sort Margin descending**
|
|
69
69
|
> [ Apply ] [ Discard ]
|
|
70
70
|
|
|
71
|
-
Nothing changes until Apply. That is not a configurable nicety
|
|
71
|
+
Nothing changes until Apply. That is not a configurable nicety, it is the
|
|
72
72
|
reason the feature is shippable to a customer with an audit function.
|
|
73
73
|
|
|
74
74
|
## The callback contract
|
|
@@ -186,13 +186,13 @@ if (plan.ok && await userConfirms(plan.describe())) {
|
|
|
186
186
|
|
|
187
187
|
`plan` is `{ ok, actions, rejected, explain, describe() }`:
|
|
188
188
|
|
|
189
|
-
- `ok
|
|
190
|
-
- `actions
|
|
191
|
-
- `rejected
|
|
189
|
+
- `ok`: true when at least one action survived validation.
|
|
190
|
+
- `actions`, the validated, normalised actions.
|
|
191
|
+
- `rejected`: `{ at, what, reason }` for every part refused, whether or not
|
|
192
192
|
anything survived. Show these: a user approving three of five conditions
|
|
193
193
|
needs to see the other two.
|
|
194
|
-
- `explain
|
|
195
|
-
- `describe()
|
|
194
|
+
- `explain`, the model's own one-liner. Informational only.
|
|
195
|
+
- `describe()`, the plan in English, **built from the validated actions**, not
|
|
196
196
|
from `explain`. A model is not a reliable narrator of its own output.
|
|
197
197
|
|
|
198
198
|
## Keeping the schema small
|
|
@@ -200,7 +200,7 @@ if (plan.ok && await userConfirms(plan.describe())) {
|
|
|
200
200
|
A 200-column grid with a 5,000-option lookup on every column would produce a
|
|
201
201
|
schema nobody can afford to send, and a schema truncated by the transport is a
|
|
202
202
|
schema the model silently misreads. Everything is budgeted, and every cut is
|
|
203
|
-
reported in `schema.truncated` and stated in the prompt text
|
|
203
|
+
reported in `schema.truncated` and stated in the prompt text, a model told
|
|
204
204
|
"20 of 812 options shown" asks for the rest or falls back to `contains`,
|
|
205
205
|
whereas one shown a silently short list concludes those 20 are all there is.
|
|
206
206
|
|
|
@@ -222,7 +222,7 @@ ai: {
|
|
|
222
222
|
## Events
|
|
223
223
|
|
|
224
224
|
Applying goes through `filters.set`, `sort.set`, `columns.group`,
|
|
225
|
-
`columns.show` and `columns.hide
|
|
225
|
+
`columns.show` and `columns.hide`, the public API, nothing private. So a
|
|
226
226
|
model-driven change emits the same `filter:changed`, `sort:changed` and
|
|
227
227
|
`model:changed` events, lands in the same `state.get()` snapshot, and sits on
|
|
228
228
|
the same undo path as the user having done it by hand. If you want to record
|
|
@@ -262,12 +262,12 @@ And the boundary this feature does *not* claim:
|
|
|
262
262
|
> boundary against a hostile model. **Never give a model more authority than
|
|
263
263
|
> the user already has.** Run the callback with the user's own credentials,
|
|
264
264
|
> filter server-side by the user's own permissions, and treat what comes back
|
|
265
|
-
> as a suggestion from an untrusted source
|
|
265
|
+
> as a suggestion from an untrusted source, because that is exactly what it
|
|
266
266
|
> is.
|
|
267
267
|
|
|
268
268
|
---
|
|
269
269
|
|
|
270
|
-
# Part two
|
|
270
|
+
# Part two, the skill, for the model
|
|
271
271
|
|
|
272
272
|
*Everything below is written to be given to a model, whether pasted into a
|
|
273
273
|
system prompt or emitted by `promptText(schema)`.*
|
|
@@ -276,7 +276,7 @@ system prompt or emitted by `promptText(schema)`.*
|
|
|
276
276
|
|
|
277
277
|
You can reshape a Lattice data grid: filter rows, sort them, group them, and
|
|
278
278
|
show or hide columns. You cannot read, edit, delete or export data, and you
|
|
279
|
-
cannot run code. Your output is a proposal
|
|
279
|
+
cannot run code. Your output is a proposal, a human sees a plain-English
|
|
280
280
|
summary of it and decides whether to apply it.
|
|
281
281
|
|
|
282
282
|
You will be given a schema listing every column: its id, its title, its family,
|
|
@@ -307,7 +307,7 @@ Reply with one JSON object and no other text:
|
|
|
307
307
|
| `setQuick` | `text` | Sets the quick filter, which matches across every column |
|
|
308
308
|
| `clear` | `what` | One of `filters`, `sort`, `group`, `quick`, `all` |
|
|
309
309
|
|
|
310
|
-
Nothing outside this table exists. To remove something, use `clear
|
|
310
|
+
Nothing outside this table exists. To remove something, use `clear`, an empty
|
|
311
311
|
`setSort` or `groupBy` is rejected, not treated as a clear.
|
|
312
312
|
|
|
313
313
|
### Filters
|
|
@@ -356,7 +356,7 @@ Which operators apply depends on the column's **family**, given in the schema:
|
|
|
356
356
|
| `object` | `eq` `ne` `blank` `notBlank` |
|
|
357
357
|
|
|
358
358
|
`contains` on a number column is rejected. So is `eq` on a `lookupMulti`
|
|
359
|
-
column, whose cells hold arrays
|
|
359
|
+
column, whose cells hold arrays: use `containsAny`.
|
|
360
360
|
|
|
361
361
|
Dates are ISO 8601 strings: `"2026-01-01"` or `"2026-01-01T00:00:00Z"`.
|
|
362
362
|
|
|
@@ -396,7 +396,7 @@ notes | Notes | text |
|
|
|
396
396
|
```json
|
|
397
397
|
{
|
|
398
398
|
"actions": [ { "type": "groupBy", "columns": ["region"] } ],
|
|
399
|
-
"explain": "Grouped by region. I cannot add total rows
|
|
399
|
+
"explain": "Grouped by region. I cannot add total rows: that is a grid setting."
|
|
400
400
|
}
|
|
401
401
|
```
|
|
402
402
|
|
|
@@ -436,7 +436,7 @@ column is the commonest way to answer this question wrongly.
|
|
|
436
436
|
{ "actions": [ { "type": "clear", "what": "all" } ], "explain": "Cleared the view." }
|
|
437
437
|
```
|
|
438
438
|
|
|
439
|
-
**"sort by notes"
|
|
439
|
+
**"sort by notes"**: `notes` has no capabilities listed, so it cannot be
|
|
440
440
|
sorted:
|
|
441
441
|
|
|
442
442
|
```json
|