@sanity/workflow-studio-plugin 0.27.0 → 0.28.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.
@@ -436,13 +436,45 @@ function deployedPhrase(definition) {
436
436
  return ago === "" ? index.formatShortDateTime(deployedAt) : `${index.formatShortDateTime(deployedAt)} (${ago})`;
437
437
  }
438
438
 
439
- const TOOL_PANEL_PADDING = 3, TOOL_HEADING_PADDING = 2;
439
+ const TOOL_PANEL_PADDING = 3, TOOL_HEADING_PADDING = 2, logged = /* @__PURE__ */ new WeakSet;
440
440
 
441
- function catalogReadError(error) {
442
- return `Could not load the deployed workflows: ${error}`;
441
+ function logReadFailure(what, error) {
442
+ if (typeof error == "object" && error !== null) {
443
+ if (logged.has(error)) return;
444
+ logged.add(error);
445
+ }
446
+ console.error(`[workflow-studio-plugin] could not load ${what}:`, error);
447
+ }
448
+
449
+ function useReadFailureLog(what, error) {
450
+ react.useEffect(() => {
451
+ error !== void 0 && logReadFailure(what, error);
452
+ }, [ what, error ]);
443
453
  }
444
454
 
445
- const lastRead = /* @__PURE__ */ new WeakMap, issuedReads = /* @__PURE__ */ new WeakMap;
455
+ const INSTANCE_CAP = 200, INSTANCES_READ_FAILED = "Couldn’t load workflow data. Try again later.";
456
+
457
+ function useCappedInstances(filter) {
458
+ const {engine: engine} = index.useWorkflowContext(), capped = react.useMemo(() => ({
459
+ ...filter,
460
+ limit: INSTANCE_CAP
461
+ }), [ filter ]), {instances: instances, loading: loading, unreadable: unreadable, error: error} = workflowStudio.useWorkflowInstances({
462
+ engine: engine,
463
+ filter: capped
464
+ });
465
+ return useReadFailureLog("workflow data", error), react.useMemo(() => {
466
+ const rows = instances ?? [];
467
+ return {
468
+ rows: rows,
469
+ truncated: rows.length + unreadable.length === INSTANCE_CAP,
470
+ loading: loading,
471
+ unreadable: unreadable,
472
+ error: error === void 0 ? void 0 : workflowEngine.errorMessage(error)
473
+ };
474
+ }, [ instances, loading, unreadable, error ]);
475
+ }
476
+
477
+ const CATALOG_READ_FAILED = "Couldn’t load the deployed workflows. Try again later.", lastRead = /* @__PURE__ */ new WeakMap, issuedReads = /* @__PURE__ */ new WeakMap;
446
478
 
447
479
  function useDeployedDefinitions() {
448
480
  const {engine: engine} = index.useWorkflowContext(), [definitions, setDefinitions] = react.useState(() => lastRead.get(engine)?.rows), [error, setError] = react.useState(void 0);
@@ -457,7 +489,7 @@ function useDeployedDefinitions() {
457
489
  rows: latest
458
490
  }), cancelled || (setDefinitions(latest), setError(void 0));
459
491
  })().catch(err => {
460
- cancelled || setError(index.describeError(err));
492
+ logReadFailure("the deployed workflows", err), cancelled || setError(index.describeError(err));
461
493
  }), () => {
462
494
  cancelled = !0;
463
495
  };
@@ -467,46 +499,30 @@ function useDeployedDefinitions() {
467
499
  };
468
500
  }
469
501
 
470
- const INSTANCE_CAP = 200;
471
-
472
- function useCappedInstances(filter) {
473
- const {engine: engine} = index.useWorkflowContext(), capped = react.useMemo(() => ({
474
- ...filter,
475
- limit: INSTANCE_CAP
476
- }), [ filter ]), {instances: instances, loading: loading, unreadable: unreadable} = workflowStudio.useWorkflowInstances({
477
- engine: engine,
478
- filter: capped
479
- });
480
- return react.useMemo(() => {
481
- const rows = instances ?? [];
482
- return {
483
- rows: rows,
484
- truncated: rows.length + unreadable.length === INSTANCE_CAP,
485
- loading: loading,
486
- unreadable: unreadable
487
- };
488
- }, [ instances, loading, unreadable ]);
489
- }
490
-
491
502
  const INSTANCE_CAP_COUNT_NOTE = `Counts from the latest ${INSTANCE_CAP} workflows — older ones aren’t counted.`, NEWEST_INSTANCES = {
492
503
  includeCompleted: !0
493
504
  };
