@morscherlab/mint-sdk 1.4.0-beta.12 → 1.4.0-beta.13

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.
Files changed (43) hide show
  1. package/dist/{AppSidebar-DGK5i-hJ.js → AppSidebar-CIXJBzDv.js} +234 -67
  2. package/dist/{AppSidebar-DGK5i-hJ.js.map → AppSidebar-CIXJBzDv.js.map} +1 -1
  3. package/dist/{ExperimentSelectorModal-BoofZZxF.js → ExperimentSelectorModal-BbFtr1Fr.js} +109 -93
  4. package/dist/ExperimentSelectorModal-BbFtr1Fr.js.map +1 -0
  5. package/dist/{SettingsModal-BXsjIVnm.js → SettingsModal-CdhFMi8j.js} +2 -2
  6. package/dist/{SettingsModal-BXsjIVnm.js.map → SettingsModal-CdhFMi8j.js.map} +1 -1
  7. package/dist/__stories__/experiment-helpers.d.ts +10 -0
  8. package/dist/components/AppTopBar.vue.d.ts +13 -5
  9. package/dist/components/ExperimentSelectorModal.vue.d.ts +15 -1
  10. package/dist/components/internal/AppTopBarPageSelectorInternal.vue.d.ts +2 -1
  11. package/dist/{data-ihsBd9bs.js → data-DUt0TIp5.js} +2 -2
  12. package/dist/{data-ihsBd9bs.js.map → data-DUt0TIp5.js.map} +1 -1
  13. package/dist/data.js +2 -2
  14. package/dist/index.js +7 -7
  15. package/dist/{install-CFgfRO64.js → install-Czoe1rA8.js} +6 -6
  16. package/dist/{install-CFgfRO64.js.map → install-Czoe1rA8.js.map} +1 -1
  17. package/dist/install.js +1 -1
  18. package/dist/{runtime-pKfF_iql.js → runtime-fPb_FEZr.js} +2 -2
  19. package/dist/{runtime-pKfF_iql.js.map → runtime-fPb_FEZr.js.map} +1 -1
  20. package/dist/runtime.js +2 -2
  21. package/dist/{shell-BIH8Rc21.js → shell-lDf_EY-x.js} +2 -2
  22. package/dist/{shell-BIH8Rc21.js.map → shell-lDf_EY-x.js.map} +1 -1
  23. package/dist/shell.js +2 -2
  24. package/dist/styles.css +288 -45
  25. package/dist/types/index.d.ts +1 -1
  26. package/dist/types/jobs.d.ts +9 -0
  27. package/package.json +1 -1
  28. package/src/__stories__/experiment-helpers.ts +3 -3
  29. package/src/__tests__/components/AppTopBar.test.ts +175 -1
  30. package/src/__tests__/components/AppTopBarPageSelector.test.ts +125 -9
  31. package/src/__tests__/components/ExperimentSelectorModal.test.ts +34 -1
  32. package/src/__tests__/styles/menusShellRefresh.test.ts +8 -2
  33. package/src/components/AppTopBar.story.vue +59 -4
  34. package/src/components/AppTopBar.vue +107 -8
  35. package/src/components/ExperimentSelectorModal.story.vue +38 -0
  36. package/src/components/ExperimentSelectorModal.vue +20 -1
  37. package/src/components/internal/AppTopBarPageSelectorInternal.vue +140 -72
  38. package/src/styles/components/app-page-selector.css +120 -45
  39. package/src/styles/components/app-top-bar.css +155 -0
  40. package/src/styles/components/experiment-selector-modal.css +13 -0
  41. package/src/types/index.ts +1 -0
  42. package/src/types/jobs.ts +10 -0
  43. package/dist/ExperimentSelectorModal-BoofZZxF.js.map +0 -1
@@ -1,9 +1,9 @@
1
1
  import { a as BaseButton_default, i as useEventListener, t as useDropdownState } from "./useDropdownState-8yWMu-7_.js";
2
2
  import { n as integrationHost, u as useSettingsStore } from "./experiment-DyO54FQB.js";
3
- import { I as FormField_default, _ as APP_EXPERIMENT_KEY, t as isRecord, z as BaseCheckbox_default } from "./records-DnK_1Q_S.js";
3
+ import { E as useMenuKeyboard, I as FormField_default, _ as APP_EXPERIMENT_KEY, t as isRecord, z as BaseCheckbox_default } from "./records-DnK_1Q_S.js";
4
4
  import { F as applySpecDefaults, _ as getFieldRegistryEntry, a as StepWizard_default, d as humanize, f as numericValue, l as normalizeControls, m as orderedUnique, o as usePlatform, s as defaultValueForControl, u as normalizeOption, v as getTypeDefault } from "./useListReorder-DPynGrCj.js";
5
- import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineAsyncComponent, defineComponent, guardReactiveProps, inject, mergeProps, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, openBlock, reactive, readonly, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, shallowRef, toDisplayString, toRaw, toValue, unref, useSlots, useTemplateRef, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
6
- import { Moon, Sun } from "lucide-vue-next";
5
+ import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineAsyncComponent, defineComponent, guardReactiveProps, inject, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, openBlock, reactive, readonly, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, shallowRef, toDisplayString, toRaw, toValue, unref, useSlots, useTemplateRef, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
6
+ import { CircleAlert, CircleCheck, CircleX, ListChecks, LoaderCircle, Moon, Sun } from "lucide-vue-next";
7
7
  //#region src/composables/useTheme.ts
8
8
  /** Reads and toggles the active theme (light/dark/system) with reactivity to OS preference changes. */
