@atscript/vue-table 0.1.132 → 0.1.134

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 (163) hide show
  1. package/dist/as-action-form-dialog.cjs +42 -30
  2. package/dist/as-action-form-dialog.mjs +42 -30
  3. package/dist/{as-action-menu-content-C5qx9MPE.cjs → as-action-menu-content-C_D_Fepo.cjs} +1 -1
  4. package/dist/{as-action-menu-content-4UfcabUe.mjs → as-action-menu-content-rim8hAO9.mjs} +1 -1
  5. package/dist/{as-cell-array-2qmJ1lT2.mjs → as-cell-array-BWHkJX3I.mjs} +2 -2
  6. package/dist/{as-cell-array-iPeUnk2G.cjs → as-cell-array-D-8Pqlgo.cjs} +2 -2
  7. package/dist/as-cell-array.cjs +1 -1
  8. package/dist/as-cell-array.mjs +1 -1
  9. package/dist/{as-cell-date-DyixWKuS.cjs → as-cell-date-DviMJEqs.cjs} +2 -2
  10. package/dist/{as-cell-date-BwFgi6O0.mjs → as-cell-date-mGlnDeLP.mjs} +2 -2
  11. package/dist/as-cell-date.cjs +1 -1
  12. package/dist/as-cell-date.mjs +1 -1
  13. package/dist/{as-cell-json--95Xq6yq.mjs → as-cell-json-2I081xnO.mjs} +2 -2
  14. package/dist/{as-cell-json-Bvv2P7YV.cjs → as-cell-json-CaVB6e7V.cjs} +2 -2
  15. package/dist/as-cell-json.cjs +1 -1
  16. package/dist/as-cell-json.mjs +1 -1
  17. package/dist/{as-cell-number-DuPMOesI.cjs → as-cell-number-BnYbxOiG.cjs} +2 -2
  18. package/dist/{as-cell-number-DKRaS9pM.mjs → as-cell-number-CP2AZI9g.mjs} +2 -2
  19. package/dist/as-cell-number.cjs +1 -1
  20. package/dist/as-cell-number.mjs +1 -1
  21. package/dist/{as-cell-union-DJNsEKTi.cjs → as-cell-union-BjMP91PS.cjs} +3 -3
  22. package/dist/{as-cell-union-C9FukGqF.mjs → as-cell-union-NHpDCXty.mjs} +3 -3
  23. package/dist/as-cell-union.cjs +1 -1
  24. package/dist/as-cell-union.mjs +1 -1
  25. package/dist/as-column-menu.cjs +1 -1
  26. package/dist/as-column-menu.d.cts +1 -1
  27. package/dist/as-column-menu.d.mts +1 -1
  28. package/dist/as-column-menu.mjs +1 -1
  29. package/dist/{as-column-menu.vue-u_DNy3f-.d.cts → as-column-menu.vue-De7SRhj6.d.cts} +1 -1
  30. package/dist/{as-column-menu.vue-DL5N9mKR.d.mts → as-column-menu.vue-Dg0H1dOd.d.mts} +1 -1
  31. package/dist/{as-config-dialog-BehfqIGd.mjs → as-config-dialog-BUBHiVlf.mjs} +56 -35
  32. package/dist/{as-config-dialog-BOYWPYYH.cjs → as-config-dialog-DvBptYMS.cjs} +55 -34
  33. package/dist/as-config-dialog.cjs +1 -1
  34. package/dist/as-config-dialog.mjs +1 -1
  35. package/dist/{as-confirm-dialog-UwhDHysk.cjs → as-confirm-dialog-ByMfIG0A.cjs} +12 -9
  36. package/dist/{as-confirm-dialog-bpN4A-KN.mjs → as-confirm-dialog-G4ZoL_Xo.mjs} +12 -9
  37. package/dist/as-confirm-dialog.cjs +1 -1
  38. package/dist/as-confirm-dialog.mjs +1 -1
  39. package/dist/{as-filter-dialog-D1qzq-8b.mjs → as-filter-dialog-BJWH8cvc.mjs} +34 -26
  40. package/dist/{as-filter-dialog-Dh2Ylthb.cjs → as-filter-dialog-C2oyT0yt.cjs} +33 -25
  41. package/dist/as-filter-dialog.cjs +1 -1
  42. package/dist/as-filter-dialog.mjs +1 -1
  43. package/dist/{as-filter-field-DirBmnbb.mjs → as-filter-field-B2skq4K0.mjs} +4 -4
  44. package/dist/{as-filter-field-DRsDJdpx.cjs → as-filter-field-DxGfasQj.cjs} +4 -4
  45. package/dist/as-filter-field.cjs +1 -1
  46. package/dist/as-filter-field.mjs +1 -1
  47. package/dist/as-filter-input.cjs +1 -1
  48. package/dist/as-filter-input.mjs +1 -1
  49. package/dist/as-filters-Bhte22La.cjs +130 -0
  50. package/dist/as-filters-DogNVlqr.mjs +125 -0
  51. package/dist/as-filters.cjs +1 -1
  52. package/dist/as-filters.d.cts +1 -1
  53. package/dist/as-filters.d.mts +1 -1
  54. package/dist/as-filters.mjs +1 -1
  55. package/dist/as-filters.vue-BG_ysCkC.d.mts +65 -0
  56. package/dist/as-filters.vue-DcxDnWAU.d.cts +65 -0
  57. package/dist/{as-preset-dialog-CDqCAR7N.mjs → as-preset-dialog-BwHV6Y77.mjs} +71 -21
  58. package/dist/{as-preset-dialog-DpM06jqR.cjs → as-preset-dialog-D2a6nxEX.cjs} +75 -25
  59. package/dist/as-preset-dialog.cjs +1 -1
  60. package/dist/as-preset-dialog.mjs +1 -1
  61. package/dist/{as-preset-picker-CISaxEZ0.mjs → as-preset-picker-B0JnyAPA.mjs} +39 -15
  62. package/dist/{as-preset-picker-jUS_YDX8.cjs → as-preset-picker-DbkmapBx.cjs} +45 -21
  63. package/dist/as-preset-picker.cjs +1 -1
  64. package/dist/as-preset-picker.mjs +1 -1
  65. package/dist/{as-row-actions-xqJeAdQl.mjs → as-row-actions-BkIsJVBm.mjs} +24 -11
  66. package/dist/{as-row-actions-Bm6Bzyno.cjs → as-row-actions-CRg8LHGk.cjs} +24 -11
  67. package/dist/as-row-actions.cjs +1 -1
  68. package/dist/as-row-actions.d.cts +1 -1
  69. package/dist/as-row-actions.d.mts +1 -1
  70. package/dist/as-row-actions.mjs +1 -1
  71. package/dist/{as-row-actions.vue-Bvcc2tUN.d.cts → as-row-actions.vue-VpJsBAJ4.d.mts} +8 -0
  72. package/dist/{as-row-actions.vue-DUSDuoR2.d.mts → as-row-actions.vue-dn_DKcMm.d.cts} +8 -0
  73. package/dist/{as-table-CDSG2yED.mjs → as-table-BEvsX87E.mjs} +26 -8
  74. package/dist/{as-table-actions-DMxeaczm.mjs → as-table-actions-B5upF1bQ.mjs} +69 -18
  75. package/dist/{as-table-actions-gV4lqqxc.cjs → as-table-actions-B6sKd4sl.cjs} +68 -17
  76. package/dist/as-table-actions.cjs +1 -1
  77. package/dist/as-table-actions.d.cts +1 -1
  78. package/dist/as-table-actions.d.mts +1 -1
  79. package/dist/as-table-actions.mjs +1 -1
  80. package/dist/{as-table-actions.vue-B-cgiCXP.d.cts → as-table-actions.vue-CoxhpIlJ.d.mts} +2 -2
  81. package/dist/{as-table-actions.vue-ClMa0OD1.d.mts → as-table-actions.vue-Kic8m28V.d.cts} +2 -2
  82. package/dist/{as-table-base-BaTE3VSN.mjs → as-table-base-BxKBdIdS.mjs} +142 -47
  83. package/dist/{as-table-base-RG2TEIgV.cjs → as-table-base-DLuhKz69.cjs} +142 -47
  84. package/dist/{as-table-cell-value-D1JkTQt0.cjs → as-table-cell-value-BAi5yadc.cjs} +2 -2
  85. package/dist/{as-table-cell-value-CPcFxSOj.mjs → as-table-cell-value-BVcfhhCb.mjs} +2 -2
  86. package/dist/as-table-cell-value.cjs +1 -1
  87. package/dist/as-table-cell-value.mjs +1 -1
  88. package/dist/{as-table-header-cell-CIqlO6Lw.cjs → as-table-header-cell-Bv6q5iKA.cjs} +2 -2
  89. package/dist/{as-table-header-cell-Bdhl5Lox.mjs → as-table-header-cell-Xd3cvnII.mjs} +2 -2
  90. package/dist/as-table-header-cell.cjs +1 -1
  91. package/dist/as-table-header-cell.d.cts +1 -1
  92. package/dist/as-table-header-cell.d.mts +1 -1
  93. package/dist/as-table-header-cell.mjs +1 -1
  94. package/dist/{as-table-header-cell.vue-BCszzxtU.d.mts → as-table-header-cell.vue-AS6u4e6v.d.cts} +2 -2
  95. package/dist/{as-table-header-cell.vue-BzTzfGRo.d.cts → as-table-header-cell.vue-zKOmlzhT.d.mts} +2 -2
  96. package/dist/{as-table-root-BLReUbRH.mjs → as-table-root-C1A6JkwL.mjs} +112 -10
  97. package/dist/{as-table-root-DLJ_3Jf4.cjs → as-table-root-DlYjnZax.cjs} +112 -10
  98. package/dist/as-table-root.cjs +1 -1
  99. package/dist/as-table-root.d.cts +1 -1
  100. package/dist/as-table-root.d.mts +1 -1
  101. package/dist/as-table-root.mjs +1 -1
  102. package/dist/{as-table-root.vue-QMT93qPk.d.mts → as-table-root.vue-CWk9YgpG.d.mts} +257 -41
  103. package/dist/{as-table-root.vue-D0T3n-Vm.d.cts → as-table-root.vue-D94eypcL.d.cts} +258 -42
  104. package/dist/{as-table-status-Du4WLF4k.cjs → as-table-status-B2HPerJT.cjs} +54 -38
  105. package/dist/{as-table-status-DGTZlpyq.mjs → as-table-status-QzlBdSiR.mjs} +54 -38
  106. package/dist/{as-table-BWUPzjRn.cjs → as-table-vJbZyZVx.cjs} +26 -8
  107. package/dist/as-table.cjs +1 -1
  108. package/dist/as-table.d.cts +1 -1
  109. package/dist/as-table.d.mts +1 -1
  110. package/dist/as-table.mjs +1 -1
  111. package/dist/{as-table.vue-Ds7MEp37.d.cts → as-table.vue-BB1vaNL6.d.cts} +28 -4
  112. package/dist/{as-table.vue-Ce5606ZO.d.mts → as-table.vue-BUDFTCpo.d.mts} +28 -4
  113. package/dist/{as-window-table-DWujiUQy.mjs → as-window-table-BH0tDDnr.mjs} +107 -24
  114. package/dist/{as-window-table-jD_y9yet.cjs → as-window-table-Bl_q72WL.cjs} +107 -24
  115. package/dist/as-window-table.cjs +1 -1
  116. package/dist/as-window-table.d.cts +1 -1
  117. package/dist/as-window-table.d.mts +1 -1
  118. package/dist/as-window-table.mjs +1 -1
  119. package/dist/{as-window-table.vue-DfZF1Mux.d.mts → as-window-table.vue-Be2IA0Eb.d.cts} +27 -4
  120. package/dist/{as-window-table.vue-Bhf9BK8E.d.cts → as-window-table.vue-CLqFM2ff.d.mts} +27 -4
  121. package/dist/error-message-CfKpn_5w.cjs +18 -0
  122. package/dist/error-message-gNEXnnbb.mjs +13 -0
  123. package/dist/index.cjs +237 -41
  124. package/dist/index.d.cts +10 -10
  125. package/dist/index.d.mts +10 -10
  126. package/dist/index.mjs +230 -43
  127. package/dist/{types-ByU4O0Yf.d.mts → types--ex8BJIO.d.cts} +263 -5
  128. package/dist/{types-CTMxE_zA.d.cts → types-CBGaTR2Z.d.mts} +263 -5
  129. package/dist/{use-table-CyFcVtUN.mjs → use-table-BFhbfWgY.mjs} +48 -23
  130. package/dist/{use-table-component-K6xj1obF.mjs → use-table-component-CRmLHdqi.mjs} +1 -1
  131. package/dist/{use-table-component-DO_kvKSf.cjs → use-table-component-DS5NJPzs.cjs} +1 -1
  132. package/dist/{use-table-nav-bridge-uOQUDooh.cjs → use-table-nav-bridge-DS14D_rG.cjs} +1 -1
  133. package/dist/{use-table-nav-bridge-DeGeaQX-.mjs → use-table-nav-bridge-DzJN5v9a.mjs} +1 -1
  134. package/dist/{use-table-nvBq1dZ4.cjs → use-table-nvuZdgUd.cjs} +51 -20
  135. package/dist/{use-table-state-BxX3SpeW.mjs → use-table-state-mBXx11aH.mjs} +501 -105
  136. package/dist/{use-table-state-Oi2ds4_a.cjs → use-table-state-mhm-YWnu.cjs} +541 -109
  137. package/package.json +9 -9
  138. package/dist/as-filters-DCZTHjf5.cjs +0 -51
  139. package/dist/as-filters-beIud9sF.mjs +0 -46
  140. package/dist/as-filters.vue-DmECMd1v.d.mts +0 -10
  141. package/dist/as-filters.vue-fv-tRL2H.d.cts +0 -10
  142. package/dist/preset-aspect-display-IICxAlVo.mjs +0 -43
  143. package/dist/preset-aspect-display-TWwf6j1B.cjs +0 -72
  144. /package/dist/{as-cell-json-popover-Dkdv5Y9E.mjs → as-cell-json-popover-CH5bAcLE.mjs} +0 -0
  145. /package/dist/{as-cell-json-popover-BM2QLgfk.cjs → as-cell-json-popover-vty5vMjW.cjs} +0 -0
  146. /package/dist/{as-column-menu-kTIQfLTi.mjs → as-column-menu-BMTS3DO2.mjs} +0 -0
  147. /package/dist/{as-column-menu-fZVbJ9lU.cjs → as-column-menu-D_8NxujZ.cjs} +0 -0
  148. /package/dist/{as-filter-input-BM23TNeh.mjs → as-filter-input-C8KmOus8.mjs} +0 -0
  149. /package/dist/{as-filter-input-DJu2k9gO.cjs → as-filter-input-DUqpkTkg.cjs} +0 -0
  150. /package/dist/{format-cell-D1Ziv96Q.mjs → format-cell-Bx7wNc4X.mjs} +0 -0
  151. /package/dist/{format-cell-vCNTh4WZ.cjs → format-cell-DaxV6WIJ.cjs} +0 -0
  152. /package/dist/{get-cell-value-4rHKP-TG.cjs → get-cell-value-CJT4fk4y.cjs} +0 -0
  153. /package/dist/{get-cell-value-C8LLc_Rr.mjs → get-cell-value-Cb3X8nUn.mjs} +0 -0
  154. /package/dist/{use-cell-locale-MQXoONh5.mjs → use-cell-locale-CxQOQsns.mjs} +0 -0
  155. /package/dist/{use-cell-locale-BGBRQB7s.cjs → use-cell-locale-caG2Fzpc.cjs} +0 -0
  156. /package/dist/{use-has-emit-listener-hhOH8CBI.cjs → use-has-emit-listener-BaGFZDyM.cjs} +0 -0
  157. /package/dist/{use-has-emit-listener-BTMDIv2e.mjs → use-has-emit-listener-DrBbsLHQ.mjs} +0 -0
  158. /package/dist/{use-seed-on-open-Dg9I89fU.cjs → use-seed-on-open-9TSm1Vbv.cjs} +0 -0
  159. /package/dist/{use-seed-on-open-DO3A1kIb.mjs → use-seed-on-open-DSh4XFyp.mjs} +0 -0
  160. /package/dist/{use-table-column-handlers-ehreEzcx.cjs → use-table-column-handlers-BMrP0WY2.cjs} +0 -0
  161. /package/dist/{use-table-column-handlers-CpiiIniD.mjs → use-table-column-handlers-Bx3JERqs.mjs} +0 -0
  162. /package/dist/{use-table-selection-Cmiu1h4S.cjs → use-table-selection-DtCV3rhu.cjs} +0 -0
  163. /package/dist/{use-table-selection-C84z4OZy.mjs → use-table-selection-ULbKT2xW.mjs} +0 -0