494
505
 
495
506
  function useToolInstances() {
496
- const {rows: rows, truncated: truncated, loading: loading, unreadable: unreadable} = useCappedInstances(NEWEST_INSTANCES);
507
+ const {rows: rows, truncated: truncated, loading: loading, unreadable: unreadable, error: error} = useCappedInstances(NEWEST_INSTANCES);
497
508
  return react.useMemo(() => ({
498
509
  inFlight: rows.filter(instance => workflowEngine.terminalState(instance) === "in-flight"),
499
510
  settled: rows.filter(instance => workflowEngine.terminalState(instance) !== "in-flight"),
500
511
  truncated: truncated,
501
512
  loading: loading,
502
- unreadable: unreadable
503
- }), [ rows, truncated, loading, unreadable ]);
513
+ unreadable: unreadable,
514
+ error: error
515
+ }), [ rows, truncated, loading, unreadable, error ]);
504
516
  }
505
517
 
506
518
  function activeSummary(active) {
507
519
  return active === 0 ? "No active instances" : pluralize__default.default("active instance", active, !0);
508
520
  }
509
521
 
522
+ function activeHeadline(args) {
523
+ if (args.error === void 0) return args.loading ? "counting active instances…" : activeSummary(args.active);
524
+ }
525
+
510
526
  const CARD_MIN_WIDTH = 280, CARD_RADIUS$1 = 3, CARD_PADDING = 4, CARD_MIN_HEIGHT = 180;
511
527
 
512
528
  function OverviewTab({onOpenWorkflow: onOpenWorkflow}) {
@@ -516,13 +532,9 @@ function OverviewTab({onOpenWorkflow: onOpenWorkflow}) {
516
532
  titleOf: name => schema.get(name)?.title
517
533
  })
518
534
  });
519
- if (error !== void 0) /* @__PURE__ */
520
- return jsxRuntime.jsx(TabStatusRow, {
521
- children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
522
- muted: !0,
523
- size: 1,
524
- children: catalogReadError(error)
525
- })
535
+ if (error !== void 0) /* @__PURE__ */ return jsxRuntime.jsx(index.NoteBanner, {
536
+ label: CATALOG_READ_FAILED,
537
+ tone: "critical"
526
538
  });
527
539
  if (definitions === void 0) /* @__PURE__ */
528
540
  return jsxRuntime.jsx(TabStatusRow, {
@@ -549,13 +561,20 @@ function OverviewTab({onOpenWorkflow: onOpenWorkflow}) {
549
561
  mappings: mappings,
550
562
  inFlight: instances.inFlight,
551
563
  issues: mappingIssues
552
- }), active = rows.reduce((sum, row) => sum + row.activeCount, 0);
564
+ }), active = rows.reduce((sum, row) => sum + row.activeCount, 0), activity = activeHeadline({
565
+ active: active,
566
+ error: instances.error,
567
+ loading: instances.loading
568
+ });
553
569
  /* @__PURE__ */
554
570
  return jsxRuntime.jsxs(ui.Stack, {
555
571
  gap: 3,
556
572
  paddingBottom: 4,
557
573
  paddingTop: 3,
558
- children: [ undeployed,
574
+ children: [ undeployed, instances.error === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
575
+ label: INSTANCES_READ_FAILED,
576
+ tone: "critical"
577
+ }),
559
578
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, {
560
579
  align: "center",
561
580
  gap: 2,
@@ -565,11 +584,10 @@ function OverviewTab({onOpenWorkflow: onOpenWorkflow}) {
565
584
  size: 1,
566
585
  weight: "semibold",
567
586
  children: pluralize__default.default("workflow", rows.length, !0)
568
- }),
569
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
587
+ }), activity === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
570
588
  muted: !0,
571
589
  size: 1,
572
- children: instances.loading ? "counting active instances…" : activeSummary(active)
590
+ children: activity
573
591
  }) ]
574
592
  }),