9
9
  function useTheme() {
@@ -56,18 +56,18 @@ var _hoisted_4$7 = ["d"];
56
56
  var _hoisted_5$7 = ["d"];
57
57
  var _hoisted_6$6 = { class: "mint-collapsible-card__titles" };
58
58
  var _hoisted_7$5 = { class: "mint-collapsible-card__title" };
59
- var _hoisted_8$4 = {
59
+ var _hoisted_8$5 = {
60
60
  key: 0,
61
61
  class: "mint-collapsible-card__subtitle"
62
62
  };
63
- var _hoisted_9$4 = { class: "mint-collapsible-card__actions" };
64
- var _hoisted_10$3 = [
63
+ var _hoisted_9$5 = { class: "mint-collapsible-card__actions" };
64
+ var _hoisted_10$4 = [
65
65
  "disabled",
66
66
  "aria-label",
67
67
  "title",
68
68
  "onClick"
69
69
  ];
70
- var _hoisted_11$3 = {
70
+ var _hoisted_11$4 = {
71
71
  key: 0,
72
72
  class: "mint-collapsible-card__action-icon",
73
73
  viewBox: "0 0 24 24",
@@ -78,8 +78,8 @@ var _hoisted_11$3 = {
78
78
  "stroke-linejoin": "round",
79
79
  "aria-hidden": "true"
80
80
  };
81
- var _hoisted_12$3 = ["d"];
82
- var _hoisted_13$3 = ["d"];
81
+ var _hoisted_12$4 = ["d"];
82
+ var _hoisted_13$4 = ["d"];
83
83
  var _hoisted_14$2 = {
84
84
  key: 1,
85
85
  class: "mint-collapsible-card__action-text-icon"
@@ -192,7 +192,7 @@ var CollapsibleCard_default = /* @__PURE__ */ defineComponent({
192
192
  key: 1,
193
193
  class: "mint-collapsible-card__icon-text",
194
194
  style: normalizeStyle(iconColorStyle.value)
195
- }, toDisplayString(__props.icon), 5))], 4)) : createCommentVNode("", true), createElementVNode("div", _hoisted_6$6, [createElementVNode("h3", _hoisted_7$5, toDisplayString(__props.title), 1), __props.subtitle ? (openBlock(), createElementBlock("p", _hoisted_8$4, toDisplayString(__props.subtitle), 1)) : createCommentVNode("", true)])])], 10, _hoisted_2$8), createElementVNode("div", _hoisted_9$4, [
195
+ }, toDisplayString(__props.icon), 5))], 4)) : createCommentVNode("", true), createElementVNode("div", _hoisted_6$6, [createElementVNode("h3", _hoisted_7$5, toDisplayString(__props.title), 1), __props.subtitle ? (openBlock(), createElementBlock("p", _hoisted_8$5, toDisplayString(__props.subtitle), 1)) : createCommentVNode("", true)])])], 10, _hoisted_2$8), createElementVNode("div", _hoisted_9$5, [
196
196
  __props.badge !== void 0 ? (openBlock(), createElementBlock("span", {
197
197
  key: 0,
198
198
  class: normalizeClass(badgeClasses.value)
@@ -207,15 +207,15 @@ var CollapsibleCard_default = /* @__PURE__ */ defineComponent({
207
207
  "aria-label": action.label,
208
208
  title: action.label,
209
209
  onClick: ($event) => handleActionClick(action)
210
- }, [action.icon && isSvgIconValue(action.icon) ? (openBlock(), createElementBlock("svg", _hoisted_11$3, [Array.isArray(action.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(action.icon, (d, i) => {
210
+ }, [action.icon && isSvgIconValue(action.icon) ? (openBlock(), createElementBlock("svg", _hoisted_11$4, [Array.isArray(action.icon) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(action.icon, (d, i) => {
211
211
  return openBlock(), createElementBlock("path", {
212
212
  key: i,
213
213
  d
214
- }, null, 8, _hoisted_12$3);
214
+ }, null, 8, _hoisted_12$4);
215
215
  }), 128)) : (openBlock(), createElementBlock("path", {
216
216
  key: 1,
217
217
  d: action.icon
218
- }, null, 8, _hoisted_13$3))])) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_14$2, toDisplayString(action.icon), 1)) : createCommentVNode("", true)], 14, _hoisted_10$3);
218
+ }, null, 8, _hoisted_13$4))])) : action.icon ? (openBlock(), createElementBlock("span", _hoisted_14$2, toDisplayString(action.icon), 1)) : createCommentVNode("", true)], 14, _hoisted_10$4);
219
219
  }), 128)),
220
220
  __props.showToggle ? (openBlock(), createElementBlock("div", {
221
221
  key: 1,
@@ -1242,8 +1242,8 @@ var _hoisted_7$4 = {
1242
1242
  "stroke-linejoin": "round",
1243
1243
  "aria-hidden": "true"
1244
1244
  };
1245
- var _hoisted_8$3 = ["d"];
1246
- var _hoisted_9$3 = ["src"];
1245
+ var _hoisted_8$4 = ["d"];
1246
+ var _hoisted_9$4 = ["src"];
1247
1247
  //#endregion
1248
1248
  //#region src/components/PluginIcon.vue
1249
1249
  var PluginIcon_default = /* @__PURE__ */ defineComponent({
@@ -1354,39 +1354,54 @@ var PluginIcon_default = /* @__PURE__ */ defineComponent({
1354
1354
  "stroke-linejoin": "round"
1355
1355
  }, null, 8, _hoisted_6$4);
1356
1356
  }), 128))
1357
- ], 8, _hoisted_1$7)) : detected.value.format === "path" || detected.value.format === "fallback" ? (openBlock(), createElementBlock("svg", _hoisted_7$4, [createElementVNode("path", { d: iconValue.value }, null, 8, _hoisted_8$3)])) : (openBlock(), createElementBlock("img", {
1357
+ ], 8, _hoisted_1$7)) : detected.value.format === "path" || detected.value.format === "fallback" ? (openBlock(), createElementBlock("svg", _hoisted_7$4, [createElementVNode("path", { d: iconValue.value }, null, 8, _hoisted_8$4)])) : (openBlock(), createElementBlock("img", {
1358
1358
  key: 2,
1359
1359
  class: "mint-plugin-icon__img",
1360
1360
  src: iconValue.value,
1361
1361
  alt: "",
1362
1362
  referrerpolicy: "no-referrer",
1363
1363
  loading: "lazy"
1364
- }, null, 8, _hoisted_9$3))], 6);
1364
+ }, null, 8, _hoisted_9$4))], 6);
1365
1365
  };
