@leverege/imaginarium-ui 1.2.2 → 1.3.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.
Files changed (110) hide show
  1. package/lib/ImaginariumApp-D7jCl_VH.js +514 -0
  2. package/lib/ImaginariumApp-D7jCl_VH.js.map +1 -0
  3. package/lib/ImaginariumApp-DeLr4nad.cjs +2 -0
  4. package/lib/ImaginariumApp-DeLr4nad.cjs.map +1 -0
  5. package/lib/MarkdownPageDoc-BZF02iL5.cjs +2 -0
  6. package/lib/MarkdownPageDoc-BZF02iL5.cjs.map +1 -0
  7. package/lib/MarkdownPageDoc-DR1FmNpF.js +157 -0
  8. package/lib/MarkdownPageDoc-DR1FmNpF.js.map +1 -0
  9. package/lib/{PluginSetup-NL8jYfpN.js → PluginSetup-CTRJO5hU.js} +164 -118
  10. package/lib/PluginSetup-CTRJO5hU.js.map +1 -0
  11. package/lib/PluginSetup-CuLezaDw.cjs +45 -0
  12. package/lib/PluginSetup-CuLezaDw.cjs.map +1 -0
  13. package/lib/{PluginSetup-Co-WnS3V.js → PluginSetup-DNKri9P1.js} +2 -2
  14. package/lib/{PluginSetup-Co-WnS3V.js.map → PluginSetup-DNKri9P1.js.map} +1 -1
  15. package/lib/{PluginSetup-BQk4FFh9.js → PluginSetup-DaNNHmql.js} +782 -671
  16. package/lib/PluginSetup-DaNNHmql.js.map +1 -0
  17. package/lib/{PluginSetup-CQPpS_Js.cjs → PluginSetup-De9E1hRC.cjs} +2 -2
  18. package/lib/{PluginSetup-CQPpS_Js.cjs.map → PluginSetup-De9E1hRC.cjs.map} +1 -1
  19. package/lib/PluginSetup-o9elzgOQ.cjs +112 -0
  20. package/lib/PluginSetup-o9elzgOQ.cjs.map +1 -0
  21. package/lib/PluginTypes-BmYA5_B9.cjs +2 -0
  22. package/lib/PluginTypes-BmYA5_B9.cjs.map +1 -0
  23. package/lib/PluginTypes-mZ4TjxPV.js +9 -0
  24. package/lib/PluginTypes-mZ4TjxPV.js.map +1 -0
  25. package/lib/docs/DocsPanel.d.ts +15 -0
  26. package/lib/docs/DocsPanel.d.ts.map +1 -0
  27. package/lib/docs/MarkdownPageDoc.d.ts +8 -0
  28. package/lib/docs/MarkdownPageDoc.d.ts.map +1 -0
  29. package/lib/docs/PageDoc.d.ts +9 -0
  30. package/lib/docs/PageDoc.d.ts.map +1 -0
  31. package/lib/docs/PageDocsContext.d.ts +12 -0
  32. package/lib/docs/PageDocsContext.d.ts.map +1 -0
  33. package/lib/docs/index.d.ts +5 -0
  34. package/lib/docs/index.d.ts.map +1 -0
  35. package/lib/docs/mdComponents.d.ts +21 -0
  36. package/lib/docs/mdComponents.d.ts.map +1 -0
  37. package/lib/imp/release/ImpPageDoc.d.ts +3 -0
  38. package/lib/imp/release/ImpPageDoc.d.ts.map +1 -0
  39. package/lib/imp/release/PluginSetup.d.ts.map +1 -1
  40. package/lib/index.cjs +1 -1
  41. package/lib/index.cjs.map +1 -1
  42. package/lib/index.d.ts +4 -1
  43. package/lib/index.d.ts.map +1 -1
  44. package/lib/index.js +75 -72
  45. package/lib/mdComponents-BiOJ7Epf.cjs +16 -0
  46. package/lib/mdComponents-BiOJ7Epf.cjs.map +1 -0
  47. package/lib/mdComponents-kPa8Rxqz.js +6792 -0
  48. package/lib/mdComponents-kPa8Rxqz.js.map +1 -0
  49. package/lib/plugins/PluginTypes.d.ts +1 -0
  50. package/lib/plugins/PluginTypes.d.ts.map +1 -1
  51. package/lib/plugins/registry.d.ts +3 -1
  52. package/lib/plugins/registry.d.ts.map +1 -1
  53. package/lib/plugins/types.d.ts +5 -0
  54. package/lib/plugins/types.d.ts.map +1 -1
  55. package/lib/plugins.cjs +1 -1
  56. package/lib/plugins.js +2 -2
  57. package/lib/registry-Bq42i86Q.cjs +2 -0
  58. package/lib/registry-Bq42i86Q.cjs.map +1 -0
  59. package/lib/registry-CMZCG8pH.js +44 -0
  60. package/lib/registry-CMZCG8pH.js.map +1 -0
  61. package/lib/release.cjs +1 -1
  62. package/lib/release.js +1 -1
  63. package/lib/secret.cjs +1 -1
  64. package/lib/secret.js +1 -1
  65. package/lib/shell/Shell.d.ts.map +1 -1
  66. package/lib/shell.cjs +1 -1
  67. package/lib/shell.js +1 -1
  68. package/lib/system/PluginSetup.d.ts.map +1 -1
  69. package/lib/system/SystemPageDoc.d.ts +3 -0
  70. package/lib/system/SystemPageDoc.d.ts.map +1 -0
  71. package/lib/system.cjs +1 -1
  72. package/lib/system.js +2 -2
  73. package/package.json +3 -2
  74. package/src/docs/DocsPanel.tsx +80 -0
  75. package/src/docs/MarkdownPageDoc.tsx +35 -0
  76. package/src/docs/PageDoc.ts +12 -0
  77. package/src/docs/PageDocsContext.tsx +37 -0
  78. package/src/docs/index.ts +4 -0
  79. package/src/docs/mdComponents.tsx +75 -0
  80. package/src/imp/release/ImpPageDoc.ts +113 -0
  81. package/src/imp/release/PluginSetup.ts +3 -0
  82. package/src/index.ts +4 -0
  83. package/src/plugins/PluginTypes.ts +1 -0
  84. package/src/plugins/registry.ts +13 -2
  85. package/src/plugins/types.ts +6 -0
  86. package/src/shell/Shell.tsx +48 -14
  87. package/src/system/PluginSetup.ts +4 -0
  88. package/src/system/SystemPageDoc.ts +49 -0
  89. package/lib/ImaginariumApp-Bp1toCAd.js +0 -437
  90. package/lib/ImaginariumApp-Bp1toCAd.js.map +0 -1
  91. package/lib/ImaginariumApp-DpQNMjG_.cjs +0 -2
  92. package/lib/ImaginariumApp-DpQNMjG_.cjs.map +0 -1
  93. package/lib/PluginSetup-3m6kjRze.cjs +0 -2
  94. package/lib/PluginSetup-3m6kjRze.cjs.map +0 -1
  95. package/lib/PluginSetup-BQk4FFh9.js.map +0 -1
  96. package/lib/PluginSetup-DoIf-dYR.cjs +0 -5
  97. package/lib/PluginSetup-DoIf-dYR.cjs.map +0 -1
  98. package/lib/PluginSetup-NL8jYfpN.js.map +0 -1
  99. package/lib/PluginTypes-C4a2lmPj.cjs +0 -2
  100. package/lib/PluginTypes-C4a2lmPj.cjs.map +0 -1
  101. package/lib/PluginTypes-DsLT43Y8.js +0 -8
  102. package/lib/PluginTypes-DsLT43Y8.js.map +0 -1
  103. package/lib/SystemConfigsContext-D0hXRSH-.js +0 -128
  104. package/lib/SystemConfigsContext-D0hXRSH-.js.map +0 -1
  105. package/lib/SystemConfigsContext-yOuS10VO.cjs +0 -2
  106. package/lib/SystemConfigsContext-yOuS10VO.cjs.map +0 -1
  107. package/lib/registry-8kQ494RA.js +0 -36
  108. package/lib/registry-8kQ494RA.js.map +0 -1
  109. package/lib/registry-CHzOVHAg.cjs +0 -2
  110. package/lib/registry-CHzOVHAg.cjs.map +0 -1
@@ -1,43 +1,154 @@
1
- import { P as Pt, N as Tt } from "./PluginTypes-DsLT43Y8.js";
2
- import { jsx as e, jsxs as n, Fragment as De } from "react/jsx-runtime";
1
+ import { P as Pt, N as St } from "./PluginTypes-mZ4TjxPV.js";
2
+ import { M as Kt, u as ge, P as $t } from "./MarkdownPageDoc-DR1FmNpF.js";
3
+ import { jsx as e, jsxs as n, Fragment as Me } from "react/jsx-runtime";
3
4
  import { useState as A, useMemo as J, useEffect as je, Fragment as ct } from "react";
4
- import { u as le, a as ne, B as E, C as we, f as Se, c as ce } from "./Card-D2LdIJwJ.js";
5
- import { u as fe } from "./SystemConfigsContext-D0hXRSH-.js";
6
- import { useQueryClient as oe, useMutation as Q, useQuery as ae } from "@tanstack/react-query";
7
- import { X as xe, Loader2 as mt, Save as ut, Plus as Me, Ban as Fe, RotateCcw as Kt, AlertTriangle as ge, Check as ht, ChevronDown as Pe, ChevronRight as Te, Send as $t, Circle as Et, ArrowLeft as We, RefreshCw as pt, BarChart2 as Ot, Pencil as It, Trash2 as gt, Bot as At } from "lucide-react";
5
+ import { u as le, a as ne, B as E, C as Ce, f as Te, c as ce } from "./Card-D2LdIJwJ.js";
6
+ import { useQueryClient as oe, useMutation as L, useQuery as re } from "@tanstack/react-query";
7
+ import { X as xe, Loader2 as ut, Save as mt, Plus as De, Ban as Fe, RotateCcw as Et, AlertTriangle as fe, Check as ht, ChevronDown as Pe, ChevronRight as Se, Send as It, Circle as Ot, ArrowLeft as We, RefreshCw as pt, BarChart2 as At, Pencil as Rt, Trash2 as ft, Bot as Mt } from "lucide-react";
8
8
  import { Config as ze } from "@leverege/plugin";
