@object-ui/types 3.0.3 → 3.1.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/dist/app.d.ts +217 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +85 -1
- package/dist/complex.d.ts +128 -0
- package/dist/complex.d.ts.map +1 -1
- package/dist/data-display.d.ts +105 -1
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data.d.ts +45 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/designer.d.ts +197 -35
- package/dist/designer.d.ts.map +1 -1
- package/dist/designer.js +11 -1
- package/dist/index.d.ts +21 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/layout.d.ts +39 -2
- package/dist/layout.d.ts.map +1 -1
- package/dist/navigation.d.ts +27 -0
- package/dist/navigation.d.ts.map +1 -1
- package/dist/objectql.d.ts +641 -7
- package/dist/objectql.d.ts.map +1 -1
- package/dist/record-components.d.ts +160 -0
- package/dist/record-components.d.ts.map +1 -0
- package/dist/record-components.js +8 -0
- package/dist/reports.d.ts +37 -0
- package/dist/reports.d.ts.map +1 -1
- package/dist/theme.d.ts +5 -0
- package/dist/theme.d.ts.map +1 -1
- package/dist/views.d.ts +324 -4
- package/dist/views.d.ts.map +1 -1
- package/dist/workflow.d.ts +198 -0
- package/dist/workflow.d.ts.map +1 -1
- package/dist/zod/app.zod.d.ts +42 -2
- package/dist/zod/app.zod.d.ts.map +1 -1
- package/dist/zod/app.zod.js +61 -1
- package/dist/zod/complex.zod.d.ts +122 -0
- package/dist/zod/complex.zod.d.ts.map +1 -1
- package/dist/zod/complex.zod.js +57 -0
- package/dist/zod/data-display.zod.d.ts +4 -0
- package/dist/zod/data-display.zod.d.ts.map +1 -1
- package/dist/zod/data-display.zod.js +2 -0
- package/dist/zod/form.zod.d.ts +6 -6
- package/dist/zod/index.zod.d.ts +365 -41
- package/dist/zod/index.zod.d.ts.map +1 -1
- package/dist/zod/index.zod.js +2 -2
- package/dist/zod/layout.zod.d.ts +6 -6
- package/dist/zod/navigation.zod.d.ts +58 -12
- package/dist/zod/navigation.zod.d.ts.map +1 -1
- package/dist/zod/navigation.zod.js +21 -9
- package/dist/zod/objectql.zod.d.ts +515 -27
- package/dist/zod/objectql.zod.d.ts.map +1 -1
- package/dist/zod/objectql.zod.js +162 -0
- package/dist/zod/reports.zod.d.ts +38 -38
- package/dist/zod/views.zod.d.ts +163 -7
- package/dist/zod/views.zod.d.ts.map +1 -1
- package/dist/zod/views.zod.js +22 -3
- package/package.json +2 -2
- package/src/__tests__/app-creation-types.test.ts +177 -0
- package/src/__tests__/dashboard-config.test.ts +208 -0
- package/src/__tests__/examples-metadata-compliance.test.ts +264 -0
- package/src/__tests__/navigation-model.test.ts +406 -0
- package/src/__tests__/p1-spec-alignment.test.ts +660 -0
- package/src/__tests__/p2-spec-exports.test.ts +312 -0
- package/src/__tests__/phase2-schemas.test.ts +108 -0
- package/src/app.ts +377 -0
- package/src/complex.ts +130 -0
- package/src/data-display.ts +107 -0
- package/src/data.ts +49 -0
- package/src/designer.ts +219 -30
- package/src/index.ts +194 -3
- package/src/layout.ts +55 -2
- package/src/navigation.ts +20 -0
- package/src/objectql.ts +757 -8
- package/src/record-components.ts +188 -0
- package/src/reports.ts +43 -0
- package/src/theme.ts +6 -0
- package/src/views.ts +344 -4
- package/src/workflow.ts +226 -0
- package/src/zod/app.zod.ts +74 -1
- package/src/zod/complex.zod.ts +59 -0
- package/src/zod/data-display.zod.ts +2 -0
- package/src/zod/index.zod.ts +5 -0
- package/src/zod/navigation.zod.ts +22 -10
- package/src/zod/objectql.zod.ts +167 -0
- package/src/zod/views.zod.ts +22 -3
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* P2.3/P2.4 Spec Protocol Type Re-export Tests
|
|
11
|
+
*
|
|
12
|
+
* Verifies that P2.3 (Sharing & Embedding) and P2.4 (View Configuration)
|
|
13
|
+
* Zod schemas from @objectstack/spec/ui are properly re-exported and functional.
|
|
14
|
+
*
|
|
15
|
+
* The types index re-exports these as `export type { ... }`, so we verify:
|
|
16
|
+
* 1. Type-level re-exports compile correctly (import type from '../index')
|
|
17
|
+
* 2. Runtime Zod schemas from @objectstack/spec/ui validate data correctly
|
|
18
|
+
*/
|
|
19
|
+
import { describe, it, expect } from 'vitest';
|
|
20
|
+
import type {
|
|
21
|
+
SharingConfig,
|
|
22
|
+
SharingConfigSchema,
|
|
23
|
+
EmbedConfig,
|
|
24
|
+
EmbedConfigSchema,
|
|
25
|
+
AddRecordConfig,
|
|
26
|
+
AddRecordConfigSchema,
|
|
27
|
+
AppearanceConfig,
|
|
28
|
+
AppearanceConfigSchema,
|
|
29
|
+
UserActionsConfig,
|
|
30
|
+
UserActionsConfigSchema,
|
|
31
|
+
ViewTab,
|
|
32
|
+
ViewTabSchema,
|
|
33
|
+
ViewFilterRule,
|
|
34
|
+
ViewFilterRuleSchema,
|
|
35
|
+
DensityModeSchema,
|
|
36
|
+
WcagContrastLevelSchema,
|
|
37
|
+
} from '../index';
|
|
38
|
+
|
|
39
|
+
import type {
|
|
40
|
+
ThemeModeSchema,
|
|
41
|
+
} from '../theme';
|
|
42
|
+
|
|
43
|
+
// Runtime Zod schemas are imported directly from the spec package
|
|
44
|
+
import {
|
|
45
|
+
SharingConfigSchema as SharingConfigZod,
|
|
46
|
+
EmbedConfigSchema as EmbedConfigZod,
|
|
47
|
+
AddRecordConfigSchema as AddRecordConfigZod,
|
|
48
|
+
AppearanceConfigSchema as AppearanceConfigZod,
|
|
49
|
+
UserActionsConfigSchema as UserActionsConfigZod,
|
|
50
|
+
ViewTabSchema as ViewTabZod,
|
|
51
|
+
ViewFilterRuleSchema as ViewFilterRuleZod,
|
|
52
|
+
DensityModeSchema as DensityModeZod,
|
|
53
|
+
WcagContrastLevelSchema as WcagContrastLevelZod,
|
|
54
|
+
ThemeModeSchema as ThemeModeZod,
|
|
55
|
+
} from '@objectstack/spec/ui';
|
|
56
|
+
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// P2.3 Sharing & Embedding
|
|
59
|
+
// ============================================================================
|
|
60
|
+
describe('P2.3 Spec Protocol Type Re-exports — Sharing & Embedding', () => {
|
|
61
|
+
describe('SharingConfigSchema', () => {
|
|
62
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
63
|
+
expect(SharingConfigZod).toBeDefined();
|
|
64
|
+
expect(typeof SharingConfigZod.parse).toBe('function');
|
|
65
|
+
expect(typeof SharingConfigZod.safeParse).toBe('function');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should validate a minimal SharingConfig', () => {
|
|
69
|
+
const config: SharingConfig = { enabled: true };
|
|
70
|
+
const result = SharingConfigZod.safeParse(config);
|
|
71
|
+
expect(result.success).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should validate a full SharingConfig', () => {
|
|
75
|
+
const config: SharingConfig = {
|
|
76
|
+
enabled: true,
|
|
77
|
+
publicLink: 'https://example.com/shared/abc123',
|
|
78
|
+
password: 'secret',
|
|
79
|
+
allowedDomains: ['example.com'],
|
|
80
|
+
expiresAt: '2025-12-31',
|
|
81
|
+
allowAnonymous: false,
|
|
82
|
+
};
|
|
83
|
+
const result = SharingConfigZod.safeParse(config);
|
|
84
|
+
expect(result.success).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('EmbedConfigSchema', () => {
|
|
89
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
90
|
+
expect(EmbedConfigZod).toBeDefined();
|
|
91
|
+
expect(typeof EmbedConfigZod.parse).toBe('function');
|
|
92
|
+
expect(typeof EmbedConfigZod.safeParse).toBe('function');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should validate a minimal EmbedConfig', () => {
|
|
96
|
+
const config: EmbedConfig = { enabled: true };
|
|
97
|
+
const result = EmbedConfigZod.safeParse(config);
|
|
98
|
+
expect(result.success).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should validate a full EmbedConfig', () => {
|
|
102
|
+
const config: EmbedConfig = {
|
|
103
|
+
enabled: true,
|
|
104
|
+
allowedOrigins: ['https://example.com'],
|
|
105
|
+
width: '100%',
|
|
106
|
+
height: '600px',
|
|
107
|
+
showHeader: false,
|
|
108
|
+
showNavigation: false,
|
|
109
|
+
responsive: true,
|
|
110
|
+
};
|
|
111
|
+
const result = EmbedConfigZod.safeParse(config);
|
|
112
|
+
expect(result.success).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// P2.4 View Configuration
|
|
119
|
+
// ============================================================================
|
|
120
|
+
describe('P2.4 Spec Protocol Type Re-exports — View Configuration', () => {
|
|
121
|
+
describe('AddRecordConfigSchema', () => {
|
|
122
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
123
|
+
expect(AddRecordConfigZod).toBeDefined();
|
|
124
|
+
expect(typeof AddRecordConfigZod.parse).toBe('function');
|
|
125
|
+
expect(typeof AddRecordConfigZod.safeParse).toBe('function');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should validate a minimal AddRecordConfig', () => {
|
|
129
|
+
const config: AddRecordConfig = { enabled: true };
|
|
130
|
+
const result = AddRecordConfigZod.safeParse(config);
|
|
131
|
+
expect(result.success).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should validate a full AddRecordConfig', () => {
|
|
135
|
+
const config: AddRecordConfig = {
|
|
136
|
+
enabled: true,
|
|
137
|
+
position: 'top',
|
|
138
|
+
mode: 'inline',
|
|
139
|
+
formView: 'new-contact-form',
|
|
140
|
+
};
|
|
141
|
+
const result = AddRecordConfigZod.safeParse(config);
|
|
142
|
+
expect(result.success).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('AppearanceConfigSchema', () => {
|
|
147
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
148
|
+
expect(AppearanceConfigZod).toBeDefined();
|
|
149
|
+
expect(typeof AppearanceConfigZod.parse).toBe('function');
|
|
150
|
+
expect(typeof AppearanceConfigZod.safeParse).toBe('function');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should validate a minimal AppearanceConfig', () => {
|
|
154
|
+
const config: AppearanceConfig = {};
|
|
155
|
+
const result = AppearanceConfigZod.safeParse(config);
|
|
156
|
+
expect(result.success).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should validate a full AppearanceConfig', () => {
|
|
160
|
+
const config: AppearanceConfig = {
|
|
161
|
+
showDescription: true,
|
|
162
|
+
allowedVisualizations: ['grid', 'kanban', 'calendar'],
|
|
163
|
+
};
|
|
164
|
+
const result = AppearanceConfigZod.safeParse(config);
|
|
165
|
+
expect(result.success).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('UserActionsConfigSchema', () => {
|
|
170
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
171
|
+
expect(UserActionsConfigZod).toBeDefined();
|
|
172
|
+
expect(typeof UserActionsConfigZod.parse).toBe('function');
|
|
173
|
+
expect(typeof UserActionsConfigZod.safeParse).toBe('function');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should validate a minimal UserActionsConfig', () => {
|
|
177
|
+
const config: UserActionsConfig = {};
|
|
178
|
+
const result = UserActionsConfigZod.safeParse(config);
|
|
179
|
+
expect(result.success).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should validate a full UserActionsConfig', () => {
|
|
183
|
+
const config: UserActionsConfig = {
|
|
184
|
+
sort: true,
|
|
185
|
+
search: true,
|
|
186
|
+
filter: true,
|
|
187
|
+
rowHeight: true,
|
|
188
|
+
};
|
|
189
|
+
const result = UserActionsConfigZod.safeParse(config);
|
|
190
|
+
expect(result.success).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe('ViewTabSchema', () => {
|
|
195
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
196
|
+
expect(ViewTabZod).toBeDefined();
|
|
197
|
+
expect(typeof ViewTabZod.parse).toBe('function');
|
|
198
|
+
expect(typeof ViewTabZod.safeParse).toBe('function');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should validate a minimal ViewTab', () => {
|
|
202
|
+
const tab: ViewTab = { name: 'all', label: 'All Records' };
|
|
203
|
+
const result = ViewTabZod.safeParse(tab);
|
|
204
|
+
expect(result.success).toBe(true);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should validate a full ViewTab', () => {
|
|
208
|
+
const tab: ViewTab = {
|
|
209
|
+
name: 'active',
|
|
210
|
+
label: 'Active',
|
|
211
|
+
icon: 'CheckCircle',
|
|
212
|
+
filter: [{ field: 'status', operator: 'eq', value: 'active' }],
|
|
213
|
+
order: 1,
|
|
214
|
+
pinned: true,
|
|
215
|
+
isDefault: true,
|
|
216
|
+
visible: true,
|
|
217
|
+
};
|
|
218
|
+
const result = ViewTabZod.safeParse(tab);
|
|
219
|
+
expect(result.success).toBe(true);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// ============================================================================
|
|
225
|
+
// v3.0.10 New Spec Types
|
|
226
|
+
// ============================================================================
|
|
227
|
+
describe('v3.0.10 Spec Protocol New Types', () => {
|
|
228
|
+
describe('ViewFilterRuleSchema', () => {
|
|
229
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
230
|
+
expect(ViewFilterRuleZod).toBeDefined();
|
|
231
|
+
expect(typeof ViewFilterRuleZod.parse).toBe('function');
|
|
232
|
+
expect(typeof ViewFilterRuleZod.safeParse).toBe('function');
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should validate a ViewFilterRule', () => {
|
|
236
|
+
const rule: ViewFilterRule = { field: 'status', operator: 'eq', value: 'active' };
|
|
237
|
+
const result = ViewFilterRuleZod.safeParse(rule);
|
|
238
|
+
expect(result.success).toBe(true);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('DensityModeSchema', () => {
|
|
243
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
244
|
+
expect(DensityModeZod).toBeDefined();
|
|
245
|
+
expect(typeof DensityModeZod.parse).toBe('function');
|
|
246
|
+
expect(typeof DensityModeZod.safeParse).toBe('function');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should validate density mode values', () => {
|
|
250
|
+
expect(DensityModeZod.safeParse('compact').success).toBe(true);
|
|
251
|
+
expect(DensityModeZod.safeParse('regular').success).toBe(true);
|
|
252
|
+
expect(DensityModeZod.safeParse('spacious').success).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
describe('ThemeModeSchema', () => {
|
|
257
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
258
|
+
expect(ThemeModeZod).toBeDefined();
|
|
259
|
+
expect(typeof ThemeModeZod.parse).toBe('function');
|
|
260
|
+
expect(typeof ThemeModeZod.safeParse).toBe('function');
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('should validate theme mode values', () => {
|
|
264
|
+
expect(ThemeModeZod.safeParse('light').success).toBe(true);
|
|
265
|
+
expect(ThemeModeZod.safeParse('dark').success).toBe(true);
|
|
266
|
+
expect(ThemeModeZod.safeParse('auto').success).toBe(true);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe('WcagContrastLevelSchema', () => {
|
|
271
|
+
it('should be a valid Zod schema with parse method', () => {
|
|
272
|
+
expect(WcagContrastLevelZod).toBeDefined();
|
|
273
|
+
expect(typeof WcagContrastLevelZod.parse).toBe('function');
|
|
274
|
+
expect(typeof WcagContrastLevelZod.safeParse).toBe('function');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('should validate contrast level values', () => {
|
|
278
|
+
expect(WcagContrastLevelZod.safeParse('AA').success).toBe(true);
|
|
279
|
+
expect(WcagContrastLevelZod.safeParse('AAA').success).toBe(true);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
describe('Type re-exports from @object-ui/types index', () => {
|
|
284
|
+
it('should re-export P2.3 types (compile-time verification)', async () => {
|
|
285
|
+
// Dynamic import to verify exports exist on the module
|
|
286
|
+
const types = await import('../index');
|
|
287
|
+
|
|
288
|
+
// These are type-only re-exports, so they won't appear as runtime properties.
|
|
289
|
+
// We verify the module itself is importable and other runtime exports are intact.
|
|
290
|
+
expect(types).toBeDefined();
|
|
291
|
+
expect(typeof types.defineStack).toBe('function');
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it('should allow type annotations with P2.3 Sharing & Embedding types', () => {
|
|
295
|
+
// Compile-time check: these lines would fail to compile if types were not re-exported
|
|
296
|
+
const sharing: SharingConfig = { enabled: true };
|
|
297
|
+
const embed: EmbedConfig = { enabled: false };
|
|
298
|
+
expect(sharing.enabled).toBe(true);
|
|
299
|
+
expect(embed.enabled).toBe(false);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('should allow type annotations with P2.4 View Configuration types', () => {
|
|
303
|
+
const addRecord: AddRecordConfig = { enabled: true };
|
|
304
|
+
const appearance: AppearanceConfig = { showDescription: true };
|
|
305
|
+
const userActions: UserActionsConfig = { sort: true };
|
|
306
|
+
const tab: ViewTab = { name: 'main', label: 'Main' };
|
|
307
|
+
expect(addRecord.enabled).toBe(true);
|
|
308
|
+
expect(appearance.showDescription).toBe(true);
|
|
309
|
+
expect(userActions.sort).toBe(true);
|
|
310
|
+
expect(tab.name).toBe('main');
|
|
311
|
+
});
|
|
312
|
+
});
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
FilterUISchema,
|
|
28
28
|
SortUISchema,
|
|
29
29
|
AnyComponentSchema,
|
|
30
|
+
ListViewSchema,
|
|
30
31
|
} from '../zod/index.zod';
|
|
31
32
|
|
|
32
33
|
describe('Phase 2: AppSchema Zod Validation', () => {
|
|
@@ -632,3 +633,110 @@ describe('Phase 2: AnyComponentSchema Union Type', () => {
|
|
|
632
633
|
});
|
|
633
634
|
});
|
|
634
635
|
});
|
|
636
|
+
|
|
637
|
+
describe('ListViewSchema userFilters Zod Validation', () => {
|
|
638
|
+
it('should validate dropdown mode userFilters', () => {
|
|
639
|
+
const schema = {
|
|
640
|
+
type: 'list-view',
|
|
641
|
+
objectName: 'accounts',
|
|
642
|
+
userFilters: {
|
|
643
|
+
element: 'dropdown',
|
|
644
|
+
fields: [
|
|
645
|
+
{
|
|
646
|
+
field: 'status',
|
|
647
|
+
label: 'Status',
|
|
648
|
+
type: 'multi-select',
|
|
649
|
+
showCount: true,
|
|
650
|
+
options: [
|
|
651
|
+
{ label: 'Active', value: 'active' },
|
|
652
|
+
{ label: 'Inactive', value: 'inactive', color: '#dc2626' },
|
|
653
|
+
],
|
|
654
|
+
defaultValues: ['active'],
|
|
655
|
+
},
|
|
656
|
+
],
|
|
657
|
+
},
|
|
658
|
+
};
|
|
659
|
+
const result = ListViewSchema.safeParse(schema);
|
|
660
|
+
expect(result.success).toBe(true);
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it('should validate tabs mode userFilters', () => {
|
|
664
|
+
const schema = {
|
|
665
|
+
type: 'list-view',
|
|
666
|
+
objectName: 'accounts',
|
|
667
|
+
userFilters: {
|
|
668
|
+
element: 'tabs',
|
|
669
|
+
showAllRecords: true,
|
|
670
|
+
allowAddTab: true,
|
|
671
|
+
tabs: [
|
|
672
|
+
{ id: 'tab-1', label: 'Active', filters: [['status', '=', 'active']], default: true },
|
|
673
|
+
{ id: 'tab-2', label: 'My Items', filters: [['owner', '=', '$currentUser']] },
|
|
674
|
+
],
|
|
675
|
+
},
|
|
676
|
+
};
|
|
677
|
+
const result = ListViewSchema.safeParse(schema);
|
|
678
|
+
expect(result.success).toBe(true);
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
it('should validate toggle mode userFilters', () => {
|
|
682
|
+
const schema = {
|
|
683
|
+
type: 'list-view',
|
|
684
|
+
objectName: 'accounts',
|
|
685
|
+
userFilters: {
|
|
686
|
+
element: 'toggle',
|
|
687
|
+
fields: [
|
|
688
|
+
{ field: 'is_active', label: 'Active Only' },
|
|
689
|
+
{ field: 'is_vip', label: 'VIP', defaultValues: [true] },
|
|
690
|
+
],
|
|
691
|
+
},
|
|
692
|
+
};
|
|
693
|
+
const result = ListViewSchema.safeParse(schema);
|
|
694
|
+
expect(result.success).toBe(true);
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
it('should reject invalid element type', () => {
|
|
698
|
+
const schema = {
|
|
699
|
+
type: 'list-view',
|
|
700
|
+
objectName: 'accounts',
|
|
701
|
+
userFilters: {
|
|
702
|
+
element: 'invalid',
|
|
703
|
+
},
|
|
704
|
+
};
|
|
705
|
+
const result = ListViewSchema.safeParse(schema);
|
|
706
|
+
expect(result.success).toBe(false);
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it('should validate ListViewSchema without userFilters (backward compat)', () => {
|
|
710
|
+
const schema = {
|
|
711
|
+
type: 'list-view',
|
|
712
|
+
objectName: 'accounts',
|
|
713
|
+
fields: ['name', 'email'],
|
|
714
|
+
};
|
|
715
|
+
const result = ListViewSchema.safeParse(schema);
|
|
716
|
+
expect(result.success).toBe(true);
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
it('should validate ListViewSchema with showSearch/showSort/showFilters/striped/bordered/color', () => {
|
|
720
|
+
const schema = {
|
|
721
|
+
type: 'list-view',
|
|
722
|
+
objectName: 'accounts',
|
|
723
|
+
fields: ['name', 'email'],
|
|
724
|
+
showSearch: true,
|
|
725
|
+
showSort: false,
|
|
726
|
+
showFilters: true,
|
|
727
|
+
striped: true,
|
|
728
|
+
bordered: false,
|
|
729
|
+
color: 'status',
|
|
730
|
+
};
|
|
731
|
+
const result = ListViewSchema.safeParse(schema);
|
|
732
|
+
expect(result.success).toBe(true);
|
|
733
|
+
if (result.success) {
|
|
734
|
+
expect(result.data.showSearch).toBe(true);
|
|
735
|
+
expect(result.data.showSort).toBe(false);
|
|
736
|
+
expect(result.data.showFilters).toBe(true);
|
|
737
|
+
expect(result.data.striped).toBe(true);
|
|
738
|
+
expect(result.data.bordered).toBe(false);
|
|
739
|
+
expect(result.data.color).toBe('status');
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
});
|