1366
1366
  }
1367
1367
  });
1368
1368
  //#endregion
1369
1369
  //#region src/components/internal/AppTopBarPageSelectorInternal.vue?vue&type=script&setup=true&lang.ts
1370
- var _hoisted_1$6 = ["aria-expanded"];
1371
- var _hoisted_2$4 = {
1370
+ var _hoisted_1$6 = {
1371
+ ref: "root",
1372
+ class: "mint-page-selector__crumb"
1373
+ };
1374
+ var _hoisted_2$4 = { class: "mint-page-selector__plugin" };
1375
+ var _hoisted_3$4 = ["aria-expanded"];
1376
+ var _hoisted_4$4 = {
1372
1377
  key: 1,
1373
1378
  class: "mint-page-selector__icon-fallback"
1374
1379
  };
1375
- var _hoisted_3$4 = { class: "mint-page-selector__label" };
1376
- var _hoisted_4$4 = {
1380
+ var _hoisted_5$4 = { class: "mint-page-selector__label" };
1381
+ var _hoisted_6$3 = {
1377
1382
  class: "mint-page-selector__chevron-wrap",
1378
1383
  "aria-hidden": "true"
1379
1384
  };
1380
- var _hoisted_5$4 = {
1381
- key: 0,
1382
- class: "mint-page-selector__menu",
1383
- role: "menu"
1385
+ var _hoisted_7$3 = ["aria-label"];
1386
+ var _hoisted_8$3 = {
1387
+ class: "mint-page-selector__menu-title",
1388
+ "aria-hidden": "true"
1384
1389
  };
1385
- var _hoisted_6$3 = {
1390
+ var _hoisted_9$3 = {
1386
1391
  key: 1,
1387
1392
  class: "mint-page-selector__icon-fallback"
1388
1393
  };
1389
- var _hoisted_7$3 = { class: "mint-page-selector__item-label" };
1394
+ var _hoisted_10$3 = { class: "mint-page-selector__item-text" };
1395
+ var _hoisted_11$3 = { class: "mint-page-selector__item-label" };
1396
+ var _hoisted_12$3 = {
1397
+ key: 0,
1398
+ class: "mint-page-selector__item-hint"
1399
+ };
1400
+ var _hoisted_13$3 = {
1401
+ key: 0,
1402
+ class: "mint-page-selector__item-key",
1403
+ "aria-hidden": "true"
1404
+ };
1390
1405
  //#endregion
1391
1406
  //#region src/components/internal/AppTopBarPageSelectorInternal.vue
1392
1407
  var AppTopBarPageSelectorInternal_default = /* @__PURE__ */ defineComponent({
@@ -1395,19 +1410,64 @@ var AppTopBarPageSelectorInternal_default = /* @__PURE__ */ defineComponent({
1395
1410
  pages: {},
1396
1411
  currentPageId: {},
1397
1412
  placeholder: { default: "Go to…" },
1398
- minWidth: { default: "11.25rem" }
1413
+ minWidth: {},
1414
+ pluginName: {}
1399
1415
  },
1400
1416
  emits: ["select"],
1401
1417
  setup(__props, { emit: __emit }) {
1402
- /** Dropdown trigger that switches between named pages, closing on outside click or Escape. */
1418
+ /** "Plugin / page" switcher: the plugin name, then a trigger that opens the page menu (hints, number keys 1-9). */
1403
1419
  const props = __props;
1404
1420
  const emit = __emit;
1405
- const { isOpen, close, toggle } = useDropdownState({
1421
+ const triggerEl = useTemplateRef("trigger");
1422
+ const menuEl = useTemplateRef("menu");
1423
+ const { isOpen, open, close, toggle } = useDropdownState({
1406
1424
  rootRef: useTemplateRef("root"),
1407
- triggerRef: useTemplateRef("trigger")
1425
+ triggerRef: triggerEl
1408
1426
  });
1409
1427
  const normalizedPages = computed(() => props.pages.map(normalizeItemInput));
1428
+ const menuTitle = computed(() => props.pluginName ? `${props.pluginName} pages` : "Pages");
1410
1429
  const current = computed(() => normalizedPages.value.find((p) => p.id === props.currentPageId) ?? normalizedPages.value[0]);
1430
+ const rows = () => Array.from(menuEl.value?.querySelectorAll("[role=\"menuitem\"]") ?? []);
1431
+ const isEnabled = (row) => !row.hasAttribute("disabled") && row.getAttribute("aria-disabled") !== "true";
1432
+ const enabledRows = () => rows().filter(isEnabled);
1433
+ const { handlePanelKeydown } = useMenuKeyboard({
1434
+ items: enabledRows,
1435
+ isOpen: () => isOpen.value,
1436
+ open,
1437
+ close
1438
+ });
1439
+ function handleTriggerKeydown(event) {
1440
+ if (isOpen.value || ![
1441
+ "ArrowDown",
1442
+ "Enter",
1443
+ " "
1444
+ ].includes(event.key)) return;
1445
+ event.preventDefault();
1446
+ open();
1447
+ nextTick(() => {
1448
+ const items = enabledRows();
1449
+ (items.find((row) => row.getAttribute("aria-current") === "page") ?? items[0])?.focus();
1450
+ });
1451
+ }
1452
+ function activate(row) {
1453
+ row.click();
1454
+ if (!isOpen.value) triggerEl.value?.focus();
1455
+ }
1456
+ function handleMenuKeydown(event) {
1457
+ if (/^[1-9]$/.test(event.key)) {
1458
+ event.preventDefault();
1459
+ const row = rows()[Number(event.key) - 1];
1460
+ if (row && isEnabled(row)) activate(row);
1461
+ return;
1462
+ }
1463
+ const focused = document.activeElement;
1464
+ if ((event.key === "Enter" || event.key === " ") && focused && enabledRows().includes(focused)) {
1465
+ event.preventDefault();
1466
+ activate(focused);
1467
+ return;
1468
+ }
1469
+ handlePanelKeydown(event);
1470
+ }
1411
1471
  function handleSelect(page) {
1412
1472
  if (page.disabled) return;
1413
1473
  if (page.href || page.to) {
@@ -1418,17 +1478,20 @@ var AppTopBarPageSelectorInternal_default = /* @__PURE__ */ defineComponent({
1418
1478
  close();
1419
1479
  }
1420
1480
  return (_ctx, _cache) => {
1421
- return openBlock(), createElementBlock("div", {
1422
- ref: "root",
1481
+ return openBlock(), createElementBlock("div", _hoisted_1$6, [__props.pluginName ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createElementVNode("span", _hoisted_2$4, toDisplayString(__props.pluginName), 1), _cache[1] || (_cache[1] = createElementVNode("span", {
1482
+ class: "mint-page-selector__slash",
1483
+ "aria-hidden": "true"
1484
+ }, "/", -1))], 64)) : createCommentVNode("", true), createElementVNode("div", {
1423
1485
  class: "mint-page-selector",
1424
- style: normalizeStyle({ minWidth: __props.minWidth })
1486
+ style: normalizeStyle(__props.minWidth ? { minWidth: __props.minWidth } : void 0)
1425
1487
  }, [createElementVNode("button", {
1426
1488
  ref: "trigger",
1427
1489
  type: "button",
1428
1490
  class: normalizeClass(["mint-page-selector__trigger", { "mint-page-selector__trigger--open": unref(isOpen) }]),
1429
1491
  "aria-expanded": unref(isOpen),
1430
1492
  "aria-haspopup": "menu",
1431
- onClick: _cache[0] || (_cache[0] = withModifiers((...args) => unref(toggle) && unref(toggle)(...args), ["stop"]))
1493
+ onClick: _cache[0] || (_cache[0] = withModifiers((...args) => unref(toggle) && unref(toggle)(...args), ["stop"])),
1494
+ onKeydown: handleTriggerKeydown
1432
1495
  }, [
1433
1496
  current.value ? (openBlock(), createElementBlock("span", {
1434
1497
  key: 0,
@@ -1439,9 +1502,9 @@ var AppTopBarPageSelectorInternal_default = /* @__PURE__ */ defineComponent({
1439
1502
  icon: current.value.icon,
1440
1503
  size: "sm",
1441
1504
  variant: "solid"
1442
- }, null, 8, ["icon"])) : (openBlock(), createElementBlock("span", _hoisted_2$4, toDisplayString(current.value.label.charAt(0)), 1))])], 2)) : createCommentVNode("", true),
1443
- createElementVNode("span", _hoisted_3$4, toDisplayString(current.value?.label ?? __props.placeholder), 1),
1444
- createElementVNode("span", _hoisted_4$4, [(openBlock(), createElementBlock("svg", {
1505
+ }, null, 8, ["icon"])) : (openBlock(), createElementBlock("span", _hoisted_4$4, toDisplayString(current.value.label.charAt(0)), 1))])], 2)) : createCommentVNode("", true),
1506
+ createElementVNode("span", _hoisted_5$4, toDisplayString(current.value?.label ?? __props.placeholder), 1),
1507
+ createElementVNode("span", _hoisted_6$3, [(openBlock(), createElementBlock("svg", {
1445
1508
  class: normalizeClass(["mint-page-selector__chevron", { "mint-page-selector__chevron--open": unref(isOpen) }]),
1446
1509
  viewBox: "0 0 24 24",
1447
1510
  fill: "none",
@@ -1449,8 +1512,15 @@ var AppTopBarPageSelectorInternal_default = /* @__PURE__ */ defineComponent({
1449
1512
  "stroke-width": "2",
1450
1513
  "stroke-linecap": "round",
1451
1514
  "stroke-linejoin": "round"
1452
- }, [..._cache[1] || (_cache[1] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))])
1453
- ], 10, _hoisted_1$6), unref(isOpen) ? (openBlock(), createElementBlock("div", _hoisted_5$4, [_cache[2] || (_cache[2] = createElementVNode("div", { class: "mint-page-selector__menu-title" }, "Go to", -1)), (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedPages.value, (page) => {
1515
+ }, [..._cache[2] || (_cache[2] = [createElementVNode("path", { d: "m6 9 6 6 6-6" }, null, -1)])], 2))])
1516
+ ], 42, _hoisted_3$4), unref(isOpen) ? (openBlock(), createElementBlock("div", {
1517
+ key: 0,
1518
+ ref: "menu",
1519
+ class: "mint-page-selector__menu",
1520
+ role: "menu",
1521
+ "aria-label": menuTitle.value,
1522
+ onKeydown: handleMenuKeydown
1523
+ }, [createElementVNode("div", _hoisted_8$3, toDisplayString(menuTitle.value), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(normalizedPages.value, (page, index) => {
1454
1524
  return openBlock(), createBlock(ActionItemInternal_default, {
1455
1525
  key: page.id,
1456
1526
  href: page.href,
@@ -1462,24 +1532,32 @@ var AppTopBarPageSelectorInternal_default = /* @__PURE__ */ defineComponent({
1462
1532
  { "mint-page-selector__item--disabled": page.disabled }
1463
1533
  ]),
1464
1534
  role: "menuitem",
1535
+ "aria-current": page.id === current.value?.id ? "page" : void 0,
1536
+ "aria-keyshortcuts": index < 9 ? String(index + 1) : void 0,
1465
1537
  onClick: ($event) => handleSelect(page)
1466
1538
  }, {
1467
- default: withCtx(() => [createElementVNode("span", { class: normalizeClass(["mint-page-selector__item-icon", { "mint-page-selector__item-icon--metadata": unref(isPluginIconFormat)(page.icon) }]) }, [renderSlot(_ctx.$slots, "item-icon", { page }, () => [unref(isPluginIconFormat)(page.icon) ? (openBlock(), createBlock(PluginIcon_default, {
1468
- key: 0,
1469
- class: "mint-page-selector__metadata-icon",
1470
- icon: page.icon,
1471
- size: "sm",
1472
- variant: "solid"
1473
- }, null, 8, ["icon"])) : (openBlock(), createElementBlock("span", _hoisted_6$3, toDisplayString(page.label.charAt(0)), 1))])], 2), createElementVNode("span", _hoisted_7$3, toDisplayString(page.label), 1)]),
1539
+ default: withCtx(() => [
1540
+ createElementVNode("span", { class: normalizeClass(["mint-page-selector__item-icon", { "mint-page-selector__item-icon--metadata": unref(isPluginIconFormat)(page.icon) }]) }, [renderSlot(_ctx.$slots, "item-icon", { page }, () => [unref(isPluginIconFormat)(page.icon) ? (openBlock(), createBlock(PluginIcon_default, {
1541
+ key: 0,
1542
+ class: "mint-page-selector__metadata-icon",
1543
+ icon: page.icon,
1544
+ size: "sm",
1545
+ variant: "solid"
1546
+ }, null, 8, ["icon"])) : (openBlock(), createElementBlock("span", _hoisted_9$3, toDisplayString(page.label.charAt(0)), 1))])], 2),
1547
+ createElementVNode("span", _hoisted_10$3, [createElementVNode("span", _hoisted_11$3, toDisplayString(page.label), 1), page.hint ? (openBlock(), createElementBlock("span", _hoisted_12$3, toDisplayString(page.hint), 1)) : createCommentVNode("", true)]),
1548
+ index < 9 ? (openBlock(), createElementBlock("span", _hoisted_13$3, toDisplayString(index + 1), 1)) : createCommentVNode("", true)
1549
+ ]),
1474
1550
  _: 2
1475
1551
  }, 1032, [
1476
1552
  "href",
1477
1553
  "to",
1478
1554
  "disabled",
1479
1555
  "class",
1556
+ "aria-current",
1557
+ "aria-keyshortcuts",
1480
1558
  "onClick"
1481
1559
  ]);
1482
- }), 128))])) : createCommentVNode("", true)], 4);
1560
+ }), 128))], 40, _hoisted_7$3)) : createCommentVNode("", true)], 4)], 512);
1483
1561
  };
