@lotics/app-sdk 0.123.7 → 0.123.9
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/dist/index.js +8 -7
- package/dist/queries.d.ts +14 -0
- package/docs/data_fetching.md +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11370,27 +11370,28 @@ function evaluateCondition(record, fieldByKey, looseCondition, memberContext, fi
|
|
|
11370
11370
|
const columnValue = data[fieldKey];
|
|
11371
11371
|
const field = fieldByKey[fieldKey];
|
|
11372
11372
|
const resolvedType = field ? resolveFilterType(field) : looseCondition.type;
|
|
11373
|
-
|
|
11373
|
+
let filterCondition = {
|
|
11374
11374
|
...looseCondition,
|
|
11375
11375
|
type: resolvedType
|
|
11376
11376
|
};
|
|
11377
|
+
let figureFactor = 1;
|
|
11377
11378
|
if (field !== void 0 && filterCondition.type === "number") {
|
|
11378
11379
|
const reading = conditionUnit(looseCondition, field, (key) => fieldByKey[key]);
|
|
11379
11380
|
if (!reading.ok) throw new Error(`Filter on "${fieldKey}": ${reading.reason}`);
|
|
11380
11381
|
if (reading.unit !== void 0 && filterCondition.value !== null && filterCondition.value !== void 0) {
|
|
11381
11382
|
const factor = rowUnitFactor(reading.unit, data);
|
|
11382
11383
|
if (factor === void 0) return false;
|
|
11383
|
-
|
|
11384
|
-
|
|
11384
|
+
figureFactor = factor;
|
|
11385
|
+
filterCondition = { ...filterCondition, value: multiplyExactly(filterCondition.value, reading.unit.factor) };
|
|
11385
11386
|
}
|
|
11386
11387
|
}
|
|
11387
11388
|
if (field?.type === "lookup" && (Array.isArray(columnValue) || columnValue == null)) {
|
|
11388
11389
|
const values2 = Array.isArray(columnValue) ? columnValue : [];
|
|
11389
|
-
return matchLookup(values2, field, filterCondition, looseCondition, memberContext, fileFacts);
|
|
11390
|
+
return matchLookup(values2, field, filterCondition, looseCondition, memberContext, fileFacts, figureFactor);
|
|
11390
11391
|
}
|
|
11391
|
-
return matchCell(columnValue, field, filterCondition, looseCondition, memberContext, fileFacts);
|
|
11392
|
+
return matchCell(columnValue, field, filterCondition, looseCondition, memberContext, fileFacts, figureFactor);
|
|
11392
11393
|
}
|
|
11393
|
-
function matchLookup(cell, field, filterCondition, looseCondition, memberContext, fileFacts) {
|
|
11394
|
+
function matchLookup(cell, field, filterCondition, looseCondition, memberContext, fileFacts, figureFactor) {
|
|
11394
11395
|
switch (filterCondition.type) {
|
|
11395
11396
|
case "select":
|
|
11396
11397
|
case "select_member":
|
|
@@ -11417,7 +11418,7 @@ function matchLookup(cell, field, filterCondition, looseCondition, memberContext
|
|
|
11417
11418
|
let anyMatched = false;
|
|
11418
11419
|
for (const value of values2) {
|
|
11419
11420
|
const element = filterCondition.type === "text" && typeof value !== "string" && value !== null && value !== void 0 ? String(value) : value;
|
|
11420
|
-
const result = matchCell(element, field, positive, looseCondition, memberContext, fileFacts);
|
|
11421
|
+
const result = matchCell(element, field, positive, looseCondition, memberContext, fileFacts, figureFactor);
|
|
11421
11422
|
if (result !== null) allSkipped = false;
|
|
11422
11423
|
if (result === true) {
|
|
11423
11424
|
anyMatched = true;
|
package/dist/queries.d.ts
CHANGED
|
@@ -221,6 +221,9 @@ export interface ExportReport {
|
|
|
221
221
|
};
|
|
222
222
|
/** The value the report was picked for (its `per`), as the reader names it. */
|
|
223
223
|
per?: string;
|
|
224
|
+
/** The fields of the picked row a one-link `per` names that `filename` reads as `per_row.<field>`, by field alias: a
|
|
225
|
+
* scalar, null where the row holds none. */
|
|
226
|
+
per_row?: Record<string, string | number | boolean | null>;
|
|
224
227
|
}
|
|
225
228
|
/** One tab of the register: its rows read as the export's own are — same query and params — under its own filter and order. */
|
|
226
229
|
export interface ExportTab {
|
|
@@ -228,6 +231,17 @@ export interface ExportTab {
|
|
|
228
231
|
label: string;
|
|
229
232
|
filter?: QueryFilter;
|
|
230
233
|
sort?: readonly QuerySortKey[];
|
|
234
|
+
/** A tab of totals over the period: the declared query `query` read again under `params` (the period's two days), its
|
|
235
|
+
* rows joined to the tab's by the link column `via`, and the columns `columns` each one's `alias` and header. */
|
|
236
|
+
totals?: {
|
|
237
|
+
query: string;
|
|
238
|
+
params: Record<string, string>;
|
|
239
|
+
via: string;
|
|
240
|
+
columns: {
|
|
241
|
+
alias: string;
|
|
242
|
+
label: string;
|
|
243
|
+
}[];
|
|
244
|
+
};
|
|
231
245
|
}
|
|
232
246
|
/** The file an export makes: the default report workbook — its words in `language`, the rows under `columns` on the
|
|
233
247
|
* tab `sheet` — or a template the query declares under `templates`, by its name there. */
|
package/docs/data_fetching.md
CHANGED
|
@@ -24,7 +24,7 @@ untyped. It is written from the app's live bindings by `lotics app create --cust
|
|
|
24
24
|
| `useQuery(alias, params?, { rows: false, total: true })` | `total` only, no rows (`total: { by: column }` or `total: { where: { name: filter } }` adds `counts`) | a facet chip, a queue badge, an "N awaiting approval" tile — the size of a set you are not listing |
|
|
25
25
|
| `useQueries(calls, opts?)` | one state per `{ alias, params?, filter?, sort?, aggregate?, total?, rows? }`, in order — a `sort` orders that call's rows before the cap cuts them | reads that are DATA — a list known only at render, one read per item, or one count per stage (`rows: false, total: true`, each state's `.total`); the deploy's alias scan reads a list as dynamic, so every alias in it is still declared. With `aggregate` a call answers the groups of its filtered rows instead of the rows ([queries](./queries.md)) |
|
|
26
26
|
| `queryAll(alias, params?, { filter, sort })` | a promise of every row | outside React, for a job that must hold the whole narrowed set in the browser (the ids an act runs on): it asks page after page until the server says the set ended, never stopping at the 10,000-row cap. The server's rows as stored — no write of this app is drawn over them |
|
|
27
|
-
| `exportQuery(alias, { params, filter, sort, tabs?, report, file, labels? })` | a promise of an `ExportedFile`: `{ filename, mime_type, url, size, created_at }` | every row the narrowed set holds, made into one file by the server — no row reaches the browser. `tabs` (2 to 5, each `{ tab, label, filter?, sort? }`) are each read as the export's own rows are — same query and params, under the tab's own filter and sort (absent, the declared order) — and a template reads each one's rows under its `tab`, a name none of the report's keys nor the template's `rows` key holds. `report` is `{ title, lines, readings, dates?, period?, per?, filename? }` — `dates` each date filter's `{ from?, to? }` by field alias, each bound a day (`yyyy-MM-dd`) or a minute of one (`yyyy-MM-ddTHH:mm`) with no zone; `period` the tabs' `{ from, to }`, bounds of the same form; `per` the value the report was picked for, in the reader's words; `filename` the file's name in the template grammar over one value each — `title`, `at` (the moment the server made the file), `dates.<field>.from` or `.to`, `period.from` or `.to`, `per`, `lines | lookup:<n>` — at most 200 bytes once filled (absent, the template's name, or `title`); `file` is `{ kind: "workbook", language, sheet, columns }` (the default report workbook, its head closing with the moment the server made it, each column `{ key, header, type }` an output column of the query — a `number` one on a number column, a `date` one on a date or datetime; with `tabs`, one sheet per tab named by its `label` in place of `sheet`) or `{ kind: "template", template }`, one the query declares under `templates` by name ([queries](./queries.md)). `labels`, by `select` output column, the words each option key prints as in either file — a cell no field of the query names (a union's literal column) arrives as its bare key; a cell its field's option names prints as that, a key the map lacks as itself, and a column no select of the query holds as it is. Past 20,000 rows, in any tab, it rejects, never cuts; each caller makes at most 60 exports a minute. The file has no `id` — it is a download, not a workspace file a workflow or a field takes: its `url` is signed for the caller for at most an hour, so download it with `downloadFileFromUrl(url, filename)` (`@lotics/ui/download`) when the promise resolves — a tab `openExternal` opens seconds after the click is a pop-up the browser blocks; the server deletes the file a day after it is made |
|
|
27
|
+
| `exportQuery(alias, { params, filter, sort, tabs?, report, file, labels? })` | a promise of an `ExportedFile`: `{ filename, mime_type, url, size, created_at }` | every row the narrowed set holds, made into one file by the server — no row reaches the browser. `tabs` (2 to 5, each `{ tab, label, filter?, sort?, totals? }`; `totals` is `{ query, params, via, columns }`, the read of a totals tab beside its rows, joined on the link column `via`, refused where that read lacks `via` or a column or answers two groups for one row) are each read as the export's own rows are — same query and params, under the tab's own filter and sort (absent, the declared order) — and a template reads each one's rows under its `tab`, a name none of the report's keys nor the template's `rows` key holds. `report` is `{ title, lines, readings, dates?, period?, per?, per_row?, filename? }` — `dates` each date filter's `{ from?, to? }` by field alias, each bound a day (`yyyy-MM-dd`) or a minute of one (`yyyy-MM-ddTHH:mm`) with no zone; `period` the tabs' `{ from, to }`, bounds of the same form; `per` the value the report was picked for, in the reader's words; `per_row` the picked row's fields by field alias, each a text, number, boolean or `null`, which `filename` and a template read as `per_row.<field>`; `filename` the file's name in the template grammar over one value each — `title`, `at` (the moment the server made the file), `dates.<field>.from` or `.to`, `period.from` or `.to`, `per`, `per_row.<field>`, `lines | lookup:<n>`, with `| add_days:<n>` shifting a date by whole days — at most 200 bytes once filled (absent, the template's name, or `title`); `file` is `{ kind: "workbook", language, sheet, columns }` (the default report workbook, its head closing with the moment the server made it, each column `{ key, header, type }` an output column of the query — a `number` one on a number column, a `date` one on a date or datetime; with `tabs`, one sheet per tab named by its `label` in place of `sheet`) or `{ kind: "template", template }`, one the query declares under `templates` by name ([queries](./queries.md)). `labels`, by `select` output column, the words each option key prints as in either file — a cell no field of the query names (a union's literal column) arrives as its bare key; a cell its field's option names prints as that, a key the map lacks as itself, and a column no select of the query holds as it is. Past 20,000 rows, in any tab, it rejects, never cuts; each caller makes at most 60 exports a minute. The file has no `id` — it is a download, not a workspace file a workflow or a field takes: its `url` is signed for the caller for at most an hour, so download it with `downloadFileFromUrl(url, filename)` (`@lotics/ui/download`) when the promise resolves — a tab `openExternal` opens seconds after the click is a pop-up the browser blocks; the server deletes the file a day after it is made |
|
|
28
28
|
|
|
29
29
|
Every hook answers the same `QueryState`: `rows`, `truncated`, `total`, `counts`, `loading`,
|
|
30
30
|
`isValidating`, `answeredAt`, `error`, `pending`, `refetch`, `page`, `setPage`, `pageCount`, `hasMore`,
|
package/package.json
CHANGED