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