1484
1562
  }
1485
1563
  });
@@ -1859,6 +1937,16 @@ var _hoisted_20$1 = {
1859
1937
  key: 0,
1860
1938
  class: "mint-topbar__standalone-badge"
1861
1939
  };
1940
+ var _hoisted_21$1 = {
1941
+ class: "mint-topbar__job-status",
1942
+ "aria-live": "polite"
1943
+ };
1944
+ var _hoisted_22$1 = ["title", "aria-label"];
1945
+ var _hoisted_23$1 = {
1946
+ key: 0,
1947
+ class: "mint-topbar__job-bar",
1948
+ "aria-hidden": "true"
1949
+ };
1862
1950
  //#endregion
1863
1951
  //#region src/components/AppTopBar.vue
1864
1952
  var AppTopBar_default = /* @__PURE__ */ defineComponent({
@@ -1869,14 +1957,16 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1869
1957
  spec: { default: () => ({}) },
1870
1958
  pill: {},
1871
1959
  pageSelector: {},
1872
- currentPageSelectorId: {}
1960
+ currentPageSelectorId: {},
1961
+ job: {}
1873
1962
  },
1874
1963
  emits: [
1875
1964
  "page-selector-select",
1876
1965
  "update:pill",
1877
1966
  "pill-select",
1878
1967
  "pill-option-select",
1879
- "settings-values-change"
1968
+ "settings-values-change",
1969
+ "job-click"
1880
1970
  ],
1881
1971
  setup(__props, { emit: __emit }) {
1882
1972
  /**
@@ -1895,9 +1985,9 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1895
1985
  }, props.spec));
1896
1986
  const settingsConfig = computed(() => toValue(config.value.settings) || void 0);
1897
1987
  const showSettings = computed(() => settingsConfig.value !== void 0);
1898
- const SettingsModal = defineAsyncComponent(() => import("./SettingsModal-BXsjIVnm.js").then((n) => n.n));
1988
+ const SettingsModal = defineAsyncComponent(() => import("./SettingsModal-CdhFMi8j.js").then((n) => n.n));
1899
1989
  const ExperimentPopover = defineAsyncComponent(() => import("./ExperimentPopover-CbD7BR_s.js").then((n) => n.n));
1900
- const ExperimentSelectorModal = defineAsyncComponent(() => import("./ExperimentSelectorModal-BoofZZxF.js").then((n) => n.n));
1990
+ const ExperimentSelectorModal = defineAsyncComponent(() => import("./ExperimentSelectorModal-BbFtr1Fr.js").then((n) => n.n));
1901
1991
  const emit = __emit;
1902
1992
  const settingsOpen = ref(false);
1903
1993
  const headerEl = ref(null);
@@ -1910,6 +2000,37 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1910
2000
  const isStandalone = computed(() => !isIntegrated.value);
1911
2001
  const appExperiment = inject(APP_EXPERIMENT_KEY, null);
1912
2002
  const canBindExperiment = computed(() => plugin.value?.plugin_type !== "static");
2003
+ const showExperiment = computed(() => !!appExperiment && !isStandalone.value && canBindExperiment.value);
2004
+ const runSlotJoined = ref(!!props.job);
2005
+ const JOB_STATUS_TEXT = {
2006
+ queued: "Job queued",
2007
+ running: "Job running",
2008
+ awaiting_input: "Job needs input",
2009
+ completed: "Job completed",
2010
+ failed: "Job failed",
2011
+ cancelled: "Job cancelled"
2012
+ };
2013
+ const jobPercent = computed(() => props.job?.percent == null ? null : Math.min(100, Math.max(0, Math.round(props.job.percent))));
2014
+ const jobName = computed(() => props.job ? jobPercent.value != null ? `${props.job.label} ${jobPercent.value}%` : props.job.label : void 0);
2015
+ function syncRunSlotJoined() {
2016
+ runSlotJoined.value = !!props.job;
2017
+ }
2018
+ const JOB_TONES = {
2019
+ queued: "primary",
2020
+ running: "primary",
2021
+ awaiting_input: "warning",
2022
+ completed: "success",
2023
+ failed: "error",
2024
+ cancelled: "neutral"
2025
+ };
2026
+ const JOB_ICONS = {
2027
+ queued: LoaderCircle,
2028
+ running: LoaderCircle,
2029
+ awaiting_input: CircleAlert,
2030
+ completed: CircleCheck,
2031
+ failed: CircleX,
2032
+ cancelled: CircleX
2033
+ };
1913
2034
  const slots = useSlots();
1914
2035
  const pluginIcon = computed(() => plugin.value?.icon || (slots.logo ? void 0 : pluginIdentity.icon));
1915
2036
  const seeded = computed(() => isStandalone.value && !props.title && !props.subtitle);
@@ -1925,6 +2046,8 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1925
2046
  }, { flush: "sync" });
1926
2047
  /** Integrated plugins show their name as a static identity in place of the title; the page selector replaces it. */
1927
2048
  const identityName = computed(() => isIntegrated.value && !hasPageSelector.value ? plugin.value?.display_name || plugin.value?.name : void 0);
2049
+ /** The page selector crumb reads "<plugin> / <page>". */
2050
+ const pageSelectorPluginName = computed(() => isIntegrated.value ? plugin.value?.display_name || plugin.value?.name : props.title || pluginIdentity.name);
1928
2051
  const identitySubtitle = computed(() => plugin.value?.subtitle || plugin.value?.description);
1929
2052
  const hasPillNav = computed(() => !!config.value.pills?.length);
1930
2053
  const hasTitleGroup = computed(() => !hasPageSelector.value && !identityName.value && !!titleText.value && !!subtitleText.value);
@@ -1961,7 +2084,7 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1961
2084
  icon: pluginIcon.value,
1962
2085
  size: "topbar",
1963
2086
  variant: "solid"
1964
- }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_6$1, [..._cache[9] || (_cache[9] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)], 8, _hoisted_4$2)) : config.value.homePath ? (openBlock(), createBlock(_component_router_link, {
2087
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_6$1, [..._cache[11] || (_cache[11] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)], 8, _hoisted_4$2)) : config.value.homePath ? (openBlock(), createBlock(_component_router_link, {
1965
2088
  key: 1,
1966
2089
  to: config.value.homePath,
1967
2090
  class: "mint-topbar-home-link"
@@ -1978,7 +2101,7 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1978
2101
  icon: pluginIcon.value,
1979
2102
  size: "topbar",
1980
2103
  variant: "solid"
1981
- }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_8$1, [..._cache[10] || (_cache[10] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)]),
2104
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_8$1, [..._cache[12] || (_cache[12] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)]),
1982
2105
  _: 3
1983
2106
  }, 8, ["to"])) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [unref(isIntegrated) || _ctx.$slots.icon || _ctx.$slots.logo || pluginIcon.value || config.value.logo ? (openBlock(), createElementBlock("span", _hoisted_9$1, [unref(isIntegrated) ? (openBlock(), createBlock(PluginIcon_default, {
1984
2107
  key: 0,
@@ -1992,7 +2115,7 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
1992
2115
  icon: pluginIcon.value,
1993
2116
  size: "topbar",
1994
2117
  variant: "solid"
1995
- }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_10$1, [..._cache[11] || (_cache[11] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)], 64))]),
2118
+ }, null, 8, ["icon"])) : renderSlot(_ctx.$slots, "logo", {}, () => [config.value.logo ? (openBlock(), createElementBlock("div", _hoisted_10$1, [..._cache[13] || (_cache[13] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)], void 0, 1)], void 0, 1)])) : createCommentVNode("", true)], 64))]),
1996
2119
  identityName.value ? (openBlock(), createElementBlock("span", _hoisted_11$1, [createElementVNode("span", _hoisted_12$1, toDisplayString(identityName.value), 1), identitySubtitle.value ? (openBlock(), createElementBlock("span", _hoisted_13$1, toDisplayString(identitySubtitle.value), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true),
1997
2120
  hasPlatformPageSelector.value ? (openBlock(), createElementBlock("span", {
1998
2121
  key: 1,
@@ -2003,6 +2126,7 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
2003
2126
  key: 2,
2004
2127
  pages: normalizedPageSelector.value,
2005
2128
  "current-page-id": __props.currentPageSelectorId,
2129
+ "plugin-name": pageSelectorPluginName.value,
2006
2130
  onSelect: _cache[0] || (_cache[0] = ($event) => emit("page-selector-select", $event))
2007
2131
  }, createSlots({ _: 2 }, [_ctx.$slots["page-selector-icon"] ? {
2008
2132
  name: "icon",
@@ -2012,7 +2136,11 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
2012
2136
  name: "item-icon",
2013
2137
  fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "page-selector-item-icon", normalizeProps(guardReactiveProps(slotProps)))]),
2014
2138
  key: "1"
2015
- } : void 0]), 1032, ["pages", "current-page-id"])) : createCommentVNode("", true),
2139
+ } : void 0]), 1032, [
2140
+ "pages",
2141
+ "current-page-id",
2142
+ "plugin-name"
2143
+ ])) : createCommentVNode("", true),
2016
2144
  hasTitleGroup.value ? (openBlock(), createElementBlock("div", _hoisted_14$1, [createElementVNode("span", _hoisted_15$1, toDisplayString(titleText.value), 1), createElementVNode("span", _hoisted_16$1, toDisplayString(subtitleText.value), 1)])) : hasTitleOnly.value ? (openBlock(), createElementBlock("span", _hoisted_17$1, toDisplayString(titleText.value), 1)) : createCommentVNode("", true),
