@svgrid/enterprise 2.2.1 → 2.3.1
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 +95 -81
- package/dist/cdn/svgrid-enterprise.svelte-external.js +26642 -11252
- package/dist/designer/assets/GridMenus-BtWVk9Ab.js +7 -0
- package/dist/designer/assets/SvGridChartPanel-DWlBO2SD.js +10 -0
- package/dist/designer/assets/SvGridChartView-8c8Mb4j8.js +1 -0
- package/dist/designer/assets/SvGridChartView-DX9HfkBR.css +1 -0
- package/dist/designer/assets/index-DsDgp9Xq.js +78758 -0
- package/dist/designer/assets/index-tTY_Dx4P.css +1 -0
- package/dist/designer/assets/jszip.min-fkJdmAmj.js +2 -0
- package/dist/designer/assets/pdfmake-DeCsnyl9.js +242 -0
- package/dist/designer/assets/smart.export-BZlSCE8T.js +35 -0
- package/dist/designer/assets/vfs_fonts-eX2NpmfX.js +1 -0
- package/dist/designer/index.html +13 -0
- package/dist/node/studio.js +15304 -2708
- package/package.json +35 -11
- package/src/SvAlertRuleEditor.svelte +294 -0
- package/src/SvAlertsManager.svelte +210 -0
- package/src/SvAlertsPanel.svelte +129 -0
- package/src/SvBoard.svelte +3 -1
- package/src/SvExpressionEditor.svelte +341 -0
- package/src/SvGridAlerts.dom.test.ts +113 -0
- package/src/SvGridAlerts.svelte +265 -0
- package/src/SvGridBoard.svelte +2358 -0
- package/src/SvGridEditPanel.svelte +849 -794
- package/src/SvGridScheduler.svelte +5358 -4410
- package/src/SvPivotDesigner.svelte +3 -3
- package/src/SvRecordDetail.svelte +6 -2
- package/src/SvSchedule.svelte +3 -1
- package/src/{ai-export-pdf.test.ts → ai-export-pdf.dom.test.ts} +77 -74
- package/src/{ai-export-xlsx.test.ts → ai-export-xlsx.dom.test.ts} +90 -87
- package/src/{ai-export.test.ts → ai-export.dom.test.ts} +114 -110
- package/src/alerts/alert-engine-attach.ts +165 -0
- package/src/alerts/alert-engine.test.ts +135 -0
- package/src/alerts/alert-engine.ts +260 -0
- package/src/alerts/alert-formats.test.ts +87 -0
- package/src/alerts/alert-formats.ts +77 -0
- package/src/alerts/alert-observer.test.ts +189 -0
- package/src/alerts/alert-observer.ts +208 -0
- package/src/alerts/alert-scheduler.ts +96 -0
- package/src/alerts/alert-storage.test.ts +54 -0
- package/src/alerts/alert-storage.ts +116 -0
- package/src/alerts/alert-store.svelte.ts +80 -0
- package/src/alerts/alert-types.ts +94 -0
- package/src/alerts.ts +28 -0
- package/src/board.dom.test.ts +941 -0
- package/src/board.ts +36 -0
- package/src/export-ooxml.ts +4 -0
- package/src/export-xls.ts +3 -0
- package/src/export.ts +6 -0
- package/src/expressions/evaluate.test.ts +111 -0
- package/src/expressions/evaluate.ts +237 -0
- package/src/expressions/expression-columns.ts +133 -0
- package/src/expressions/expression-types.ts +84 -0
- package/src/expressions/parse.test.ts +106 -0
- package/src/expressions/parse.ts +610 -0
- package/src/import.test.ts +1 -1
- package/src/import.ts +3 -1
- package/src/index.ts +192 -46
- package/src/install.ts +12 -2
- package/src/pivot-enable.ts +44 -0
- package/src/pivot.test.ts +0 -1
- package/src/scheduler-assignments.test.ts +97 -0
- package/src/scheduler-assignments.ts +134 -0
- package/src/scheduler-axis.test.ts +108 -0
- package/src/scheduler-axis.ts +238 -0
- package/src/scheduler-booking.test.ts +57 -0
- package/src/scheduler-booking.ts +63 -0
- package/src/scheduler-config.ts +179 -0
- package/src/scheduler-dependencies.test.ts +155 -0
- package/src/scheduler-dependencies.ts +223 -0
- package/src/scheduler-freebusy.test.ts +41 -0
- package/src/scheduler-freebusy.ts +36 -0
- package/src/scheduler-heatmap.test.ts +39 -0
- package/src/scheduler-heatmap.ts +55 -0
- package/src/scheduler-resource-tree.test.ts +84 -0
- package/src/scheduler-resource-tree.ts +107 -0
- package/src/scheduler-slots.test.ts +53 -0
- package/src/scheduler-slots.ts +94 -0
- package/src/scheduler-summary.test.ts +47 -0
- package/src/scheduler-summary.ts +81 -0
- package/src/schema-designer.ts +1 -1
- package/src/sources/index.ts +1 -1
- package/src/sources/introspect-supabase.test.ts +13 -1
- package/src/sources/introspect-supabase.ts +20 -0
- package/src/studio/copilot-core.test.ts +45 -0
- package/src/studio/copilot-core.ts +65 -0
- package/src/studio/deploy-cli.test.ts +56 -0
- package/src/studio/deploy-cli.ts +100 -0
- package/src/studio/emit-project.test.ts +800 -24
- package/src/studio/emit-project.ts +1307 -135
- package/src/studio/emit-schema.test.ts +17 -0
- package/src/studio/emit-schema.ts +182 -41
- package/src/studio/index.ts +59 -1
- package/src/studio/init-flow.test.ts +239 -0
- package/src/studio/init-flow.ts +358 -0
- package/src/studio/introspect-openapi.test.ts +84 -0
- package/src/studio/introspect-openapi.ts +252 -0
- package/src/studio/project.test.ts +57 -1
- package/src/studio/project.ts +302 -8
- package/src/studio/samples/crm.ts +282 -258
- package/src/studio/samples/datasets.test.ts +84 -0
- package/src/studio/samples/datasets.ts +340 -0
- package/src/studio/samples/fleet.ts +213 -186
- package/src/studio/samples/insurance.ts +223 -195
- package/src/studio/samples/inventory.ts +213 -182
- package/src/studio/samples/live-data.test.ts +99 -98
- package/src/studio/samples/live-data.ts +8 -10
- package/src/studio/samples/projects.ts +212 -190
- package/src/studio/samples/samples.test.ts +268 -216
- package/src/studio/samples/shared.ts +22 -145
- package/src/studio/samples/starter.ts +251 -0
- package/src/studio/samples/support.ts +209 -184
- package/src/studio/screen-suites.test.ts +226 -0
- package/src/studio/screen-suites.ts +445 -0
- package/src/studio/ui-components-surface.test.ts +185 -0
- package/src/studio/ui-components.generated.ts +7154 -0
- package/src/studio/ui-components.ts +273 -3
- package/src/sveltekit/index.ts +1 -0
- package/src/sveltekit/sql-source.test.ts +13 -0
- package/src/sveltekit/sql-source.ts +12 -7
- package/src/sveltekit/transport-scope.test.ts +125 -0
- package/src/sveltekit/transport.ts +76 -2
- package/src/upgrade-prompt.ts +2 -2
- package/src/watermark.ts +2 -2
- package/src/ai.test.ts +0 -522
- package/src/ai.ts +0 -1388
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
ExpressionParseError,
|
|
4
|
+
collectColumnRefs,
|
|
5
|
+
parsePredicate,
|
|
6
|
+
stringifyPredicate,
|
|
7
|
+
validateExpression,
|
|
8
|
+
} from './parse'
|
|
9
|
+
import { evaluatePredicate } from './evaluate'
|
|
10
|
+
import type { ExprColumn } from './expression-columns'
|
|
11
|
+
import type { PredicateExpr } from './expression-types'
|
|
12
|
+
|
|
13
|
+
const columns: ExprColumn[] = [
|
|
14
|
+
{ id: 'price', name: 'Unit Price', type: 'number' },
|
|
15
|
+
{ id: 'qty', name: 'Qty', type: 'number' },
|
|
16
|
+
{ id: 'name', name: 'Name', type: 'text' },
|
|
17
|
+
{ id: 'region', name: 'Region', type: 'text' },
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
describe('parsePredicate', () => {
|
|
21
|
+
it('parses a col-vs-literal comparison into a cmp node (grid-filter semantics)', () => {
|
|
22
|
+
const e = parsePredicate('price > 100', columns)
|
|
23
|
+
expect(e).toEqual({ kind: 'cmp', column: 'price', op: 'greaterThan', value: 100 })
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('resolves [Bracketed Name] references to ids', () => {
|
|
27
|
+
const e = parsePredicate('[Unit Price] >= 50', columns) as Extract<PredicateExpr, { kind: 'scalarCmp' }>
|
|
28
|
+
// >= has no cmp equivalent, so it becomes a scalarCmp over the resolved column id
|
|
29
|
+
expect(e.kind).toBe('scalarCmp')
|
|
30
|
+
expect(e.left).toEqual({ kind: 'col', id: 'price' })
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('parses keyword text/set/range operators', () => {
|
|
34
|
+
expect(parsePredicate('name CONTAINS "wid"', columns)).toEqual({ kind: 'cmp', column: 'name', op: 'contains', value: 'wid' })
|
|
35
|
+
expect(parsePredicate('region IN ("EU", "US")', columns)).toEqual({ kind: 'cmp', column: 'region', op: 'in', value: ['EU', 'US'] })
|
|
36
|
+
expect(parsePredicate('price BETWEEN 10 AND 20', columns)).toEqual({ kind: 'cmp', column: 'price', op: 'between', value: 10, valueTo: 20 })
|
|
37
|
+
expect(parsePredicate('name ISBLANK', columns)).toEqual({ kind: 'cmp', column: 'name', op: 'isBlank' })
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('honours AND/OR/NOT precedence and grouping', () => {
|
|
41
|
+
const e = parsePredicate('price > 100 AND (region = "EU" OR region = "US")', columns) as Extract<PredicateExpr, { kind: 'and' }>
|
|
42
|
+
expect(e.kind).toBe('and')
|
|
43
|
+
expect(e.parts[1]!.kind).toBe('or')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('parses cross-column scalar maths', () => {
|
|
47
|
+
const e = parsePredicate('price / qty >= 40', columns) as Extract<PredicateExpr, { kind: 'scalarCmp' }>
|
|
48
|
+
expect(e.kind).toBe('scalarCmp')
|
|
49
|
+
expect(e.op).toBe('>=')
|
|
50
|
+
expect(e.left).toEqual({ kind: 'bin', op: '/', left: { kind: 'col', id: 'price' }, right: { kind: 'col', id: 'qty' } })
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('throws a positioned error on a syntax problem', () => {
|
|
54
|
+
expect(() => parsePredicate('price >', columns)).toThrow(ExpressionParseError)
|
|
55
|
+
try {
|
|
56
|
+
parsePredicate('price @ 5', columns)
|
|
57
|
+
} catch (err) {
|
|
58
|
+
expect(err).toBeInstanceOf(ExpressionParseError)
|
|
59
|
+
expect((err as ExpressionParseError).pos).toBeGreaterThan(0)
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('parsed expressions evaluate correctly end to end', () => {
|
|
64
|
+
const e = parsePredicate('price > 100 AND region = "EU"', columns)
|
|
65
|
+
expect(evaluatePredicate(e, { row: { price: 120, region: 'EU' } })).toBe(true)
|
|
66
|
+
expect(evaluatePredicate(e, { row: { price: 120, region: 'US' } })).toBe(false)
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
describe('stringifyPredicate', () => {
|
|
71
|
+
it('round-trips through parse for the common forms', () => {
|
|
72
|
+
for (const src of [
|
|
73
|
+
'price > 100',
|
|
74
|
+
'name CONTAINS "wid"',
|
|
75
|
+
'region IN ("EU", "US")',
|
|
76
|
+
'price BETWEEN 10 AND 20',
|
|
77
|
+
'name ISBLANK',
|
|
78
|
+
]) {
|
|
79
|
+
const ast = parsePredicate(src, columns)
|
|
80
|
+
const back = stringifyPredicate(ast, columns)
|
|
81
|
+
expect(stringifyPredicate(parsePredicate(back, columns), columns)).toBe(back)
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('writes [bracketed] names when a label has spaces', () => {
|
|
86
|
+
const ast = parsePredicate('price > 100', columns)
|
|
87
|
+
expect(stringifyPredicate(ast, columns)).toBe('[Unit Price] > 100')
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
describe('validateExpression + collectColumnRefs', () => {
|
|
92
|
+
it('collects every referenced column id', () => {
|
|
93
|
+
const ast = parsePredicate('price / qty >= 40 AND region = "EU"', columns)
|
|
94
|
+
expect(collectColumnRefs(ast).sort()).toEqual(['price', 'qty', 'region'])
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('flags unknown columns and functions', () => {
|
|
98
|
+
const ast = parsePredicate('bogus > 5', columns)
|
|
99
|
+
expect(validateExpression(ast, columns)).toContain('Unknown column "bogus"')
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('passes a sound expression', () => {
|
|
103
|
+
const ast = parsePredicate('price > 100', columns)
|
|
104
|
+
expect(validateExpression(ast, columns)).toEqual([])
|
|
105
|
+
})
|
|
106
|
+
})
|