@@ -1,9 +1,9 @@
1
- import { a as useTableContext } from "./use-table-state-BxX3SpeW.mjs";
2
- import { t as useSeedOnOpen } from "./use-seed-on-open-DO3A1kIb.mjs";
3
- import { a as readPresetLabel, i as ownerNameOf, n as ASPECT_LABELS, r as aspectsOf, t as ASPECT_ICONS } from "./preset-aspect-display-IICxAlVo.mjs";
1
+ import { a as useTableContext, c as ASPECT_ICONS, d as readPresetLabel, l as ASPECT_LABELS, u as ownerNameOf } from "./use-table-state-mBXx11aH.mjs";
2
+ import { t as useSeedOnOpen } from "./use-seed-on-open-DSh4XFyp.mjs";
3
+ import { t as errorMessage } from "./error-message-gNEXnnbb.mjs";
4
4
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, isRef, nextTick, normalizeClass, openBlock, ref, renderList, toDisplayString, unref, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
5
5
  import { isSystemPresetId, setsEqual } from "@atscript/ui-table";
6
- import { DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogRoot, DialogTitle } from "reka-ui";
6
+ import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle } from "reka-ui";
7
7
  //#region src/components/defaults/as-preset-dialog.vue?vue&type=script&setup=true&lang.ts