2017
2145
  renderSlot(_ctx.$slots, "nav")
2018
2146
  ]),
@@ -2025,11 +2153,50 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
2025
2153
  }, null, 8, ["items", "current-item-id"])) : createCommentVNode("", true)])])) : createCommentVNode("", true),
2026
2154
  createElementVNode("div", _hoisted_19$1, [
2027
2155
  config.value.standaloneLabel !== false && isStandalone.value ? (openBlock(), createElementBlock("span", _hoisted_20$1, toDisplayString(config.value.standaloneLabel), 1)) : createCommentVNode("", true),
2028
- unref(appExperiment) && !isStandalone.value && canBindExperiment.value ? (openBlock(), createBlock(unref(ExperimentPopover), mergeProps({ key: 1 }, unref(appExperiment).popover.value, {
2029
- onSelect: _cache[2] || (_cache[2] = ($event) => unref(appExperiment).openModal()),
2030
- onSave: _cache[3] || (_cache[3] = ($event) => unref(appExperiment).handleSave()),
2031
- onDetach: _cache[4] || (_cache[4] = ($event) => unref(appExperiment).handleDetach())
2032
- }), null, 16)) : createCommentVNode("", true),
2156
+ showExperiment.value || __props.job !== void 0 || runSlotJoined.value ? (openBlock(), createElementBlock("div", {
2157
+ key: 1,
2158
+ class: normalizeClass(["mint-topbar__run-slot", { "mint-topbar__run-slot--joined": runSlotJoined.value }])
2159
+ }, [
2160
+ showExperiment.value && unref(appExperiment) ? (openBlock(), createBlock(unref(ExperimentPopover), mergeProps({ key: 0 }, __props.job ? {
2161
+ ...unref(appExperiment).popover.value,
2162
+ showSave: false
2163
+ } : unref(appExperiment).popover.value, {
2164
+ onSelect: _cache[2] || (_cache[2] = ($event) => unref(appExperiment).openModal()),
2165
+ onSave: _cache[3] || (_cache[3] = ($event) => unref(appExperiment).handleSave()),
2166
+ onDetach: _cache[4] || (_cache[4] = ($event) => unref(appExperiment).handleDetach())
2167
+ }), null, 16)) : createCommentVNode("", true),
2168
+ createElementVNode("span", _hoisted_21$1, toDisplayString(__props.job ? JOB_STATUS_TEXT[__props.job.status] : ""), 1),
2169
+ createVNode(Transition, {
2170
+ name: "mint-topbar-job",
2171
+ mode: "out-in",
2172
+ appear: "",
2173
+ onBeforeEnter: syncRunSlotJoined,
2174
+ onAfterLeave: syncRunSlotJoined
2175
+ }, {
2176
+ default: withCtx(() => [__props.job ? (openBlock(), createElementBlock("button", {
2177
+ key: "run",
2178
+ type: "button",
2179
+ class: normalizeClass(["mint-topbar__job", `mint-topbar__job--${JOB_TONES[__props.job.status]}`]),
2180
+ title: jobName.value,
2181
+ "aria-label": jobName.value,
2182
+ onClick: _cache[5] || (_cache[5] = ($event) => emit("job-click"))
2183
+ }, [(openBlock(), createBlock(resolveDynamicComponent(JOB_ICONS[__props.job.status]), {
2184
+ class: normalizeClass(["mint-topbar__job-icon", { "mint-topbar__job-icon--spin": __props.job.status === "running" || __props.job.status === "queued" }]),
2185
+ size: 14,
2186
+ "aria-hidden": "true"
2187
+ }, null, 8, ["class"])), jobPercent.value != null ? (openBlock(), createElementBlock("span", _hoisted_23$1, [createElementVNode("span", { style: normalizeStyle({ width: `${jobPercent.value}%` }) }, null, 4)])) : createCommentVNode("", true)], 10, _hoisted_22$1)) : __props.job === null ? (openBlock(), createElementBlock("button", {
2188
+ key: "idle",
2189
+ type: "button",
2190
+ class: "mint-topbar__job mint-topbar__job--idle",
2191
+ onClick: _cache[6] || (_cache[6] = ($event) => emit("job-click"))
2192
+ }, [createVNode(unref(ListChecks), {
2193
+ class: "mint-topbar__job-icon",
2194
+ size: 14,
2195
+ "aria-hidden": "true"
2196
+ }), _cache[14] || (_cache[14] = createElementVNode("span", { class: "mint-topbar__job-label" }, "Jobs", -1))])) : createCommentVNode("", true)]),
2197
+ _: 1
2198
+ })
2199
+ ], 2)) : createCommentVNode("", true),
2033
2200
  renderSlot(_ctx.$slots, "actions"),
2034
2201
  config.value.themeToggle ? (openBlock(), createBlock(ThemeToggle_default, {
2035
2202
  key: 2,
@@ -2040,8 +2207,8 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
2040
2207
  type: "button",
2041
2208
  class: "mint-topbar__settings-btn",
2042
2209
  "aria-label": "Open settings",
2043
- onClick: _cache[5] || (_cache[5] = ($event) => settingsOpen.value = true)
2044
- }, [..._cache[12] || (_cache[12] = [createElementVNode("svg", {
2210
+ onClick: _cache[7] || (_cache[7] = ($event) => settingsOpen.value = true)
2211
+ }, [..._cache[15] || (_cache[15] = [createElementVNode("svg", {
2045
2212
  class: "mint-topbar__settings-icon",
2046
2213
  viewBox: "0 0 24 24",
2047
2214
  fill: "none",
@@ -2060,7 +2227,7 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
2060
2227
  showSettings.value && settingsOpen.value ? (openBlock(), createBlock(unref(SettingsModal), {
2061
2228
  key: 0,
2062
2229
  open: settingsOpen.value,
2063
- "onUpdate:open": _cache[6] || (_cache[6] = ($event) => settingsOpen.value = $event),
2230
+ "onUpdate:open": _cache[8] || (_cache[8] = ($event) => settingsOpen.value = $event),
2064
2231
  title: settingsConfig.value?.title,
2065
2232
  tabs: normalizedSettingsTabs.value,
2066
2233
  "show-appearance": settingsConfig.value?.showAppearance ?? true,
@@ -2070,7 +2237,7 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
2070
2237
  spec: settingsConfig.value?.spec,
2071
2238
  values: settingsConfig.value?.values,
2072
2239
  "user-type": settingsConfig.value?.userType,
2073
- "onUpdate:values": _cache[7] || (_cache[7] = ($event) => emit("settings-values-change", $event))
2240
+ "onUpdate:values": _cache[9] || (_cache[9] = ($event) => emit("settings-values-change", $event))
2074
2241
  }, createSlots({
2075
2242
  appearance: withCtx(() => [renderSlot(_ctx.$slots, "settings-appearance")]),
2076
2243
  _: 2
@@ -2091,7 +2258,7 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
2091
2258
  "values",
2092
2259
  "user-type"
2093
2260
  ])) : createCommentVNode("", true),
2094
- unref(appExperiment) && !isStandalone.value && canBindExperiment.value && unref(appExperiment).selectorModal.value.open ? (openBlock(), createBlock(unref(ExperimentSelectorModal), mergeProps({ key: 1 }, unref(appExperiment).selectorModal.value, { "onUpdate:open": _cache[8] || (_cache[8] = ($event) => $event ? unref(appExperiment).openModal() : unref(appExperiment).closeModal()) }), null, 16)) : createCommentVNode("", true)
2261
+ unref(appExperiment) && !isStandalone.value && canBindExperiment.value && unref(appExperiment).selectorModal.value.open ? (openBlock(), createBlock(unref(ExperimentSelectorModal), mergeProps({ key: 1 }, unref(appExperiment).selectorModal.value, { "onUpdate:open": _cache[10] || (_cache[10] = ($event) => $event ? unref(appExperiment).openModal() : unref(appExperiment).closeModal()) }), null, 16)) : createCommentVNode("", true)
2095
2262
  ], 64);
2096
2263
  };
2097
2264
  }
@@ -3562,4 +3729,4 @@ var AppSidebar_default = /* @__PURE__ */ defineComponent({
3562
3729
  //#endregion
3563
3730
  export { getDefaultControlView as A, controlBindings as C, controlsTo as D, controlValuesToComponentProps as E, ThemeToggle_default as M, useTheme as N, controlsToFormSchema as O, useControlSchema as S, controlValuesToComponentBindingsById as T, AppLayout_default as _, pickExistingRecordKeys as a, defineControls as b, valuesEqual as c, useForm as d, AppTopBar_default as f, normalizeLabelItemInput as g, normalizeItemInput as h, formSchemaFieldNames as i, CollapsibleCard_default as j, controlsToSettingsSchema as k, useFormBuilder as l, PluginIcon_default as m, FormSchemaInternal_default as n, pickRecordKeys as o, providePluginIdentity as p, FormFieldRendererInternal_default as r, recordValuesEqualForKeys as s, AppSidebar_default as t, evaluateCondition as u, usePluginWorkspace as v, controlValuesToComponentBindings as w, getControlDefaults as x, defineControlComponentBindings as y };
3564
3731
 
3565
- //# sourceMappingURL=AppSidebar-DGK5i-hJ.js.map
3732
+ //# sourceMappingURL=AppSidebar-CIXJBzDv.js.map