575
593
  /* @__PURE__ */ jsxRuntime.jsx(ui.Grid, {
@@ -579,7 +597,7 @@ function OverviewTab({onOpenWorkflow: onOpenWorkflow}) {
579
597
  gridTemplateColumns: `repeat(auto-fill, minmax(${CARD_MIN_WIDTH}px, 1fr))`
580
598
  },
581
599
  children: rows.map(row => /* @__PURE__ */ jsxRuntime.jsx(WorkflowCard, {
582
- countPending: instances.loading,
600
+ countKnown: instances.error === void 0 && !instances.loading,
583
601
  onOpen: () => onOpenWorkflow(row.name),
584
602
  row: row
585
603
  }, row.name))
@@ -596,13 +614,13 @@ function UndeployedWorkflows({notices: notices}) {
596
614
  /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
597
615
  gap: 2,
598
616
  paddingBottom: 1,
599
- children: notices.map(notice => /* @__PURE__ */ jsxRuntime.jsx(index.CautionNote, {
617
+ children: notices.map(notice => /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
600
618
  label: notice
601
619
  }, notice))
602
620
  });
603
621
  }
604
622
 
605
- function WorkflowCard({countPending: countPending, onOpen: onOpen, row: row}) {
623
+ function WorkflowCard({countKnown: countKnown, onOpen: onOpen, row: row}) {
606
624
  const flagged = row.brokenBindings.length > 0, card = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, {
607
625
  as: "button",
608
626
  onClick: onOpen,
@@ -637,11 +655,11 @@ function WorkflowCard({countPending: countPending, onOpen: onOpen, row: row}) {
637
655
  size: 1,
638
656
  weight: "semibold",
639
657
  children: row.title
640
- }), countPending ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
658
+ }), countKnown ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
641
659
  muted: !0,
642
660
  size: 1,
643
661
  children: activeSummary(row.activeCount)
644
- }) ]
662
+ }) : null ]
645
663
  }) ]
646
664
  })
647
665
  });
@@ -695,7 +713,7 @@ function DefinitionPickerPanel({onPick: onPick}) {
695
713
  const {definitions: definitions, error: error} = useStartableDefinitions(), [query, setQuery] = react.useState(""), visible = react.useMemo(() => {
696
714
  const q = query.trim().toLowerCase();
697
715
  return definitions ? q ? definitions.filter(d => `${d.title} ${d.name}`.toLowerCase().includes(q)) : definitions : [];
698
- }, [ definitions, query ]);
716
+ }, [ definitions, query ]), settled = error === void 0 ? definitions : void 0;
699
717
  /* @__PURE__ */
700
718
  return jsxRuntime.jsx(ui.Box, {
701
719
  padding: 2,
@@ -712,13 +730,14 @@ function DefinitionPickerPanel({onPick: onPick}) {
712
730
  onChange: event => setQuery(event.currentTarget.value),
713
731
  placeholder: "Filter workflows…",
714
732
  value: query
715
- }), error ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
716
- text: catalogReadError(error)
733
+ }), error ? /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
734
+ label: CATALOG_READ_FAILED,
735
+ tone: "critical"
717
736
  }) : null, !definitions && !error ? /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
718
737
  label: "Loading workflows…"
719
- }) : null, definitions && definitions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
738
+ }) : null, settled?.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
720
739
  text: "No startable workflows are deployed"
721
- }) : null, definitions && definitions.length > 0 && visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
740
+ }) : null, settled !== void 0 && settled.length > 0 && visible.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
722
741
  text: "No workflows match"
723
742
  }) : null,
724
743
  /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, {
@@ -1049,6 +1068,10 @@ function taskRowsOf(args) {
1049
1068
  state: fields,
1050
1069
  who: identity
1051
1070
  }),
1071
+ roleMatched: identity !== void 0 && index.isRoleAssignedTo({
1072
+ state: fields,
1073
+ who: identity
1074
+ }),
1052
1075
  assignControl: index.rowAssignControlState(controlArgs),
1053
1076
  dateControl: index.rowDateControlState(controlArgs)
1054
1077
  };
@@ -1131,6 +1154,11 @@ function onlyMyTasks(groups) {
1131
1154
  });
1132
1155
  }
1133
1156
 