9
- import { D as $e, a as Ee, b as Oe, c as Ie, d as Ae, L as ie, I as he, e as Re } from "./Label-v0wUXs4O.js";
10
- import { b as Rt, T as Dt, c as Mt, a as Ft } from "./Tooltip-CIwKmgzA.js";
11
- function qt({ open: t, onOpenChange: s, onCreated: r }) {
12
- const a = ze.get("Release", "apiPath", "/releases"), { toast: d } = le(), { fetchJson: m } = ne(), l = oe(), { configs: c } = fe(), [g, v] = A(""), [N, o] = A(""), [h, O] = A(""), [M, j] = A([]), H = ["imaginarium", "releases", a], U = () => {
13
- v(""), o(""), O(""), j([]);
9
+ import { D as $e, a as Ee, b as Ie, c as Oe, d as Ae, L as ae, I as he, e as Re } from "./Label-v0wUXs4O.js";
10
+ import { b as Dt, T as Ft, c as qt, a as jt } from "./Tooltip-CIwKmgzA.js";
11
+ const zt = Kt.create({
12
+ path: "/imp",
13
+ markdown: `# imp
14
+
15
+ Manage cross-cluster releases for your Imagine project. A release captures a snapshot of entities from an origin cluster and lets you review diffs and push to one or more destination clusters.
16
+
17
+ ---
18
+
19
+ ## Releases tab
20
+
21
+ ### Creating a release
22
+
23
+ A release snapshots all entities (blueprints, rules, scripts, attributes, enums, roles, etc.) from an origin cluster at a point in time and tracks what differs from one or more destination clusters.
24
+
25
+ ### Reading the diff
26
+
27
+ Each row is one entity. The status column tells you what changed:
28
+
29
+ - new: exists on origin, not on any destination
30
+ - updated: exists on both but differs
31
+ - removed: exists on destination(s) but no longer on origin
32
+ - skip: automatically excluded (e.g. a rule with no published version, or all versions already exist on the destination)
33
+
34
+ Selecting a row opens the diff panel on the right, which shows a side-by-side JSON diff for updated items.
35
+
36
+ ### Including / excluding items
37
+
38
+ The toggle at the left of each row controls whether that item is included in the push. The type chips and Enabled / Disabled filter help narrow down what you're looking at.
39
+
40
+ Items with children (e.g. a blueprint with changed attributes) show a child count chip. Expanding the row lets you include or exclude individual child changes. The top-level toggle only controls the parent entity's own changes (tags, metadata, etc.) and does not automatically include or exclude its children.
41
+
42
+ ### Previously skipped
43
+
44
+ Items that were excluded in the most recent previous release are automatically carried over as excluded in the next one and marked "previously skipped." This prevents accidentally re-including something you intentionally left out last time. Manually toggling the item clears the badge and the carry-over behavior.
45
+
46
+ ### Refreshing a snapshot
47
+
48
+ Refresh re-snapshots the origin against the current state of the destinations. New items appear, removed items drop out, and diffs update. Manual overrides (excluded tags, metadata keys, etc.) are preserved across refreshes.
49
+
50
+ ### Pushing
51
+
52
+ Pushing sends all included items to the selected destination clusters. The release becomes read-only after a push. Each row surfaces its result as a success or failure chip. Hover a chip for error detail if something failed.
53
+
54
+ ---
55
+
56
+ ## Manual overrides (diff panel)
57
+
58
+ When you click a row, the diff panel shows per-field overrides for that item. These let you include an item but exclude specific sub-fields from the push.
59
+
60
+ ### Tags
61
+
62
+ Uncheck a tag to exclude it. The destination will keep its existing value for that tag and the origin's other tags will still be pushed.
63
+
64
+ ### Metadata keys
65
+
66
+ Each key in the entity's \`metadata\` object can be individually excluded. Useful when one cluster carries environment-specific metadata (e.g. an API base URL or a feature flag) that should not be overwritten.
67
+
68
+ ### i18n paths
69
+
70
+ Individual translation paths can be excluded so the destination keeps its own localized strings for specific fields while receiving the rest of the entity update.
71
+
72
+ ### Permissions (roles)
73
+
74
+ For role entities, individual permission entries (module/action pairs) can be excluded. Useful when destination clusters have different access policies for specific modules.
75
+
76
+ ---
77
+
78
+ ## Ignoring items permanently
79
+
80
+ The ⊘ button on a release row permanently ignores that item for the origin cluster. Ignored items are excluded from this and all future releases for that origin, show an "Ignored" pill in the release list, and are not pushed even if their toggle is on.
81
+
82
+ The ⊘ button on a release row creates an ignore rule for that item, which excludes it immediately and refreshes the snapshot.
83
+
84
+ To remove an ignore, delete it from the Ignored tab. The item will reappear in any release draft the next time you refresh the snapshot.
85
+
86
+ ---
87
+
88
+ ## Status tab
89
+
90
+ Shows a matrix of every entity in the origin cluster vs. every destination cluster. Cell states:
91
+
92
+ - match: origin and destination are identical
93
+ - diff: values differ
94
+ - translated: differs but a translation rule accounts for the difference (counts as match)
95
+ - missing: exists on origin, not on destination
96
+ - extra: exists on destination, not on origin
97
+ - skip: excluded from comparison
98
+
99
+ The Reference dropdown controls which cluster is treated as the source of truth.
100
+
101
+ ---
102
+
103
+ ## Translations tab
104
+
105
+ Translation rules let you declare that two different values across clusters are intentionally equivalent. The Status matrix shows those cells as translated instead of diff.
106
+
107
+ A common use case: an API base URL that differs between dev and prod clusters. Without a translation rule, every blueprint referencing that URL shows as diff. With a rule mapping \`https://api.dev.example.com\` → \`https://api.prod.example.com\`, the diff is suppressed in the matrix.
108
+
109
+ Each rule has a name and a value per cluster. Leaving a cluster's field blank skips it for that pairing.
110
+
111
+ Translation rules affect both the Status matrix and releases. In the matrix they suppress diffs that are explained by a translation rule, showing the cell as translated instead of diff. In releases the substitutions are applied during push, so destination clusters receive the remapped values rather than the origin values verbatim.
112
+
113
+ ---
114
+
115
+ ## Ignored tab
116
+
117
+ Lists all permanently-ignored items for the selected origin cluster. Removing a single item (trash icon) makes it reappear in future release snapshots. Clear all removes every ignore rule for that cluster at once.
118
+
119
+ After removing an ignore, refreshing an existing release draft will bring the item back.
120
+ `
121
+ });
122
+ function Bt({ open: t, onOpenChange: s, onCreated: i }) {
123
+ const r = ze.get("Release", "apiPath", "/releases"), { toast: d } = le(), { fetchJson: u } = ne(), l = oe(), { configs: c } = ge(), [f, v] = A(""), [N, o] = A(""), [h, I] = A(""), [D, j] = A([]), U = ["imaginarium", "releases", r], H = () => {
124
+ v(""), o(""), I(""), j([]);
14
125
  }, z = J(
15
126
  () => c.filter((x) => x.id !== h),
16
127
  [c, h]
17
- ), D = (x) => {
18
- O(x), j((K) => K.filter((p) => p !== x));
128
+ ), M = (x) => {
129
+ I(x), j((K) => K.filter((p) => p !== x));
19
130
  }, B = (x) => {
20
131
  j(
21
132
  (K) => K.includes(x) ? K.filter((p) => p !== x) : [...K, x]
22
133
  );
23
- }, f = Q({
134
+ }, g = L({
24
135
  mutationFn: async () => {
25
- const x = await m(a, {
136
+ const x = await u(r, {
26
137
  method: "POST",
27
138
  body: JSON.stringify({
28
- name: g.trim(),
139
+ name: f.trim(),
29
140
  description: N.trim() || null,
30
141
  originConfigId: h,
31
- targetConfigIds: M
142
+ targetConfigIds: D
32
143
  })
33
144
  });
34
- return await m(`${a}/${x.id}/snapshot-from-compare`, {
145
+ return await u(`${r}/${x.id}/snapshot-from-compare`, {
35
146
  method: "POST",
36
147
  body: JSON.stringify({})
37
148
  }), x;
38
149
  },
39
150
  onSuccess: (x) => {
40
- l.invalidateQueries({ queryKey: H }), d({ title: "Success", description: "Release created and snapshotted" }), s(!1), U(), r(x.id);
151
+ l.invalidateQueries({ queryKey: U }), d({ title: "Success", description: "Release created and snapshotted" }), s(!1), H(), i(x.id);
41
152
  },
42
153
  onError: (x) => {
43
154
  d({ title: "Error", description: x.message, variant: "destructive" });
@@ -45,31 +156,31 @@ function qt({ open: t, onOpenChange: s, onCreated: r }) {
45
156
  // Refetch regardless of outcome: if create succeeds but snapshot fails, the
46
157
  // new release would otherwise be orphaned and missing from the list.
47
158
  onSettled: () => {
48
- l.invalidateQueries({ queryKey: H });
159
+ l.invalidateQueries({ queryKey: U });
49
160
  }
50
161
  }), k = (x) => {
51
- x || U(), s(x);
52
- }, w = !!(g.trim() && h && M.length > 0);
162
+ x || H(), s(x);
163
+ }, C = !!(f.trim() && h && D.length > 0);
53
164
  return /* @__PURE__ */ e($e, { open: t, onOpenChange: k, children: /* @__PURE__ */ n(Ee, { children: [
54
- /* @__PURE__ */ n(Oe, { children: [
55
- /* @__PURE__ */ e(Ie, { children: "New Release" }),
165
+ /* @__PURE__ */ n(Ie, { children: [
166
+ /* @__PURE__ */ e(Oe, { children: "New Release" }),
56
167
  /* @__PURE__ */ e(Ae, { children: "Create a release from an origin cluster and snapshot the diff against its targets." })
57
168
  ] }),
58
169
  /* @__PURE__ */ n("div", { className: "space-y-4 py-4", children: [
59
170
  /* @__PURE__ */ n("div", { className: "space-y-2", children: [
60
- /* @__PURE__ */ e(ie, { htmlFor: "release-name", children: "Name" }),
171
+ /* @__PURE__ */ e(ae, { htmlFor: "release-name", children: "Name" }),
61
172
  /* @__PURE__ */ e(
62
173
  he,
63
174
  {
64
175
  id: "release-name",
65
- value: g,
176
+ value: f,
66
177
  onChange: (x) => v(x.target.value),
67
178
  placeholder: "2026.05 Release"
68
179
  }
69
180
  )
70
181
  ] }),
71
182
  /* @__PURE__ */ n("div", { className: "space-y-2", children: [
72
- /* @__PURE__ */ e(ie, { htmlFor: "release-description", children: "Description (Optional)" }),
183
+ /* @__PURE__ */ e(ae, { htmlFor: "release-description", children: "Description (Optional)" }),
73
184
  /* @__PURE__ */ e(
74
185
  he,
75
186
  {
@@ -81,13 +192,13 @@ function qt({ open: t, onOpenChange: s, onCreated: r }) {
81
192
  )
82
193
  ] }),
83
194
  /* @__PURE__ */ n("div", { className: "space-y-2", children: [
84
- /* @__PURE__ */ e(ie, { htmlFor: "release-origin", children: "Origin Cluster" }),
195
+ /* @__PURE__ */ e(ae, { htmlFor: "release-origin", children: "Origin Cluster" }),
85
196
  /* @__PURE__ */ n(
86
197
  "select",
87
198
  {
88
199
  id: "release-origin",
89
200
  value: h,
90
- onChange: (x) => D(x.target.value),
201
+ onChange: (x) => M(x.target.value),
91
202
  className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
92
203
  children: [
93
204
  /* @__PURE__ */ e("option", { value: "", children: "Select origin…" }),
@@ -97,13 +208,13 @@ function qt({ open: t, onOpenChange: s, onCreated: r }) {
97
208
  )
98
209
  ] }),
99
210
  /* @__PURE__ */ n("div", { className: "space-y-2", children: [
100
- /* @__PURE__ */ e(ie, { children: "Target Clusters" }),
211
+ /* @__PURE__ */ e(ae, { children: "Target Clusters" }),
101
212
  z.length > 0 ? /* @__PURE__ */ e("div", { className: "space-y-1 rounded-md border border-input p-2 max-h-48 overflow-y-auto", children: z.map((x) => /* @__PURE__ */ n("label", { className: "flex items-center gap-2 text-sm cursor-pointer", children: [
102
213
  /* @__PURE__ */ e(
103
214
  "input",
104
215
  {
105
216
  type: "checkbox",
106
- checked: M.includes(x.id),
217
+ checked: D.includes(x.id),
107
218
  onChange: () => B(x.id)
108
219
  }
109
220
  ),
@@ -112,40 +223,40 @@ function qt({ open: t, onOpenChange: s, onCreated: r }) {
112
223
  ] })
113
224
  ] }),
114
225
  /* @__PURE__ */ n(Re, { children: [
115
- /* @__PURE__ */ n(E, { variant: "outline", onClick: () => k(!1), disabled: f.isPending, children: [
226
+ /* @__PURE__ */ n(E, { variant: "outline", onClick: () => k(!1), disabled: g.isPending, children: [
116
227
  /* @__PURE__ */ e(xe, { className: "w-4 h-4 mr-2" }),
117
228
  "Cancel"
118
229
  ] }),
119
- /* @__PURE__ */ e(E, { onClick: () => f.mutate(), disabled: !w || f.isPending, children: f.isPending ? /* @__PURE__ */ n(De, { children: [
120
- /* @__PURE__ */ e(mt, { className: "w-4 h-4 mr-2 animate-spin" }),
230
+ /* @__PURE__ */ e(E, { onClick: () => g.mutate(), disabled: !C || g.isPending, children: g.isPending ? /* @__PURE__ */ n(Me, { children: [
231
+ /* @__PURE__ */ e(ut, { className: "w-4 h-4 mr-2 animate-spin" }),
121
232
  "Snapshotting…"
122
- ] }) : /* @__PURE__ */ n(De, { children: [
123
- /* @__PURE__ */ e(ut, { className: "w-4 h-4 mr-2" }),
233
+ ] }) : /* @__PURE__ */ n(Me, { children: [
234
+ /* @__PURE__ */ e(mt, { className: "w-4 h-4 mr-2" }),
124
235
  "Create & snapshot"
125
236
  ] }) })
126
237
  ] })
127
238
  ] }) });
128
239
  }
129
- function ft({ status: t }) {
240
+ function gt({ status: t }) {
130
241
  return /* @__PURE__ */ e("span", { className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium border ${t === "pushed" ? "bg-emerald-500/15 text-emerald-700 dark:text-emerald-300 border-emerald-500/30" : "bg-muted text-muted-foreground border-border"}`, children: t });
131
242
  }
132
- function jt({ onOpen: t }) {
133
- const s = ze.get("Release", "apiPath", "/releases"), { fetchJson: r } = ne(), { configs: a } = fe(), [d, m] = A(!1), l = ["imaginarium", "releases", s], { data: c, isLoading: g } = ae({
243
+ function Jt({ onOpen: t }) {
244
+ const s = ze.get("Release", "apiPath", "/releases"), { fetchJson: i } = ne(), { configs: r } = ge(), [d, u] = A(!1), l = ["imaginarium", "releases", s], { data: c, isLoading: f } = re({
134
245
  queryKey: l,
135
246
  queryFn: async () => {
136
- const o = await r(s);
137
- return [...Array.isArray(o) ? o : (o == null ? void 0 : o.items) ?? []].sort((O, M) => (M.createdAt ?? "").localeCompare(O.createdAt ?? ""));
247
+ const o = await i(s);
248
+ return [...Array.isArray(o) ? o : (o == null ? void 0 : o.items) ?? []].sort((I, D) => (D.createdAt ?? "").localeCompare(I.createdAt ?? ""));
138
249
  }
139
250
  }), v = J(() => {
140
251
  const o = /* @__PURE__ */ new Map();
141
- return a.forEach((h) => o.set(String(h.id), h.displayName)), o;
142
- }, [a]), N = (o) => v.get(o) ?? o;
252
+ return r.forEach((h) => o.set(String(h.id), h.displayName)), o;
253
+ }, [r]), N = (o) => v.get(o) ?? o;
143
254
  return /* @__PURE__ */ n("div", { className: "space-y-4", children: [
144
- /* @__PURE__ */ e("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ n(E, { onClick: () => m(!0), children: [
145
- /* @__PURE__ */ e(Me, { className: "w-4 h-4 mr-2" }),
255
+ /* @__PURE__ */ e("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ n(E, { onClick: () => u(!0), children: [
256
+ /* @__PURE__ */ e(De, { className: "w-4 h-4 mr-2" }),
146
257
  "New Release"
147
258
  ] }) }),
148
- g ? /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground", children: "Loading…" }) : c && c.length > 0 ? /* @__PURE__ */ e(we, { children: /* @__PURE__ */ e(Se, { className: "p-0", children: /* @__PURE__ */ n("table", { className: "w-full text-sm", children: [
259
+ f ? /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground", children: "Loading…" }) : c && c.length > 0 ? /* @__PURE__ */ e(Ce, { children: /* @__PURE__ */ e(Te, { className: "p-0", children: /* @__PURE__ */ n("table", { className: "w-full text-sm", children: [
149
260
  /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ n("tr", { className: "border-b text-left text-muted-foreground", children: [
150
261
  /* @__PURE__ */ e("th", { className: "p-3 font-medium", children: "Name" }),
151
262
  /* @__PURE__ */ e("th", { className: "p-3 font-medium", children: "Origin" }),
@@ -174,7 +285,7 @@ function jt({ onOpen: t }) {
174
285
  },
175
286
  h
176
287
  )) }) }),
177
- /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(ft, { status: o.status }) }),
288
+ /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(gt, { status: o.status }) }),
178
289
  /* @__PURE__ */ e("td", { className: "p-3 text-muted-foreground", children: o.snapshotAt ? new Date(o.snapshotAt).toLocaleString() : "—" }),
179
290
  /* @__PURE__ */ e("td", { className: "p-3 text-muted-foreground", children: o.pushedAt ? new Date(o.pushedAt).toLocaleString() : "—" }),
180
291
  /* @__PURE__ */ e("td", { className: "p-3 text-right", children: /* @__PURE__ */ e(
@@ -192,30 +303,30 @@ function jt({ onOpen: t }) {
192
303
  },
193
304
  o.id
194
305
  )) })
195
- ] }) }) }) : /* @__PURE__ */ e(we, { children: /* @__PURE__ */ n(Se, { className: "py-12 text-center", children: [
306
+ ] }) }) }) : /* @__PURE__ */ e(Ce, { children: /* @__PURE__ */ n(Te, { className: "py-12 text-center", children: [
196
307
  /* @__PURE__ */ e("p", { className: "text-muted-foreground mb-4", children: "No releases yet" }),
197
- /* @__PURE__ */ n(E, { onClick: () => m(!0), children: [
198
- /* @__PURE__ */ e(Me, { className: "w-4 h-4 mr-2" }),
308
+ /* @__PURE__ */ n(E, { onClick: () => u(!0), children: [
309
+ /* @__PURE__ */ e(De, { className: "w-4 h-4 mr-2" }),
199
310
  "Create Your First Release"
200
311
  ] })
201
312
  ] }) }),
202
313
  /* @__PURE__ */ e(
203
- qt,
314
+ Bt,
204
315
  {
205
316
  open: d,
206
- onOpenChange: m,
317
+ onOpenChange: u,
207
318
  onCreated: t
208
319
  }
209
320
  )
210
321
  ] });
211
322
  }
212
- function zt({
323
+ function Lt({
213
324
  originName: t,
214
325
  className: s
215
326
  }) {
216
- const r = t ? `Skipped in your last release from ${t}.` : "Skipped in your last release.";
217
- return /* @__PURE__ */ e(Rt, { children: /* @__PURE__ */ n(Dt, { children: [
218
- /* @__PURE__ */ e(Mt, { asChild: !0, children: /* @__PURE__ */ e(
327
+ const i = t ? `Skipped in your last release from ${t}.` : "Skipped in your last release.";
328
+ return /* @__PURE__ */ e(Dt, { children: /* @__PURE__ */ n(Ft, { children: [
329
+ /* @__PURE__ */ e(qt, { asChild: !0, children: /* @__PURE__ */ e(
219
330
  "span",
220
331
  {
221
332
  className: ce(
@@ -226,10 +337,10 @@ function zt({
226
337
  children: "previously skipped"
227
338
  }
228
339
  ) }),
229
- /* @__PURE__ */ e(Ft, { side: "top", children: r })
340
+ /* @__PURE__ */ e(jt, { side: "top", children: i })
230
341
  ] }) });
231
342
  }
232
- function Bt({ className: t }) {
343
+ function Qt({ className: t }) {
233
344
  return /* @__PURE__ */ e(
234
345
  "span",
235
346
  {
@@ -242,51 +353,51 @@ function Bt({ className: t }) {
242
353
  }
243
354
  );
244
355
  }
245
- function Jt({
356
+ function Vt({
246
357
  ignoreRule: t,
247
358
  createPayload: s,
248
- apiPath: r = "/release-ignores",
249
- onChange: a,
359
+ apiPath: i = "/release-ignores",
360
+ onChange: r,
250
361
  className: d
251
362
  }) {
252
- const { toast: m } = le(), { fetchJson: l } = ne(), c = oe(), [g, v] = A(!1), N = !!t, o = () => {
253
- c.invalidateQueries({ queryKey: ["imaginarium", "release-ignores"] }), a == null || a();
254
- }, h = Q({
255
- mutationFn: () => l(r, {
363
+ const { toast: u } = le(), { fetchJson: l } = ne(), c = oe(), [f, v] = A(!1), N = !!t, o = () => {
364
+ c.invalidateQueries({ queryKey: ["imaginarium", "release-ignores"] }), r == null || r();
365
+ }, h = L({
366
+ mutationFn: () => l(i, {
256
367
  method: "POST",
257
368
  body: JSON.stringify(s)
258
369
  }),
259
370
  onSuccess: () => {
260
- m({ title: "Item ignored", description: "Will be excluded from all future snapshots." }), v(!1), o();
371
+ u({ title: "Item ignored", description: "Will be excluded from all future snapshots." }), v(!1), o();
261
372
  },
262
373
  onError: (j) => {
263
- m({ title: "Error", description: j.message, variant: "destructive" });
374
+ u({ title: "Error", description: j.message, variant: "destructive" });
264
375
  }
265
- }), O = Q({
266
- mutationFn: () => l(`${r}/${t.id}`, { method: "DELETE" }),
376
+ }), I = L({
377
+ mutationFn: () => l(`${i}/${t.id}`, { method: "DELETE" }),
267
378
  onSuccess: () => {
268
- m({ title: "Item un-ignored", description: "Will appear normally in future snapshots." }), o();
379
+ u({ title: "Item un-ignored", description: "Will appear normally in future snapshots." }), o();
269
380
  },
270
381
  onError: (j) => {
271
- m({ title: "Error", description: j.message, variant: "destructive" });
382
+ u({ title: "Error", description: j.message, variant: "destructive" });
272
383
  }
273
- }), M = h.isPending || O.isPending;
274
- return /* @__PURE__ */ n(De, { children: [
384
+ }), D = h.isPending || I.isPending;
385
+ return /* @__PURE__ */ n(Me, { children: [
275
386
  /* @__PURE__ */ e(
276
387
  E,
277
388
  {
278
389
  variant: "ghost",
279
390
  size: "icon",
280
391
  title: N ? "Remove from ignore list" : "Ignore this item",
281
- disabled: M,
282
- onClick: () => N ? O.mutate() : v(!0),
392
+ disabled: D,
393
+ onClick: () => N ? I.mutate() : v(!0),
283
394
  className: ce(N && "text-red-500 hover:text-red-500 dark:text-red-400 dark:hover:text-red-400", d),
284
395
  children: /* @__PURE__ */ e(Fe, {})
285
396
  }
286
397
  ),
287
- /* @__PURE__ */ e($e, { open: g, onOpenChange: v, children: /* @__PURE__ */ n(Ee, { children: [
288
- /* @__PURE__ */ n(Oe, { children: [
289
- /* @__PURE__ */ e(Ie, { children: "Ignore this item?" }),
398
+ /* @__PURE__ */ e($e, { open: f, onOpenChange: v, children: /* @__PURE__ */ n(Ee, { children: [
399
+ /* @__PURE__ */ n(Ie, { children: [
400
+ /* @__PURE__ */ e(Oe, { children: "Ignore this item?" }),
290
401
  /* @__PURE__ */ n(Ae, { children: [
291
402
  "Ignoring excludes this item from ",
292
403
  /* @__PURE__ */ e("strong", { children: "this and all future releases" }),
@@ -319,23 +430,23 @@ function Jt({
319
430
  ] }) })
320
431
  ] });
321
432
  }
322
- function Qt({
433
+ function Ut({
323
434
  releaseId: t,
324
435
  apiPath: s = "/releases",
325
- onReset: r
436
+ onReset: i
326
437
  }) {
327
- const { toast: a } = le(), { fetchJson: d } = ne(), m = oe(), l = Q({
438
+ const { toast: r } = le(), { fetchJson: d } = ne(), u = oe(), l = L({
328
439
  mutationFn: () => d(`${s}/${t}/reset-exclusions`, {
329
440
  method: "POST"
330
441
  }),
331
442
  onSuccess: (c) => {
332
- m.invalidateQueries({ queryKey: ["imaginarium", "release-items", t] }), a({
443
+ u.invalidateQueries({ queryKey: ["imaginarium", "release-items", t] }), r({
333
444
  title: "Exclusions reset",
334
445
  description: `${c.reset} item${c.reset === 1 ? "" : "s"} re-enabled.`
335
- }), r == null || r(c.reset);
446
+ }), i == null || i(c.reset);
336
447
  },
337
448
  onError: (c) => {
338
- a({ title: "Error", description: c.message, variant: "destructive" });
449
+ r({ title: "Error", description: c.message, variant: "destructive" });
339
450
  }
340
451
  });
341
452
  return /* @__PURE__ */ n(
@@ -346,23 +457,23 @@ function Qt({
346
457
  onClick: () => l.mutate(),
347
458
  disabled: l.isPending,
348
459
  children: [
349
- /* @__PURE__ */ e(Kt, {}),
460
+ /* @__PURE__ */ e(Et, {}),
350
461
  l.isPending ? "Resetting…" : "Reset exclusions"
351
462
  ]
352
463
  }
353
464
  );
354
465
  }
355
- function Ke({ label: t, value: s, highlightLines: r }) {
466
+ function Ke({ label: t, value: s, highlightLines: i }) {
356
467
  return /* @__PURE__ */ n("div", { className: "flex min-w-0 flex-1 flex-col", children: [
357
468
  /* @__PURE__ */ e("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: t }),
358
- /* @__PURE__ */ e("pre", { className: "flex-1 overflow-auto rounded border bg-muted/30 p-3 text-xs", children: r === void 0 ? s === void 0 ? "null" : JSON.stringify(s, null, 2) : (s === void 0 ? "null" : JSON.stringify(s, null, 2)).split(`
359
- `).map((a, d) => (
469
+ /* @__PURE__ */ e("pre", { className: "flex-1 overflow-auto rounded border bg-muted/30 p-3 text-xs", children: i === void 0 ? s === void 0 ? "null" : JSON.stringify(s, null, 2) : (s === void 0 ? "null" : JSON.stringify(s, null, 2)).split(`
470
+ `).map((r, d) => (
360
471
  // eslint-disable-next-line react/no-array-index-key
361
472
  /* @__PURE__ */ e(
362
473
  "div",
363
474
  {
364
- className: r[d] ? "bg-yellow-200/70 text-yellow-950 dark:bg-yellow-400/20 dark:text-yellow-100" : void 0,
365
- children: a === "" ? " " : a
475
+ className: i[d] ? "bg-yellow-200/70 text-yellow-950 dark:bg-yellow-400/20 dark:text-yellow-100" : void 0,
476
+ children: r === "" ? " " : r
366
477
  },
367
478
  d
368
479
  )
@@ -372,56 +483,56 @@ function Ke({ label: t, value: s, highlightLines: r }) {
372
483
  function Ge(t) {
373
484
  return t === void 0 ? "null" : JSON.stringify(t, null, 2);
374
485
  }
375
- function xt(t, s, r) {
376
- let a = Ge(t);
377
- if (r && r.length > 0)
378
- for (const { replace: h, with: O } of r)
379
- h && (a = a.split(h).join(O));
380
- const d = a.split(`
381
- `), m = Ge(s).split(`
382
- `), l = d.length, c = m.length, g = Array.from({ length: l + 1 }, () => new Array(c + 1).fill(0));
486
+ function xt(t, s, i) {
487
+ let r = Ge(t);
488
+ if (i && i.length > 0)
489
+ for (const { replace: h, with: I } of i)
490
+ h && (r = r.split(h).join(I));
491
+ const d = r.split(`
492
+ `), u = Ge(s).split(`
493
+ `), l = d.length, c = u.length, f = Array.from({ length: l + 1 }, () => new Array(c + 1).fill(0));
383
494
  for (let h = l - 1; h >= 0; h -= 1)
384
- for (let O = c - 1; O >= 0; O -= 1)
385
- g[h][O] = d[h] === m[O] ? g[h + 1][O + 1] + 1 : Math.max(g[h + 1][O], g[h][O + 1]);
495
+ for (let I = c - 1; I >= 0; I -= 1)
496
+ f[h][I] = d[h] === u[I] ? f[h + 1][I + 1] + 1 : Math.max(f[h + 1][I], f[h][I + 1]);
386
497
  const v = new Array(l).fill(!0);
387
498
  let N = 0, o = 0;
388
499
  for (; N < l && o < c; )
389
- d[N] === m[o] ? (v[N] = !1, N += 1, o += 1) : g[N + 1][o] >= g[N][o + 1] ? N += 1 : o += 1;
500
+ d[N] === u[o] ? (v[N] = !1, N += 1, o += 1) : f[N + 1][o] >= f[N][o + 1] ? N += 1 : o += 1;
390
501
  return v;
391
502
  }
392
- function Ce({
503
+ function we({
393
504
  title: t,
394
505
  values: s,
395
- excluded: r,
396
- editable: a,
506
+ excluded: i,
507
+ editable: r,
397
508
  onToggle: d,
398
- formatLabel: m
509
+ formatLabel: u
399
510
  }) {
400
- const [l, c] = A(r.length > 0);
511
+ const [l, c] = A(i.length > 0);
401
512
  return je(() => {
402
- r.length > 0 && c(!0);
403
- }, [r.length]), /* @__PURE__ */ n("div", { className: "border-b p-2", children: [
513
+ i.length > 0 && c(!0);
514
+ }, [i.length]), /* @__PURE__ */ n("div", { className: "border-b p-2", children: [
404
515
  /* @__PURE__ */ n(
405
516
  "button",
406
517
  {
407
518
  type: "button",
408
519
  className: "flex w-full items-center justify-between gap-2",
409
- onClick: () => c((g) => !g),
520
+ onClick: () => c((f) => !f),
410
521
  "aria-expanded": l,
411
522
  children: [
412
523
  /* @__PURE__ */ n("span", { className: "flex items-center gap-1 text-xs font-medium text-muted-foreground", children: [
413
- l ? /* @__PURE__ */ e(Pe, { size: 12 }) : /* @__PURE__ */ e(Te, { size: 12 }),
524
+ l ? /* @__PURE__ */ e(Pe, { size: 12 }) : /* @__PURE__ */ e(Se, { size: 12 }),
414
525
  t,
415
526
  " (",
416
- r.length,
527
+ i.length,
417
528
  ")"
418
529
  ] }),
419
- a ? null : /* @__PURE__ */ e("span", { className: "text-[10px] text-muted-foreground", children: "read-only" })
530
+ r ? null : /* @__PURE__ */ e("span", { className: "text-[10px] text-muted-foreground", children: "read-only" })
420
531
  ]
421
532
  }
422
533
  ),
423
- l ? /* @__PURE__ */ e("div", { className: "mt-1 flex flex-col gap-1", children: s.map((g) => {
424
- const v = !r.includes(g);
534
+ l ? /* @__PURE__ */ e("div", { className: "mt-1 flex flex-col gap-1", children: s.map((f) => {
535
+ const v = !i.includes(f);
425
536
  return /* @__PURE__ */ n(
426
537
  "label",
427
538
  {
@@ -433,49 +544,49 @@ function Ce({
433
544
  type: "checkbox",
434
545
  className: "mt-0.5 shrink-0",
435
546
  checked: v,
436
- disabled: !a,
437
- onChange: (N) => d == null ? void 0 : d(g, N.target.checked)
547
+ disabled: !r,
548
+ onChange: (N) => d == null ? void 0 : d(f, N.target.checked)
438
549
  }
439
550
  ),
440
- /* @__PURE__ */ e("span", { className: `min-w-0 break-all font-mono ${v ? "" : "text-muted-foreground line-through"}`, children: m ? m(g) : g })
551
+ /* @__PURE__ */ e("span", { className: `min-w-0 break-all font-mono ${v ? "" : "text-muted-foreground line-through"}`, children: u ? u(f) : f })
441
552
  ]
442
553
  },
443
- g
554
+ f
444
555
  );
445
556
  }) }) : null
446
557
  ] });
447
558
  }
448
- function Lt({
559
+ function Ht({
449
560
  item: t,
450
561
  targets: s,
451
- onClose: r,
452
- unmetDependencyNames: a = [],
562
+ onClose: i,
563
+ unmetDependencyNames: r = [],
453
564
  tags: d = [],
454
- excludedTags: m = [],
565
+ excludedTags: u = [],
455
566
  editable: l = !0,
456
567
  onToggleTag: c,
457
- metadataKeys: g = [],
568
+ metadataKeys: f = [],
458
569
  excludedMetadataKeys: v = [],
459
570
  onToggleMetadataKey: N,
460
571
  i18nPaths: o = [],
461
572
  excludedI18nPaths: h = [],
462
- onToggleI18nPath: O,
463
- permissionKeys: M = [],
573
+ onToggleI18nPath: I,
574
+ permissionKeys: D = [],
464
575
  excludedPermissions: j = [],
465
- onTogglePermission: H,
466
- formatPermissionLabel: U,
576
+ onTogglePermission: U,
577
+ formatPermissionLabel: H,
467
578
  replacementMaps: z
468
579
  }) {
469
- var Y, L, V, q;
470
- const D = ((Y = s[0]) == null ? void 0 : Y.id) ?? null, [B, f] = A(D);
580
+ var Y, Q, V, q;
581
+ const M = ((Y = s[0]) == null ? void 0 : Y.id) ?? null, [B, g] = A(M);
471
582
  je(() => {
472
- var I;
473
- f(((I = s[0]) == null ? void 0 : I.id) ?? null);
583
+ var O;
584
+ g(((O = s[0]) == null ? void 0 : O.id) ?? null);
474
585
  }, [t == null ? void 0 : t.id]);
475
- const k = s.find((I) => I.id === B) ?? s[0] ?? null, w = (L = t == null ? void 0 : t.diff) == null ? void 0 : L.byTarget, x = w != null, K = x ? w[(k == null ? void 0 : k.id) ?? ""] : (V = t == null ? void 0 : t.diff) == null ? void 0 : V.target, p = x && k != null && !(k.id in w), F = J(
586
+ const k = s.find((O) => O.id === B) ?? s[0] ?? null, C = (Q = t == null ? void 0 : t.diff) == null ? void 0 : Q.byTarget, x = C != null, K = x ? C[(k == null ? void 0 : k.id) ?? ""] : (V = t == null ? void 0 : t.diff) == null ? void 0 : V.target, p = x && k != null && !(k.id in C), F = J(
476
587
  () => {
477
- var I;
478
- return p ? void 0 : xt((I = t == null ? void 0 : t.diff) == null ? void 0 : I.origin, K, z == null ? void 0 : z[(k == null ? void 0 : k.id) ?? ""]);
588
+ var O;
589
+ return p ? void 0 : xt((O = t == null ? void 0 : t.diff) == null ? void 0 : O.origin, K, z == null ? void 0 : z[(k == null ? void 0 : k.id) ?? ""]);
479
590
  },
480
591
  [t, K, p, z, k == null ? void 0 : k.id]
481
592
  );
@@ -485,71 +596,71 @@ function Lt({
485
596
  /* @__PURE__ */ e("div", { className: "truncate font-medium", children: t.itemName }),
486
597
  /* @__PURE__ */ e("div", { className: "font-mono text-xs text-muted-foreground", children: t.itemType })
487
598
  ] }),
488
- /* @__PURE__ */ e(E, { variant: "ghost", size: "icon", title: "Close", onClick: r, children: /* @__PURE__ */ e(xe, {}) })
599
+ /* @__PURE__ */ e(E, { variant: "ghost", size: "icon", title: "Close", onClick: i, children: /* @__PURE__ */ e(xe, {}) })
489
600
  ] }),
490
- a.length > 0 ? /* @__PURE__ */ n("div", { className: "flex items-start gap-2 border-b bg-amber-50 p-2 text-xs text-amber-700 dark:bg-amber-500/10 dark:text-amber-300", children: [
491
- /* @__PURE__ */ e(ge, { size: 14, className: "mt-0.5 shrink-0 text-amber-600 dark:text-amber-400" }),
601
+ r.length > 0 ? /* @__PURE__ */ n("div", { className: "flex items-start gap-2 border-b bg-amber-50 p-2 text-xs text-amber-700 dark:bg-amber-500/10 dark:text-amber-300", children: [
602
+ /* @__PURE__ */ e(fe, { size: 14, className: "mt-0.5 shrink-0 text-amber-600 dark:text-amber-400" }),
492
603
  /* @__PURE__ */ n("span", { children: [
493
604
  "Depends on excluded items: ",
494
- a.join(", "),
605
+ r.join(", "),
495
606
  ". Push will fail for this item until they're included."
496
607
  ] })
497
608
  ] }) : null,
498
609
  d.length > 0 ? /* @__PURE__ */ e(
499
- Ce,
610
+ we,
500
611
  {
501
612
  title: "Tag Overrides",
502
613
  values: d,
503
- excluded: m,
614
+ excluded: u,
504
615
  editable: l,
505
616
  onToggle: c
506
617
  }
507
618
  ) : null,
508
- g.length > 0 ? /* @__PURE__ */ e(
509
- Ce,
619
+ f.length > 0 ? /* @__PURE__ */ e(
620
+ we,
510
621
  {
511
622
  title: "Metadata Overrides",
512
- values: g,
623
+ values: f,
513
624
  excluded: v,
514
625
  editable: l,
515
626
  onToggle: N
516
627
  }
517
628
  ) : null,
518
629
  o.length > 0 ? /* @__PURE__ */ e(
519
- Ce,
630
+ we,
520
631
  {
521
632
  title: "Translation Overrides",
522
633
  values: o,
523
634
  excluded: h,
524
635
  editable: l,
525
- onToggle: O
636
+ onToggle: I
526
637
  }
527
638
  ) : null,
528
- M.length > 0 ? /* @__PURE__ */ e(
529
- Ce,
639
+ D.length > 0 ? /* @__PURE__ */ e(
640
+ we,
530
641
  {
531
642
  title: "Permission Overrides",
532
- values: M,
643
+ values: D,
533
644
  excluded: j,
534
645
  editable: l,
535
- onToggle: H,
536
- formatLabel: U
646
+ onToggle: U,
647
+ formatLabel: H
537
648
  }
538
649
  ) : null,
539
- s.length > 0 ? /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1 border-b p-2", children: s.map((I) => {
540
- const G = x && !(I.id in w);
650
+ s.length > 0 ? /* @__PURE__ */ e("div", { className: "flex flex-wrap gap-1 border-b p-2", children: s.map((O) => {
651
+ const G = x && !(O.id in C);
541
652
  return /* @__PURE__ */ n(
542
653
  "button",
543
654
  {
544
655
  type: "button",
545
- onClick: () => f(I.id),
546
- className: `inline-flex items-center gap-1 rounded px-2 py-1 text-xs ${I.id === (k == null ? void 0 : k.id) ? "bg-muted font-medium" : "hover:bg-muted/50"}`,
656
+ onClick: () => g(O.id),
657
+ className: `inline-flex items-center gap-1 rounded px-2 py-1 text-xs ${O.id === (k == null ? void 0 : k.id) ? "bg-muted font-medium" : "hover:bg-muted/50"}`,
547
658
  children: [
548
659
  G ? /* @__PURE__ */ e(ht, { size: 12, className: "text-green-600" }) : /* @__PURE__ */ e("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-red-500", "aria-hidden": !0 }),
549
- I.name
660
+ O.name
550
661
  ]
551
662
  },
552
- I.id
663
+ O.id
553
664
  );
554
665
  }) }) : null,
555
666
  /* @__PURE__ */ n("div", { className: "flex flex-1 gap-3 overflow-auto p-3", children: [
@@ -562,11 +673,11 @@ function Lt({
562
673
  ] })
563
674
  ] }) : null;
564
675
  }
565
- function Vt({ state: t }) {
676
+ function Yt({ state: t }) {
566
677
  switch (t.status) {
567
678
  case "pushing":
568
679
  return /* @__PURE__ */ n("span", { className: "inline-flex items-center gap-1 text-sm text-muted-foreground", children: [
569
- /* @__PURE__ */ e(mt, { className: "h-4 w-4 animate-spin" }),
680
+ /* @__PURE__ */ e(ut, { className: "h-4 w-4 animate-spin" }),
570
681
  "Pushing…"
571
682
  ] });
572
683
  case "success":
@@ -576,7 +687,7 @@ function Vt({ state: t }) {
576
687
  ] });
577
688
  case "partial":
578
689
  return /* @__PURE__ */ n("span", { className: "inline-flex items-center gap-1 text-sm text-amber-600", children: [
579
- /* @__PURE__ */ e(ge, { className: "h-4 w-4" }),
690
+ /* @__PURE__ */ e(fe, { className: "h-4 w-4" }),
580
691
  "Partial — ",
581
692
  t.failed ?? 0,
582
693
  " failed"
@@ -595,74 +706,74 @@ function Vt({ state: t }) {
595
706
  );
596
707
  default:
597
708
  return /* @__PURE__ */ n("span", { className: "inline-flex items-center gap-1 text-sm text-muted-foreground", children: [
598
- /* @__PURE__ */ e(Et, { className: "h-3 w-3" }),
709
+ /* @__PURE__ */ e(Ot, { className: "h-3 w-3" }),
599
710
  "Pending"
600
711
  ] });
601
712
  }
602
713
  }
603
- function Ht({
714
+ function _t({
604
715
  open: t,
605
716
  onOpenChange: s,
606
- releaseId: r,
607
- targetConfigIds: a,
717
+ releaseId: i,
718
+ targetConfigIds: r,
608
719
  targetNames: d,
609
- apiPath: m = "/releases",
720
+ apiPath: u = "/releases",
610
721
  onComplete: l,
611
722
  dependencyWarnings: c = []
612
723
  }) {
613
- const { toast: g } = le(), { fetchJson: v } = ne(), N = oe(), [o, h] = A(!1), [O, M] = A({}), [j, H] = A(!1), U = (f) => (d == null ? void 0 : d[f]) ?? f, z = (f, k) => M((w) => ({ ...w, [f]: k })), D = async () => {
614
- h(!0), H(!1), M(Object.fromEntries(a.map((w) => [w, { status: "idle" }])));
615
- let f = 0, k = 0;
616
- for (const w of a) {
617
- z(w, { status: "pushing" });
724
+ const { toast: f } = le(), { fetchJson: v } = ne(), N = oe(), [o, h] = A(!1), [I, D] = A({}), [j, U] = A(!1), H = (g) => (d == null ? void 0 : d[g]) ?? g, z = (g, k) => D((C) => ({ ...C, [g]: k })), M = async () => {
725
+ h(!0), U(!1), D(Object.fromEntries(r.map((C) => [C, { status: "idle" }])));
726
+ let g = 0, k = 0;
727
+ for (const C of r) {
728
+ z(C, { status: "pushing" });
618
729
  try {
619
- const x = await v(`${m}/${r}/push`, {
730
+ const x = await v(`${u}/${i}/push`, {
620
731
  method: "POST",
621
- body: JSON.stringify({ destConfigId: w })
732
+ body: JSON.stringify({ destConfigId: C })
622
733
  }), K = (x.results ?? []).filter((p) => !p.ok);
623
- x.status === "success" ? (f += 1, z(w, { status: "success" })) : x.status === "partial" ? (k += 1, z(w, { status: "partial", failed: K.length, failures: K })) : (k += 1, z(w, { status: "failed", failures: K }));
734
+ x.status === "success" ? (g += 1, z(C, { status: "success" })) : x.status === "partial" ? (k += 1, z(C, { status: "partial", failed: K.length, failures: K })) : (k += 1, z(C, { status: "failed", failures: K }));
624
735
  } catch (x) {
625
736
  k += 1;
626
737
  const K = x instanceof Error ? x.message : String(x);
627
- z(w, { status: "failed", error: K });
738
+ z(C, { status: "failed", error: K });
628
739
  }
629
740
  }
630
- N.invalidateQueries({ queryKey: ["imaginarium", "releases"] }), N.invalidateQueries({ queryKey: ["imaginarium", "release", r] }), N.invalidateQueries({ queryKey: ["imaginarium", "release-items", r] }), N.invalidateQueries({ queryKey: ["imaginarium", "release-pushes", r] }), g(k === 0 ? { title: "Push complete", description: `Pushed to ${f} target${f === 1 ? "" : "s"}.` } : {
741
+ N.invalidateQueries({ queryKey: ["imaginarium", "releases"] }), N.invalidateQueries({ queryKey: ["imaginarium", "release", i] }), N.invalidateQueries({ queryKey: ["imaginarium", "release-items", i] }), N.invalidateQueries({ queryKey: ["imaginarium", "release-pushes", i] }), f(k === 0 ? { title: "Push complete", description: `Pushed to ${g} target${g === 1 ? "" : "s"}.` } : {
631
742
  title: "Push finished with errors",
632
743
  description: `${k} target${k === 1 ? "" : "s"} did not fully succeed.`,
633
744
  variant: "destructive"
634
- }), h(!1), H(!0), l == null || l();
635
- }, B = (f) => {
636
- o || (f || (M({}), H(!1)), s(f));
745
+ }), h(!1), U(!0), l == null || l();
746
+ }, B = (g) => {
747
+ o || (g || (D({}), U(!1)), s(g));
637
748
  };
638
749
  return /* @__PURE__ */ e($e, { open: t, onOpenChange: B, children: /* @__PURE__ */ n(Ee, { children: [
639
- /* @__PURE__ */ n(Oe, { children: [
640
- /* @__PURE__ */ e(Ie, { children: "Push release" }),
750
+ /* @__PURE__ */ n(Ie, { children: [
751
+ /* @__PURE__ */ e(Oe, { children: "Push release" }),
641
752
  /* @__PURE__ */ e(Ae, { children: "Pushes the included items to each target cluster, one at a time. Each target re-compares against the latest origin before applying." })
642
753
  ] }),
643
754
  c.length > 0 ? /* @__PURE__ */ n("div", { className: "space-y-1 rounded border border-amber-200 bg-amber-50 p-3 text-xs text-amber-700 dark:border-amber-500/30 dark:bg-amber-500/10 dark:text-amber-300", children: [
644
755
  /* @__PURE__ */ n("div", { className: "flex items-center gap-2 font-medium", children: [
645
- /* @__PURE__ */ e(ge, { className: "h-4 w-4 shrink-0 text-amber-600 dark:text-amber-400" }),
756
+ /* @__PURE__ */ e(fe, { className: "h-4 w-4 shrink-0 text-amber-600 dark:text-amber-400" }),
646
757
  c.length,
647
758
  " item",
648
759
  c.length === 1 ? "" : "s",
649
760
  " reference excluded dependencies"
650
761
  ] }),
651
- /* @__PURE__ */ e("ul", { className: "list-disc space-y-0.5 pl-8", children: c.map((f) => /* @__PURE__ */ n("li", { children: [
652
- f.itemName,
762
+ /* @__PURE__ */ e("ul", { className: "list-disc space-y-0.5 pl-8", children: c.map((g) => /* @__PURE__ */ n("li", { children: [
763
+ g.itemName,
653
764
  " → ",
654
- f.missing.join(", ")
655
- ] }, f.itemName)) }),
765
+ g.missing.join(", ")
766
+ ] }, g.itemName)) }),
656
767
  /* @__PURE__ */ e("p", { className: "pl-8 text-amber-600", children: "Push may fail for these items. You can proceed anyway." })
657
768
  ] }) : null,
658
- /* @__PURE__ */ e("div", { className: "space-y-2 py-2", children: a.length === 0 ? /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: "This release has no targets." }) : a.map((f) => {
659
- const k = O[f] ?? { status: "idle" }, w = k.failures ?? [];
769
+ /* @__PURE__ */ e("div", { className: "space-y-2 py-2", children: r.length === 0 ? /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: "This release has no targets." }) : r.map((g) => {
770
+ const k = I[g] ?? { status: "idle" }, C = k.failures ?? [];
660
771
  return /* @__PURE__ */ n("div", { className: "rounded border px-3 py-2", children: [
661
772
  /* @__PURE__ */ n("div", { className: "flex items-center justify-between", children: [
662
- /* @__PURE__ */ e("span", { className: "text-sm font-medium", children: U(f) }),
663
- /* @__PURE__ */ e(Vt, { state: k })
773
+ /* @__PURE__ */ e("span", { className: "text-sm font-medium", children: H(g) }),
774
+ /* @__PURE__ */ e(Yt, { state: k })
664
775
  ] }),
665
- w.length > 0 ? /* @__PURE__ */ e("ul", { className: "mt-2 max-h-48 space-y-1 overflow-auto border-t pt-2 text-xs", children: w.map((x, K) => /* @__PURE__ */ n("li", { className: "text-destructive", children: [
776
+ C.length > 0 ? /* @__PURE__ */ e("ul", { className: "mt-2 max-h-48 space-y-1 overflow-auto border-t pt-2 text-xs", children: C.map((x, K) => /* @__PURE__ */ n("li", { className: "text-destructive", children: [
666
777
  /* @__PURE__ */ n("span", { className: "font-mono", children: [
667
778
  x.action ? `${x.action} ` : "",
668
779
  x.itemKey ?? "item"
@@ -672,7 +783,7 @@ function Ht({
672
783
  x.error
673
784
  ] }) : null
674
785
  ] }, `${x.itemKey ?? "item"}-${K}`)) }) : null
675
- ] }, f);
786
+ ] }, g);
676
787
  }) }),
677
788
  /* @__PURE__ */ n(Re, { children: [
678
789
  /* @__PURE__ */ e(E, { variant: "outline", onClick: () => B(!1), disabled: o, children: "Close" }),
@@ -680,10 +791,10 @@ function Ht({
680
791
  E,
681
792
  {
682
793
  variant: "destructive",
683
- onClick: D,
684
- disabled: o || j || a.length === 0,
794
+ onClick: M,
795
+ disabled: o || j || r.length === 0,
685
796
  children: [
686
- /* @__PURE__ */ e($t, { className: "w-4 h-4 mr-2" }),
797
+ /* @__PURE__ */ e(It, { className: "w-4 h-4 mr-2" }),
687
798
  o ? "Pushing…" : "Confirm push"
688
799
  ]
689
800
  }
@@ -691,33 +802,33 @@ function Ht({
691
802
  ] })
692
803
  ] }) });
693
804
  }
694
- function Ut(t) {
805
+ function Wt(t) {
695
806
  var s;
696
- return (((s = t.diff) == null ? void 0 : s.versions) ?? []).filter((r) => !r.existsOnTarget);
807
+ return (((s = t.diff) == null ? void 0 : s.versions) ?? []).filter((i) => !i.existsOnTarget);
697
808
  }
698
- function Yt({ item: t, disabled: s, onChange: r }) {
809
+ function Gt({ item: t, disabled: s, onChange: i }) {
699
810
  var d;
700
- const a = ((d = t.diff) == null ? void 0 : d.versions) ?? [];
811
+ const r = ((d = t.diff) == null ? void 0 : d.versions) ?? [];
701
812
  return /* @__PURE__ */ n(
702
813
  "select",
703
814
  {
704
815
  value: t.selectedVersion ?? "",
705
816
  disabled: s,
706
- onClick: (m) => m.stopPropagation(),
707
- onChange: (m) => r(m.target.value),
817
+ onClick: (u) => u.stopPropagation(),
818
+ onChange: (u) => i(u.target.value),
708
819
  className: "h-7 rounded-md border border-input bg-background px-2 py-0.5 text-xs disabled:cursor-not-allowed disabled:opacity-50",
709
820
  "aria-label": "Rule version",
710
821
  children: [
711
822
  /* @__PURE__ */ e("option", { value: "", disabled: !0, children: "Select a version" }),
712
- a.map((m) => {
713
- const l = String(m.version), c = m.existsOnTarget ? `v${m.version} — already on target` : `v${m.version}${m.isPublished ? " (published)" : ""}`;
714
- return /* @__PURE__ */ e("option", { value: l, disabled: m.existsOnTarget, children: c }, l);
823
+ r.map((u) => {
824
+ const l = String(u.version), c = u.existsOnTarget ? `v${u.version} — already on target` : `v${u.version}${u.isPublished ? " (published)" : ""}`;
825
+ return /* @__PURE__ */ e("option", { value: l, disabled: u.existsOnTarget, children: c }, l);
715
826
  })
716
827
  ]
717
828
  }
718
829
  );
719
830
  }
720
- const _t = {
831
+ const Xt = {
721
832
  blueprint: "bg-blue-100 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300",
722
833
  rule: "bg-orange-100 text-orange-700 dark:bg-orange-500/15 dark:text-orange-300",
723
834
  messageRoute: "bg-teal-100 text-teal-700 dark:bg-teal-500/15 dark:text-teal-300",
@@ -737,14 +848,14 @@ const _t = {
737
848
  project: "bg-fuchsia-50 text-fuchsia-800 dark:bg-fuchsia-500/15 dark:text-fuchsia-300"
738
849
  };
739
850
  function pe({ type: t }) {
740
- const s = _t[t] ?? "bg-muted text-muted-foreground";
851
+ const s = Xt[t] ?? "bg-muted text-muted-foreground";
741
852
  return /* @__PURE__ */ e("span", { className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs font-semibold ${s}`, children: t });
742
853
  }
743
- function Xe({ checked: t, onChange: s, disabled: r = !1 }) {
854
+ function Xe({ checked: t, onChange: s, disabled: i = !1 }) {
744
855
  return /* @__PURE__ */ n(
745
856
  "label",
746
857
  {
747
- className: `relative inline-block h-[18px] w-8 shrink-0 ${r ? "cursor-not-allowed opacity-40" : "cursor-pointer"}`,
858
+ className: `relative inline-block h-[18px] w-8 shrink-0 ${i ? "cursor-not-allowed opacity-40" : "cursor-pointer"}`,
748
859
  children: [
749
860
  /* @__PURE__ */ e(
750
861
  "input",
@@ -752,8 +863,8 @@ function Xe({ checked: t, onChange: s, disabled: r = !1 }) {
752
863
  type: "checkbox",
753
864
  className: "peer sr-only",
754
865
  checked: t,
755
- disabled: r,
756
- onChange: (a) => s(a.target.checked)
866
+ disabled: i,
867
+ onChange: (r) => s(r.target.checked)
757
868
  }
758
869
  ),
759
870
  /* @__PURE__ */ e("span", { className: "absolute inset-0 rounded-full bg-input transition-colors peer-checked:bg-primary" }),
@@ -762,43 +873,43 @@ function Xe({ checked: t, onChange: s, disabled: r = !1 }) {
762
873
  }
763
874
  );
764
875
  }
765
- function Wt(t) {
876
+ function Zt(t) {
766
877
  const s = /* @__PURE__ */ new Map();
767
- for (const a of t) {
768
- const d = s.get(a.destConfigId);
769
- (!d || a.createdAt > d.createdAt) && s.set(a.destConfigId, a);
878
+ for (const r of t) {
879
+ const d = s.get(r.destConfigId);
880
+ (!d || r.createdAt > d.createdAt) && s.set(r.destConfigId, r);
770
881
  }
771
- const r = /* @__PURE__ */ new Map();
772
- for (const a of s.values())
773
- for (const d of a.results ?? []) {
882
+ const i = /* @__PURE__ */ new Map();
883
+ for (const r of s.values())
884
+ for (const d of r.results ?? []) {
774
885
  if (!d.itemKey)
775
886
  continue;
776
- let m = r.get(d.itemKey);
777
- m || (m = /* @__PURE__ */ new Map(), r.set(d.itemKey, m)), m.set(a.destConfigId, { ok: d.ok, error: d.error });
887
+ let u = i.get(d.itemKey);
888
+ u || (u = /* @__PURE__ */ new Map(), i.set(d.itemKey, u)), u.set(r.destConfigId, { ok: d.ok, error: d.error });
778
889
  }
779
- return r;
890
+ return i;
780
891
  }
781
- function Gt(t, s, r) {
782
- var a;
783
- return (a = t.get(s)) == null ? void 0 : a.get(r);
892
+ function en(t, s, i) {
893
+ var r;
894
+ return (r = t.get(s)) == null ? void 0 : r.get(i);
784
895
  }
785
- function $n(t, s) {
786
- return t.filter((r) => !(s.type !== "all" && r.itemType !== s.type || s.included === "enabled" && (!r.included || r.ignored) || s.included === "disabled" && r.included && !r.ignored));
896
+ function On(t, s) {
897
+ return t.filter((i) => !(s.type !== "all" && i.itemType !== s.type || s.included === "enabled" && (!i.included || i.ignored) || s.included === "disabled" && i.included && !i.ignored));
787
898
  }
788
- function Xt(t) {
899
+ function tn(t) {
789
900
  const s = {};
790
- for (const r of t)
791
- s[r.itemType] = (s[r.itemType] ?? 0) + 1;
901
+ for (const i of t)
902
+ s[i.itemType] = (s[i.itemType] ?? 0) + 1;
792
903
  return s;
793
904
  }
794
- function Zt(t) {
795
- const s = t.indexOf(":"), r = s >= 0 ? t.slice(0, s) : t, a = s >= 0 ? t.slice(s + 1) : t;
905
+ function nn(t) {
906
+ const s = t.indexOf(":"), i = s >= 0 ? t.slice(0, s) : t, r = s >= 0 ? t.slice(s + 1) : t;
796
907
  return {
797
908
  id: "",
798
909
  releaseId: "",
799
910
  itemKey: t,
800
- itemType: r,
801
- itemName: a,
911
+ itemType: i,
912
+ itemName: r,
802
913
  parentKey: null,
803
914
  selectedVersion: null,
804
915
  status: "updated",
@@ -810,92 +921,92 @@ function Zt(t) {
810
921
  updatedAt: ""
811
922
  };
812
923
  }
813
- function en(t) {
814
- var m;
924
+ function sn(t) {
925
+ var u;
815
926
  const s = new Set(
816
927
  t.filter((l) => !l.parentKey).map((l) => l.itemKey)
817
- ), r = [], a = /* @__PURE__ */ new Map();
928
+ ), i = [], r = /* @__PURE__ */ new Map();
818
929
  for (const l of t) {
819
930
  if (l.parentKey)
820
931
  continue;
821
932
  const c = { item: l, children: [] };
822
- r.push(c), a.set(l.itemKey, c);
933
+ i.push(c), r.set(l.itemKey, c);
823
934
  }
824
935
  const d = /* @__PURE__ */ new Map();
825
936
  for (const l of t) {
826
937
  if (!l.parentKey)
827
938
  continue;
828
939
  if (s.has(l.parentKey)) {
829
- (m = a.get(l.parentKey)) == null || m.children.push(l);
940
+ (u = r.get(l.parentKey)) == null || u.children.push(l);
830
941
  continue;
831
942
  }
832
943
  let c = d.get(l.parentKey);
833
- c || (c = { item: Zt(l.parentKey), children: [], synthetic: !0 }, d.set(l.parentKey, c), r.push(c)), c.children.push(l);
944
+ c || (c = { item: nn(l.parentKey), children: [], synthetic: !0 }, d.set(l.parentKey, c), i.push(c)), c.children.push(l);
834
945
  }
835
- return r;
946
+ return i;
836
947
  }
837
- function tn(t) {
838
- const s = t.indexOf(":"), r = s >= 0 ? t.slice(0, s) : t, a = s >= 0 ? t.slice(s + 1) : t;
839
- return { itemKey: t, itemType: r, itemName: a, parentKey: null, cells: {} };
948
+ function an(t) {
949
+ const s = t.indexOf(":"), i = s >= 0 ? t.slice(0, s) : t, r = s >= 0 ? t.slice(s + 1) : t;
950
+ return { itemKey: t, itemType: i, itemName: r, parentKey: null, cells: {} };
840
951
  }
841
- function nn(t) {
842
- var m;
952
+ function rn(t) {
953
+ var u;
843
954
  const s = new Set(
844
955
  t.filter((l) => !l.parentKey).map((l) => l.itemKey)
845
- ), r = [], a = /* @__PURE__ */ new Map();
956
+ ), i = [], r = /* @__PURE__ */ new Map();
846
957
  for (const l of t) {
847
958
  if (l.parentKey)
848
959
  continue;
849
960
  const c = { row: l, children: [] };
850
- r.push(c), a.set(l.itemKey, c);
961
+ i.push(c), r.set(l.itemKey, c);
851
962
  }
852
963
  const d = /* @__PURE__ */ new Map();
853
964
  for (const l of t) {
854
965
  if (!l.parentKey)
855
966
  continue;
856
967
  if (s.has(l.parentKey)) {
857
- (m = a.get(l.parentKey)) == null || m.children.push(l);
968
+ (u = r.get(l.parentKey)) == null || u.children.push(l);
858
969
  continue;
859
970
  }
860
971
  let c = d.get(l.parentKey);
861
- c || (c = { row: tn(l.parentKey), children: [], synthetic: !0 }, d.set(l.parentKey, c), r.push(c)), c.children.push(l);
972
+ c || (c = { row: an(l.parentKey), children: [], synthetic: !0 }, d.set(l.parentKey, c), i.push(c)), c.children.push(l);
862
973
  }
863
- return r;
974
+ return i;
864
975
  }
865
- function sn(t) {
976
+ function ln(t) {
866
977
  let s = 0;
867
- for (const r of t.children)
868
- r.included && !r.ignored && (s += 1);
978
+ for (const i of t.children)
979
+ i.included && !i.ignored && (s += 1);
869
980
  return { included: s, total: t.children.length };
870
981
  }
871
- function rn(t) {
872
- var a, d;
982
+ function on(t) {
983
+ var r, d;
873
984
  const s = [];
874
- for (const m of t) {
875
- if (m.status !== "new")
985
+ for (const u of t) {
986
+ if (u.status !== "new")
876
987
  continue;
877
- const l = (a = m.diff) == null ? void 0 : a.origin, c = l == null ? void 0 : l.id;
878
- if (typeof c == "string" && c && s.push({ token: c, depKey: m.itemKey }), m.itemType === "enum") {
879
- const g = l == null ? void 0 : l.type;
880
- typeof g == "string" && g && s.push({ token: g, depKey: m.itemKey });
988
+ const l = (r = u.diff) == null ? void 0 : r.origin, c = l == null ? void 0 : l.id;
989
+ if (typeof c == "string" && c && s.push({ token: c, depKey: u.itemKey }), u.itemType === "enum") {
990
+ const f = l == null ? void 0 : l.type;
991
+ typeof f == "string" && f && s.push({ token: f, depKey: u.itemKey });
881
992
  }
882
993
  }
883
- const r = /* @__PURE__ */ new Map();
884
- for (const m of t) {
885
- const l = /* @__PURE__ */ new Set(), c = JSON.stringify(((d = m.diff) == null ? void 0 : d.origin) ?? null);
886
- for (const { token: g, depKey: v } of s)
887
- v !== m.itemKey && c.includes(g) && l.add(v);
888
- r.set(m.itemKey, l);
994
+ const i = /* @__PURE__ */ new Map();
995
+ for (const u of t) {
996
+ const l = /* @__PURE__ */ new Set(), c = JSON.stringify(((d = u.diff) == null ? void 0 : d.origin) ?? null);
997
+ for (const { token: f, depKey: v } of s)
998
+ v !== u.itemKey && c.includes(f) && l.add(v);
999
+ i.set(u.itemKey, l);
889
1000
  }
890
- return r;
1001
+ return i;
891
1002
  }
892
- function ke(t, s, r) {
893
- const a = s.get(t.itemKey);
894
- if (!a || a.size === 0)
1003
+ function ke(t, s, i) {
1004
+ const r = s.get(t.itemKey);
1005
+ if (!r || r.size === 0)
895
1006
  return [];
896
1007
  const d = [];
897
- for (const m of a) {
898
- const l = r.get(m);
1008
+ for (const u of r) {
1009
+ const l = i.get(u);
899
1010
  l && l.status === "new" && (!l.included || l.ignored) && d.push(l);
900
1011
  }
901
1012
  return d;
@@ -927,17 +1038,17 @@ function et(t) {
927
1038
  return s === -1 ? Ze.length : s;
928
1039
  }
929
1040
  function qe(t, s) {
930
- const r = et(t) - et(s);
931
- return r !== 0 ? r : t.localeCompare(s);
1041
+ const i = et(t) - et(s);
1042
+ return i !== 0 ? i : t.localeCompare(s);
932
1043
  }
933
- function an(t) {
1044
+ function dn(t) {
934
1045
  return t.tags + t.metadataKeys + t.i18nPaths + t.permissions;
935
1046
  }
936
- function ln(t) {
1047
+ function cn(t) {
937
1048
  const s = [];
938
1049
  return t.tags > 0 && s.push(`${t.tags} tag${t.tags === 1 ? "" : "s"}`), t.metadataKeys > 0 && s.push(`${t.metadataKeys} metadata key${t.metadataKeys === 1 ? "" : "s"}`), t.i18nPaths > 0 && s.push(`${t.i18nPaths} translation${t.i18nPaths === 1 ? "" : "s"}`), t.permissions > 0 && s.push(`${t.permissions} permission${t.permissions === 1 ? "" : "s"}`), s.length === 0 ? "" : `${s.join(", ")} excluded from push`;
939
1050
  }
940
- const on = [
1051
+ const un = [
941
1052
  { value: "all", label: "All" },
942
1053
  { value: "enabled", label: "Enabled" },
943
1054
  { value: "disabled", label: "Disabled" }
@@ -954,7 +1065,7 @@ function X(t) {
954
1065
  if (typeof t == "string" && t.length > 0)
955
1066
  try {
956
1067
  const s = JSON.parse(t);
957
- return Array.isArray(s) ? s.filter((r) => typeof r == "string") : [];
1068
+ return Array.isArray(s) ? s.filter((i) => typeof i == "string") : [];
958
1069
  } catch {
959
1070
  return [];
960
1071
  }
@@ -966,30 +1077,30 @@ function st({ item: t }) {
966
1077
  metadataKeys: X(t.excludedMetadataKeys).length,
967
1078
  i18nPaths: X(t.excludedI18nPaths).length,
968
1079
  permissions: X(t.excludedPermissions).length
969
- }, r = an(s);
970
- return r <= 0 ? null : /* @__PURE__ */ n(
1080
+ }, i = dn(s);
1081
+ return i <= 0 ? null : /* @__PURE__ */ n(
971
1082
  "span",
972
1083
  {
973
- title: ln(s),
1084
+ title: cn(s),
974
1085
  className: "inline-flex items-center rounded px-1.5 py-0.5 text-xs bg-red-100 text-red-700 dark:bg-red-500/15 dark:text-red-300",
975
1086
  children: [
976
- r,
1087
+ i,
977
1088
  " manual override",
978
- r === 1 ? "" : "s"
1089
+ i === 1 ? "" : "s"
979
1090
  ]
980
1091
  }
981
1092
  );
982
1093
  }
983
- function rt({
1094
+ function it({
984
1095
  item: t,
985
1096
  targetConfigIds: s,
986
- results: r,
987
- pushedDests: a,
1097
+ results: i,
1098
+ pushedDests: r,
988
1099
  displayName: d
989
1100
  }) {
990
- const m = t.included && !t.ignored, l = s.filter((c) => a.has(c)).map((c) => ({ id: c, result: Gt(r, t.itemKey, c) })).filter((c) => c.result != null || m);
991
- return l.length === 0 ? null : /* @__PURE__ */ e("div", { className: "flex flex-wrap justify-end gap-1", children: l.map(({ id: c, result: g }) => {
992
- const v = g ? g.ok ? "bg-green-100 text-green-700 dark:bg-green-500/15 dark:text-green-300" : "bg-red-100 text-red-700 dark:bg-red-500/15 dark:text-red-300" : "bg-muted text-muted-foreground", N = g ? g.ok ? "✓" : "✗" : "=", o = g ? g.ok ? void 0 : g.error : "No change — already in sync";
1101
+ const u = t.included && !t.ignored, l = s.filter((c) => r.has(c)).map((c) => ({ id: c, result: en(i, t.itemKey, c) })).filter((c) => c.result != null || u);
1102
+ return l.length === 0 ? null : /* @__PURE__ */ e("div", { className: "flex flex-wrap justify-end gap-1", children: l.map(({ id: c, result: f }) => {
1103
+ const v = f ? f.ok ? "bg-green-100 text-green-700 dark:bg-green-500/15 dark:text-green-300" : "bg-red-100 text-red-700 dark:bg-red-500/15 dark:text-red-300" : "bg-muted text-muted-foreground", N = f ? f.ok ? "✓" : "✗" : "=", o = f ? f.ok ? void 0 : f.error : "No change — already in sync";
993
1104
  return /* @__PURE__ */ n(
994
1105
  "span",
995
1106
  {
@@ -1005,117 +1116,117 @@ function rt({
1005
1116
  );
1006
1117
  }) });
1007
1118
  }
1008
- function dn({ releaseId: t, onBack: s }) {
1009
- var Je, Qe, Le;
1010
- const r = ze.get("Release", "apiPath", "/releases"), { toast: a } = le(), { fetchJson: d } = ne(), { configs: m } = fe(), l = oe(), [c, g] = A("all"), [v, N] = A("all"), [o, h] = A(null), [O, M] = A(!1), [j, H] = A(() => /* @__PURE__ */ new Set()), U = (i) => H((b) => {
1011
- const u = new Set(b);
1012
- return u.has(i) ? u.delete(i) : u.add(i), u;
1013
- }), z = ["imaginarium", "release", t], D = ["imaginarium", "release-items", t], B = ["imaginarium", "release-pushes", t], { data: f, isLoading: k } = ae({
1119
+ function mn({ releaseId: t, onBack: s }) {
1120
+ var Je, Le, Qe;
1121
+ const i = ze.get("Release", "apiPath", "/releases"), { toast: r } = le(), { fetchJson: d } = ne(), { configs: u } = ge(), l = oe(), [c, f] = A("all"), [v, N] = A("all"), [o, h] = A(null), [I, D] = A(!1), [j, U] = A(() => /* @__PURE__ */ new Set()), H = (a) => U((b) => {
1122
+ const m = new Set(b);
1123
+ return m.has(a) ? m.delete(a) : m.add(a), m;
1124
+ }), z = ["imaginarium", "release", t], M = ["imaginarium", "release-items", t], B = ["imaginarium", "release-pushes", t], { data: g, isLoading: k } = re({
1014
1125
  queryKey: z,
1015
- queryFn: () => d(`${r}/${t}`)
1016
- }), { data: w, isLoading: x } = ae({
1017
- queryKey: D,
1126
+ queryFn: () => d(`${i}/${t}`)
1127
+ }), { data: C, isLoading: x } = re({
1128
+ queryKey: M,
1018
1129
  queryFn: async () => {
1019
- const i = await d(`${r}/${t}/items`);
1020
- return Array.isArray(i) ? i : (i == null ? void 0 : i.items) ?? [];
1130
+ const a = await d(`${i}/${t}/items`);
1131
+ return Array.isArray(a) ? a : (a == null ? void 0 : a.items) ?? [];
1021
1132
  }
1022
- }), { data: K } = ae({
1133
+ }), { data: K } = re({
1023
1134
  queryKey: B,
1024
1135
  queryFn: async () => {
1025
- const i = await d(`${r}/${t}/pushes`);
1026
- return Array.isArray(i) ? i : (i == null ? void 0 : i.items) ?? [];
1136
+ const a = await d(`${i}/${t}/pushes`);
1137
+ return Array.isArray(a) ? a : (a == null ? void 0 : a.items) ?? [];
1027
1138
  }
1028
- }), p = J(() => Wt(K ?? []), [K]), F = J(
1029
- () => new Set((K ?? []).map((i) => i.destConfigId)),
1139
+ }), p = J(() => Zt(K ?? []), [K]), F = J(
1140
+ () => new Set((K ?? []).map((a) => a.destConfigId)),
1030
1141
  [K]
1031
- ), Y = (K ?? []).length > 0, L = J(() => (f == null ? void 0 : f.targetConfigIds) ?? [], [f]), V = J(() => {
1032
- const i = /* @__PURE__ */ new Map();
1033
- return m.forEach((b) => i.set(String(b.id), b.displayName)), i;
1034
- }, [m]), q = (i) => V.get(i) ?? i, I = J(() => en(w ?? []), [w]), G = J(() => I.map((i) => i.item), [I]), Z = J(() => rn(w ?? []), [w]), C = J(
1035
- () => new Map((w ?? []).map((i) => [i.itemKey, i])),
1036
- [w]
1037
- ), R = (i) => {
1038
- var u;
1142
+ ), Y = (K ?? []).length > 0, Q = J(() => (g == null ? void 0 : g.targetConfigIds) ?? [], [g]), V = J(() => {
1143
+ const a = /* @__PURE__ */ new Map();
1144
+ return u.forEach((b) => a.set(String(b.id), b.displayName)), a;
1145
+ }, [u]), q = (a) => V.get(a) ?? a, O = J(() => sn(C ?? []), [C]), G = J(() => O.map((a) => a.item), [O]), Z = J(() => on(C ?? []), [C]), w = J(
1146
+ () => new Map((C ?? []).map((a) => [a.itemKey, a])),
1147
+ [C]
1148
+ ), R = (a) => {
1149
+ var m;
1039
1150
  let b;
1040
- if (i.parentKey) {
1041
- const $ = (u = C.get(i.parentKey)) == null ? void 0 : u.itemName, S = i.parentKey.indexOf(":");
1042
- b = $ ?? (S >= 0 ? i.parentKey.slice(S + 1) : void 0);
1151
+ if (a.parentKey) {
1152
+ const $ = (m = w.get(a.parentKey)) == null ? void 0 : m.itemName, T = a.parentKey.indexOf(":");
1153
+ b = $ ?? (T >= 0 ? a.parentKey.slice(T + 1) : void 0);
1043
1154
  }
1044
- return `${b ? b + " " : ""}${i.itemType} "${i.itemName}"`;
1045
- }, T = J(() => {
1046
- var b, u;
1047
- const i = /* @__PURE__ */ new Map();
1048
- for (const $ of w ?? []) {
1049
- const S = (u = (b = $.diff) == null ? void 0 : b.origin) == null ? void 0 : u.id;
1050
- typeof S == "string" && S && i.set(S, $.itemName);
1155
+ return `${b ? b + " " : ""}${a.itemType} "${a.itemName}"`;
1156
+ }, S = J(() => {
1157
+ var b, m;
1158
+ const a = /* @__PURE__ */ new Map();
1159
+ for (const $ of C ?? []) {
1160
+ const T = (m = (b = $.diff) == null ? void 0 : b.origin) == null ? void 0 : m.id;
1161
+ typeof T == "string" && T && a.set(T, $.itemName);
1051
1162
  }
1052
- return i;
1053
- }, [w]), de = J(
1054
- () => (w ?? []).filter((i) => i.included && !i.ignored).map((i) => ({
1055
- itemName: i.itemName,
1056
- missing: ke(i, Z, C).map(R)
1057
- })).filter((i) => i.missing.length > 0),
1163
+ return a;
1164
+ }, [C]), de = J(
1165
+ () => (C ?? []).filter((a) => a.included && !a.ignored).map((a) => ({
1166
+ itemName: a.itemName,
1167
+ missing: ke(a, Z, w).map(R)
1168
+ })).filter((a) => a.missing.length > 0),
1058
1169
  // eslint-disable-next-line react-hooks/exhaustive-deps
1059
- [w, Z, C]
1060
- ), me = J(() => Xt(G), [G]), ye = J(() => Object.keys(me).sort(qe), [me]), _ = J(() => I.filter((i) => c === "all" || i.item.itemType === c).map((i) => {
1061
- const b = v === "all" ? i.children : i.children.filter((u) => tt(u, v));
1062
- return { node: i, renderChildren: b };
1170
+ [C, Z, w]
1171
+ ), ue = J(() => tn(G), [G]), ye = J(() => Object.keys(ue).sort(qe), [ue]), _ = J(() => O.filter((a) => c === "all" || a.item.itemType === c).map((a) => {
1172
+ const b = v === "all" ? a.children : a.children.filter((m) => tt(m, v));
1173
+ return { node: a, renderChildren: b };
1063
1174
  }).filter(
1064
- ({ node: i, renderChildren: b }) => v === "all" || tt(i.item, v) || b.length > 0
1065
- ).sort((i, b) => {
1066
- const u = qe(i.node.item.itemType, b.node.item.itemType);
1067
- return u !== 0 ? u : i.node.item.itemName.localeCompare(b.node.item.itemName);
1068
- }), [I, c, v]), ee = Q({
1069
- mutationFn: () => d(`${r}/${t}/refresh`, { method: "POST" }),
1175
+ ({ node: a, renderChildren: b }) => v === "all" || tt(a.item, v) || b.length > 0
1176
+ ).sort((a, b) => {
1177
+ const m = qe(a.node.item.itemType, b.node.item.itemType);
1178
+ return m !== 0 ? m : a.node.item.itemName.localeCompare(b.node.item.itemName);
1179
+ }), [O, c, v]), ee = L({
1180
+ mutationFn: () => d(`${i}/${t}/refresh`, { method: "POST" }),
1070
1181
  onSuccess: () => {
1071
- l.invalidateQueries({ queryKey: D }), a({ title: "Snapshot refreshed", description: "Items re-computed from origin." });
1182
+ l.invalidateQueries({ queryKey: M }), r({ title: "Snapshot refreshed", description: "Items re-computed from origin." });
1072
1183
  },
1073
- onError: (i) => {
1074
- a({ title: "Error", description: i.message, variant: "destructive" });
1184
+ onError: (a) => {
1185
+ r({ title: "Error", description: a.message, variant: "destructive" });
1075
1186
  }
1076
- }), be = Q({
1077
- mutationFn: ({ itemId: i, included: b }) => d(`${r}/${t}/items/${i}`, {
1187
+ }), be = L({
1188
+ mutationFn: ({ itemId: a, included: b }) => d(`${i}/${t}/items/${a}`, {
1078
1189
  method: "PATCH",
1079
1190
  body: JSON.stringify({ included: b })
1080
1191
  }),
1081
1192
  onSuccess: () => {
1082
- l.invalidateQueries({ queryKey: D });
1193
+ l.invalidateQueries({ queryKey: M });
1083
1194
  },
1084
- onError: (i) => {
1085
- a({ title: "Error", description: i.message, variant: "destructive" });
1195
+ onError: (a) => {
1196
+ r({ title: "Error", description: a.message, variant: "destructive" });
1086
1197
  }
1087
- }), Be = Q({
1088
- mutationFn: ({ itemId: i, selectedVersion: b }) => d(`${r}/${t}/items/${i}`, {
1198
+ }), Be = L({
1199
+ mutationFn: ({ itemId: a, selectedVersion: b }) => d(`${i}/${t}/items/${a}`, {
1089
1200
  method: "PATCH",
1090
1201
  body: JSON.stringify({ selectedVersion: b })
1091
1202
  }),
1092
1203
  onSuccess: () => {
1093
- l.invalidateQueries({ queryKey: D });
1204
+ l.invalidateQueries({ queryKey: M });
1094
1205
  },
1095
- onError: (i) => {
1096
- a({ title: "Error", description: i.message, variant: "destructive" });
1206
+ onError: (a) => {
1207
+ r({ title: "Error", description: a.message, variant: "destructive" });
1097
1208
  }
1098
- }), Ne = (i) => ({
1099
- mutationFn: ({ itemId: b, value: u }) => d(`${r}/${t}/items/${b}`, {
1209
+ }), Ne = (a) => ({
1210
+ mutationFn: ({ itemId: b, value: m }) => d(`${i}/${t}/items/${b}`, {
1100
1211
  method: "PATCH",
1101
- body: JSON.stringify({ [i]: u })
1212
+ body: JSON.stringify({ [a]: m })
1102
1213
  }),
1103
- onMutate: async ({ itemId: b, value: u }) => {
1104
- await l.cancelQueries({ queryKey: D });
1105
- const $ = l.getQueryData(D);
1214
+ onMutate: async ({ itemId: b, value: m }) => {
1215
+ await l.cancelQueries({ queryKey: M });
1216
+ const $ = l.getQueryData(M);
1106
1217
  return l.setQueryData(
1107
- D,
1108
- (S) => (S ?? []).map((se) => se.id === b ? { ...se, [i]: u } : se)
1218
+ M,
1219
+ (T) => (T ?? []).map((se) => se.id === b ? { ...se, [a]: m } : se)
1109
1220
  ), { prev: $ };
1110
1221
  },
1111
- onError: (b, u, $) => {
1112
- $ != null && $.prev && l.setQueryData(D, $.prev), a({ title: "Error", description: b.message, variant: "destructive" });
1222
+ onError: (b, m, $) => {
1223
+ $ != null && $.prev && l.setQueryData(M, $.prev), r({ title: "Error", description: b.message, variant: "destructive" });
1113
1224
  },
1114
1225
  onSettled: () => {
1115
- l.invalidateQueries({ queryKey: D });
1226
+ l.invalidateQueries({ queryKey: M });
1116
1227
  }
1117
- }), yt = Q(Ne("excludedTags")), bt = Q(Ne("excludedMetadataKeys")), Nt = Q(Ne("excludedI18nPaths")), vt = Q(Ne("excludedPermissions")), Ct = () => l.invalidateQueries({ queryKey: D }), te = (f == null ? void 0 : f.status) === "pushed", y = o ? C.get(o.itemKey) ?? o : null;
1118
- return k ? /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground py-8", children: "Loading…" }) : f ? /* @__PURE__ */ n("div", { className: "space-y-4", children: [
1228
+ }), yt = L(Ne("excludedTags")), bt = L(Ne("excludedMetadataKeys")), Nt = L(Ne("excludedI18nPaths")), vt = L(Ne("excludedPermissions")), wt = () => l.invalidateQueries({ queryKey: M }), te = (g == null ? void 0 : g.status) === "pushed", y = o ? w.get(o.itemKey) ?? o : null;
1229
+ return k ? /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground py-8", children: "Loading…" }) : g ? /* @__PURE__ */ n("div", { className: "space-y-4", children: [
1119
1230
  te && /* @__PURE__ */ e("div", { className: "bg-muted text-muted-foreground rounded-md px-3 py-2 text-sm", children: "This release was pushed and is read-only." }),
1120
1231
  /* @__PURE__ */ n("div", { className: "space-y-3", children: [
1121
1232
  /* @__PURE__ */ n("div", { className: "flex items-center justify-between", children: [
@@ -1124,16 +1235,16 @@ function dn({ releaseId: t, onBack: s }) {
1124
1235
  /* @__PURE__ */ e(We, {}),
1125
1236
  "Back"
1126
1237
  ] }),
1127
- /* @__PURE__ */ e("h3", { className: "text-lg font-semibold", children: f.name }),
1128
- /* @__PURE__ */ e(ft, { status: f.status })
1238
+ /* @__PURE__ */ e("h3", { className: "text-lg font-semibold", children: g.name }),
1239
+ /* @__PURE__ */ e(gt, { status: g.status })
1129
1240
  ] }),
1130
1241
  /* @__PURE__ */ n("div", { className: "flex items-center gap-2", children: [
1131
1242
  !te && /* @__PURE__ */ e(
1132
- Qt,
1243
+ Ut,
1133
1244
  {
1134
1245
  releaseId: t,
1135
- apiPath: r,
1136
- onReset: Ct
1246
+ apiPath: i,
1247
+ onReset: wt
1137
1248
  }
1138
1249
  ),
1139
1250
  /* @__PURE__ */ n(
@@ -1153,24 +1264,24 @@ function dn({ releaseId: t, onBack: s }) {
1153
1264
  E,
1154
1265
  {
1155
1266
  size: "sm",
1156
- onClick: () => M(!0),
1157
- disabled: (f.targetConfigIds ?? []).length === 0,
1267
+ onClick: () => D(!0),
1268
+ disabled: (g.targetConfigIds ?? []).length === 0,
1158
1269
  children: "Push"
1159
1270
  }
1160
1271
  )
1161
1272
  ] })
1162
1273
  ] }),
1163
1274
  /* @__PURE__ */ n("div", { className: "flex flex-wrap items-center gap-2 text-sm text-muted-foreground", children: [
1164
- /* @__PURE__ */ e("span", { className: "inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs", children: q(f.originConfigId) }),
1275
+ /* @__PURE__ */ e("span", { className: "inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs", children: q(g.originConfigId) }),
1165
1276
  /* @__PURE__ */ e("span", { children: "→" }),
1166
- (f.targetConfigIds ?? []).map((i) => /* @__PURE__ */ e("span", { className: "inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs", children: q(i) }, i)),
1277
+ (g.targetConfigIds ?? []).map((a) => /* @__PURE__ */ e("span", { className: "inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs", children: q(a) }, a)),
1167
1278
  /* @__PURE__ */ n("span", { className: "ml-2", children: [
1168
1279
  "Snapshot: ",
1169
- f.snapshotAt ? new Date(f.snapshotAt).toLocaleString() : "—"
1280
+ g.snapshotAt ? new Date(g.snapshotAt).toLocaleString() : "—"
1170
1281
  ] }),
1171
1282
  /* @__PURE__ */ n("span", { children: [
1172
1283
  "Pushed: ",
1173
- f.pushedAt ? new Date(f.pushedAt).toLocaleString() : "—"
1284
+ g.pushedAt ? new Date(g.pushedAt).toLocaleString() : "—"
1174
1285
  ] })
1175
1286
  ] })
1176
1287
  ] }),
@@ -1181,7 +1292,7 @@ function dn({ releaseId: t, onBack: s }) {
1181
1292
  {
1182
1293
  variant: c === "all" ? "secondary" : "ghost",
1183
1294
  size: "sm",
1184
- onClick: () => g("all"),
1295
+ onClick: () => f("all"),
1185
1296
  children: [
1186
1297
  "All types (",
1187
1298
  G.length,
@@ -1189,35 +1300,35 @@ function dn({ releaseId: t, onBack: s }) {
1189
1300
  ]
1190
1301
  }
1191
1302
  ),
1192
- ye.map((i) => /* @__PURE__ */ n(
1303
+ ye.map((a) => /* @__PURE__ */ n(
1193
1304
  E,
1194
1305
  {
1195
- variant: c === i ? "secondary" : "ghost",
1306
+ variant: c === a ? "secondary" : "ghost",
1196
1307
  size: "sm",
1197
- onClick: () => g(i),
1308
+ onClick: () => f(a),
1198
1309
  children: [
1199
- i,
1310
+ a,
1200
1311
  " (",
1201
- me[i],
1312
+ ue[a],
1202
1313
  ")"
1203
1314
  ]
1204
1315
  },
1205
- i
1316
+ a
1206
1317
  ))
1207
1318
  ] }),
1208
- /* @__PURE__ */ e("div", { className: "flex flex-wrap items-center gap-1", children: on.map((i) => /* @__PURE__ */ e(
1319
+ /* @__PURE__ */ e("div", { className: "flex flex-wrap items-center gap-1", children: un.map((a) => /* @__PURE__ */ e(
1209
1320
  E,
1210
1321
  {
1211
- variant: v === i.value ? "secondary" : "outline",
1322
+ variant: v === a.value ? "secondary" : "outline",
1212
1323
  size: "sm",
1213
- onClick: () => N(i.value),
1214
- children: i.label
1324
+ onClick: () => N(a.value),
1325
+ children: a.label
1215
1326
  },
1216
- i.value
1327
+ a.value
1217
1328
  )) })
1218
1329
  ] }),
1219
1330
  /* @__PURE__ */ n("div", { className: "flex gap-4", children: [
1220
- /* @__PURE__ */ e("div", { className: "min-w-0 flex-1", children: x ? /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground py-8", children: "Loading items…" }) : _.length === 0 ? /* @__PURE__ */ e(we, { children: /* @__PURE__ */ e(Se, { className: "py-12 text-center text-muted-foreground", children: G.length === 0 ? "No items in this release yet." : "No items match the current filters." }) }) : /* @__PURE__ */ e(we, { children: /* @__PURE__ */ e(Se, { className: "p-0", children: /* @__PURE__ */ n("table", { className: "w-full text-sm", children: [
1331
+ /* @__PURE__ */ e("div", { className: "min-w-0 flex-1", children: x ? /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground py-8", children: "Loading items…" }) : _.length === 0 ? /* @__PURE__ */ e(Ce, { children: /* @__PURE__ */ e(Te, { className: "py-12 text-center text-muted-foreground", children: G.length === 0 ? "No items in this release yet." : "No items match the current filters." }) }) : /* @__PURE__ */ e(Ce, { children: /* @__PURE__ */ e(Te, { className: "p-0", children: /* @__PURE__ */ n("table", { className: "w-full text-sm", children: [
1221
1332
  /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ n("tr", { className: "border-b text-left text-muted-foreground", children: [
1222
1333
  /* @__PURE__ */ e("th", { className: "p-3 font-medium w-10", children: "Inc." }),
1223
1334
  /* @__PURE__ */ e("th", { className: "p-3 font-medium", children: "Type" }),
@@ -1225,18 +1336,18 @@ function dn({ releaseId: t, onBack: s }) {
1225
1336
  /* @__PURE__ */ e("th", { className: "p-3 font-medium", children: "Status" }),
1226
1337
  /* @__PURE__ */ e("th", { className: "p-3 font-medium" })
1227
1338
  ] }) }),
1228
- /* @__PURE__ */ e("tbody", { children: _.map(({ node: i, renderChildren: b }) => {
1339
+ /* @__PURE__ */ e("tbody", { children: _.map(({ node: a, renderChildren: b }) => {
1229
1340
  var _e;
1230
- const u = i.item, $ = b.length > 0, S = j.has(u.itemKey) || v !== "all", se = j.has(u.itemKey), re = sn(i), Ve = ((_e = u.diff) == null ? void 0 : _e.versions) ?? [], ue = u.itemType === "rule" && Ve.length > 0, He = Ve.some((P) => P.isPublished), kt = ue ? Ut(u) : [], Ue = ue && !He, Ye = ue && He && kt.length === 0, ve = Ue || Ye, wt = ue && !ve && u.selectedVersion == null;
1341
+ const m = a.item, $ = b.length > 0, T = j.has(m.itemKey) || v !== "all", se = j.has(m.itemKey), ie = ln(a), Ve = ((_e = m.diff) == null ? void 0 : _e.versions) ?? [], me = m.itemType === "rule" && Ve.length > 0, Ue = Ve.some((P) => P.isPublished), kt = me ? Wt(m) : [], He = me && !Ue, Ye = me && Ue && kt.length === 0, ve = He || Ye, Ct = me && !ve && m.selectedVersion == null;
1231
1342
  return /* @__PURE__ */ n(ct, { children: [
1232
- i.synthetic ? /* @__PURE__ */ n(
1343
+ a.synthetic ? /* @__PURE__ */ n(
1233
1344
  "tr",
1234
1345
  {
1235
1346
  className: "border-b last:border-0 cursor-pointer hover:bg-muted/50",
1236
- onClick: () => U(u.itemKey),
1347
+ onClick: () => H(m.itemKey),
1237
1348
  children: [
1238
1349
  /* @__PURE__ */ e("td", { className: "p-3" }),
1239
- /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(pe, { type: u.itemType }) }),
1350
+ /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(pe, { type: m.itemType }) }),
1240
1351
  /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ n("div", { className: "flex items-center gap-2", children: [
1241
1352
  /* @__PURE__ */ e(
1242
1353
  "button",
@@ -1244,17 +1355,17 @@ function dn({ releaseId: t, onBack: s }) {
1244
1355
  type: "button",
1245
1356
  className: "text-muted-foreground hover:text-foreground",
1246
1357
  onClick: (P) => {
1247
- P.stopPropagation(), U(u.itemKey);
1358
+ P.stopPropagation(), H(m.itemKey);
1248
1359
  },
1249
1360
  "aria-label": se ? "Collapse" : "Expand",
1250
- children: se ? /* @__PURE__ */ e(Pe, { size: 14 }) : /* @__PURE__ */ e(Te, { size: 14 })
1361
+ children: se ? /* @__PURE__ */ e(Pe, { size: 14 }) : /* @__PURE__ */ e(Se, { size: 14 })
1251
1362
  }
1252
1363
  ),
1253
- /* @__PURE__ */ e("span", { className: "font-medium", children: u.itemName }),
1254
- /* @__PURE__ */ n("span", { className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs ${re.included < re.total ? "bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300" : "bg-muted text-muted-foreground"}`, children: [
1255
- re.included,
1364
+ /* @__PURE__ */ e("span", { className: "font-medium", children: m.itemName }),
1365
+ /* @__PURE__ */ n("span", { className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs ${ie.included < ie.total ? "bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300" : "bg-muted text-muted-foreground"}`, children: [
1366
+ ie.included,
1256
1367
  "/",
1257
- re.total,
1368
+ ie.total,
1258
1369
  " changes included"
1259
1370
  ] })
1260
1371
  ] }) }),
@@ -1265,18 +1376,18 @@ function dn({ releaseId: t, onBack: s }) {
1265
1376
  ) : /* @__PURE__ */ n(
1266
1377
  "tr",
1267
1378
  {
1268
- className: `border-b last:border-0 cursor-pointer hover:bg-muted/50 ${(o == null ? void 0 : o.id) === u.id ? "bg-muted/50" : ""} ${ve ? "opacity-60" : ""}`,
1269
- onClick: () => h(u),
1379
+ className: `border-b last:border-0 cursor-pointer hover:bg-muted/50 ${(o == null ? void 0 : o.id) === m.id ? "bg-muted/50" : ""} ${ve ? "opacity-60" : ""}`,
1380
+ onClick: () => h(m),
1270
1381
  children: [
1271
1382
  /* @__PURE__ */ e("td", { className: "p-3", onClick: (P) => P.stopPropagation(), children: /* @__PURE__ */ e(
1272
1383
  Xe,
1273
1384
  {
1274
- checked: u.included,
1275
- disabled: u.ignored || be.isPending || te || ve,
1276
- onChange: (P) => be.mutate({ itemId: u.id, included: P })
1385
+ checked: m.included,
1386
+ disabled: m.ignored || be.isPending || te || ve,
1387
+ onChange: (P) => be.mutate({ itemId: m.id, included: P })
1277
1388
  }
1278
1389
  ) }),
1279
- /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(pe, { type: u.itemType }) }),
1390
+ /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(pe, { type: m.itemType }) }),
1280
1391
  /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ n("div", { className: "flex items-center gap-2", children: [
1281
1392
  $ ? /* @__PURE__ */ e(
1282
1393
  "button",
@@ -1284,65 +1395,65 @@ function dn({ releaseId: t, onBack: s }) {
1284
1395
  type: "button",
1285
1396
  className: "text-muted-foreground hover:text-foreground",
1286
1397
  onClick: (P) => {
1287
- P.stopPropagation(), U(u.itemKey);
1398
+ P.stopPropagation(), H(m.itemKey);
1288
1399
  },
1289
1400
  "aria-label": se ? "Collapse" : "Expand",
1290
- children: se ? /* @__PURE__ */ e(Pe, { size: 14 }) : /* @__PURE__ */ e(Te, { size: 14 })
1401
+ children: se ? /* @__PURE__ */ e(Pe, { size: 14 }) : /* @__PURE__ */ e(Se, { size: 14 })
1291
1402
  }
1292
1403
  ) : null,
1293
- /* @__PURE__ */ e("span", { className: "font-medium", children: u.itemName }),
1404
+ /* @__PURE__ */ e("span", { className: "font-medium", children: m.itemName }),
1294
1405
  (() => {
1295
- if (!u.included || u.ignored)
1406
+ if (!m.included || m.ignored)
1296
1407
  return null;
1297
- const P = ke(u, Z, C);
1298
- return P.length === 0 ? null : /* @__PURE__ */ e("span", { title: `Depends on excluded: ${P.map((W) => W.itemName).join(", ")}`, children: /* @__PURE__ */ e(ge, { size: 14, className: "shrink-0 text-amber-600" }) });
1408
+ const P = ke(m, Z, w);
1409
+ return P.length === 0 ? null : /* @__PURE__ */ e("span", { title: `Depends on excluded: ${P.map((W) => W.itemName).join(", ")}`, children: /* @__PURE__ */ e(fe, { size: 14, className: "shrink-0 text-amber-600" }) });
1299
1410
  })(),
1300
- /* @__PURE__ */ e(st, { item: u }),
1301
- $ ? /* @__PURE__ */ n("span", { className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs ${re.included < re.total ? "bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300" : "bg-muted text-muted-foreground"}`, children: [
1302
- re.included,
1411
+ /* @__PURE__ */ e(st, { item: m }),
1412
+ $ ? /* @__PURE__ */ n("span", { className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs ${ie.included < ie.total ? "bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300" : "bg-muted text-muted-foreground"}`, children: [
1413
+ ie.included,
1303
1414
  "/",
1304
- re.total,
1415
+ ie.total,
1305
1416
  " changes included"
1306
1417
  ] }) : null,
1307
- u.carriedOver ? /* @__PURE__ */ e(zt, { originName: q(f.originConfigId) }) : null,
1308
- u.ignored ? /* @__PURE__ */ e(Bt, {}) : null,
1309
- ue && !ve ? /* @__PURE__ */ e("span", { onClick: (P) => P.stopPropagation(), children: /* @__PURE__ */ e(
1310
- Yt,
1418
+ m.carriedOver ? /* @__PURE__ */ e(Lt, { originName: q(g.originConfigId) }) : null,
1419
+ m.ignored ? /* @__PURE__ */ e(Qt, {}) : null,
1420
+ me && !ve ? /* @__PURE__ */ e("span", { onClick: (P) => P.stopPropagation(), children: /* @__PURE__ */ e(
1421
+ Gt,
1311
1422
  {
1312
- item: u,
1423
+ item: m,
1313
1424
  disabled: te || Be.isPending,
1314
- onChange: (P) => Be.mutate({ itemId: u.id, selectedVersion: P })
1425
+ onChange: (P) => Be.mutate({ itemId: m.id, selectedVersion: P })
1315
1426
  }
1316
1427
  ) }) : null,
1317
- Ue ? /* @__PURE__ */ e("span", { className: "text-xs text-muted-foreground", children: "Rules without a published version cannot be pushed" }) : null,
1428
+ He ? /* @__PURE__ */ e("span", { className: "text-xs text-muted-foreground", children: "Rules without a published version cannot be pushed" }) : null,
1318
1429
  Ye ? /* @__PURE__ */ e("span", { className: "text-xs text-muted-foreground", children: "Nothing to push — all versions exist on target" }) : null,
1319
- wt ? /* @__PURE__ */ e("span", { className: "text-xs text-amber-600", children: "Pushable version not selected" }) : null
1430
+ Ct ? /* @__PURE__ */ e("span", { className: "text-xs text-amber-600", children: "Pushable version not selected" }) : null
1320
1431
  ] }) }),
1321
- /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(nt, { status: u.status }) }),
1432
+ /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(nt, { status: m.status }) }),
1322
1433
  /* @__PURE__ */ e("td", { className: "p-3 text-right", onClick: (P) => P.stopPropagation(), children: /* @__PURE__ */ n("div", { className: "flex items-center justify-end gap-2", children: [
1323
1434
  Y ? /* @__PURE__ */ e(
1324
- rt,
1435
+ it,
1325
1436
  {
1326
- item: u,
1327
- targetConfigIds: L,
1437
+ item: m,
1438
+ targetConfigIds: Q,
1328
1439
  results: p,
1329
1440
  pushedDests: F,
1330
1441
  displayName: q
1331
1442
  }
1332
1443
  ) : null,
1333
- !u.ignored && !te && /* @__PURE__ */ e(
1334
- Jt,
1444
+ !m.ignored && !te && /* @__PURE__ */ e(
1445
+ Vt,
1335
1446
  {
1336
1447
  createPayload: {
1337
- originConfigId: f.originConfigId,
1338
- itemKey: u.itemKey,
1339
- itemType: u.itemType,
1340
- itemName: u.itemName
1448
+ originConfigId: g.originConfigId,
1449
+ itemKey: m.itemKey,
1450
+ itemType: m.itemType,
1451
+ itemName: m.itemName
1341
1452
  },
1342
1453
  onChange: () => {
1343
1454
  l.setQueryData(
1344
- D,
1345
- (P) => (P ?? []).map((W) => W.id === u.id ? { ...W, ignored: !0, included: !1 } : W)
1455
+ M,
1456
+ (P) => (P ?? []).map((W) => W.id === m.id ? { ...W, ignored: !0, included: !1 } : W)
1346
1457
  ), ee.mutate();
1347
1458
  }
1348
1459
  }
@@ -1351,7 +1462,7 @@ function dn({ releaseId: t, onBack: s }) {
1351
1462
  ]
1352
1463
  }
1353
1464
  ),
1354
- $ && S ? b.map((P) => /* @__PURE__ */ n(
1465
+ $ && T ? b.map((P) => /* @__PURE__ */ n(
1355
1466
  "tr",
1356
1467
  {
1357
1468
  className: `border-b last:border-0 cursor-pointer hover:bg-muted/50 ${(o == null ? void 0 : o.id) === P.id ? "bg-muted/50" : ""}`,
@@ -1371,17 +1482,17 @@ function dn({ releaseId: t, onBack: s }) {
1371
1482
  (() => {
1372
1483
  if (!P.included || P.ignored)
1373
1484
  return null;
1374
- const W = ke(P, Z, C);
1375
- return W.length === 0 ? null : /* @__PURE__ */ e("span", { title: `Depends on excluded: ${W.map((St) => St.itemName).join(", ")}`, children: /* @__PURE__ */ e(ge, { size: 14, className: "shrink-0 text-amber-600" }) });
1485
+ const W = ke(P, Z, w);
1486
+ return W.length === 0 ? null : /* @__PURE__ */ e("span", { title: `Depends on excluded: ${W.map((Tt) => Tt.itemName).join(", ")}`, children: /* @__PURE__ */ e(fe, { size: 14, className: "shrink-0 text-amber-600" }) });
1376
1487
  })(),
1377
1488
  /* @__PURE__ */ e(st, { item: P })
1378
1489
  ] }) }),
1379
1490
  /* @__PURE__ */ e("td", { className: "p-3", children: /* @__PURE__ */ e(nt, { status: P.status }) }),
1380
1491
  /* @__PURE__ */ e("td", { className: "p-3 text-right", onClick: (W) => W.stopPropagation(), children: Y ? /* @__PURE__ */ e(
1381
- rt,
1492
+ it,
1382
1493
  {
1383
1494
  item: P,
1384
- targetConfigIds: L,
1495
+ targetConfigIds: Q,
1385
1496
  results: p,
1386
1497
  pushedDests: F,
1387
1498
  displayName: q
@@ -1391,87 +1502,87 @@ function dn({ releaseId: t, onBack: s }) {
1391
1502
  },
1392
1503
  P.id
1393
1504
  )) : null
1394
- ] }, i.synthetic ? u.itemKey : u.id);
1505
+ ] }, a.synthetic ? m.itemKey : m.id);
1395
1506
  }) })
1396
1507
  ] }) }) }) }),
1397
1508
  o ? /* @__PURE__ */ e("div", { className: "w-[28rem] shrink-0 self-start sticky top-4 max-h-[calc(100vh-2rem)] overflow-auto", children: /* @__PURE__ */ e(
1398
- Lt,
1509
+ Ht,
1399
1510
  {
1400
1511
  item: y,
1401
- targets: (f.targetConfigIds ?? []).map((i) => ({ id: i, name: q(i) })),
1512
+ targets: (g.targetConfigIds ?? []).map((a) => ({ id: a, name: q(a) })),
1402
1513
  onClose: () => h(null),
1403
- unmetDependencyNames: y && y.included && !y.ignored ? ke(y, Z, C).map(R) : [],
1404
- tags: Array.isArray((Qe = (Je = y == null ? void 0 : y.diff) == null ? void 0 : Je.origin) == null ? void 0 : Qe.tags) ? ((Le = y == null ? void 0 : y.diff) == null ? void 0 : Le.origin).tags ?? [] : [],
1514
+ unmetDependencyNames: y && y.included && !y.ignored ? ke(y, Z, w).map(R) : [],
1515
+ tags: Array.isArray((Le = (Je = y == null ? void 0 : y.diff) == null ? void 0 : Je.origin) == null ? void 0 : Le.tags) ? ((Qe = y == null ? void 0 : y.diff) == null ? void 0 : Qe.origin).tags ?? [] : [],
1405
1516
  excludedTags: X(y == null ? void 0 : y.excludedTags),
1406
1517
  metadataKeys: (() => {
1407
- var b, u;
1408
- const i = (u = (b = y == null ? void 0 : y.diff) == null ? void 0 : b.origin) == null ? void 0 : u.metadata;
1409
- return i != null && typeof i == "object" && !Array.isArray(i) ? Object.keys(i) : [];
1518
+ var b, m;
1519
+ const a = (m = (b = y == null ? void 0 : y.diff) == null ? void 0 : b.origin) == null ? void 0 : m.metadata;
1520
+ return a != null && typeof a == "object" && !Array.isArray(a) ? Object.keys(a) : [];
1410
1521
  })(),
1411
1522
  excludedMetadataKeys: X(y == null ? void 0 : y.excludedMetadataKeys),
1412
1523
  i18nPaths: (() => {
1413
- var u, $;
1414
- const i = ($ = (u = y == null ? void 0 : y.diff) == null ? void 0 : u.origin) == null ? void 0 : $.i18n;
1415
- if (!Array.isArray(i))
1524
+ var m, $;
1525
+ const a = ($ = (m = y == null ? void 0 : y.diff) == null ? void 0 : m.origin) == null ? void 0 : $.i18n;
1526
+ if (!Array.isArray(a))
1416
1527
  return [];
1417
- const b = i.map((S) => S == null ? void 0 : S.path).filter((S) => typeof S == "string");
1528
+ const b = a.map((T) => T == null ? void 0 : T.path).filter((T) => typeof T == "string");
1418
1529
  return Array.from(new Set(b));
1419
1530
  })(),
1420
1531
  excludedI18nPaths: X(y == null ? void 0 : y.excludedI18nPaths),
1421
1532
  permissionKeys: (() => {
1422
- var u, $;
1533
+ var m, $;
1423
1534
  if ((y == null ? void 0 : y.itemType) !== "role")
1424
1535
  return [];
1425
- const i = ($ = (u = y == null ? void 0 : y.diff) == null ? void 0 : u.origin) == null ? void 0 : $.permissions;
1426
- if (!Array.isArray(i))
1536
+ const a = ($ = (m = y == null ? void 0 : y.diff) == null ? void 0 : m.origin) == null ? void 0 : $.permissions;
1537
+ if (!Array.isArray(a))
1427
1538
  return [];
1428
- const b = i.map((S) => `${(S == null ? void 0 : S.module) ?? ""}/${(S == null ? void 0 : S.name) ?? (S == null ? void 0 : S.id) ?? ""}`).filter((S) => S !== "/");
1539
+ const b = a.map((T) => `${(T == null ? void 0 : T.module) ?? ""}/${(T == null ? void 0 : T.name) ?? (T == null ? void 0 : T.id) ?? ""}`).filter((T) => T !== "/");
1429
1540
  return Array.from(new Set(b));
1430
1541
  })(),
1431
1542
  excludedPermissions: X(y == null ? void 0 : y.excludedPermissions),
1432
- formatPermissionLabel: (i) => i.split(/([/.])/).map((b) => {
1433
- var u, $;
1434
- return (($ = (u = y == null ? void 0 : y.diff) == null ? void 0 : u.nameMap) == null ? void 0 : $[b]) ?? T.get(b) ?? b;
1543
+ formatPermissionLabel: (a) => a.split(/([/.])/).map((b) => {
1544
+ var m, $;
1545
+ return (($ = (m = y == null ? void 0 : y.diff) == null ? void 0 : m.nameMap) == null ? void 0 : $[b]) ?? S.get(b) ?? b;
1435
1546
  }).join(""),
1436
- replacementMaps: f.replacementMaps ?? void 0,
1547
+ replacementMaps: g.replacementMaps ?? void 0,
1437
1548
  editable: !te,
1438
- onToggleTag: (i, b) => {
1549
+ onToggleTag: (a, b) => {
1439
1550
  if (!y)
1440
1551
  return;
1441
- const u = X(y.excludedTags), $ = b ? u.filter((S) => S !== i) : Array.from(/* @__PURE__ */ new Set([...u, i]));
1552
+ const m = X(y.excludedTags), $ = b ? m.filter((T) => T !== a) : Array.from(/* @__PURE__ */ new Set([...m, a]));
1442
1553
  yt.mutate({ itemId: y.id, value: $ });
1443
1554
  },
1444
- onToggleMetadataKey: (i, b) => {
1555
+ onToggleMetadataKey: (a, b) => {
1445
1556
  if (!y)
1446
1557
  return;
1447
- const u = X(y.excludedMetadataKeys), $ = b ? u.filter((S) => S !== i) : Array.from(/* @__PURE__ */ new Set([...u, i]));
1558
+ const m = X(y.excludedMetadataKeys), $ = b ? m.filter((T) => T !== a) : Array.from(/* @__PURE__ */ new Set([...m, a]));
1448
1559
  bt.mutate({ itemId: y.id, value: $ });
1449
1560
  },
1450
- onToggleI18nPath: (i, b) => {
1561
+ onToggleI18nPath: (a, b) => {
1451
1562
  if (!y)
1452
1563
  return;
1453
- const u = X(y.excludedI18nPaths), $ = b ? u.filter((S) => S !== i) : Array.from(/* @__PURE__ */ new Set([...u, i]));
1564
+ const m = X(y.excludedI18nPaths), $ = b ? m.filter((T) => T !== a) : Array.from(/* @__PURE__ */ new Set([...m, a]));
1454
1565
  Nt.mutate({ itemId: y.id, value: $ });
1455
1566
  },
1456
- onTogglePermission: (i, b) => {
1567
+ onTogglePermission: (a, b) => {
1457
1568
  if (!y)
1458
1569
  return;
1459
- const u = X(y.excludedPermissions), $ = b ? u.filter((S) => S !== i) : Array.from(/* @__PURE__ */ new Set([...u, i]));
1570
+ const m = X(y.excludedPermissions), $ = b ? m.filter((T) => T !== a) : Array.from(/* @__PURE__ */ new Set([...m, a]));
1460
1571
  vt.mutate({ itemId: y.id, value: $ });
1461
1572
  }
1462
1573
  }
1463
1574
  ) }) : null
1464
1575
  ] }),
1465
1576
  /* @__PURE__ */ e(
1466
- Ht,
1577
+ _t,
1467
1578
  {
1468
- open: O,
1469
- onOpenChange: M,
1579
+ open: I,
1580
+ onOpenChange: D,
1470
1581
  releaseId: t,
1471
- apiPath: r,
1472
- targetConfigIds: f.targetConfigIds ?? [],
1582
+ apiPath: i,
1583
+ targetConfigIds: g.targetConfigIds ?? [],
1473
1584
  targetNames: Object.fromEntries(
1474
- (f.targetConfigIds ?? []).map((i) => [i, q(i)])
1585
+ (g.targetConfigIds ?? []).map((a) => [a, q(a)])
1475
1586
  ),
1476
1587
  dependencyWarnings: de
1477
1588
  }
@@ -1484,31 +1595,31 @@ function dn({ releaseId: t, onBack: s }) {
1484
1595
  /* @__PURE__ */ e("p", { className: "text-muted-foreground", children: "Release not found." })
1485
1596
  ] });
1486
1597
  }
1487
- function it({ value: t, onChange: s, configs: r, label: a }) {
1488
- const d = `cluster-select-${a.toLowerCase().replace(/\s+/g, "-")}`;
1598
+ function at({ value: t, onChange: s, configs: i, label: r }) {
1599
+ const d = `cluster-select-${r.toLowerCase().replace(/\s+/g, "-")}`;
1489
1600
  return /* @__PURE__ */ n("div", { className: "space-y-2", children: [
1490
- /* @__PURE__ */ e(ie, { htmlFor: d, children: a }),
1601
+ /* @__PURE__ */ e(ae, { htmlFor: d, children: r }),
1491
1602
  /* @__PURE__ */ n(
1492
1603
  "select",
1493
1604
  {
1494
1605
  id: d,
1495
1606
  value: t,
1496
- onChange: (m) => s(m.target.value),
1607
+ onChange: (u) => s(u.target.value),
1497
1608
  className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
1498
1609
  children: [
1499
1610
  /* @__PURE__ */ e("option", { value: "", children: "Select cluster…" }),
1500
- r.map((m) => /* @__PURE__ */ e("option", { value: m.id, children: m.displayName }, m.id))
1611
+ i.map((u) => /* @__PURE__ */ e("option", { value: u.id, children: u.displayName }, u.id))
1501
1612
  ]
1502
1613
  }
1503
1614
  )
1504
1615
  ] });
1505
1616
  }
1506
- function cn({ item: t, onClose: s }) {
1507
- var a, d;
1508
- const r = J(
1617
+ function hn({ item: t, onClose: s }) {
1618
+ var r, d;
1619
+ const i = J(
1509
1620
  () => {
1510
- var m, l;
1511
- return xt((m = t == null ? void 0 : t.diff) == null ? void 0 : m.origin, (l = t == null ? void 0 : t.diff) == null ? void 0 : l.target);
1621
+ var u, l;
1622
+ return xt((u = t == null ? void 0 : t.diff) == null ? void 0 : u.origin, (l = t == null ? void 0 : t.diff) == null ? void 0 : l.target);
1512
1623
  },
1513
1624
  [t]
1514
1625
  );
@@ -1521,12 +1632,12 @@ function cn({ item: t, onClose: s }) {
1521
1632
  /* @__PURE__ */ e(E, { variant: "ghost", size: "icon", title: "Close", onClick: s, children: /* @__PURE__ */ e(xe, {}) })
1522
1633
  ] }),
1523
1634
  /* @__PURE__ */ n("div", { className: "flex flex-1 gap-3 overflow-auto p-3", children: [
1524
- /* @__PURE__ */ e(Ke, { label: "Origin", value: (a = t.diff) == null ? void 0 : a.origin, highlightLines: r }),
1635
+ /* @__PURE__ */ e(Ke, { label: "Origin", value: (r = t.diff) == null ? void 0 : r.origin, highlightLines: i }),
1525
1636
  /* @__PURE__ */ e(Ke, { label: "Target", value: (d = t.diff) == null ? void 0 : d.target })
1526
1637
  ] })
1527
1638
  ] }) : null;
1528
1639
  }
1529
- const at = {
1640
+ const rt = {
1530
1641
  match: { symbol: "✓", className: "text-muted-foreground", label: "Match" },
1531
1642
  diff: { symbol: "≠", className: "text-red-500 dark:text-red-400 font-semibold", label: "Diff" },
1532
1643
  translated: { symbol: "≈", className: "text-blue-600 dark:text-blue-400 font-semibold", label: "Translated" },
@@ -1537,114 +1648,114 @@ const at = {
1537
1648
  function lt({
1538
1649
  state: t,
1539
1650
  onClick: s,
1540
- active: r
1651
+ active: i
1541
1652
  }) {
1542
- const a = at[t] ?? at.match, d = t !== "match" && t !== "skip" && !!s;
1653
+ const r = rt[t] ?? rt.match, d = t !== "match" && t !== "skip" && !!s;
1543
1654
  return /* @__PURE__ */ e(
1544
1655
  "button",
1545
1656
  {
1546
1657
  type: "button",
1547
1658
  onClick: d ? s : void 0,
1548
1659
  disabled: !d,
1549
- title: a.label,
1660
+ title: r.label,
1550
1661
  className: ce(
1551
1662
  "w-full text-center text-sm py-1 rounded",
1552
- a.className,
1663
+ r.className,
1553
1664
  d && "hover:bg-muted cursor-pointer",
1554
1665
  !d && "cursor-default",
1555
- r && "bg-muted ring-1 ring-ring"
1666
+ i && "bg-muted ring-1 ring-ring"
1556
1667
  ),
1557
- children: a.symbol
1668
+ children: r.symbol
1558
1669
  }
1559
1670
  );
1560
1671
  }
1561
- function mn({ stats: t, destConfigIds: s }) {
1562
- return /* @__PURE__ */ e("div", { className: "flex gap-6 text-xs text-muted-foreground py-2 px-1", children: s.map((r) => {
1563
- const a = t[r];
1564
- if (!a)
1672
+ function pn({ stats: t, destConfigIds: s }) {
1673
+ return /* @__PURE__ */ e("div", { className: "flex gap-6 text-xs text-muted-foreground py-2 px-1", children: s.map((i) => {
1674
+ const r = t[i];
1675
+ if (!r)
1565
1676
  return null;
1566
- const d = a.match + a.diff + a.missing + a.extra;
1677
+ const d = r.match + r.diff + r.missing + r.extra;
1567
1678
  return /* @__PURE__ */ n("span", { children: [
1568
1679
  /* @__PURE__ */ n("span", { className: "font-mono font-medium", children: [
1569
- a.match,
1680
+ r.match,
1570
1681
  "/",
1571
1682
  d
1572
1683
  ] }),
1573
1684
  " match",
1574
- a.diff > 0 && /* @__PURE__ */ n("span", { className: "text-destructive ml-2", children: [
1575
- a.diff,
1685
+ r.diff > 0 && /* @__PURE__ */ n("span", { className: "text-destructive ml-2", children: [
1686
+ r.diff,
1576
1687
  " diff"
1577
1688
  ] }),
1578
- a.missing > 0 && /* @__PURE__ */ n("span", { className: "text-destructive ml-2", children: [
1579
- a.missing,
1689
+ r.missing > 0 && /* @__PURE__ */ n("span", { className: "text-destructive ml-2", children: [
1690
+ r.missing,
1580
1691
  " missing"
1581
1692
  ] }),
1582
- a.extra > 0 && /* @__PURE__ */ n("span", { className: "text-amber-600 ml-2", children: [
1583
- a.extra,
1693
+ r.extra > 0 && /* @__PURE__ */ n("span", { className: "text-amber-600 ml-2", children: [
1694
+ r.extra,
1584
1695
  " extra"
1585
1696
  ] })
1586
- ] }, r);
1697
+ ] }, i);
1587
1698
  }) });
1588
1699
  }
1589
1700
  function ot(t) {
1590
1701
  return Object.values(t.cells).some((s) => s === "diff" || s === "missing" || s === "extra");
1591
1702
  }
1592
- function un({
1703
+ function fn({
1593
1704
  originConfigId: t,
1594
1705
  destConfigIds: s,
1595
- apiPath: r = "/release-status"
1706
+ apiPath: i = "/release-status"
1596
1707
  }) {
1597
- const { toast: a } = le(), { fetchJson: d } = ne(), { configs: m } = fe(), l = oe(), [c, g] = A("issues"), [v, N] = A(!1), [o, h] = A(null), [O, M] = A(/* @__PURE__ */ new Set()), [j, H] = A(() => /* @__PURE__ */ new Set()), U = (C) => H((R) => {
1598
- const T = new Set(R);
1599
- return T.has(C) ? T.delete(C) : T.add(C), T;
1708
+ const { toast: r } = le(), { fetchJson: d } = ne(), { configs: u } = ge(), l = oe(), [c, f] = A("issues"), [v, N] = A(!1), [o, h] = A(null), [I, D] = A(/* @__PURE__ */ new Set()), [j, U] = A(() => /* @__PURE__ */ new Set()), H = (w) => U((R) => {
1709
+ const S = new Set(R);
1710
+ return S.has(w) ? S.delete(w) : S.add(w), S;
1600
1711
  }), z = J(() => {
1601
- const C = /* @__PURE__ */ new Map();
1602
- return m.forEach((R) => C.set(R.id, R.displayName)), C;
1603
- }, [m]), D = (C) => z.get(C) ?? C, B = s.filter((C) => !O.has(C)), f = new URLSearchParams();
1604
- f.set("originConfigId", t), B.forEach((C) => f.append("destConfigIds[]", C));
1605
- const k = ["imaginarium", "release-status", t, B], { data: w, isLoading: x, isError: K } = ae({
1712
+ const w = /* @__PURE__ */ new Map();
1713
+ return u.forEach((R) => w.set(R.id, R.displayName)), w;
1714
+ }, [u]), M = (w) => z.get(w) ?? w, B = s.filter((w) => !I.has(w)), g = new URLSearchParams();
1715
+ g.set("originConfigId", t), B.forEach((w) => g.append("destConfigIds[]", w));
1716
+ const k = ["imaginarium", "release-status", t, B], { data: C, isLoading: x, isError: K } = re({
1606
1717
  queryKey: k,
1607
- queryFn: () => d(`${r}?${f.toString()}`),
1718
+ queryFn: () => d(`${i}?${g.toString()}`),
1608
1719
  enabled: B.length > 0
1609
- }), p = Q({
1610
- mutationFn: () => d(`${r}/refresh`, {
1720
+ }), p = L({
1721
+ mutationFn: () => d(`${i}/refresh`, {
1611
1722
  method: "POST",
1612
1723
  body: JSON.stringify({ originConfigId: t, destConfigIds: B })
1613
1724
  }),
1614
1725
  onSuccess: () => {
1615
- l.invalidateQueries({ queryKey: k }), a({ title: "Cache cleared", description: "Refreshing comparison data…" });
1726
+ l.invalidateQueries({ queryKey: k }), r({ title: "Cache cleared", description: "Refreshing comparison data…" });
1616
1727
  },
1617
- onError: (C) => {
1618
- a({ title: "Error", description: C.message, variant: "destructive" });
1728
+ onError: (w) => {
1729
+ r({ title: "Error", description: w.message, variant: "destructive" });
1619
1730
  }
1620
1731
  }), {
1621
1732
  data: F,
1622
1733
  isLoading: Y,
1623
- isError: L
1624
- } = ae({
1734
+ isError: Q
1735
+ } = re({
1625
1736
  queryKey: ["imaginarium", "release-status-diff", t, o == null ? void 0 : o.destConfigId, o == null ? void 0 : o.itemKey],
1626
1737
  queryFn: () => d(
1627
- `${r}/diff?originConfigId=${encodeURIComponent(t)}&destConfigId=${encodeURIComponent(o.destConfigId)}&itemKey=${encodeURIComponent(o.itemKey)}`
1738
+ `${i}/diff?originConfigId=${encodeURIComponent(t)}&destConfigId=${encodeURIComponent(o.destConfigId)}&itemKey=${encodeURIComponent(o.itemKey)}`
1628
1739
  ),
1629
1740
  enabled: !!o
1630
- }), V = (C) => {
1631
- M((R) => {
1632
- const T = new Set(R);
1633
- return T.has(C) ? T.delete(C) : T.add(C), T;
1741
+ }), V = (w) => {
1742
+ D((R) => {
1743
+ const S = new Set(R);
1744
+ return S.has(w) ? S.delete(w) : S.add(w), S;
1634
1745
  });
1635
- }, q = (C, R) => {
1746
+ }, q = (w, R) => {
1636
1747
  h(
1637
- (T) => (T == null ? void 0 : T.itemKey) === C && T.destConfigId === R ? null : { itemKey: C, destConfigId: R }
1748
+ (S) => (S == null ? void 0 : S.itemKey) === w && S.destConfigId === R ? null : { itemKey: w, destConfigId: R }
1638
1749
  );
1639
- }, I = (w == null ? void 0 : w.rows) ?? [], G = (w == null ? void 0 : w.stats) ?? {}, Z = J(() => nn(I).map((R) => {
1640
- const T = c === "issues" ? R.children.filter(ot) : R.children;
1641
- return { node: R, renderChildren: T };
1750
+ }, O = (C == null ? void 0 : C.rows) ?? [], G = (C == null ? void 0 : C.stats) ?? {}, Z = J(() => rn(O).map((R) => {
1751
+ const S = c === "issues" ? R.children.filter(ot) : R.children;
1752
+ return { node: R, renderChildren: S };
1642
1753
  }).filter(
1643
- ({ node: R, renderChildren: T }) => c === "all" || ot(R.row) || T.length > 0
1644
- ).sort((R, T) => {
1645
- const de = qe(R.node.row.itemType, T.node.row.itemType);
1646
- return de !== 0 ? de : R.node.row.itemName.localeCompare(T.node.row.itemName);
1647
- }), [I, c]);
1754
+ ({ node: R, renderChildren: S }) => c === "all" || ot(R.row) || S.length > 0
1755
+ ).sort((R, S) => {
1756
+ const de = qe(R.node.row.itemType, S.node.row.itemType);
1757
+ return de !== 0 ? de : R.node.row.itemName.localeCompare(S.node.row.itemName);
1758
+ }), [O, c]);
1648
1759
  return /* @__PURE__ */ n("div", { className: "space-y-3", children: [
1649
1760
  /* @__PURE__ */ n("div", { className: "flex items-center gap-2 flex-wrap", children: [
1650
1761
  /* @__PURE__ */ n("div", { className: "flex rounded-md border text-sm overflow-hidden", children: [
@@ -1652,7 +1763,7 @@ function un({
1652
1763
  "button",
1653
1764
  {
1654
1765
  className: ce("px-3 py-1.5", c === "issues" ? "bg-muted font-medium" : "hover:bg-muted/50"),
1655
- onClick: () => g("issues"),
1766
+ onClick: () => f("issues"),
1656
1767
  children: "Issues only"
1657
1768
  }
1658
1769
  ),
@@ -1660,13 +1771,13 @@ function un({
1660
1771
  "button",
1661
1772
  {
1662
1773
  className: ce("px-3 py-1.5 border-l", c === "all" ? "bg-muted font-medium" : "hover:bg-muted/50"),
1663
- onClick: () => g("all"),
1774
+ onClick: () => f("all"),
1664
1775
  children: "All"
1665
1776
  }
1666
1777
  )
1667
1778
  ] }),
1668
- /* @__PURE__ */ n(E, { variant: "ghost", size: "sm", onClick: () => N((C) => !C), children: [
1669
- /* @__PURE__ */ e(Ot, {}),
1779
+ /* @__PURE__ */ n(E, { variant: "ghost", size: "sm", onClick: () => N((w) => !w), children: [
1780
+ /* @__PURE__ */ e(At, {}),
1670
1781
  "Stats"
1671
1782
  ] }),
1672
1783
  /* @__PURE__ */ n(
@@ -1682,41 +1793,41 @@ function un({
1682
1793
  ]
1683
1794
  }
1684
1795
  ),
1685
- [...O].map((C) => /* @__PURE__ */ n(
1796
+ [...I].map((w) => /* @__PURE__ */ n(
1686
1797
  "button",
1687
1798
  {
1688
- onClick: () => V(C),
1799
+ onClick: () => V(w),
1689
1800
  className: "text-xs border rounded px-2 py-1 text-muted-foreground hover:bg-muted",
1690
1801
  children: [
1691
1802
  "+ ",
1692
- D(C)
1803
+ M(w)
1693
1804
  ]
1694
1805
  },
1695
- C
1806
+ w
1696
1807
  ))
1697
1808
  ] }),
1698
- v && w && /* @__PURE__ */ e(mn, { stats: G, destConfigIds: B }),
1809
+ v && C && /* @__PURE__ */ e(pn, { stats: G, destConfigIds: B }),
1699
1810
  x && /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground py-8", children: "Loading…" }),
1700
1811
  K && /* @__PURE__ */ e("div", { className: "text-center text-destructive py-8", children: "Failed to load comparison data." }),
1701
1812
  !x && !K && /* @__PURE__ */ n("div", { className: "flex gap-4", children: [
1702
1813
  /* @__PURE__ */ e("div", { className: "min-w-0 flex-1 rounded-md border overflow-x-auto", children: /* @__PURE__ */ n("table", { className: "w-full text-sm", children: [
1703
1814
  /* @__PURE__ */ e("thead", { children: /* @__PURE__ */ n("tr", { className: "border-b bg-muted/50", children: [
1704
1815
  /* @__PURE__ */ e("th", { className: "px-4 py-2 text-left font-medium min-w-[200px]", children: "Item" }),
1705
- B.map((C) => /* @__PURE__ */ e("th", { className: "px-2 py-2 text-center font-medium min-w-[80px]", children: /* @__PURE__ */ n("div", { className: "flex items-center justify-center gap-1", children: [
1706
- /* @__PURE__ */ e("span", { className: "truncate max-w-[120px]", title: D(C), children: D(C) }),
1816
+ B.map((w) => /* @__PURE__ */ e("th", { className: "px-2 py-2 text-center font-medium min-w-[80px]", children: /* @__PURE__ */ n("div", { className: "flex items-center justify-center gap-1", children: [
1817
+ /* @__PURE__ */ e("span", { className: "truncate max-w-[120px]", title: M(w), children: M(w) }),
1707
1818
  /* @__PURE__ */ e(
1708
1819
  "button",
1709
1820
  {
1710
1821
  className: "text-muted-foreground hover:text-foreground",
1711
- onClick: () => V(C),
1822
+ onClick: () => V(w),
1712
1823
  title: "Hide column",
1713
1824
  children: "×"
1714
1825
  }
1715
1826
  )
1716
- ] }) }, C))
1827
+ ] }) }, w))
1717
1828
  ] }) }),
1718
- /* @__PURE__ */ e("tbody", { children: Z.length === 0 ? /* @__PURE__ */ e("tr", { children: /* @__PURE__ */ e("td", { colSpan: B.length + 1, className: "text-center text-muted-foreground py-8", children: c === "issues" ? "No issues found — all clusters in sync." : "No items." }) }) : Z.map(({ node: C, renderChildren: R }) => {
1719
- const T = C.row, de = R.length > 0, me = j.has(T.itemKey) || c === "issues", ye = j.has(T.itemKey);
1829
+ /* @__PURE__ */ e("tbody", { children: Z.length === 0 ? /* @__PURE__ */ e("tr", { children: /* @__PURE__ */ e("td", { colSpan: B.length + 1, className: "text-center text-muted-foreground py-8", children: c === "issues" ? "No issues found — all clusters in sync." : "No items." }) }) : Z.map(({ node: w, renderChildren: R }) => {
1830
+ const S = w.row, de = R.length > 0, ue = j.has(S.itemKey) || c === "issues", ye = j.has(S.itemKey);
1720
1831
  return /* @__PURE__ */ n(ct, { children: [
1721
1832
  /* @__PURE__ */ n("tr", { className: "border-b last:border-0 hover:bg-muted/25", children: [
1722
1833
  /* @__PURE__ */ e("td", { className: "px-4 py-1.5", children: /* @__PURE__ */ n("div", { className: "flex items-center gap-2", children: [
@@ -1725,24 +1836,24 @@ function un({
1725
1836
  {
1726
1837
  type: "button",
1727
1838
  className: "text-muted-foreground hover:text-foreground",
1728
- onClick: () => U(T.itemKey),
1839
+ onClick: () => H(S.itemKey),
1729
1840
  "aria-label": ye ? "Collapse" : "Expand",
1730
- children: ye ? /* @__PURE__ */ e(Pe, { size: 14 }) : /* @__PURE__ */ e(Te, { size: 14 })
1841
+ children: ye ? /* @__PURE__ */ e(Pe, { size: 14 }) : /* @__PURE__ */ e(Se, { size: 14 })
1731
1842
  }
1732
1843
  ) : null,
1733
- /* @__PURE__ */ e("span", { className: "inline-flex align-middle", children: /* @__PURE__ */ e(pe, { type: T.itemType }) }),
1734
- /* @__PURE__ */ e("span", { className: "font-medium", children: T.itemName })
1844
+ /* @__PURE__ */ e("span", { className: "inline-flex align-middle", children: /* @__PURE__ */ e(pe, { type: S.itemType }) }),
1845
+ /* @__PURE__ */ e("span", { className: "font-medium", children: S.itemName })
1735
1846
  ] }) }),
1736
1847
  B.map((_) => /* @__PURE__ */ e("td", { className: "px-2 py-1", children: /* @__PURE__ */ e(
1737
1848
  lt,
1738
1849
  {
1739
- state: T.cells[_] ?? "match",
1740
- active: (o == null ? void 0 : o.itemKey) === T.itemKey && o.destConfigId === _,
1741
- onClick: () => q(T.itemKey, _)
1850
+ state: S.cells[_] ?? "match",
1851
+ active: (o == null ? void 0 : o.itemKey) === S.itemKey && o.destConfigId === _,
1852
+ onClick: () => q(S.itemKey, _)
1742
1853
  }
1743
1854
  ) }, _))
1744
1855
  ] }),
1745
- de && me ? R.map((_) => /* @__PURE__ */ n("tr", { className: "border-b last:border-0 hover:bg-muted/25", children: [
1856
+ de && ue ? R.map((_) => /* @__PURE__ */ n("tr", { className: "border-b last:border-0 hover:bg-muted/25", children: [
1746
1857
  /* @__PURE__ */ e("td", { className: "px-4 py-1.5 pl-8", children: /* @__PURE__ */ n("div", { className: "flex items-center gap-2", children: [
1747
1858
  /* @__PURE__ */ e("span", { className: "inline-flex align-middle", children: /* @__PURE__ */ e(pe, { type: _.itemType }) }),
1748
1859
  /* @__PURE__ */ e("span", { className: "font-medium", children: _.itemName })
@@ -1756,11 +1867,11 @@ function un({
1756
1867
  }
1757
1868
  ) }, ee))
1758
1869
  ] }, _.itemKey)) : null
1759
- ] }, T.itemKey);
1870
+ ] }, S.itemKey);
1760
1871
  }) })
1761
1872
  ] }) }),
1762
- o ? /* @__PURE__ */ e("div", { className: "w-[28rem] shrink-0 self-start sticky top-4 max-h-[calc(100vh-2rem)] overflow-auto", children: Y ? /* @__PURE__ */ e("div", { className: "flex h-full items-center justify-center rounded-md border bg-background p-4 text-sm text-muted-foreground", children: "Loading diff…" }) : L || !F ? /* @__PURE__ */ e("div", { className: "flex h-full items-center justify-center rounded-md border bg-background p-4 text-sm text-muted-foreground", children: "No diff available." }) : /* @__PURE__ */ e(
1763
- cn,
1873
+ o ? /* @__PURE__ */ e("div", { className: "w-[28rem] shrink-0 self-start sticky top-4 max-h-[calc(100vh-2rem)] overflow-auto", children: Y ? /* @__PURE__ */ e("div", { className: "flex h-full items-center justify-center rounded-md border bg-background p-4 text-sm text-muted-foreground", children: "Loading diff…" }) : Q || !F ? /* @__PURE__ */ e("div", { className: "flex h-full items-center justify-center rounded-md border bg-background p-4 text-sm text-muted-foreground", children: "No diff available." }) : /* @__PURE__ */ e(
1874
+ hn,
1764
1875
  {
1765
1876
  item: {
1766
1877
  itemName: F.itemName,
@@ -1778,85 +1889,85 @@ const dt = (t) => ({
1778
1889
  description: "",
1779
1890
  values: Object.fromEntries(t.map((s) => [s, ""]))
1780
1891
  });
1781
- function hn({
1892
+ function gn({
1782
1893
  configIds: t,
1783
1894
  clusterNames: s = {},
1784
- apiPath: r = "/release-translations"
1895
+ apiPath: i = "/release-translations"
1785
1896
  }) {
1786
- const { toast: a } = le(), { fetchJson: d } = ne(), m = oe(), [l, c] = A(!1), [g, v] = A(null), [N, o] = A(dt(t)), h = ["imaginarium", "release-translations"], { data: O, isLoading: M } = ae({
1897
+ const { toast: r } = le(), { fetchJson: d } = ne(), u = oe(), [l, c] = A(!1), [f, v] = A(null), [N, o] = A(dt(t)), h = ["imaginarium", "release-translations"], { data: I, isLoading: D } = re({
1787
1898
  queryKey: h,
1788
1899
  queryFn: async () => {
1789
- const p = await d(r);
1900
+ const p = await d(i);
1790
1901
  return (p == null ? void 0 : p.items) ?? [];
1791
1902
  }
1792
- }), j = Q({
1903
+ }), j = L({
1793
1904
  mutationFn: async (p) => {
1794
- const F = await d(r, {
1905
+ const F = await d(i, {
1795
1906
  method: "POST",
1796
1907
  body: JSON.stringify({ name: p.name.trim(), description: p.description.trim() || null })
1797
1908
  });
1798
1909
  await z(F.id, p.values);
1799
1910
  },
1800
1911
  onSuccess: () => {
1801
- m.invalidateQueries({ queryKey: h }), a({ title: "Translation created" }), f();
1912
+ u.invalidateQueries({ queryKey: h }), r({ title: "Translation created" }), g();
1802
1913
  },
1803
- onError: (p) => a({ title: "Error", description: p.message, variant: "destructive" })
1804
- }), H = Q({
1914
+ onError: (p) => r({ title: "Error", description: p.message, variant: "destructive" })
1915
+ }), U = L({
1805
1916
  mutationFn: async (p) => {
1806
- await d(`${r}/${g.id}`, {
1917
+ await d(`${i}/${f.id}`, {
1807
1918
  method: "PATCH",
1808
1919
  body: JSON.stringify({ name: p.name.trim(), description: p.description.trim() || null })
1809
- }), await z(g.id, p.values);
1920
+ }), await z(f.id, p.values);
1810
1921
  },
1811
1922
  onSuccess: () => {
1812
- m.invalidateQueries({ queryKey: h }), a({ title: "Translation updated" }), f();
1923
+ u.invalidateQueries({ queryKey: h }), r({ title: "Translation updated" }), g();
1813
1924
  },
1814
- onError: (p) => a({ title: "Error", description: p.message, variant: "destructive" })
1815
- }), U = Q({
1816
- mutationFn: (p) => d(`${r}/${p}`, { method: "DELETE" }),
1925
+ onError: (p) => r({ title: "Error", description: p.message, variant: "destructive" })
1926
+ }), H = L({
1927
+ mutationFn: (p) => d(`${i}/${p}`, { method: "DELETE" }),
1817
1928
  onSuccess: () => {
1818
- m.invalidateQueries({ queryKey: h }), a({ title: "Translation deleted" });
1929
+ u.invalidateQueries({ queryKey: h }), r({ title: "Translation deleted" });
1819
1930
  },
1820
- onError: (p) => a({ title: "Error", description: p.message, variant: "destructive" })
1931
+ onError: (p) => r({ title: "Error", description: p.message, variant: "destructive" })
1821
1932
  });
1822
1933
  async function z(p, F) {
1823
- var L;
1824
- const Y = (g == null ? void 0 : g.values) ?? [];
1934
+ var Q;
1935
+ const Y = (f == null ? void 0 : f.values) ?? [];
1825
1936
  for (const V of t) {
1826
- const q = (L = F[V]) == null ? void 0 : L.trim(), I = Y.find((Z) => Z.configId === V), G = `${r}/${p}/values`;
1827
- I && q ? await d(`${G}/${I.id}`, {
1937
+ const q = (Q = F[V]) == null ? void 0 : Q.trim(), O = Y.find((Z) => Z.configId === V), G = `${i}/${p}/values`;
1938
+ O && q ? await d(`${G}/${O.id}`, {
1828
1939
  method: "PATCH",
1829
1940
  body: JSON.stringify({ value: q })
1830
- }) : I && !q ? await d(`${G}/${I.id}`, { method: "DELETE" }) : !I && q && await d(G, {
1941
+ }) : O && !q ? await d(`${G}/${O.id}`, { method: "DELETE" }) : !O && q && await d(G, {
1831
1942
  method: "POST",
1832
1943
  body: JSON.stringify({ translationId: p, configId: V, value: q })
1833
1944
  });
1834
1945
  }
1835
1946
  }
1836
- const D = () => {
1947
+ const M = () => {
1837
1948
  v(null), o(dt(t)), c(!0);
1838
1949
  }, B = (p) => {
1839
1950
  v(p);
1840
1951
  const F = p.values ?? [], Y = Object.fromEntries(
1841
- t.map((L) => {
1952
+ t.map((Q) => {
1842
1953
  var V;
1843
- return [L, ((V = F.find((q) => q.configId === L)) == null ? void 0 : V.value) ?? ""];
1954
+ return [Q, ((V = F.find((q) => q.configId === Q)) == null ? void 0 : V.value) ?? ""];
1844
1955
  })
1845
1956
  );
1846
1957
  o({ name: p.name, description: p.description ?? "", values: Y }), c(!0);
1847
- }, f = () => {
1958
+ }, g = () => {
1848
1959
  c(!1), v(null);
1849
1960
  }, k = () => {
1850
- g ? H.mutate(N) : j.mutate(N);
1851
- }, w = j.isPending || H.isPending, x = !!N.name.trim();
1852
- if (M)
1961
+ f ? U.mutate(N) : j.mutate(N);
1962
+ }, C = j.isPending || U.isPending, x = !!N.name.trim();
1963
+ if (D)
1853
1964
  return /* @__PURE__ */ e("div", { className: "text-center text-muted-foreground py-8", children: "Loading…" });
1854
- const K = O ?? [];
1965
+ const K = I ?? [];
1855
1966
  return /* @__PURE__ */ n("div", { className: "space-y-4", children: [
1856
1967
  /* @__PURE__ */ n("div", { className: "flex items-center justify-between", children: [
1857
1968
  /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: K.length === 0 ? "No translation rules yet." : `${K.length} translation rule${K.length === 1 ? "" : "s"}.` }),
1858
- /* @__PURE__ */ n(E, { size: "sm", onClick: D, children: [
1859
- /* @__PURE__ */ e(Me, {}),
1969
+ /* @__PURE__ */ n(E, { size: "sm", onClick: M, children: [
1970
+ /* @__PURE__ */ e(De, {}),
1860
1971
  "Add translation"
1861
1972
  ] })
1862
1973
  ] }),
@@ -1872,34 +1983,34 @@ function hn({
1872
1983
  p.description && /* @__PURE__ */ e("div", { className: "text-xs text-muted-foreground", children: p.description })
1873
1984
  ] }),
1874
1985
  t.map((F) => {
1875
- var L;
1876
- const Y = (L = p.values) == null ? void 0 : L.find((V) => V.configId === F);
1986
+ var Q;
1987
+ const Y = (Q = p.values) == null ? void 0 : Q.find((V) => V.configId === F);
1877
1988
  return /* @__PURE__ */ e("td", { className: "px-4 py-2 font-mono text-xs", children: Y ? Y.value : /* @__PURE__ */ e("span", { className: "text-muted-foreground", children: "—" }) }, F);
1878
1989
  }),
1879
1990
  /* @__PURE__ */ e("td", { className: "px-4 py-2 text-right", children: /* @__PURE__ */ n("div", { className: "flex gap-1 justify-end", children: [
1880
- /* @__PURE__ */ e(E, { variant: "ghost", size: "icon", onClick: () => B(p), children: /* @__PURE__ */ e(It, {}) }),
1991
+ /* @__PURE__ */ e(E, { variant: "ghost", size: "icon", onClick: () => B(p), children: /* @__PURE__ */ e(Rt, {}) }),
1881
1992
  /* @__PURE__ */ e(
1882
1993
  E,
1883
1994
  {
1884
1995
  variant: "ghost",
1885
1996
  size: "icon",
1886
1997
  onClick: () => {
1887
- window.confirm(`Delete translation "${p.name}"?`) && U.mutate(p.id);
1998
+ window.confirm(`Delete translation "${p.name}"?`) && H.mutate(p.id);
1888
1999
  },
1889
- children: /* @__PURE__ */ e(gt, {})
2000
+ children: /* @__PURE__ */ e(ft, {})
1890
2001
  }
1891
2002
  )
1892
2003
  ] }) })
1893
2004
  ] }, p.id)) })
1894
2005
  ] }) }),
1895
2006
  /* @__PURE__ */ e($e, { open: l, onOpenChange: c, children: /* @__PURE__ */ n(Ee, { className: "max-w-lg", children: [
1896
- /* @__PURE__ */ n(Oe, { children: [
1897
- /* @__PURE__ */ e(Ie, { children: g ? `Edit ${g.name}` : "New Translation Rule" }),
2007
+ /* @__PURE__ */ n(Ie, { children: [
2008
+ /* @__PURE__ */ e(Oe, { children: f ? `Edit ${f.name}` : "New Translation Rule" }),
1898
2009
  /* @__PURE__ */ e(Ae, { children: "Set the equivalent values for each cluster. Rules with values on only one side of a pair are silently skipped for that comparison." })
1899
2010
  ] }),
1900
2011
  /* @__PURE__ */ n("div", { className: "space-y-4 py-2", children: [
1901
2012
  /* @__PURE__ */ n("div", { className: "space-y-2", children: [
1902
- /* @__PURE__ */ e(ie, { htmlFor: "tr-name", children: "Name" }),
2013
+ /* @__PURE__ */ e(ae, { htmlFor: "tr-name", children: "Name" }),
1903
2014
  /* @__PURE__ */ e(
1904
2015
  he,
1905
2016
  {
@@ -1911,7 +2022,7 @@ function hn({
1911
2022
  )
1912
2023
  ] }),
1913
2024
  /* @__PURE__ */ n("div", { className: "space-y-2", children: [
1914
- /* @__PURE__ */ e(ie, { htmlFor: "tr-desc", children: "Description (optional)" }),
2025
+ /* @__PURE__ */ e(ae, { htmlFor: "tr-desc", children: "Description (optional)" }),
1915
2026
  /* @__PURE__ */ e(
1916
2027
  he,
1917
2028
  {
@@ -1925,7 +2036,7 @@ function hn({
1925
2036
  /* @__PURE__ */ n("div", { className: "space-y-3 pt-1", children: [
1926
2037
  /* @__PURE__ */ e("p", { className: "text-sm font-medium", children: "Values per cluster" }),
1927
2038
  t.map((p) => /* @__PURE__ */ n("div", { className: "space-y-1", children: [
1928
- /* @__PURE__ */ e(ie, { htmlFor: `tr-val-${p}`, className: "text-xs text-muted-foreground", children: s[p] ?? p }),
2039
+ /* @__PURE__ */ e(ae, { htmlFor: `tr-val-${p}`, className: "text-xs text-muted-foreground", children: s[p] ?? p }),
1929
2040
  /* @__PURE__ */ e(
1930
2041
  he,
1931
2042
  {
@@ -1943,47 +2054,47 @@ function hn({
1943
2054
  ] })
1944
2055
  ] }),
1945
2056
  /* @__PURE__ */ n(Re, { children: [
1946
- /* @__PURE__ */ n(E, { variant: "outline", onClick: f, children: [
2057
+ /* @__PURE__ */ n(E, { variant: "outline", onClick: g, children: [
1947
2058
  /* @__PURE__ */ e(xe, {}),
1948
2059
  "Cancel"
1949
2060
  ] }),
1950
- /* @__PURE__ */ n(E, { onClick: k, disabled: !x || w, children: [
1951
- /* @__PURE__ */ e(ut, {}),
1952
- w ? "Saving…" : "Save"
2061
+ /* @__PURE__ */ n(E, { onClick: k, disabled: !x || C, children: [
2062
+ /* @__PURE__ */ e(mt, {}),
2063
+ C ? "Saving…" : "Save"
1953
2064
  ] })
1954
2065
  ] })
1955
2066
  ] }) })
1956
2067
  ] });
1957
2068
  }
1958
- function pn({
2069
+ function xn({
1959
2070
  originConfigId: t,
1960
2071
  apiPath: s = "/release-ignores"
1961
2072
  }) {
1962
- const { toast: r } = le(), { fetchJson: a } = ne(), d = oe(), m = ["imaginarium", "release-ignores", t], { data: l, isLoading: c } = ae({
1963
- queryKey: m,
2073
+ const { toast: i } = le(), { fetchJson: r } = ne(), d = oe(), u = ["imaginarium", "release-ignores", t], { data: l, isLoading: c } = re({
2074
+ queryKey: u,
1964
2075
  queryFn: async () => {
1965
- const h = await a(
2076
+ const h = await r(
1966
2077
  `${s}?where[originConfigId]=${encodeURIComponent(t)}`
1967
2078
  );
1968
2079
  return (h == null ? void 0 : h.items) ?? [];
1969
2080
  }
1970
- }), g = Q({
1971
- mutationFn: (h) => a(`${s}/${h}`, { method: "DELETE" }),
2081
+ }), f = L({
2082
+ mutationFn: (h) => r(`${s}/${h}`, { method: "DELETE" }),
1972
2083
  onSuccess: () => {
1973
- d.invalidateQueries({ queryKey: m }), r({ title: "Item removed from ignore list" });
2084
+ d.invalidateQueries({ queryKey: u }), i({ title: "Item removed from ignore list" });
1974
2085
  },
1975
2086
  onError: (h) => {
1976
- r({ title: "Error", description: h.message, variant: "destructive" });
2087
+ i({ title: "Error", description: h.message, variant: "destructive" });
1977
2088
  }
1978
- }), v = Q({
1979
- mutationFn: () => a(`${s}?originConfigId=${encodeURIComponent(t)}`, {
2089
+ }), v = L({
2090
+ mutationFn: () => r(`${s}?originConfigId=${encodeURIComponent(t)}`, {
1980
2091
  method: "DELETE"
1981
2092
  }),
1982
2093
  onSuccess: () => {
1983
- d.invalidateQueries({ queryKey: m }), r({ title: "All ignore rules cleared" });
2094
+ d.invalidateQueries({ queryKey: u }), i({ title: "All ignore rules cleared" });
1984
2095
  },
1985
2096
  onError: (h) => {
1986
- r({ title: "Error", description: h.message, variant: "destructive" });
2097
+ i({ title: "Error", description: h.message, variant: "destructive" });
1987
2098
  }
1988
2099
  }), N = () => {
1989
2100
  window.confirm("Remove all ignore rules for this cluster? Items will appear normally in future snapshots.") && v.mutate();
@@ -2025,39 +2136,39 @@ function pn({
2025
2136
  variant: "ghost",
2026
2137
  size: "icon",
2027
2138
  title: "Remove from ignore list",
2028
- onClick: () => g.mutate(h.id),
2029
- disabled: g.isPending,
2030
- children: /* @__PURE__ */ e(gt, {})
2139
+ onClick: () => f.mutate(h.id),
2140
+ disabled: f.isPending,
2141
+ children: /* @__PURE__ */ e(ft, {})
2031
2142
  }
2032
2143
  ) })
2033
2144
  ] }, h.id)) })
2034
2145
  ] }) })
2035
2146
  ] });
2036
2147
  }
2037
- const gn = [
2148
+ const yn = [
2038
2149
  { id: "releases", label: "Releases" },
2039
2150
  { id: "status", label: "Status" },
2040
2151
  { id: "translations", label: "Translations" },
2041
2152
  { id: "ignored", label: "Ignored" }
2042
2153
  ];
2043
- function fn() {
2154
+ function bn() {
2044
2155
  var N;
2045
- const [t, s] = A("releases"), [r, a] = A(null), { configs: d } = fe(), [m, l] = A("");
2156
+ const [t, s] = A("releases"), [i, r] = A(null), { configs: d } = ge(), [u, l] = A("");
2046
2157
  je(() => {
2047
- !m && d.length > 0 && l(d[0].id);
2048
- }, [m, d]);
2158
+ !u && d.length > 0 && l(d[0].id);
2159
+ }, [u, d]);
2049
2160
  const c = J(() => {
2050
2161
  const o = {};
2051
2162
  return d.forEach((h) => {
2052
2163
  o[h.id] = h.displayName;
2053
2164
  }), o;
2054
- }, [d]), g = m || ((N = d[0]) == null ? void 0 : N.id) || "", v = d.map((o) => o.id).filter((o) => o !== g);
2165
+ }, [d]), f = u || ((N = d[0]) == null ? void 0 : N.id) || "", v = d.map((o) => o.id).filter((o) => o !== f);
2055
2166
  return /* @__PURE__ */ n("div", { className: "space-y-6", children: [
2056
2167
  /* @__PURE__ */ n("div", { children: [
2057
2168
  /* @__PURE__ */ e("h2", { className: "text-2xl font-semibold", children: "imp" }),
2058
2169
  /* @__PURE__ */ e("p", { className: "text-sm text-muted-foreground", children: "Manage releases across clusters" })
2059
2170
  ] }),
2060
- /* @__PURE__ */ e("div", { className: "flex items-center gap-1 border-b pb-2", children: gn.map(({ id: o, label: h }) => /* @__PURE__ */ e(
2171
+ /* @__PURE__ */ e("div", { className: "flex items-center gap-1 border-b pb-2", children: yn.map(({ id: o, label: h }) => /* @__PURE__ */ e(
2061
2172
  E,
2062
2173
  {
2063
2174
  variant: t === o ? "secondary" : "ghost",
@@ -2067,77 +2178,77 @@ function fn() {
2067
2178
  },
2068
2179
  o
2069
2180
  )) }),
2070
- t === "releases" && (r == null ? /* @__PURE__ */ e(jt, { onOpen: a }) : /* @__PURE__ */ e(dn, { releaseId: r, onBack: () => a(null) })),
2181
+ t === "releases" && (i == null ? /* @__PURE__ */ e(Jt, { onOpen: r }) : /* @__PURE__ */ e(mn, { releaseId: i, onBack: () => r(null) })),
2071
2182
  t === "status" && (d.length === 0 ? /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "No clusters configured." }) : /* @__PURE__ */ n("div", { className: "space-y-4", children: [
2072
2183
  /* @__PURE__ */ e("div", { className: "max-w-xs", children: /* @__PURE__ */ e(
2073
- it,
2184
+ at,
2074
2185
  {
2075
2186
  label: "Reference",
2076
- value: g,
2187
+ value: f,
2077
2188
  onChange: l,
2078
2189
  configs: d
2079
2190
  }
2080
2191
  ) }),
2081
- g ? /* @__PURE__ */ e(un, { originConfigId: g, destConfigIds: v }) : /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "Select a reference cluster." })
2192
+ f ? /* @__PURE__ */ e(fn, { originConfigId: f, destConfigIds: v }) : /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "Select a reference cluster." })
2082
2193
  ] })),
2083
- t === "translations" && (d.length === 0 ? /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "No clusters configured." }) : /* @__PURE__ */ e(hn, { configIds: d.map((o) => o.id), clusterNames: c })),
2194
+ t === "translations" && (d.length === 0 ? /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "No clusters configured." }) : /* @__PURE__ */ e(gn, { configIds: d.map((o) => o.id), clusterNames: c })),
2084
2195
  t === "ignored" && (d.length === 0 ? /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "No clusters configured." }) : /* @__PURE__ */ n("div", { className: "space-y-4", children: [
2085
2196
  /* @__PURE__ */ e("div", { className: "max-w-xs", children: /* @__PURE__ */ e(
2086
- it,
2197
+ at,
2087
2198
  {
2088
2199
  label: "Cluster",
2089
- value: g,
2200
+ value: f,
2090
2201
  onChange: l,
2091
2202
  configs: d
2092
2203
  }
2093
2204
  ) }),
2094
- g ? /* @__PURE__ */ e(pn, { originConfigId: g }) : /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "Select a cluster." })
2205
+ f ? /* @__PURE__ */ e(xn, { originConfigId: f }) : /* @__PURE__ */ e("div", { className: "text-muted-foreground", children: "Select a cluster." })
2095
2206
  ] }))
2096
2207
  ] });
2097
2208
  }
2098
- const xn = {
2209
+ const Nn = {
2099
2210
  id: "imaginarium.ui.ImpPage",
2100
2211
  path: "/imp",
2101
- element: fn
2102
- }, yn = {
2212
+ element: bn
2213
+ }, vn = {
2103
2214
  id: "imaginarium.ui.ImpNavItem",
2104
2215
  path: "/imp",
2105
2216
  label: "imp",
2106
- icon: At,
2217
+ icon: Mt,
2107
2218
  sort: 150
2108
- }, En = {
2219
+ }, An = {
2109
2220
  install(t) {
2110
- t.addPlugin(Pt, xn), t.addPlugin(Tt, yn);
2221
+ t.addPlugin(Pt, Nn), t.addPlugin(St, vn), $t.register(t, zt);
2111
2222
  }
2112
2223
  };
2113
2224
  export {
2114
- it as C,
2115
- cn as D,
2225
+ at as C,
2226
+ hn as D,
2116
2227
  pe as E,
2117
- Jt as I,
2118
- zt as P,
2119
- dn as R,
2120
- un as S,
2228
+ Vt as I,
2229
+ Lt as P,
2230
+ mn as R,
2231
+ fn as S,
2121
2232
  Xe as T,
2122
- qt as a,
2123
- Bt as b,
2124
- pn as c,
2125
- Ht as d,
2126
- Lt as e,
2127
- jt as f,
2128
- En as g,
2129
- ft as h,
2130
- fn as i,
2131
- Qt as j,
2132
- hn as k,
2133
- en as l,
2134
- Wt as m,
2135
- rn as n,
2136
- $n as o,
2137
- nn as p,
2138
- sn as q,
2139
- Gt as r,
2140
- Xt as t,
2233
+ Bt as a,
2234
+ Qt as b,
2235
+ xn as c,
2236
+ _t as d,
2237
+ Ht as e,
2238
+ Jt as f,
2239
+ An as g,
2240
+ gt as h,
2241
+ bn as i,
2242
+ Ut as j,
2243
+ gn as k,
2244
+ sn as l,
2245
+ Zt as m,
2246
+ on as n,
2247
+ On as o,
2248
+ rn as p,
2249
+ ln as q,
2250
+ en as r,
2251
+ tn as t,
2141
2252
  ke as u
2142
2253
  };
2143
- //# sourceMappingURL=PluginSetup-BQk4FFh9.js.map
2254
+ //# sourceMappingURL=PluginSetup-DaNNHmql.js.map