8
8
  const _hoisted_1 = { class: "as-preset-dialog-header" };
9
9
  const _hoisted_2 = { class: "as-preset-dialog-counter" };
@@ -81,10 +81,15 @@ const _hoisted_26 = { class: "as-preset-dialog-footer" };
81
81
  const _hoisted_27 = { class: "as-preset-dialog-footer-status" };
82
82
  const _hoisted_28 = {
83
83
  key: 0,
84
+ class: "as-preset-dialog-footer-error",
85
+ role: "alert"
86
+ };
87
+ const _hoisted_29 = {
88
+ key: 1,
84
89
  class: "as-preset-dialog-footer-unsaved"
85
90
  };
86
- const _hoisted_29 = { class: "as-preset-dialog-footer-actions" };
87
- const _hoisted_30 = ["disabled"];
91
+ const _hoisted_30 = { class: "as-preset-dialog-footer-actions" };
92
+ const _hoisted_31 = ["disabled"];
88
93
  //#endregion
89
94
  //#region src/components/defaults/as-preset-dialog.vue
90
95
  var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
@@ -162,7 +167,7 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
162
167
  kind: "system",
163
168
  isPublic: false,
164
169
  ownerLabel: "—",
165
- aspects: [...state.preset.availableAspects],
170
+ aspects: state.preset.ownedAspects(sp.id),
166
171
  pendingLabel: false