1157
+ function hasRoleMatchedTasks(groups) {
1158
+ const bandHasOne = band => band.rows.some(row => row.roleMatched);
1159
+ return groups.withDocuments.some(group => group.instances.some(bandHasOne)) || groups.withoutDocuments.some(bandHasOne);
1160
+ }
1161
+
1134
1162
  function rowActivityEval(entry, row) {
1135
1163
  const evaluation = entry?.evaluation;
1136
1164
  if (!(evaluation === void 0 || evaluation.currentStage.stage.name !== row.stage)) return evaluation.currentStage.activities.find(a => a.activity.name === row.activityName);
@@ -1274,7 +1302,7 @@ function OrphanedWorkflowsNote({orphans: orphans}) {
1274
1302
  /* @__PURE__ */
1275
1303
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1276
1304
  children: [
1277
- /* @__PURE__ */ jsxRuntime.jsx(index.CautionNote, {
1305
+ /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
1278
1306
  action: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, {
1279
1307
  fontSize: 1,
1280
1308
  mode: "ghost",
@@ -2610,7 +2638,7 @@ function useOrphanedWorkflows(groups) {
2610
2638
  }), [ groups, contentResource, missing ]);
2611
2639
  }
2612
2640
 
2613
- function TasksTab({filterSlot: filterSlot, instances: instances, loading: loading, identity: identity, onOpenInstance: onOpenInstance, onOpenTask: onOpenTask, tab: tab, truncated: truncated, unreadable: unreadable}) {
2641
+ function TasksTab({error: error, filterSlot: filterSlot, instances: instances, loading: loading, identity: identity, onOpenInstance: onOpenInstance, onOpenTask: onOpenTask, tab: tab, truncated: truncated, unreadable: unreadable}) {
2614
2642
  const mineOnly = tab === "for-me", {binding: binding} = index.useWorkflowContext(), bands = useBandOpenState({
2615
2643
  segment: TASK_BAND_SEGMENTS[tab],
2616
2644
  scope: binding.engineResource.id
@@ -2628,6 +2656,10 @@ function TasksTab({filterSlot: filterSlot, instances: instances, loading: loadin
2628
2656
  }), cut = mineOnly ? onlyMyTasks(filtered) : filtered;
2629
2657
  return orderGroupsByPreviewTitle(cut, titles.titles);
2630
2658
  }, [ listed, filters, mineOnly, titles ]);
2659
+ if (error !== void 0) /* @__PURE__ */ return jsxRuntime.jsx(index.NoteBanner, {
2660
+ label: INSTANCES_READ_FAILED,
2661
+ tone: "critical"
2662
+ });
2631
2663
  if (loading || !revealed) /* @__PURE__ */
2632
2664
  return jsxRuntime.jsx(TabStatusRow, {
2633
2665
  children: /* @__PURE__ */ jsxRuntime.jsx(index.LoadingRow, {
@@ -2667,7 +2699,7 @@ function TasksTab({filterSlot: filterSlot, instances: instances, loading: loadin
2667
2699
  }),
2668
2700
  /* @__PURE__ */ jsxRuntime.jsx(OrphanedWorkflowsNote, {
2669
2701
  orphans: orphans
2670
- }), body, truncated ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
2702
+ }), mineOnly && hasRoleMatchedTasks(visible) ? /* @__PURE__ */ jsxRuntime.jsx(index.RoleAssignedNotice, {}) : null, body, truncated ? /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
2671
2703
  text: `Tasks from the latest ${INSTANCE_CAP} workflows — older ones aren’t listed.`
2672
2704
  }) : null ]
2673
2705
  }) ]
@@ -3045,6 +3077,16 @@ function useBoardInstances(definitionName) {
3045
3077
  return useCappedInstances(filter);
3046
3078
  }
3047
3079
 
3080
+ function activeCountFace(args) {
3081
+ return args.error !== void 0 || args.loading ? {
3082
+ count: void 0,
3083
+ note: void 0
3084
+ } : {
3085
+ count: args.count,
3086
+ note: args.truncated ? INSTANCE_CAP_COUNT_NOTE : void 0
3087
+ };
3088
+ }
3089
+
3048
3090
  function DefinitionPanel({definition: definition}) {
3049
3091
  /* @__PURE__ */
3050
3092
  return jsxRuntime.jsx(ui.Box, {
@@ -3107,6 +3149,23 @@ function SetupIssues({bindings: bindings}) {
3107
3149
  });
3108
3150
  }
3109
3151
 
3152
+ function ActiveCount({face: face}) {
3153
+ /* @__PURE__ */
3154
+ return jsxRuntime.jsxs(ui.Stack, {
3155
+ gap: 2,
3156
+ children: [
3157
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3158
+ muted: face.count === void 0,
3159
+ size: 1,
3160
+ children: face.count ?? "—"
3161
+ }), face.note === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3162
+ muted: !0,
3163
+ size: 1,
3164
+ children: face.note
3165
+ }) ]
3166
+ });
3167
+ }
3168
+
3110
3169
  function DefinitionFacts({definition: definition}) {
3111
3170
  const {mappingIssues: mappingIssues, mappings: mappings} = index.useWorkflowContext(), schema = sanity.useSchema(), instances = useToolInstances(), snapshotWidth = index.useContainerToken(2), [row] = definitionCatalog({
3112
3171
  definitions: [ definition ],
@@ -3124,6 +3183,12 @@ function DefinitionFacts({definition: definition}) {
3124
3183
  children: /* @__PURE__ */ jsxRuntime.jsx(SetupIssues, {
3125
3184
  bindings: row.brokenBindings
3126
3185
  })
3186
+ }), instances.error === void 0 ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
3187
+ flex: "none",
3188
+ children: /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
3189
+ label: INSTANCES_READ_FAILED,
3190
+ tone: "critical"
3191
+ })
3127
3192
  }),
