@svgrid/enterprise 1.2.0 → 2.0.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/dist/cdn/svgrid-enterprise.svelte-external.js +26039 -805
- package/dist/designer/assets/index-Dp44bTid.js +939 -0
- package/dist/designer/assets/index-RJp6x8tw.css +1 -0
- package/dist/designer/assets/jszip.min-CjMo-QGg.js +2 -0
- package/dist/designer/index.html +13 -0
- package/dist/node/studio.js +22554 -0
- package/package.json +10 -3
- package/src/SvAuthGate.svelte +115 -0
- package/src/SvBoard.dom.test.ts +67 -0
- package/src/SvBoard.svelte +192 -0
- package/src/SvExportMenu.svelte +553 -0
- package/src/SvFileInput.svelte +113 -0
- package/src/SvGridEditPanel.dom.test.ts +146 -0
- package/src/SvGridEditPanel.svelte +793 -0
- package/src/SvGridMasterDetail.svelte +95 -0
- package/src/SvImportDialog.svelte +1020 -0
- package/src/SvLookupInput.svelte +180 -0
- package/src/SvRecordDetail.dom.test.ts +137 -0
- package/src/SvRecordDetail.svelte +288 -0
- package/src/SvSchedule.dom.test.ts +57 -0
- package/src/SvSchedule.svelte +156 -0
- package/src/SvSchemaChart.svelte +233 -0
- package/src/SvSchemaDashboard.svelte +130 -0
- package/src/ai-export-pdf.test.ts +74 -0
- package/src/ai-export-xlsx.test.ts +87 -0
- package/src/ai-export.test.ts +110 -0
- package/src/ai.ts +1188 -782
- package/src/edit-panel.test.ts +213 -0
- package/src/edit-panel.ts +228 -0
- package/src/export-conditional.test.ts +60 -0
- package/src/export-conditional.ts +94 -0
- package/src/export-ooxml.test.ts +152 -0
- package/src/export-ooxml.ts +485 -0
- package/src/export-pdf.test.ts +138 -0
- package/src/export-pdf.ts +245 -0
- package/src/export-print.test.ts +66 -0
- package/src/export-print.ts +132 -0
- package/src/export-serialize.test.ts +56 -0
- package/src/export-serialize.ts +24 -0
- package/src/export-xls.ts +196 -0
- package/src/export-xlsx-roundtrip.test.ts +120 -0
- package/src/export-xlsx.test.ts +150 -0
- package/src/export.test.ts +349 -0
- package/src/export.ts +1452 -549
- package/src/import-automap.test.ts +131 -0
- package/src/import-hardening.test.ts +158 -0
- package/src/import.ts +1042 -648
- package/src/index.ts +282 -0
- package/src/install.ts +134 -114
- package/src/license-core.test.ts +23 -0
- package/src/license-core.ts +35 -0
- package/src/license.ts +103 -90
- package/src/master-detail.test.ts +61 -0
- package/src/master-detail.ts +42 -0
- package/src/print.ts +107 -127
- package/src/schema-designer.test.ts +121 -0
- package/src/schema-designer.ts +142 -0
- package/src/schema.test.ts +268 -0
- package/src/schema.ts +499 -0
- package/src/smart-shim.ts +107 -105
- package/src/sources/aggregate.test.ts +79 -0
- package/src/sources/aggregate.ts +102 -0
- package/src/sources/auth-supabase.test.ts +80 -0
- package/src/sources/auth-supabase.ts +87 -0
- package/src/sources/dashboard.kpi.test.ts +50 -0
- package/src/sources/dashboard.test.ts +61 -0
- package/src/sources/dashboard.ts +136 -0
- package/src/sources/field-inference.test.ts +60 -0
- package/src/sources/field-inference.ts +63 -0
- package/src/sources/filters.test.ts +58 -0
- package/src/sources/filters.ts +64 -0
- package/src/sources/index.ts +67 -0
- package/src/sources/introspect-supabase.test.ts +100 -0
- package/src/sources/introspect-supabase.ts +119 -0
- package/src/sources/realtime-supabase.test.ts +93 -0
- package/src/sources/realtime-supabase.ts +99 -0
- package/src/sources/relation-lookup.test.ts +99 -0
- package/src/sources/relation-lookup.ts +128 -0
- package/src/sources/rest-adapters.test.ts +95 -0
- package/src/sources/rest-adapters.ts +120 -0
- package/src/sources/rest.test.ts +104 -0
- package/src/sources/rest.ts +129 -0
- package/src/sources/schema-from-columns.test.ts +106 -0
- package/src/sources/schema-from-columns.ts +88 -0
- package/src/sources/supabase.test.ts +110 -0
- package/src/sources/supabase.ts +99 -0
- package/src/sources/with-entity-rules.test.ts +104 -0
- package/src/sources/with-entity-rules.ts +78 -0
- package/src/sources/with-relation-labels.test.ts +75 -0
- package/src/sources/with-relation-labels.ts +73 -0
- package/src/studio/bug-report.test.ts +101 -0
- package/src/studio/bug-report.ts +165 -0
- package/src/studio/cli.test.ts +187 -0
- package/src/studio/cli.ts +112 -0
- package/src/studio/csv.test.ts +90 -0
- package/src/studio/csv.ts +165 -0
- package/src/studio/db-connect-string.test.ts +94 -0
- package/src/studio/db-connect-string.ts +128 -0
- package/src/studio/emit-project.test.ts +923 -0
- package/src/studio/emit-project.ts +1273 -0
- package/src/studio/emit-schema.test.ts +94 -0
- package/src/studio/emit-schema.ts +920 -0
- package/src/studio/index.ts +195 -0
- package/src/studio/introspect-db.test.ts +186 -0
- package/src/studio/introspect-db.ts +312 -0
- package/src/studio/introspect-prisma.test.ts +99 -0
- package/src/studio/introspect-prisma.ts +175 -0
- package/src/studio/introspect.test.ts +172 -0
- package/src/studio/introspect.ts +310 -0
- package/src/studio/pipeline.test.ts +42 -0
- package/src/studio/project-robust.test.ts +157 -0
- package/src/studio/project.test.ts +473 -0
- package/src/studio/project.ts +916 -0
- package/src/studio/sample-data.test.ts +58 -0
- package/src/studio/sample-data.ts +200 -0
- package/src/studio/samples/ats.ts +202 -0
- package/src/studio/samples/clinic.ts +177 -0
- package/src/studio/samples/crm.ts +250 -0
- package/src/studio/samples/ecommerce.ts +187 -0
- package/src/studio/samples/events.ts +199 -0
- package/src/studio/samples/fleet.ts +184 -0
- package/src/studio/samples/gym.ts +213 -0
- package/src/studio/samples/hr.ts +193 -0
- package/src/studio/samples/index.ts +55 -0
- package/src/studio/samples/insurance.ts +195 -0
- package/src/studio/samples/inventory.ts +182 -0
- package/src/studio/samples/invoicing.ts +162 -0
- package/src/studio/samples/library.ts +180 -0
- package/src/studio/samples/live-data.test.ts +98 -0
- package/src/studio/samples/live-data.ts +308 -0
- package/src/studio/samples/projects.ts +190 -0
- package/src/studio/samples/realestate.ts +196 -0
- package/src/studio/samples/restaurant.ts +187 -0
- package/src/studio/samples/samples.test.ts +208 -0
- package/src/studio/samples/school.ts +197 -0
- package/src/studio/samples/seed-floor.test.ts +25 -0
- package/src/studio/samples/shared.ts +305 -0
- package/src/studio/samples/subscriptions.ts +183 -0
- package/src/studio/samples/support.ts +182 -0
- package/src/studio/scaffold-app.test.ts +91 -0
- package/src/studio/scaffold-app.ts +161 -0
- package/src/studio/scaffold.test.ts +178 -0
- package/src/studio/scaffold.ts +374 -0
- package/src/studio/themes.ts +172 -0
- package/src/studio/verify.test.ts +47 -0
- package/src/studio/verify.ts +79 -0
- package/src/sveltekit/in-memory.test.ts +104 -0
- package/src/sveltekit/in-memory.ts +129 -0
- package/src/sveltekit/index.ts +23 -0
- package/src/sveltekit/query-plan.test.ts +109 -0
- package/src/sveltekit/query-plan.ts +125 -0
- package/src/sveltekit/sql-source.test.ts +185 -0
- package/src/sveltekit/sql-source.ts +166 -0
- package/src/sveltekit/sql.test.ts +80 -0
- package/src/sveltekit/sql.ts +131 -0
- package/src/sveltekit/transport.test.ts +175 -0
- package/src/sveltekit/transport.ts +254 -0
- package/src/sveltekit/types.ts +11 -0
- package/src/upgrade-prompt.ts +149 -148
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
+
|
|
3
|
+
// Capture downloads instead of touching the DOM (aiExport -> exportGrid).
|
|
4
|
+
const downloads: Array<{ text: string; filename: string }> = []
|
|
5
|
+
vi.mock('./export-serialize', async (importOriginal) => {
|
|
6
|
+
const actual = (await importOriginal()) as Record<string, unknown>
|
|
7
|
+
return {
|
|
8
|
+
...actual,
|
|
9
|
+
downloadTextFile: (text: string, filename: string) => {
|
|
10
|
+
downloads.push({ text, filename })
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
import { aiExport, aiFindAnomalies, setAIProvider, mockAIProvider } from './ai'
|
|
16
|
+
import { setLicenseKey } from './license'
|
|
17
|
+
|
|
18
|
+
type Row = { region: string; amount: number; name: string }
|
|
19
|
+
const rows: Row[] = [
|
|
20
|
+
{ region: 'EMEA', amount: 100, name: 'A' },
|
|
21
|
+
{ region: 'NA', amount: 2000, name: 'B' },
|
|
22
|
+
{ region: 'EMEA', amount: 50, name: 'C' },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
function makeApi() {
|
|
26
|
+
return {
|
|
27
|
+
getData: () => rows,
|
|
28
|
+
getDisplayedRows: () => rows,
|
|
29
|
+
getSelectedRows: () => [],
|
|
30
|
+
getColumns: () => [
|
|
31
|
+
{ id: 'region', field: 'region', header: 'Region', visible: true },
|
|
32
|
+
{ id: 'amount', field: 'amount', header: 'Amount', visible: true },
|
|
33
|
+
{ id: 'name', field: 'name', header: 'Name', visible: true },
|
|
34
|
+
],
|
|
35
|
+
getState: () => ({ grouping: [] }),
|
|
36
|
+
clearAllFilters: vi.fn(),
|
|
37
|
+
clearSort: vi.fn(),
|
|
38
|
+
setFilter: vi.fn(),
|
|
39
|
+
setSort: vi.fn(),
|
|
40
|
+
} as any
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
downloads.length = 0
|
|
45
|
+
setLicenseKey('SVENTERPRISE-DEV-TEST')
|
|
46
|
+
setAIProvider(mockAIProvider)
|
|
47
|
+
})
|
|
48
|
+
afterEach(() => setAIProvider(null))
|
|
49
|
+
|
|
50
|
+
describe('aiExport', () => {
|
|
51
|
+
it('parses format + groupBy + filters; applies to the grid only when asked', async () => {
|
|
52
|
+
const api = makeApi()
|
|
53
|
+
const plan = await aiExport(api, 'export deals over 500 grouped by region as a pdf', {
|
|
54
|
+
run: false,
|
|
55
|
+
apply: true,
|
|
56
|
+
})
|
|
57
|
+
expect(plan.format).toBe('pdf')
|
|
58
|
+
expect(plan.groupBy).toEqual(['region'])
|
|
59
|
+
expect(plan.filters).toContainEqual({ field: 'amount', operator: 'greaterThan', value: '500' })
|
|
60
|
+
// apply: true -> the grid is mutated
|
|
61
|
+
expect(api.clearAllFilters).toHaveBeenCalled()
|
|
62
|
+
expect(api.setFilter).toHaveBeenCalledWith('amount', { operator: 'greaterThan', value: '500' })
|
|
63
|
+
// run:false -> nothing downloaded
|
|
64
|
+
expect(downloads).toHaveLength(0)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('defaults to xlsx and does NOT touch the grid (apply defaults off)', async () => {
|
|
68
|
+
const api = makeApi()
|
|
69
|
+
const plan = await aiExport(api, 'just export everything', { run: false })
|
|
70
|
+
expect(plan.format).toBe('xlsx')
|
|
71
|
+
expect(api.clearAllFilters).not.toHaveBeenCalled()
|
|
72
|
+
expect(api.setFilter).not.toHaveBeenCalled()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('runs the export (downloads) when run is not false', async () => {
|
|
76
|
+
const api = makeApi()
|
|
77
|
+
await aiExport(api, 'export as csv', { filename: 'report' })
|
|
78
|
+
expect(downloads).toHaveLength(1)
|
|
79
|
+
expect(downloads[0]!.filename).toBe('report.csv')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('exports the plan-filtered rows directly (not the grid displayed rows)', async () => {
|
|
83
|
+
// getDisplayedRows returns EVERYTHING (as if the grid hadn't re-filtered);
|
|
84
|
+
// the export must still contain only rows matching the plan's filter.
|
|
85
|
+
const api = makeApi()
|
|
86
|
+
await aiExport(api, 'export deals over 500 as csv', { filename: 'big' })
|
|
87
|
+
const { text } = downloads[0]!
|
|
88
|
+
expect(text).toContain('2000') // amount 2000 > 500 kept
|
|
89
|
+
expect(text).not.toContain('100') // amount 100 filtered out
|
|
90
|
+
expect(text).not.toContain('50') // amount 50 filtered out
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe('aiFindAnomalies', () => {
|
|
95
|
+
it('flags a numeric outlier over the scanned rows', async () => {
|
|
96
|
+
const api = makeApi()
|
|
97
|
+
const result = await aiFindAnomalies(api, {})
|
|
98
|
+
expect(result.anomalies.length).toBeGreaterThan(0)
|
|
99
|
+
const amountAnomaly = result.anomalies.find((a) => a.field === 'amount')
|
|
100
|
+
expect(amountAnomaly?.value).toBe(2000) // the max in the sample
|
|
101
|
+
expect(amountAnomaly?.severity).toBe('medium')
|
|
102
|
+
expect(result.summary).toBeTruthy()
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('returns empty for an empty selection', async () => {
|
|
106
|
+
const api = makeApi()
|
|
107
|
+
const result = await aiFindAnomalies(api, { target: { kind: 'selection', rowIndices: [] } })
|
|
108
|
+
expect(result.anomalies).toEqual([])
|
|
109
|
+
})
|
|
110
|
+
})
|