167
172
  });
168
173
  const stored = [];
@@ -177,7 +182,7 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
177
182
  kind: isOwned ? "owned" : "public",
178
183
  isPublic: pendingPublicIds.value.has(row.id),
179
184
  ownerLabel: isOwned ? "you" : ownerNameOf(row, "—"),
180
- aspects: aspectsOf(row, state.preset.availableAspects),
185
+ aspects: state.preset.ownedAspects(row.id),
181
186
  pendingLabel: pending !== void 0 && pending !== original
182
187
  });
183
188
  }
@@ -289,9 +294,15 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
289
294
  cancelRename();
290
295
  }
291
296
  const saving = ref(false);
297
+ const errorText = ref("");
292
298
  async function save() {
293
299
  if (!isDirty.value || saving.value) return;
294
300
  saving.value = true;
301
+ errorText.value = "";
302
+ const failedLabels = /* @__PURE__ */ new Map();
303
+ const failedPublicIds = /* @__PURE__ */ new Set();
304
+ const failedDeleteIds = /* @__PURE__ */ new Set();
305
+ const failures = [];
295
306
  try {
296
307
  await state.preset.batch(async () => {
297
308
  const deleted = pendingDeleteIds.value;
@@ -304,17 +315,28 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
304
315
  if (state.preset.isOwned(id)) continue;
305
316
  cleaned.push(id);
306
317
  }
307
- await state.preset.setFavorites(cleaned);
318
+ try {
319
+ await state.preset.setFavorites(cleaned);
320
+ } catch (err) {
321
+ failures.push(errorMessage(err, "The change could not be saved."));
322
+ }
308
323
  }
309
324
  if (pendingDefaultId.value !== serverDefaultId.value) {
310
325
  const next = pendingDefaultId.value && deleted.has(pendingDefaultId.value) ? null : pendingDefaultId.value;
311
- if (next !== serverDefaultId.value) await state.preset.setDefault(next);
326
+ if (next !== serverDefaultId.value) try {
327
+ await state.preset.setDefault(next);
328
+ } catch (err) {
329
+ failures.push(errorMessage(err, "The change could not be saved."));
330
+ }
312
331
  }
313
332
  if (pendingLabels.value.size > 0) for (const [id, label] of pendingLabels.value) {
314
333
  if (deleted.has(id)) continue;
315
334
  try {
316
335
  await state.preset.rename(id, label);
317
- } catch (_err) {}
336
+ } catch (err) {
337
+ failedLabels.set(id, label);
338
+ failures.push(errorMessage(err, "The change could not be saved."));
339
+ }
318
340
  }
319
341
  if (!setsEqual(pendingPublicIds.value, serverPublicIds.value)) {
320
342
  const flips = [];
@@ -328,12 +350,35 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
328
350
  }
329
351
  for (const id of flips) try {
330
352
  await state.preset.togglePublic(id);
331
- } catch (_err) {}
353
+ } catch (err) {
354
+ failedPublicIds.add(id);
355
+ failures.push(errorMessage(err, "The change could not be saved."));
356
+ }
332
357
  }
333
358
  if (deleted.size > 0) for (const id of deleted) try {
334
359
  await state.preset.remove(id);
335
- } catch (_err) {}
360
+ } catch (err) {
361
+ failedDeleteIds.add(id);
362
+ failures.push(errorMessage(err, "The change could not be saved."));
363
+ }
336
364
  });
365
+ if (failures.length > 0) {
366
+ syncPendingFromServer();
367
+ if (failedLabels.size > 0) {
368
+ const labels = new Map(pendingLabels.value);
369
+ for (const [id, label] of failedLabels) labels.set(id, label);
370
+ pendingLabels.value = labels;
371
+ }
372
+ if (failedPublicIds.size > 0) {
373
+ const publics = new Set(pendingPublicIds.value);
374
+ for (const id of failedPublicIds) if (publics.has(id)) publics.delete(id);
375
+ else publics.add(id);
376
+ pendingPublicIds.value = publics;
377
+ }
378
+ if (failedDeleteIds.size > 0) pendingDeleteIds.value = new Set([...pendingDeleteIds.value, ...failedDeleteIds]);
379
+ errorText.value = failures.length === 1 ? failures[0] : `${failures.length} changes could not be saved.`;
380
+ return;
381
+ }
337
382
  if (pendingActiveId.value !== null && pendingActiveId.value !== state.preset.activeId.value && !pendingDeleteIds.value.has(pendingActiveId.value)) state.preset.apply(pendingActiveId.value);
338
383
  state.preset.dialogOpen.value = false;
339
384
  } finally {
@@ -342,6 +387,7 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
342
387
  }
343
388
  function discardOrClose() {
344
389
  syncPendingFromServer();
390
+ errorText.value = "";
345
391
  state.preset.dialogOpen.value = false;
346
392
  }
347
393
  function rowFavTitle(row) {
@@ -385,20 +431,24 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
385
431
  default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode("Presets", -1)])]),
386
432
  _: 1
387
433
  }),
434
+ createVNode(unref(DialogDescription), { class: "sr-only" }, {
435
+ default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode(" Rename, share, favorite, pin as default or delete your saved table views. ", -1)])]),
436
+ _: 1
437
+ }),
388
438
  createElementVNode("span", _hoisted_2, toDisplayString(counterText.value), 1),
