@richardmcquiston01/dashboard-widgets-toolkit 0.16.0 → 0.17.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/core.cjs CHANGED
@@ -339,6 +339,9 @@ function viewChoices(item) {
339
339
  }))
340
340
  ];
341
341
  }
342
+ function isProviderView(view) {
343
+ return view.convert === void 0;
344
+ }
342
345
  function isKnownView(item, key) {
343
346
  return key !== void 0 && (key === BASE_VIEW_KEY || findView(item, key) !== void 0);
344
347
  }
@@ -351,6 +354,14 @@ function effectiveViewKey(item, chosen) {
351
354
  function viewKind(item, chosen) {
352
355
  return findView(item, effectiveViewKey(item, chosen))?.kind ?? item.kind;
353
356
  }
357
+ function loadViewKey(item, chosen) {
358
+ const key = effectiveViewKey(item, chosen);
359
+ const view = findView(item, key);
360
+ return view !== void 0 && isProviderView(view) ? key : BASE_VIEW_KEY;
361
+ }
362
+ function loadViewKind(item, chosen) {
363
+ return findView(item, loadViewKey(item, chosen))?.kind ?? item.kind;
364
+ }
354
365
  function cellValue(cell) {
355
366
  const value = cell?.value;
356
367
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
@@ -485,6 +496,11 @@ function convertView(widgetKey, view, data, options = {}) {
485
496
  where: `Widget ${JSON.stringify(widgetKey)} view ${JSON.stringify(view.key)}`,
486
497
  ...options.locale === void 0 ? {} : { locale: options.locale }
487
498
  };
499
+ if (conversion === void 0) {
500
+ return err(
501
+ `${context.where}: the provider supplies this view, so there is nothing to convert.`
502
+ );
503
+ }
488
504
  const expected = VIEW_CONVERSIONS[conversion.type]?.from;
489
505
  if (expected === void 0) {
490
506
  return err(
@@ -510,8 +526,8 @@ function convertView(widgetKey, view, data, options = {}) {
510
526
  }
511
527
  }
512
528
  function viewNote(view, data) {
513
- if (data?.kind !== "TABLE") return "";
514
529
  const conversion = view.convert;
530
+ if (data?.kind !== "TABLE" || conversion === void 0) return "";
515
531
  let indexes;
516
532
  if (conversion.type === "tableToBarList") {
517
533
  indexes = [conversion.label, conversion.value];
@@ -528,14 +544,29 @@ function viewNote(view, data) {
528
544
  function applyView(widget, chosen, options = {}) {
529
545
  const key = effectiveViewKey(widget.definition, chosen);
530
546
  const view = findView(widget.definition, key);
531
- if (view === void 0) return widget;
547
+ const wanted = loadViewKey(widget.definition, chosen);
548
+ const loaded = widget.status === "ok" ? widget.view ?? BASE_VIEW_KEY : void 0;
549
+ const mismatched = loaded !== void 0 && loaded !== wanted;
550
+ if (view === void 0) {
551
+ return mismatched ? {
552
+ definition: widget.definition,
553
+ status: "loading",
554
+ ...widget.options === void 0 ? {} : { options: widget.options }
555
+ } : widget;
556
+ }
532
557
  const definition = {
533
558
  ...widget.definition,
534
559
  kind: view.kind
535
560
  };
536
- if (widget.status === "loading") return { ...widget, definition };
537
- if (widget.status === "empty") return { ...widget, definition };
538
- if (widget.status === "error") return { ...widget, definition };
561
+ if (widget.status !== "ok") return { ...widget, definition };
562
+ if (mismatched) {
563
+ return {
564
+ definition,
565
+ status: "loading",
566
+ ...widget.options === void 0 ? {} : { options: widget.options }
567
+ };
568
+ }
569
+ if (isProviderView(view)) return { ...widget, definition };
539
570
  const converted = convertView(
540
571
  widget.definition.key,
541
572
  view,
@@ -1344,6 +1375,15 @@ function optionValuesFromLayout(definitions, layout, options = {}) {
1344
1375
  }
1345
1376
  return out;
1346
1377
  }
1378
+ function viewValuesFromLayout(definitions, layout, options = {}) {
1379
+ const out = {};
1380
+ for (const definition of definitions) {
1381
+ if (!(definition.views ?? []).some(isProviderView)) continue;
1382
+ const locked = options.overrideLocks !== true && isOptionsLocked(definition);
1383
+ out[definition.key] = locked ? "" : layout.settings?.[definition.key]?.view ?? "";
1384
+ }
1385
+ return out;
1386
+ }
1347
1387
  function sameSettings(a, b) {
1348
1388
  if (a === b) return true;
1349
1389
  return a?.title === b?.title && a?.width === b?.width && a?.flexible === b?.flexible && a?.view === b?.view && sameOptionValues(a?.options ?? {}, b?.options ?? {});
@@ -3156,11 +3196,7 @@ function checkViews(value, problems) {
3156
3196
  problems.push(`${path}.label must be a non-empty string.`);
3157
3197
  }
3158
3198
  requireOneOf(view, "kind", WIDGET_KINDS, path, problems);
3159
- if (view["convert"] === void 0) {
3160
- problems.push(
3161
- `${path}.convert is required: views supplied by a provider are not supported yet.`
3162
- );
3163
- } else {
3199
+ if (view["convert"] !== void 0) {
3164
3200
  checkConversion(
3165
3201
  view["convert"],
3166
3202
  `${path}.convert`,
@@ -3281,7 +3317,10 @@ function resolvePayload(definition, payload, options = {}) {
3281
3317
  } else {
3282
3318
  const result = validateWidgetData(payload, {
3283
3319
  widgetKey: definition.key,
3284
- expectedKind: definition.kind
3320
+ expectedKind: loadViewKind(
3321
+ definition,
3322
+ options.viewValues?.[definition.key]
3323
+ )
3285
3324
  });
3286
3325
  if (!result.ok) {
3287
3326
  return { definition, status: "error", error: result.error };
@@ -3292,7 +3331,14 @@ function resolvePayload(definition, payload, options = {}) {
3292
3331
  if (emptyText !== null) {
3293
3332
  return { definition, status: "empty", emptyText };
3294
3333
  }
3295
- return { definition, status: "ok", data: checked };
3334
+ return {
3335
+ definition,
3336
+ status: "ok",
3337
+ data: checked,
3338
+ ...hasViews(definition) ? {
3339
+ view: loadViewKey(definition, options.viewValues?.[definition.key])
3340
+ } : {}
3341
+ };
3296
3342
  }
3297
3343
  function failedWidget(definition, error) {
3298
3344
  return { definition, status: "error", error };
@@ -3302,7 +3348,14 @@ function loadingWidgets(definitions) {
3302
3348
  }
3303
3349
  function cacheKeyFor(definition, options, values) {
3304
3350
  const base = options.cacheKey === void 0 ? definition.sourceKey ?? definition.key : options.cacheKey(definition);
3305
- return values === void 0 ? base : `${base}${optionsCacheSuffix(definition, values, options)}`;
3351
+ const view = loadViewKey(
3352
+ definition,
3353
+ options.viewValues?.[definition.key]
3354
+ );
3355
+ const viewPart = view === BASE_VIEW_KEY ? "" : `view=${encodeURIComponent(view)}`;
3356
+ const optionPart = values === void 0 ? "" : optionsCacheSuffix(definition, values, options);
3357
+ if (viewPart === "") return `${base}${optionPart}`;
3358
+ return optionPart === "" ? `${base}?${viewPart}` : `${base}?${viewPart}&${optionPart.slice(1)}`;
3306
3359
  }
3307
3360
  function optionValuesFor(definition, options) {
3308
3361
  return resolveOptionValues(
@@ -3313,6 +3366,9 @@ function optionValuesFor(definition, options) {
3313
3366
  }
3314
3367
  function finalizeWidget(widget, values) {
3315
3368
  if (Object.keys(values).length === 0) return widget;
3369
+ if (widget.status === "ok" && widget.view !== void 0 && widget.view !== BASE_VIEW_KEY) {
3370
+ return { ...widget, options: values };
3371
+ }
3316
3372
  if (widget.status === "ok") {
3317
3373
  const data = applyClientOptions(
3318
3374
  widget.definition,
@@ -3370,7 +3426,8 @@ async function resolveWidgetUnapplied(definition, provider, context, options = {
3370
3426
  if (controller.signal.aborted) throw new LoadInterruption();
3371
3427
  return provider(context, definition, {
3372
3428
  signal: controller.signal,
3373
- options: values
3429
+ options: values,
3430
+ view: loadViewKey(definition, options.viewValues?.[definition.key])
3374
3431
  });
3375
3432
  }),
3376
3433
  interrupted
@@ -3434,9 +3491,18 @@ function createWidgetLoader(options) {
3434
3491
  ([key, values]) => values === void 0 ? [] : [[key, values]]
3435
3492
  )
3436
3493
  );
3494
+ const chosenViews = new Map(
3495
+ Object.entries(baseOptions.viewValues ?? {}).flatMap(
3496
+ ([key, view]) => view === void 0 ? [] : [[key, view]]
3497
+ )
3498
+ );
3437
3499
  const resolveOptions = baseOptions;
3438
3500
  function currentOptions() {
3439
- return { ...resolveOptions, optionValues: Object.fromEntries(chosen) };
3501
+ return {
3502
+ ...resolveOptions,
3503
+ optionValues: Object.fromEntries(chosen),
3504
+ viewValues: Object.fromEntries(chosenViews)
3505
+ };
3440
3506
  }
3441
3507
  const unapplied = /* @__PURE__ */ new Map();
3442
3508
  const visible = widgetsFor(definitions, context.roles);
@@ -3569,6 +3635,23 @@ function createWidgetLoader(options) {
3569
3635
  }
3570
3636
  start(definition, true);
3571
3637
  }
3638
+ function setView(key, view) {
3639
+ if (disposed) return;
3640
+ const definition = definitionFor(key);
3641
+ if (definition === void 0) return;
3642
+ const before = loadViewKey(definition, chosenViews.get(key));
3643
+ if (view === void 0 || view === "") chosenViews.delete(key);
3644
+ else chosenViews.set(key, view);
3645
+ const after = loadViewKey(definition, chosenViews.get(key));
3646
+ if (before === after || !started.has(key)) return;
3647
+ const current = snapshot.find(
3648
+ (widget) => widget.definition.key === key
3649
+ );
3650
+ if (current !== void 0 && current.status !== "loading") {
3651
+ replace(key, { definition, status: "loading" });
3652
+ }
3653
+ start(definition, true);
3654
+ }
3572
3655
  function dispose() {
3573
3656
  disposed = true;
3574
3657
  abortAll(new Error("The widget loader was disposed."));
@@ -3587,6 +3670,7 @@ function createWidgetLoader(options) {
3587
3670
  loadAll,
3588
3671
  refresh,
3589
3672
  setOptions,
3673
+ setView,
3590
3674
  dispose
3591
3675
  };
3592
3676
  }
@@ -4507,6 +4591,7 @@ exports.isHidden = isHidden;
4507
4591
  exports.isIsoInterval = isIsoInterval;
4508
4592
  exports.isMinimized = isMinimized;
4509
4593
  exports.isOptionsLocked = isOptionsLocked;
4594
+ exports.isProviderView = isProviderView;
4510
4595
  exports.isSafeHref = isSafeHref;
4511
4596
  exports.isSafeImageUrl = isSafeImageUrl;
4512
4597
  exports.isTitleInUse = isTitleInUse;
@@ -4518,6 +4603,8 @@ exports.itemWidth = itemWidth;
4518
4603
  exports.kindLabel = kindLabel;
4519
4604
  exports.kpiDelta = kpiDelta;
4520
4605
  exports.labelStride = labelStride;
4606
+ exports.loadViewKey = loadViewKey;
4607
+ exports.loadViewKind = loadViewKind;
4521
4608
  exports.loadingWidgets = loadingWidgets;
4522
4609
  exports.memoryAdapter = memoryAdapter;
4523
4610
  exports.minimizeWidget = minimizeWidget;
@@ -4589,6 +4676,7 @@ exports.validateWidgetDefinition = validateWidgetDefinition;
4589
4676
  exports.viewChoices = viewChoices;
4590
4677
  exports.viewKind = viewKind;
4591
4678
  exports.viewNote = viewNote;
4679
+ exports.viewValuesFromLayout = viewValuesFromLayout;
4592
4680
  exports.visibleWidgets = visibleWidgets;
4593
4681
  exports.widgetOptionValues = widgetOptionValues;
4594
4682
  exports.widgetsFor = widgetsFor;