@ditojs/admin 2.1.1 → 2.1.3

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.
@@ -35,20 +35,16 @@ export function getTypeComponent(type, allowNull = false) {
35
35
  return component
36
36
  }
37
37
 
38
- function getSchemas(schema) {
39
- return schema
40
- ? [...Object.values(schema.tabs || {}), schema]
41
- : []
42
- }
43
-
44
- export function iterateSchemaComponents(schema, callback) {
45
- if (isSingleComponentView(schema)) {
46
- return callback(schema.component, schema.name)
47
- } else {
48
- const schemas = getSchemas(schema)
49
- for (const schema of schemas) {
38
+ export function iterateSchemaComponents(schemas, callback) {
39
+ for (const schema of schemas) {
40
+ if (isSingleComponentView(schema)) {
41
+ const res = callback(schema.component, schema.name, 0)
42
+ if (res !== undefined) {
43
+ return res
44
+ }
45
+ } else {
50
46
  for (const [name, component] of Object.entries(schema.components || {})) {
51
- const res = callback(component, name)
47
+ const res = callback(component, name, 1)
52
48
  if (res !== undefined) {
53
49
  return res
54
50
  }
@@ -57,32 +53,36 @@ export function iterateSchemaComponents(schema, callback) {
57
53
  }
58
54
  }
59
55
 
56
+ export function iterateNestedSchemaComponents(schema, callback) {
57
+ return schema
58
+ ? iterateSchemaComponents([schema, ...getAllTabSchemas(schema)], callback)
59
+ : undefined
60
+ }
61
+
60
62
  export function findSchemaComponent(schema, callback) {
61
63
  return (
62
- iterateSchemaComponents(
64
+ iterateNestedSchemaComponents(
63
65
  schema,
64
- (component, name) => (callback(component, name) ? component : undefined)
66
+ component => (callback(component) ? component : undefined)
65
67
  ) || null
66
68
  )
67
69
  }
68
70
 
69
71
  export function someSchemaComponent(schema, callback) {
70
72
  return (
71
- iterateSchemaComponents(
73
+ iterateNestedSchemaComponents(
72
74
  schema,
73
- (component, name) => (callback(component, name) ? true : undefined)
74
- ) ===
75
- true
75
+ component => (callback(component) ? true : undefined)
76
+ ) === true
76
77
  )
77
78
  }
78
79
 
79
80
  export function everySchemaComponent(schema, callback) {
80
81
  return (
81
- iterateSchemaComponents(
82
+ iterateNestedSchemaComponents(
82
83
  schema,
83
- (component, name) => (!callback(component, name) ? false : undefined)
84
- ) !==
85
- false
84
+ component => (callback(component) ? undefined : false)
85
+ ) !== false
86
86
  )
87
87
  }
88
88
 
@@ -98,6 +98,14 @@ export function isView(schema) {
98
98
  return isSchema(schema) && schema.type === 'view'
99
99
  }
100
100
 
101
+ export function isTab(schema) {
102
+ return isSchema(schema) && schema.type === 'tab'
103
+ }
104
+
105
+ export function isPanel(schema) {
106
+ return isSchema(schema) && schema.type === 'panel'
107
+ }
108
+
101
109
  export function getSchemaIdentifier(schema) {
102
110
  return schema.name || schema.label || schema.type
103
111
  }
@@ -161,13 +169,6 @@ export async function resolveSchemas(
161
169
  return schemas
162
170
  }
163
171
 
164
- export async function resolvePanels(schema) {
165
- const { panels } = schema
166
- if (panels) {
167
- schema.panels = await resolveSchemas(panels)
168
- }
169
- }
170
-
171
172
  export async function resolveSchemaComponent(schema) {
172
173
  // Resolves async schema components and adds DitoMixin and TypeMixin to them.
173
174
  let { component } = schema
@@ -190,21 +191,54 @@ export async function resolveSchemaComponents(schemas) {
190
191
  await mapConcurrently(Object.values(schemas || {}), resolveSchemaComponent)
191
192
  }
192
193
 
194
+ export async function processSchemaComponents(api, schema, routes, level) {
195
+ const promises = []
196
+ const process = (component, name, relativeLevel) => {
197
+ promises.push(
198
+ processSchemaComponent(
199
+ api,
200
+ component,
201
+ name,
202
+ routes,
203
+ level + relativeLevel
204
+ )
205
+ )
206
+ }
207
+
208
+ iterateNestedSchemaComponents(schema, process)
209
+ iterateSchemaComponents(getAllPanelSchemas(schema), process)
210
+
211
+ await Promise.all(promises)
212
+ }
213
+
214
+ export async function processSchemaComponent(api, schema, name, routes, level) {
215
+ processDefaults(api, schema)
216
+
217
+ await Promise.all([
218
+ // Also process nested panel schemas.
219
+ mapConcurrently(getAllPanelSchemas(schema), panel =>
220
+ processSchemaComponents(api, panel, routes, level)
221
+ ),
222
+ // Delegate schema processing to the actual type components.
223
+ await getTypeOptions(schema)?.processSchema?.(
224
+ api,
225
+ schema,
226
+ name,
227
+ routes,
228
+ level
229
+ )
230
+ ])
231
+ }
232
+
193
233
  export async function processView(component, api, schema, name) {
234
+ if (!isView(schema)) {
235
+ throw new Error(`Invalid view schema: '${getSchemaIdentifier(schema)}'`)
236
+ }
194
237
  processRouteSchema(api, schema, name)
195
238
  processDefaults(api, schema)
196
- await resolvePanels(schema)
239
+ await resolveNestedSchemas(api, schema)
197
240
  const children = []
198
- if (isView(schema)) {
199
- if (isSingleComponentView(schema)) {
200
- await processComponent(api, schema.component, name, children, 0)
201
- } else {
202
- // A multi-component view, start at level 1
203
- await processSchemaComponents(api, schema, children, 1)
204
- }
205
- } else {
206
- throw new Error(`Invalid view schema: '${getSchemaIdentifier(schema)}'`)
207
- }
241
+ await processSchemaComponents(api, schema, children, 0)
208
242
  return {
209
243
  path: `/${schema.path}`,
210
244
  children,
@@ -216,18 +250,6 @@ export async function processView(component, api, schema, name) {
216
250
  }
217
251
  }
218
252
 
219
- export async function processComponent(api, schema, name, routes, level) {
220
- processDefaults(api, schema)
221
- // Delegate schema processing to the actual type components.
222
- await getTypeOptions(schema)?.processSchema?.(
223
- api,
224
- schema,
225
- name,
226
- routes,
227
- level
228
- )
229
- }
230
-
231
253
  export function processDefaults(api, schema) {
232
254
  let defaults = api.defaults[schema.type]
233
255
  if (defaults) {
@@ -252,27 +274,15 @@ export function processRouteSchema(api, schema, name) {
252
274
  schema.path ||= api.normalizePath(name)
253
275
  }
254
276
 
255
- export async function processSchemaComponents(api, schema, routes, level) {
256
- const promises = []
257
- iterateSchemaComponents(schema, (component, name) => {
258
- promises.push(processComponent(api, component, name, routes, level))
259
- })
260
- await Promise.all(promises)
261
- }
262
-
263
277
  export async function processForms(api, schema, level) {
264
- const processForm = async form => {
265
- form = await resolveForm(form)
266
- processDefaults(api, schema)
267
- return form
268
- }
269
-
270
278
  // First resolve the forms and store the results back on the schema.
271
279
  let { form, forms, components } = schema
272
280
  if (forms) {
273
- forms = schema.forms = await resolveSchemas(forms, processForm)
281
+ forms = schema.forms = await resolveSchemas(forms, form =>
282
+ processForm(api, form)
283
+ )
274
284
  } else if (form) {
275
- form = schema.form = await processForm(form)
285
+ form = schema.form = await processForm(api, form)
276
286
  } else if (components) {
277
287
  // NOTE: Processing forms in computed components is not supported, since it
278
288
  // only can be computed in conjunction with actual data.
@@ -284,20 +294,55 @@ export async function processForms(api, schema, level) {
284
294
  forms ||= { default: form } // Only used for process loop below.
285
295
  const children = []
286
296
  for (const form of Object.values(forms)) {
287
- await processSchemaComponents(api, form, children, level + 1)
297
+ await processSchemaComponents(api, form, children, level)
288
298
  }
289
299
  return children
290
300
  }
291
301
 
292
- export async function resolveForm(schema) {
302
+ export async function processForm(api, schema) {
293
303
  schema = await resolveSchema(schema, true)
294
304
  if (!isForm(schema)) {
295
305
  throw new Error(`Invalid form schema: '${getSchemaIdentifier(schema)}'`)
296
306
  }
297
- await resolvePanels(schema)
307
+ processDefaults(api, schema)
308
+ await resolveNestedSchemas(api, schema)
309
+ return schema
310
+ }
311
+
312
+ export async function processTab(api, schema) {
313
+ schema = await resolveSchema(schema, true)
314
+ if (!isTab(schema)) {
315
+ throw new Error(`Invalid tab schema: '${getSchemaIdentifier(schema)}'`)
316
+ }
317
+ processDefaults(api, schema)
318
+ return schema
319
+ }
320
+
321
+ export async function processPanel(api, schema) {
322
+ schema = await resolveSchema(schema, true)
323
+ if (!isPanel(schema)) {
324
+ throw new Error(`Invalid panel schema: '${getSchemaIdentifier(schema)}'`)
325
+ }
326
+ processDefaults(api, schema)
298
327
  return schema
299
328
  }
300
329
 
330
+ export async function resolveNestedSchemas(api, schema) {
331
+ const { tabs, panels } = schema
332
+ if (tabs) {
333
+ schema.tabs = await resolveSchemas(
334
+ tabs,
335
+ tab => processTab(api, tab)
336
+ )
337
+ }
338
+ if (panels) {
339
+ schema.panels = await resolveSchemas(
340
+ panels,
341
+ panel => processPanel(api, panel)
342
+ )
343
+ }
344
+ }
345
+
301
346
  export function hasFormSchema(schema) {
302
347
  // Support both single form and multiple forms notation, as well as inlined
303
348
  // components.
@@ -327,11 +372,7 @@ export function getViewFormSchema(schema, context) {
327
372
  return viewSchema
328
373
  ? // NOTE: Views can have tabs, in which case the view component is nested
329
374
  // in one of the tabs, go find it.
330
- iterateSchemaComponents(viewSchema, schema => {
331
- if (hasFormSchema(schema)) {
332
- return schema
333
- }
334
- }) || null
375
+ findSchemaComponent(viewSchema, hasFormSchema) || null
335
376
  : null
336
377
  }
337
378
 
@@ -474,6 +515,7 @@ export function computeValue(schema, data, name, dataPath, {
474
515
  if (compute) {
475
516
  const value = compute(
476
517
  DitoContext.get(component, {
518
+ schema,
477
519
  // Override value to prevent endless recursion through calling the
478
520
  // getter for `this.value` in `DitoContext`:
479
521
  value: data[name],
@@ -569,6 +611,7 @@ export function processData(schema, sourceSchema, data, dataPath, {
569
611
  // NOTE: We don't cache this context, since `value` is changing.
570
612
  const getContext = () =>
571
613
  DitoContext.get(component, {
614
+ schema,
572
615
  value,
573
616
  name,
574
617
  data,
@@ -659,6 +702,7 @@ export function processSchemaData(
659
702
  ? getDataPath(componentDataPath, index)
660
703
  : componentDataPath
661
704
  const context = DitoContext.get(options.component, {
705
+ schema: componentSchema,
662
706
  data,
663
707
  value: item,
664
708
  dataPath,
@@ -726,13 +770,11 @@ export function processSchemaData(
726
770
  }
727
771
 
728
772
  processComponents(schema.components)
729
- if (schema.tabs) {
730
- for (const tab of Object.values(schema.tabs)) {
731
- processComponents(tab.components)
732
- }
773
+ for (const tab of getAllTabSchemas(schema)) {
774
+ processComponents(tab.components)
733
775
  }
734
- for (const panel of getAllPanelSchemas(schema, dataPath)) {
735
- processComponents(panel.schema.components)
776
+ for (const panel of getAllPanelSchemas(schema)) {
777
+ processComponents(panel.components)
736
778
  }
737
779
 
738
780
  return processedData || data
@@ -803,52 +845,68 @@ export function getSourceType(schemaOrType) {
803
845
  )
804
846
  }
805
847
 
806
- export function getPanelSchema(schema, dataPath, tabComponent) {
848
+ export function getPanelEntry(schema, dataPath = null, tabComponent = null) {
807
849
  return schema
808
850
  ? {
809
851
  schema,
810
852
  // If the panel provides its own name, append it to the dataPath.
811
853
  // This is used e.g. for $filters panels.
812
- dataPath: schema.name
813
- ? appendDataPath(dataPath, schema.name)
814
- : dataPath,
854
+ dataPath:
855
+ dataPath != null && schema.name
856
+ ? appendDataPath(dataPath, schema.name)
857
+ : dataPath,
815
858
  tabComponent
816
859
  }
817
860
  : null
818
861
  }
819
862
 
820
- export function getPanelSchemas(schemas, dataPath, tabComponent, panels = []) {
821
- if (schemas) {
822
- for (const [key, schema] of Object.entries(schemas)) {
823
- const panel = getPanelSchema(
863
+ export function getPanelEntries(
864
+ panelSchemas,
865
+ dataPath = null,
866
+ tabComponent = null,
867
+ panelEntries = []
868
+ ) {
869
+ if (panelSchemas) {
870
+ for (const [key, schema] of Object.entries(panelSchemas)) {
871
+ const entry = getPanelEntry(
824
872
  schema,
825
- appendDataPath(dataPath, key),
873
+ dataPath != null ? appendDataPath(dataPath, key) : null,
826
874
  tabComponent
827
875
  )
828
- if (panel) {
829
- panels.push(panel)
876
+ if (entry) {
877
+ panelEntries.push(entry)
830
878
  }
831
879
  }
832
880
  }
833
- return panels
881
+ return panelEntries
834
882
  }
835
883
 
836
- export function getAllPanelSchemas(
884
+ export function getAllTabSchemas(schema) {
885
+ return schema?.tabs ? Object.values(schema.tabs) : []
886
+ }
887
+
888
+ export function getAllPanelSchemas(schema) {
889
+ return getAllPanelEntries(schema).map(entry => entry.schema)
890
+ }
891
+
892
+ export function getAllPanelEntries(
837
893
  schema,
838
- dataPath,
894
+ dataPath = null,
839
895
  schemaComponent = null,
840
896
  tabComponent = null
841
897
  ) {
842
- const panel = getTypeOptions(schema)?.getPanelSchema?.(
898
+ const panelSchema = getTypeOptions(schema)?.getPanelSchema?.(
843
899
  schema,
844
900
  dataPath,
845
901
  schemaComponent
846
902
  )
847
- const panels = panel ? [getPanelSchema(panel, dataPath, tabComponent)] : []
903
+ const panelEntries = panelSchema
904
+ ? [getPanelEntry(panelSchema, dataPath, tabComponent)]
905
+ : []
848
906
  // Allow each component to provide its own set of panels, in
849
- // addition to the default one (e.g. $filter):
850
- getPanelSchemas(schema.panels, dataPath, tabComponent, panels)
851
- return panels
907
+ // addition to the default one (e.g. getFiltersPanel(), $filters):
908
+ getPanelEntries(schema?.panels, dataPath, tabComponent, panelEntries)
909
+ return panelEntries
852
910
  }
853
911
 
854
912
  export function isObjectSource(schemaOrType) {