389
439
  createVNode(unref(DialogClose), {
390
440
  class: "as-preset-dialog-close",
391
441
  "aria-label": "Close",
392
442
  onClick: withModifiers(discardOrClose, ["prevent"])
393
443
  }, {
394
- default: withCtx(() => [..._cache[6] || (_cache[6] = [createElementVNode("span", {
444
+ default: withCtx(() => [..._cache[7] || (_cache[7] = [createElementVNode("span", {
395
445
  class: "i-as-close",
396
446
  "aria-hidden": "true"
397
447
  }, null, -1)])]),
398
448
  _: 1
399
449
  })
400
450
  ]),
401
- createElementVNode("div", _hoisted_3, [createElementVNode("div", _hoisted_4, [_cache[7] || (_cache[7] = createElementVNode("span", {
451
+ createElementVNode("div", _hoisted_3, [createElementVNode("div", _hoisted_4, [_cache[8] || (_cache[8] = createElementVNode("span", {
402
452
  class: "i-as-search as-preset-dialog-search-icon",
403
453
  "aria-hidden": "true"
404
454
  }, null, -1)), withDirectives(createElementVNode("input", {
@@ -408,7 +458,7 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
408
458
  type: "search",
409
459
  class: "as-preset-dialog-search-input",
410
460
  placeholder: "Search by name or owner…"
411
- }, null, 512), [[vModelText, searchQuery.value]])]), _cache[8] || (_cache[8] = createElementVNode("div", { class: "as-preset-dialog-legend" }, [
461
+ }, null, 512), [[vModelText, searchQuery.value]])]), _cache[9] || (_cache[9] = createElementVNode("div", { class: "as-preset-dialog-legend" }, [
412
462
  createElementVNode("span", { class: "as-preset-dialog-legend-item" }, [createElementVNode("span", {
413
463
  class: "i-as-pin as-preset-dialog-legend-icon",
414
464
  "aria-hidden": "true"
@@ -517,7 +567,7 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
517
567
  key: 3,
518
568
  class: "as-preset-dialog-row-public-indicator",
519
569
  title: rowPublicTitle(row)
520
- }, [..._cache[9] || (_cache[9] = [createElementVNode("span", {
570
+ }, [..._cache[10] || (_cache[10] = [createElementVNode("span", {
521
571
  class: "i-as-eye",
522
572
  "aria-hidden": "true"
523
573
  }, null, -1)])], 8, _hoisted_22)) : (openBlock(), createElementBlock("span", _hoisted_23)),
@@ -529,17 +579,17 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
529
579
  "aria-pressed": pendingDeleteIds.value.has(row.id),
530
580
  title: pendingDeleteIds.value.has(row.id) ? "Marked for deletion — click to undo" : "Mark for deletion (applied on Save)",
531
581
  onClick: ($event) => toggleDeletePending(row.id)
532
- }, [..._cache[10] || (_cache[10] = [createElementVNode("span", {
582
+ }, [..._cache[11] || (_cache[11] = [createElementVNode("span", {
533
583
  class: "i-as-trash",
534
584
  "aria-hidden": "true"
535
585
  }, null, -1)])], 8, _hoisted_24)) : (openBlock(), createElementBlock("span", _hoisted_25))
536
586
  ], 8, _hoisted_8);
537
587
  }), 128))], 64);
538
588
  }), 128))]),
539
- createElementVNode("footer", _hoisted_26, [createElementVNode("div", _hoisted_27, [isDirty.value ? (openBlock(), createElementBlock("span", _hoisted_28, [..._cache[11] || (_cache[11] = [createElementVNode("span", {
589
+ createElementVNode("footer", _hoisted_26, [createElementVNode("div", _hoisted_27, [errorText.value ? (openBlock(), createElementBlock("span", _hoisted_28, toDisplayString(errorText.value), 1)) : isDirty.value ? (openBlock(), createElementBlock("span", _hoisted_29, [..._cache[12] || (_cache[12] = [createElementVNode("span", {
540
590
  class: "as-preset-dialog-footer-unsaved-dot",
541
591
  "aria-hidden": "true"
542
- }, null, -1), createTextVNode(" unsaved changes ", -1)])])) : createCommentVNode("v-if", true)]), createElementVNode("div", _hoisted_29, [createElementVNode("button", {
592
+ }, null, -1), createTextVNode(" unsaved changes ", -1)])])) : createCommentVNode("v-if", true)]), createElementVNode("div", _hoisted_30, [createElementVNode("button", {
543
593
  type: "button",
544
594
  class: "as-preset-dialog-footer-close",
545
595
  onClick: discardOrClose
@@ -548,7 +598,7 @@ var as_preset_dialog_default = /* @__PURE__ */ defineComponent({
548
598
  class: "as-preset-dialog-footer-save",
549
599
  disabled: !isDirty.value || saving.value,
550
600
  onClick: save
551
- }, toDisplayString(saving.value ? "Saving…" : "Save"), 9, _hoisted_30)])])
601
+ }, toDisplayString(saving.value ? "Saving…" : "Save"), 9, _hoisted_31)])])
552
602
  ]),
553
603
  _: 1
554
604
  })]),
@@ -1,6 +1,6 @@
1
- const require_use_table_state = require("./use-table-state-Oi2ds4_a.cjs");
2
- const require_use_seed_on_open = require("./use-seed-on-open-Dg9I89fU.cjs");
3
- const require_preset_aspect_display = require("./preset-aspect-display-TWwf6j1B.cjs");
1
+ const require_use_table_state = require("./use-table-state-mhm-YWnu.cjs");
2
+ const require_use_seed_on_open = require("./use-seed-on-open-9TSm1Vbv.cjs");
3
+ const require_error_message = require("./error-message-CfKpn_5w.cjs");
4
4
  let vue = require("vue");
5
5
  let _atscript_ui_table = require("@atscript/ui-table");
6
6
  let reka_ui = require("reka-ui");
@@ -81,10 +81,15 @@ const _hoisted_26 = { class: "as-preset-dialog-footer" };
81
81
  const _hoisted_27 = { class: "as-preset-dialog-footer-status" };
82
82
  const _hoisted_28 = {
83
83
  key: 0,
84
+ class: "as-preset-dialog-footer-error",
85
+ role: "alert"
86
+ };
87
+ const _hoisted_29 = {
88
+ key: 1,
84
89
  class: "as-preset-dialog-footer-unsaved"
85
90
  };
86
- const _hoisted_29 = { class: "as-preset-dialog-footer-actions" };
87
- const _hoisted_30 = ["disabled"];
91
+ const _hoisted_30 = { class: "as-preset-dialog-footer-actions" };
92
+ const _hoisted_31 = ["disabled"];
88
93
  //#endregion
89
94
  //#region src/components/defaults/as-preset-dialog.vue
90
95
  var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -162,13 +167,13 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
162
167
  kind: "system",
163
168
  isPublic: false,
164
169
  ownerLabel: "—",
165
- aspects: [...state.preset.availableAspects],
170
+ aspects: state.preset.ownedAspects(sp.id),
166
171
  pendingLabel: false
167
172
  });
168
173
  const stored = [];
169
174
  for (const row of state.preset.presets.value) {
170
175
  const isOwned = state.preset.isOwned(row.id);
171
- const original = require_preset_aspect_display.readPresetLabel(row);
176
+ const original = require_use_table_state.readPresetLabel(row);
172
177
  const pending = pendingLabels.value.get(row.id);
173
178
  const liveLabel = pending ?? original;
174
179
  stored.push({
@@ -176,8 +181,8 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
176
181
  label: liveLabel,
177
182
  kind: isOwned ? "owned" : "public",
178
183
  isPublic: pendingPublicIds.value.has(row.id),
179
- ownerLabel: isOwned ? "you" : require_preset_aspect_display.ownerNameOf(row, "—"),
180
- aspects: require_preset_aspect_display.aspectsOf(row, state.preset.availableAspects),
184
+ ownerLabel: isOwned ? "you" : require_use_table_state.ownerNameOf(row, "—"),
185
+ aspects: state.preset.ownedAspects(row.id),
181
186
  pendingLabel: pending !== void 0 && pending !== original
182
187
  });
183
188
  }