3128
3193
  /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
3129
3194
  flex: "none",
@@ -3142,21 +3207,13 @@ function DefinitionFacts({definition: definition}) {
3142
3207
  }),
3143
3208
  /* @__PURE__ */ jsxRuntime.jsx(index.MetaRow, {
3144
3209
  label: "Active instances",
3145
- children: instances.loading ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3146
- muted: !0,
3147
- size: 1,
3148
- children: "—"
3149
- }) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, {
3150
- gap: 2,
3151
- children: [
3152
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3153
- size: 1,
3154
- children: row?.activeCount ?? 0
3155
- }), instances.truncated ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, {
3156
- muted: !0,
3157
- size: 1,
3158
- children: INSTANCE_CAP_COUNT_NOTE
3159
- }) : null ]
3210
+ children: /* @__PURE__ */ jsxRuntime.jsx(ActiveCount, {
3211
+ face: activeCountFace({
3212
+ count: row?.activeCount ?? 0,
3213
+ error: instances.error,
3214
+ loading: instances.loading,
3215
+ truncated: instances.truncated
3216
+ })
3160
3217
  })
3161
3218
  }),
3162
3219
  /* @__PURE__ */ jsxRuntime.jsx(index.MetaRow, {
@@ -3693,11 +3750,11 @@ function usePageSelection(page) {
3693
3750
  }
3694
3751
 
3695
3752
  function WorkflowPage({onOpenWorkflow: onOpenWorkflow, onSelectPage: onSelectPage, page: page, workflowName: workflowName}) {
3696
- const {definitions: definitions, error: error} = useDeployedDefinitions(), selection = resolveWorkflowSelection({
3753
+ const {definitions: definitions, error: catalogError} = useDeployedDefinitions(), selection = resolveWorkflowSelection({
3697
3754
  definitions: definitions,
3698
3755
  routeName: workflowName
3699
3756
  }), selected = resolvedDefinition(selection), view = workflowPageView({
3700
- error: error,
3757
+ error: catalogError,
3701
3758
  page: page,
3702
3759
  selection: selection
3703
3760
  }), instances = useBoardInstances(view.streamName), {board: board, ready: ready, titles: titles} = useBoard({
@@ -3709,9 +3766,9 @@ function WorkflowPage({onOpenWorkflow: onOpenWorkflow, onSelectPage: onSelectPag
3709
3766
  })), revealed = useRevealGate({
3710
3767
  loading: instances.loading,
3711
3768
  ready: ready
3712
- }), waiting = index.useDelayedFlag(selection.kind === "loading" && error === void 0, WAIT_CUE_DELAY_MS);
3769
+ }), waiting = index.useDelayedFlag(selection.kind === "loading" && catalogError === void 0, WAIT_CUE_DELAY_MS);
3713
3770
  if (selection.kind === "loading") /* @__PURE__ */ return jsxRuntime.jsx(UnresolvedPage, {
3714
- error: error,
3771
+ error: catalogError,
3715
3772
  waiting: waiting
3716
3773
  });
3717
3774
  const wiring = {
@@ -3770,7 +3827,8 @@ function WorkflowPage({onOpenWorkflow: onOpenWorkflow, onSelectPage: onSelectPag
3770
3827
  /* @__PURE__ */ jsxRuntime.jsx(PageBody, {
3771
3828
  board: board,
3772
3829
  catalogEmpty: (definitions ?? []).length === 0,
3773
- error: error,
3830
+ catalogError: catalogError,
3831
+ instancesError: instances.error,
3774
3832
  loading: !revealed,
3775
3833
  page: page,
3776
3834
  selection: selection,
@@ -3808,8 +3866,8 @@ function UnresolvedPage({error: error, waiting: waiting}) {
3808
3866
  overflow: "hidden",
3809
3867
  children: error === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(WaitingFace, {
3810
3868
  waiting: waiting
3811
- }) : /* @__PURE__ */ jsxRuntime.jsx(CatalogErrorFace, {
3812
- error: error
3869
+ }) : /* @__PURE__ */ jsxRuntime.jsx(ReadErrorFace, {
3870
+ text: CATALOG_READ_FAILED
3813
3871
  })
3814
3872
  });
3815
3873
  }
@@ -3825,18 +3883,24 @@ function WaitingFace({waiting: waiting}) {
3825
3883
  });
3826
3884
  }
3827
3885
 
3828
- function CatalogErrorFace({error: error}) {
3886
+ const BANNER_LANE_INSET = 2;
3887
+
3888
+ function ReadErrorFace({text: text}) {
3829
3889
  /* @__PURE__ */
3830
3890
  return jsxRuntime.jsx(StatusBox, {
3831
- children: /* @__PURE__ */ jsxRuntime.jsx(MutedNote, {
3832
- text: catalogReadError(error)
3891
+ children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
3892
+ paddingTop: BANNER_LANE_INSET,
3893
+ children: /* @__PURE__ */ jsxRuntime.jsx(index.NoteBanner, {
3894
+ label: text,
3895
+ tone: "critical"
3896
+ })
3833
3897
  })
3834
3898
  });
3835
3899
  }
3836
3900
 
3837
- function PageBody({board: board, catalogEmpty: catalogEmpty, error: error, loading: loading, page: page, selection: selection, wiring: wiring}) {
3838
- if (error !== void 0) /* @__PURE__ */ return jsxRuntime.jsx(CatalogErrorFace, {
3839
- error: error
3901
+ function PageBody({board: board, catalogEmpty: catalogEmpty, catalogError: catalogError, instancesError: instancesError, loading: loading, page: page, selection: selection, wiring: wiring}) {
3902
+ if (catalogError !== void 0) /* @__PURE__ */ return jsxRuntime.jsx(ReadErrorFace, {
3903
+ text: CATALOG_READ_FAILED
3840
3904
  });
3841
3905
  if (selection.kind === "unknown") {
3842
3906
  const face = unknownWorkflowFace({
@@ -3854,6 +3918,8 @@ function PageBody({board: board, catalogEmpty: catalogEmpty, error: error, loadi
3854
3918
  }
3855
3919
  return page === "definition" ? /* @__PURE__ */ jsxRuntime.jsx(DefinitionPanel, {
3856
3920
  definition: selection.definition
3921
+ }) : instancesError !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(ReadErrorFace, {
3922
+ text: INSTANCES_READ_FAILED
3857
3923
  }) : loading || board === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(StatusBox, {
3858
3924
  children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, {
3859
3925
  paddingTop: LANE_PADDING,
@@ -4020,6 +4086,7 @@ function HomePanel({filterSlot: filterSlot, identity: identity, instances: insta
4020
4086
  return tab === "overview" ? /* @__PURE__ */ jsxRuntime.jsx(OverviewTab, {
4021
4087
  onOpenWorkflow: onOpenWorkflow
4022
4088
  }) : /* @__PURE__ */ jsxRuntime.jsx(TasksTab, {
4089
+ error: instances.error,
4023
4090
  filterSlot: filterSlot,
4024
4091
  identity: identity,
4025
4092
  instances: [ ...instances.inFlight, ...instances.settled ],