@@ -279,7 +284,7 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
279
284
  const id = editingId.value;
280
285
  const next = editingValue.value.trim();
281
286
  const row = state.preset.presetsById.value.get(id);
282
- const original = row ? require_preset_aspect_display.readPresetLabel(row) : "";
287
+ const original = row ? require_use_table_state.readPresetLabel(row) : "";
283
288
  const map = new Map(pendingLabels.value);
284
289
  if (!next || next === original) map.delete(id);
285
290
  else map.set(id, next);
@@ -289,9 +294,15 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
289
294
  cancelRename();
290
295
  }
291
296
  const saving = (0, vue.ref)(false);
297
+ const errorText = (0, vue.ref)("");
292
298
  async function save() {
293
299
  if (!isDirty.value || saving.value) return;
294
300
  saving.value = true;
301
+ errorText.value = "";
302
+ const failedLabels = /* @__PURE__ */ new Map();
303
+ const failedPublicIds = /* @__PURE__ */ new Set();
304
+ const failedDeleteIds = /* @__PURE__ */ new Set();
305
+ const failures = [];
295
306
  try {
296
307
  await state.preset.batch(async () => {
297
308
  const deleted = pendingDeleteIds.value;
@@ -304,17 +315,28 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
304
315
  if (state.preset.isOwned(id)) continue;
305
316
  cleaned.push(id);
306
317
  }
307
- await state.preset.setFavorites(cleaned);
318
+ try {
319
+ await state.preset.setFavorites(cleaned);
320
+ } catch (err) {
321
+ failures.push(require_error_message.errorMessage(err, "The change could not be saved."));
322
+ }
308
323
  }
309
324
  if (pendingDefaultId.value !== serverDefaultId.value) {
310
325
  const next = pendingDefaultId.value && deleted.has(pendingDefaultId.value) ? null : pendingDefaultId.value;
311
- if (next !== serverDefaultId.value) await state.preset.setDefault(next);
326
+ if (next !== serverDefaultId.value) try {
327
+ await state.preset.setDefault(next);
328
+ } catch (err) {
329
+ failures.push(require_error_message.errorMessage(err, "The change could not be saved."));
330
+ }
312
331
  }
313
332
  if (pendingLabels.value.size > 0) for (const [id, label] of pendingLabels.value) {
314
333
  if (deleted.has(id)) continue;
315
334
  try {
316
335
  await state.preset.rename(id, label);
317
- } catch (_err) {}
336
+ } catch (err) {
337
+ failedLabels.set(id, label);
338
+ failures.push(require_error_message.errorMessage(err, "The change could not be saved."));
339
+ }
318
340
  }
319
341
  if (!(0, _atscript_ui_table.setsEqual)(pendingPublicIds.value, serverPublicIds.value)) {
320
342
  const flips = [];
@@ -328,12 +350,35 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
328
350
  }
329
351
  for (const id of flips) try {
330
352
  await state.preset.togglePublic(id);
331
- } catch (_err) {}
353
+ } catch (err) {
354
+ failedPublicIds.add(id);
355
+ failures.push(require_error_message.errorMessage(err, "The change could not be saved."));
356
+ }
332
357
  }
333
358
  if (deleted.size > 0) for (const id of deleted) try {
334
359
  await state.preset.remove(id);
335
- } catch (_err) {}
360
+ } catch (err) {
361
+ failedDeleteIds.add(id);
362
+ failures.push(require_error_message.errorMessage(err, "The change could not be saved."));
363
+ }
336
364
  });
365
+ if (failures.length > 0) {
366
+ syncPendingFromServer();
367
+ if (failedLabels.size > 0) {
368
+ const labels = new Map(pendingLabels.value);
369
+ for (const [id, label] of failedLabels) labels.set(id, label);
370
+ pendingLabels.value = labels;
371
+ }
372
+ if (failedPublicIds.size > 0) {
373
+ const publics = new Set(pendingPublicIds.value);
374
+ for (const id of failedPublicIds) if (publics.has(id)) publics.delete(id);
375
+ else publics.add(id);
376
+ pendingPublicIds.value = publics;
377
+ }
378
+ if (failedDeleteIds.size > 0) pendingDeleteIds.value = new Set([...pendingDeleteIds.value, ...failedDeleteIds]);
379
+ errorText.value = failures.length === 1 ? failures[0] : `${failures.length} changes could not be saved.`;
380
+ return;
381
+ }
337
382
  if (pendingActiveId.value !== null && pendingActiveId.value !== state.preset.activeId.value && !pendingDeleteIds.value.has(pendingActiveId.value)) state.preset.apply(pendingActiveId.value);
338
383
  state.preset.dialogOpen.value = false;
339
384
  } finally {
@@ -342,6 +387,7 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
342
387
  }
343
388
  function discardOrClose() {
344
389
  syncPendingFromServer();
390
+ errorText.value = "";
345
391
  state.preset.dialogOpen.value = false;
346
392
  }
347
393
  function rowFavTitle(row) {
@@ -385,20 +431,24 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
385
431
  default: (0, vue.withCtx)(() => [..._cache[5] || (_cache[5] = [(0, vue.createTextVNode)("Presets", -1)])]),
386
432
  _: 1
387
433
  }),
434
+ (0, vue.createVNode)((0, vue.unref)(reka_ui.DialogDescription), { class: "sr-only" }, {
435
+ default: (0, vue.withCtx)(() => [..._cache[6] || (_cache[6] = [(0, vue.createTextVNode)(" Rename, share, favorite, pin as default or delete your saved table views. ", -1)])]),
436
+ _: 1
437
+ }),
388
438
  (0, vue.createElementVNode)("span", _hoisted_2, (0, vue.toDisplayString)(counterText.value), 1),
389
439
  (0, vue.createVNode)((0, vue.unref)(reka_ui.DialogClose), {
390
440
  class: "as-preset-dialog-close",
391
441
  "aria-label": "Close",
392
442
  onClick: (0, vue.withModifiers)(discardOrClose, ["prevent"])
393
443
  }, {
394
- default: (0, vue.withCtx)(() => [..._cache[6] || (_cache[6] = [(0, vue.createElementVNode)("span", {
444
+ default: (0, vue.withCtx)(() => [..._cache[7] || (_cache[7] = [(0, vue.createElementVNode)("span", {
395
445
  class: "i-as-close",
396
446
  "aria-hidden": "true"
397
447
  }, null, -1)])]),
398
448
  _: 1
399
449
  })
400
450
  ]),
401
- (0, vue.createElementVNode)("div", _hoisted_3, [(0, vue.createElementVNode)("div", _hoisted_4, [_cache[7] || (_cache[7] = (0, vue.createElementVNode)("span", {
451
+ (0, vue.createElementVNode)("div", _hoisted_3, [(0, vue.createElementVNode)("div", _hoisted_4, [_cache[8] || (_cache[8] = (0, vue.createElementVNode)("span", {
402
452
  class: "i-as-search as-preset-dialog-search-icon",
403
453
  "aria-hidden": "true"
404
454
  }, null, -1)), (0, vue.withDirectives)((0, vue.createElementVNode)("input", {
@@ -408,7 +458,7 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
408
458
  type: "search",
409
459
  class: "as-preset-dialog-search-input",
410
460
  placeholder: "Search by name or owner…"
411
- }, null, 512), [[vue.vModelText, searchQuery.value]])]), _cache[8] || (_cache[8] = (0, vue.createElementVNode)("div", { class: "as-preset-dialog-legend" }, [
461
+ }, null, 512), [[vue.vModelText, searchQuery.value]])]), _cache[9] || (_cache[9] = (0, vue.createElementVNode)("div", { class: "as-preset-dialog-legend" }, [
412
462
  (0, vue.createElementVNode)("span", { class: "as-preset-dialog-legend-item" }, [(0, vue.createElementVNode)("span", {
413
463
  class: "i-as-pin as-preset-dialog-legend-icon",
414
464
  "aria-hidden": "true"
@@ -496,9 +546,9 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
496
546
  key: a,
497
547
  class: "as-preset-dialog-aspect-chip",
498
548
  "data-on": row.aspects.includes(a) ? "" : void 0,
499
- title: (0, vue.unref)(require_preset_aspect_display.ASPECT_LABELS)[a]
549
+ title: (0, vue.unref)(require_use_table_state.ASPECT_LABELS)[a]
500
550
  }, [(0, vue.createElementVNode)("span", {
501
- class: (0, vue.normalizeClass)((0, vue.unref)(require_preset_aspect_display.ASPECT_ICONS)[a]),
551
+ class: (0, vue.normalizeClass)((0, vue.unref)(require_use_table_state.ASPECT_ICONS)[a]),
502
552
  "aria-hidden": "true"
503
553
  }, null, 2)], 8, _hoisted_20);
504
554
  }), 128))]),
@@ -517,7 +567,7 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
517
567
  key: 3,
518
568
  class: "as-preset-dialog-row-public-indicator",
519
569
  title: rowPublicTitle(row)
520
- }, [..._cache[9] || (_cache[9] = [(0, vue.createElementVNode)("span", {
570
+ }, [..._cache[10] || (_cache[10] = [(0, vue.createElementVNode)("span", {
521
571
  class: "i-as-eye",
522
572
  "aria-hidden": "true"
523
573
  }, null, -1)])], 8, _hoisted_22)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_23)),
@@ -529,17 +579,17 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
529
579
  "aria-pressed": pendingDeleteIds.value.has(row.id),
530
580
  title: pendingDeleteIds.value.has(row.id) ? "Marked for deletion — click to undo" : "Mark for deletion (applied on Save)",
531
581
  onClick: ($event) => toggleDeletePending(row.id)
532
- }, [..._cache[10] || (_cache[10] = [(0, vue.createElementVNode)("span", {
582
+ }, [..._cache[11] || (_cache[11] = [(0, vue.createElementVNode)("span", {
533
583
  class: "i-as-trash",
534
584
  "aria-hidden": "true"
535
585
  }, null, -1)])], 8, _hoisted_24)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_25))
536
586
  ], 8, _hoisted_8);
537
587
  }), 128))], 64);
538
588
  }), 128))]),
539
- (0, vue.createElementVNode)("footer", _hoisted_26, [(0, vue.createElementVNode)("div", _hoisted_27, [isDirty.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_28, [..._cache[11] || (_cache[11] = [(0, vue.createElementVNode)("span", {
589
+ (0, vue.createElementVNode)("footer", _hoisted_26, [(0, vue.createElementVNode)("div", _hoisted_27, [errorText.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_28, (0, vue.toDisplayString)(errorText.value), 1)) : isDirty.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_29, [..._cache[12] || (_cache[12] = [(0, vue.createElementVNode)("span", {
540
590
  class: "as-preset-dialog-footer-unsaved-dot",
541
591
  "aria-hidden": "true"
542
- }, null, -1), (0, vue.createTextVNode)(" unsaved changes ", -1)])])) : (0, vue.createCommentVNode)("v-if", true)]), (0, vue.createElementVNode)("div", _hoisted_29, [(0, vue.createElementVNode)("button", {
592
+ }, null, -1), (0, vue.createTextVNode)(" unsaved changes ", -1)])])) : (0, vue.createCommentVNode)("v-if", true)]), (0, vue.createElementVNode)("div", _hoisted_30, [(0, vue.createElementVNode)("button", {
543
593
  type: "button",
544
594
  class: "as-preset-dialog-footer-close",
545
595
  onClick: discardOrClose
@@ -548,7 +598,7 @@ var as_preset_dialog_default = /* @__PURE__ */ (0, vue.defineComponent)({
548
598
  class: "as-preset-dialog-footer-save",
549
599
  disabled: !isDirty.value || saving.value,
550
600
  onClick: save
551
- }, (0, vue.toDisplayString)(saving.value ? "Saving…" : "Save"), 9, _hoisted_30)])])
601
+ }, (0, vue.toDisplayString)(saving.value ? "Saving…" : "Save"), 9, _hoisted_31)])])
552
602
  ]),
553
603
  _: 1
554
604
  })]),
@@ -1,2 +1,2 @@
1
- const require_as_preset_dialog = require("./as-preset-dialog-DpM06jqR.cjs");
1
+ const require_as_preset_dialog = require("./as-preset-dialog-D2a6nxEX.cjs");
2
2
  module.exports = require_as_preset_dialog.as_preset_dialog_default;
@@ -1,2 +1,2 @@
1
- import { t as as_preset_dialog_default } from "./as-preset-dialog-CDqCAR7N.mjs";
1
+ import { t as as_preset_dialog_default } from "./as-preset-dialog-BwHV6Y77.mjs";
2
2
  export { as_preset_dialog_default as default };
@@ -1,6 +1,6 @@
1
- import { a as useTableContext } from "./use-table-state-BxX3SpeW.mjs";
2
- import { a as readPresetLabel, i as ownerNameOf, n as ASPECT_LABELS, r as aspectsOf, t as ASPECT_ICONS } from "./preset-aspect-display-IICxAlVo.mjs";
3
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, onScopeDispose, openBlock, ref, renderList, toDisplayString, unref, vModelCheckbox, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
1
+ import { a as useTableContext, c as ASPECT_ICONS, d as readPresetLabel, l as ASPECT_LABELS, u as ownerNameOf } from "./use-table-state-mBXx11aH.mjs";
2
+ import { t as errorMessage } from "./error-message-gNEXnnbb.mjs";
3
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, h, nextTick, normalizeClass, onScopeDispose, openBlock, ref, renderList, shallowRef, toDisplayString, unref, vModelCheckbox, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
4
4
  import { isSystemPresetId } from "@atscript/ui-table";
5
5
  import { DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuRoot, DropdownMenuSeparator, DropdownMenuTrigger } from "reka-ui";
6
6
  //#region src/components/as-preset-picker.vue?vue&type=script&setup=true&lang.ts
@@ -80,6 +80,27 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
80
80
  document.addEventListener("focusin", stickFocus, true);
81
81
  });
82
82
  const aspects = computed(() => state.preset.availableAspects);
83
+ const dismissed = shallowRef(null);
84
+ function clearError() {
85
+ dismissed.value = state.preset.lastError.value;
86
+ }
87
+ const errorText = computed(() => {
88
+ const err = state.preset.lastError.value;
89
+ if (!err || err === dismissed.value) return "";
90
+ return errorMessage(err, "Could not save the preset.");
91
+ });
92
+ /**
93
+ * The one error block. The menu and the Save-as popover are mutually
94
+ * exclusive branches, so it renders through a local function instead of
95
+ * being duplicated in both templates.
96
+ */
97
+ function ErrorNote() {
98
+ if (!errorText.value) return null;
99
+ return h("div", {
100
+ class: "as-preset-picker-error",
101
+ role: "alert"
102
+ }, errorText.value);
103
+ }
83
104
  function resetSaveAsForm() {
84
105
  const base = activePresetLabel.value;
85
106
  saveAsLabel.value = base ? `Copy of ${base}` : "";
@@ -89,23 +110,20 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
89
110
  for (const a of aspects.value) initial[a] = claimed.has(a);
90
111
  saveAsAspectsMask.value = initial;
91
112
  }
92
- const activePresetClaimedAspects = computed(() => {
93
- const id = state.preset.activeId.value;
94
- if (!id || isSystemPresetId(id)) return new Set(aspects.value);
95
- const row = state.preset.presetsById.value.get(id);
96
- if (!row) return new Set(aspects.value);
97
- return new Set(aspectsOf(row, aspects.value));
98
- });
113
+ const activePresetClaimedAspects = computed(() => new Set(state.preset.ownedAspects(state.preset.activeId.value)));
99
114
  function openSaveAs() {
100
115
  resetSaveAsForm();
116
+ clearError();
101
117
  saveAsOpen.value = true;
102
118
  }
103
119
  function cancelSaveAs() {
120
+ clearError();
104
121
  saveAsOpen.value = false;
105
122
  }
106
123
  async function commitSaveAs() {
107
124
  const label = saveAsLabel.value.trim();
108
125
  if (!label) return;
126
+ clearError();
109
127
  try {
110
128
  await state.preset.saveAs(label, {
111
129
  aspects: saveAsAspectsMask.value,
@@ -113,7 +131,7 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
113
131
  });
114
132
  saveAsOpen.value = false;
115
133
  open.value = false;
116
- } catch (_err) {}
134
+ } catch {}
117
135
  }
118
136
  function authorMeta(row) {
119
137
  const name = ownerNameOf(row);
@@ -125,7 +143,7 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
125
143
  label: p.label,
126
144
  system: true,
127
145
  fav,
128
- aspects: [...state.preset.availableAspects]
146
+ aspects: state.preset.ownedAspects(p.id)
129
147
  };
130
148
  }
131
149
  function storedItem(row, fav, meta) {
@@ -134,7 +152,7 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
134
152
  label: readPresetLabel(row),
135
153
  fav,
136
154
  meta,
137
- aspects: aspectsOf(row, state.preset.availableAspects)
155
+ aspects: state.preset.ownedAspects(row.id)
138
156
  };
139
157
  }
140
158
  const favIds = computed(() => {
@@ -190,10 +208,11 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
190
208
  open.value = false;
191
209
  }
192
210
  async function saveActive() {
211
+ clearError();
193
212
  try {
194
213
  await state.preset.saveActive();
195
214
  open.value = false;
196
- } catch (_err) {}
215
+ } catch {}
197
216
  }
198
217
  function resetActive() {
199
218
  state.preset.resetActive();
@@ -227,7 +246,10 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
227
246
  }
228
247
  watch(open, (isOpen) => {
229
248
  if (isOpen) window.addEventListener("keydown", onMenuKeydown);
230
- else window.removeEventListener("keydown", onMenuKeydown);
249
+ else {
250
+ window.removeEventListener("keydown", onMenuKeydown);
251
+ clearError();
252
+ }
231
253
  });
232
254
  onScopeDispose(() => window.removeEventListener("keydown", onMenuKeydown));
233
255
  return (_ctx, _cache) => {
@@ -291,6 +313,7 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
291
313
  }), 128)),
292
314
  createCommentVNode(" Action row "),
293
315
  createVNode(unref(DropdownMenuSeparator), { class: "as-preset-picker-separator" }),
316
+ createVNode(ErrorNote),
294
317
  unref(state).preset.isDirty.value && unref(state).preset.canSaveActive.value ? (openBlock(), createBlock(unref(DropdownMenuItem), {
295
318
  key: 0,
296
319
  class: "as-preset-picker-action as-preset-picker-action-primary",
@@ -403,6 +426,7 @@ var as_preset_picker_default = /* @__PURE__ */ defineComponent({
403
426
  }, null, -1)),
404
427
  _cache[14] || (_cache[14] = createTextVNode(" Make public ", -1))
405
428
  ])], 64)) : createCommentVNode("v-if", true),
429
+ createVNode(ErrorNote),
406
430
  createElementVNode("div", _hoisted_15, [createElementVNode("button", {
407
431
  type: "button",
408
432
  class: "as-preset-picker-popover-cancel",