@leverege/imaginarium-ui 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/lib/MarkdownPageDoc-BrPfBSvd.cjs +2 -0
  2. package/lib/MarkdownPageDoc-BrPfBSvd.cjs.map +1 -0
  3. package/lib/{MarkdownPageDoc-DR1FmNpF.js → MarkdownPageDoc-xK0hMx2S.js} +61 -58
  4. package/lib/MarkdownPageDoc-xK0hMx2S.js.map +1 -0
  5. package/lib/{PluginSetup-XhNP-74n.cjs → PluginSetup-6y-Q93AW.cjs} +2 -2
  6. package/lib/{PluginSetup-XhNP-74n.cjs.map → PluginSetup-6y-Q93AW.cjs.map} +1 -1
  7. package/lib/PluginSetup-B1eP6a5H.cjs +2 -0
  8. package/lib/PluginSetup-B1eP6a5H.cjs.map +1 -0
  9. package/lib/PluginSetup-BsMKEyLI.cjs +45 -0
  10. package/lib/PluginSetup-BsMKEyLI.cjs.map +1 -0
  11. package/lib/PluginSetup-CuSRbqiM.js +192 -0
  12. package/lib/PluginSetup-CuSRbqiM.js.map +1 -0
  13. package/lib/{PluginSetup-DK7SSyOS.js → PluginSetup-IjHkViiY.js} +2 -2
  14. package/lib/{PluginSetup-DK7SSyOS.js.map → PluginSetup-IjHkViiY.js.map} +1 -1
  15. package/lib/PluginSetup-bkVVFe8I.js +506 -0
  16. package/lib/PluginSetup-bkVVFe8I.js.map +1 -0
  17. package/lib/index.cjs +1 -1
  18. package/lib/index.d.ts +1 -0
  19. package/lib/index.d.ts.map +1 -1
  20. package/lib/index.js +52 -51
  21. package/lib/release.cjs +1 -1
  22. package/lib/release.js +1 -1
  23. package/lib/secret/SecretView.d.ts.map +1 -1
  24. package/lib/secret.cjs +1 -1
  25. package/lib/secret.js +1 -1
  26. package/lib/system/ImagineSystemView.d.ts.map +1 -1
  27. package/lib/system/SystemConfigsContext.d.ts.map +1 -1
  28. package/lib/system/systemDisplay.d.ts +19 -0
  29. package/lib/system/systemDisplay.d.ts.map +1 -0
  30. package/lib/system.cjs +1 -1
  31. package/lib/system.js +2 -2
  32. package/package.json +2 -2
  33. package/src/index.ts +1 -0
  34. package/src/secret/SecretView.tsx +7 -3
  35. package/src/system/ImagineSystemView.tsx +83 -71
  36. package/src/system/SystemConfigsContext.tsx +6 -1
  37. package/src/system/systemDisplay.ts +32 -0
  38. package/lib/MarkdownPageDoc-BZF02iL5.cjs +0 -2
  39. package/lib/MarkdownPageDoc-BZF02iL5.cjs.map +0 -1
  40. package/lib/MarkdownPageDoc-DR1FmNpF.js.map +0 -1
  41. package/lib/PluginSetup-CTRJO5hU.js +0 -475
  42. package/lib/PluginSetup-CTRJO5hU.js.map +0 -1
  43. package/lib/PluginSetup-CuLezaDw.cjs +0 -45
  44. package/lib/PluginSetup-CuLezaDw.cjs.map +0 -1
  45. package/lib/PluginSetup-DNKri9P1.js +0 -190
  46. package/lib/PluginSetup-DNKri9P1.js.map +0 -1
  47. package/lib/PluginSetup-De9E1hRC.cjs +0 -2
  48. package/lib/PluginSetup-De9E1hRC.cjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ "use strict";const d=require("react/jsx-runtime"),n=require("react"),M=require("@tanstack/react-query"),j=require("@leverege/plugin"),O=require("./Card-CHVaz_7u.cjs"),I=require("./PluginTypes-BmYA5_B9.cjs"),f=require("./mdComponents-BiOJ7Epf.cjs"),b=n.createContext(null);function w(t,o){const s=new Set(t);for(const e of o)e&&s.add(e);const r=Array.from(s).sort();return r.length===t.length&&r.every((e,i)=>e===t[i])?t:r}function v(t,o){const s=t.indexOf(o);if(s===-1){const r=[...t,o];return r.sort(),r}return t.filter((r,e)=>e!==s)}function L({children:t}){const[o,s]=n.useState(!0),[r,e]=n.useState([]),[i,a]=n.useState([]),[c,m]=n.useState([]),[u,y]=n.useState([]),[C,D]=n.useState(0),p=n.useCallback(g=>{e(l=>v(l,g))},[]),h=n.useCallback(g=>{a(l=>v(l,g))},[]),S=n.useCallback(g=>{m(l=>w(l,g))},[]),T=n.useCallback(g=>{y(l=>w(l,g))},[]),x=n.useCallback(()=>{e([]),a([])},[]),E=n.useMemo(()=>({showDev:o,setShowDev:s,hiddenSystemConfigTypes:r,toggleSystemConfigType:p,hiddenSystemConfigTags:i,toggleSystemConfigTag:h,knownSystemConfigTypes:c,registerSystemConfigTypes:S,knownSystemConfigTags:u,registerSystemConfigTags:T,filteredOutCount:C,setFilteredOutCount:D,clearHidden:x}),[o,r,p,i,h,c,S,u,T,C,x]);return d.jsx(b.Provider,{value:E,children:t})}function P(){const t=n.useContext(b);if(!t)throw new Error("useFilters must be used inside FilterProvider");return t}function F(t){const o=t.displayName.toLowerCase(),s=t.baseUrl.toLowerCase();return o.includes("dev")||o.includes("staging")||s.includes("dev-")||s.includes("stg-")}function k(t,o){const s=new Set(o.hiddenSystemConfigTypes),r=new Set(o.hiddenSystemConfigTags);return t.filter(e=>!(!o.showDev&&F(e)||e.type&&s.has(e.type)||e.tags&&e.tags.length>0&&e.tags.every(i=>r.has(i))))}const q=n.createContext(null);function N({children:t}){const{fetchJson:o}=O.useImaginariumApi(),s=j.Config.get("ImagineSystemConfig","apiPath","/configs"),r=n.useMemo(()=>["imaginarium","system-configs",s],[s]),e=P(),i=M.useQuery({queryKey:r,queryFn:async()=>{const u=await o(s);return Array.isArray(u)?u:(u==null?void 0:u.items)??[]}}),a=n.useMemo(()=>i.data??[],[i.data]),c=n.useMemo(()=>k(a,e).slice().sort((u,y)=>u.displayName.localeCompare(y.displayName,void 0,{sensitivity:"base"})),[a,e]);n.useEffect(()=>{e.registerSystemConfigTypes(a.map(u=>u.type)),e.registerSystemConfigTags(a.flatMap(u=>u.tags??[]))},[a,e.registerSystemConfigTypes,e.registerSystemConfigTags]),n.useEffect(()=>{e.setFilteredOutCount(a.length-c.length)},[a.length,c.length,e.setFilteredOutCount]),n.useEffect(()=>()=>e.setFilteredOutCount(0),[e.setFilteredOutCount]);const m=n.useMemo(()=>({configs:a,filtered:c,isLoading:i.isLoading,isError:i.isError,error:i.error,refetch:i.refetch,apiPath:s,queryKey:r}),[a,c,i.isLoading,i.isError,i.error,i.refetch,s,r]);return d.jsx(q.Provider,{value:m,children:t})}function A(){const t=n.useContext(q);if(!t)throw new Error("useSystemConfigs must be used inside SystemConfigsProvider");return t}class H{static register(o,s){o.addPlugin(I.PageDocsType,s)}}class B{static create({path:o,markdown:s}){const r=f.extractH2s(s),e=a=>{var c;(c=document.getElementById(a))==null||c.scrollIntoView({behavior:"smooth",block:"start"})};return{path:o,component:()=>d.jsxs(d.Fragment,{children:[r.length>1&&d.jsx("div",{className:"flex flex-wrap gap-1.5 mb-4",children:r.map(({text:a,slug:c})=>d.jsx("button",{onClick:()=>e(c),className:"rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors",children:f.toTitleCase(a)},c))}),d.jsx(f.Markdown,{components:f.mdComponents,children:s})]})}}}exports.FilterProvider=L;exports.MarkdownPageDoc=B;exports.PageDoc=H;exports.SystemConfigsProvider=N;exports.applyConfigFilters=k;exports.isDevConfig=F;exports.useFilters=P;exports.useSystemConfigs=A;
2
+ //# sourceMappingURL=MarkdownPageDoc-BrPfBSvd.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownPageDoc-BrPfBSvd.cjs","sources":["../src/filters/FilterContext.tsx","../src/filters/applyConfigFilters.ts","../src/system/SystemConfigsContext.tsx","../src/docs/PageDoc.ts","../src/docs/MarkdownPageDoc.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from 'react'\n\nexport interface FilterContextValue {\n showDev : boolean\n setShowDev : ( v: boolean ) => void\n\n // Anything in this set is filtered out\n hiddenSystemConfigTypes : string[]\n toggleSystemConfigType : ( type: string ) => void\n\n hiddenSystemConfigTags : string[]\n toggleSystemConfigTag : ( tag: string ) => void\n\n // Known values, populated by pages as they fetch\n knownSystemConfigTypes : string[]\n registerSystemConfigTypes : ( types: ( string | null | undefined )[] ) => void\n\n knownSystemConfigTags : string[]\n registerSystemConfigTags : ( tags: ( string | null | undefined )[] ) => void\n\n // Number of system configs currently being filtered out, reported by the\n // page that owns the data (ImagineSystemView). The dropdown reads this to\n // render a badge next to the filter icon. Reset to 0 when the page unmounts.\n filteredOutCount : number\n setFilteredOutCount : ( n: number ) => void\n\n // Quick action — clears both hidden sets, leaves showDev untouched\n clearHidden : () => void\n}\n\nconst FilterCtx = createContext<FilterContextValue | null>( null )\n\nfunction registerInto( prev: string[], incoming: ( string | null | undefined )[] ): string[] {\n const next = new Set( prev )\n for ( const t of incoming ) {\n if ( t ) { next.add( t ) }\n }\n const arr = Array.from( next ).sort()\n if ( arr.length === prev.length && arr.every( ( t, i ) => t === prev[i] ) ) {\n return prev\n }\n return arr\n}\n\nfunction toggleIn( prev: string[], value: string ): string[] {\n const idx = prev.indexOf( value )\n if ( idx === -1 ) {\n const next = [ ...prev, value ]\n next.sort()\n return next\n }\n return prev.filter( ( _, i ) => i !== idx )\n}\n\nexport function FilterProvider( { children }: { children: ReactNode } ) {\n const [ showDev, setShowDev ] = useState( true )\n const [ hiddenTypes, setHiddenTypes ] = useState<string[]>( [] )\n const [ hiddenTags, setHiddenTags ] = useState<string[]>( [] )\n const [ knownTypes, setKnownTypes ] = useState<string[]>( [] )\n const [ knownTags, setKnownTags ] = useState<string[]>( [] )\n const [ filteredOutCount, setFilteredOutCount ] = useState( 0 )\n\n const toggleSystemConfigType = useCallback( ( type: string ) => {\n setHiddenTypes( ( prev ) => toggleIn( prev, type ) )\n }, [] )\n\n const toggleSystemConfigTag = useCallback( ( tag: string ) => {\n setHiddenTags( ( prev ) => toggleIn( prev, tag ) )\n }, [] )\n\n const registerSystemConfigTypes = useCallback( ( types: ( string | null | undefined )[] ) => {\n setKnownTypes( ( prev ) => registerInto( prev, types ) )\n }, [] )\n\n const registerSystemConfigTags = useCallback( ( tags: ( string | null | undefined )[] ) => {\n setKnownTags( ( prev ) => registerInto( prev, tags ) )\n }, [] )\n\n const clearHidden = useCallback( () => {\n setHiddenTypes( [] )\n setHiddenTags( [] )\n }, [] )\n\n const value = useMemo<FilterContextValue>( () => ( {\n showDev,\n setShowDev,\n hiddenSystemConfigTypes : hiddenTypes,\n toggleSystemConfigType,\n hiddenSystemConfigTags : hiddenTags,\n toggleSystemConfigTag,\n knownSystemConfigTypes : knownTypes,\n registerSystemConfigTypes,\n knownSystemConfigTags : knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n setFilteredOutCount,\n clearHidden,\n } ), [\n showDev,\n hiddenTypes,\n toggleSystemConfigType,\n hiddenTags,\n toggleSystemConfigTag,\n knownTypes,\n registerSystemConfigTypes,\n knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n clearHidden,\n ] )\n\n return <FilterCtx.Provider value={value}>{children}</FilterCtx.Provider>\n}\n\nexport function useFilters(): FilterContextValue {\n const v = useContext( FilterCtx )\n if ( !v ) {\n throw new Error( 'useFilters must be used inside FilterProvider' )\n }\n return v\n}\n","export interface ImagineSystemConfigLike {\n displayName : string\n baseUrl : string\n type? : string | null\n tags? : string[]\n}\n\nexport function isDevConfig( c: ImagineSystemConfigLike ): boolean {\n const name = c.displayName.toLowerCase()\n const url = c.baseUrl.toLowerCase()\n return name.includes( 'dev' )\n || name.includes( 'staging' )\n || url.includes( 'dev-' )\n || url.includes( 'stg-' )\n}\n\nexport interface ConfigFilterOptions {\n showDev : boolean\n hiddenSystemConfigTypes : string[]\n hiddenSystemConfigTags : string[]\n}\n\nexport function applyConfigFilters<T extends ImagineSystemConfigLike>(\n configs: T[],\n filters: ConfigFilterOptions,\n): T[] {\n const typeBlocked = new Set( filters.hiddenSystemConfigTypes )\n const tagBlocked = new Set( filters.hiddenSystemConfigTags )\n\n return configs.filter( ( c ) => {\n if ( !filters.showDev && isDevConfig( c ) ) { return false }\n if ( c.type && typeBlocked.has( c.type ) ) { return false }\n // Tags: show if at least one tag is still visible. Hide only when the\n // config has tags and every one of them is in the hidden set.\n if ( c.tags && c.tags.length > 0 && c.tags.every( ( t ) => tagBlocked.has( t ) ) ) {\n return false\n }\n return true\n } )\n}\n","import { createContext, useContext, useEffect, useMemo, type ReactNode } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { Config } from '@leverege/plugin'\n\nimport { useImaginariumApi } from '../api/ImaginariumApiContext'\nimport { useFilters } from '../filters/FilterContext'\nimport { applyConfigFilters } from '../filters/applyConfigFilters'\nimport type { ImagineSystemConfig, ImagineSystemConfigListResponse } from './types'\n\nexport interface SystemConfigsContextValue {\n /** Raw list as returned by the server (before filters). */\n configs : ImagineSystemConfig[]\n /** Filter-applied view of `configs`. */\n filtered : ImagineSystemConfig[]\n isLoading : boolean\n isError : boolean\n error : unknown\n refetch : () => Promise<unknown>\n /** API path being polled (relative to apiBaseUrl). */\n apiPath : string\n /** React Query key — share this with mutations to invalidate the cache. */\n queryKey : readonly unknown[]\n}\n\nconst Ctx = createContext<SystemConfigsContextValue | null>( null )\n\nexport function SystemConfigsProvider( { children }: { children: ReactNode } ) {\n const { fetchJson } = useImaginariumApi()\n const apiPath = Config.get<string>( 'ImagineSystemConfig', 'apiPath', '/configs' )\n const queryKey = useMemo(\n () => [ 'imaginarium', 'system-configs', apiPath ] as const,\n [ apiPath ],\n )\n const filters = useFilters()\n\n const query = useQuery<ImagineSystemConfig[]>( {\n queryKey,\n queryFn: async () => {\n const res = await fetchJson<ImagineSystemConfigListResponse | ImagineSystemConfig[]>( apiPath )\n return Array.isArray( res ) ? res : ( res?.items ?? [] )\n },\n } )\n\n const configs = useMemo( () => query.data ?? [], [ query.data ] )\n const filtered = useMemo(\n () => applyConfigFilters( configs, filters )\n .slice()\n .sort( ( a, b ) => a.displayName.localeCompare( b.displayName, undefined, { sensitivity: 'base' } ) ),\n [ configs, filters ],\n )\n\n // Surface available types/tags so the global filter dropdown can render them.\n useEffect( () => {\n filters.registerSystemConfigTypes( configs.map( ( c ) => c.type ) )\n filters.registerSystemConfigTags( configs.flatMap( ( c ) => c.tags ?? [] ) )\n }, [ configs, filters.registerSystemConfigTypes, filters.registerSystemConfigTags ] )\n\n // Surface how many configs are currently being filtered out (badge on filter button).\n useEffect( () => {\n filters.setFilteredOutCount( configs.length - filtered.length )\n }, [ configs.length, filtered.length, filters.setFilteredOutCount ] )\n\n useEffect( () => {\n return () => filters.setFilteredOutCount( 0 )\n }, [ filters.setFilteredOutCount ] )\n\n const value = useMemo<SystemConfigsContextValue>( () => ( {\n configs,\n filtered,\n isLoading : query.isLoading,\n isError : query.isError,\n error : query.error,\n refetch : query.refetch,\n apiPath,\n queryKey,\n } ), [\n configs,\n filtered,\n query.isLoading,\n query.isError,\n query.error,\n query.refetch,\n apiPath,\n queryKey,\n ] )\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>\n}\n\nexport function useSystemConfigs(): SystemConfigsContextValue {\n const v = useContext( Ctx )\n if ( !v ) {\n throw new Error( 'useSystemConfigs must be used inside SystemConfigsProvider' )\n }\n return v\n}\n","import { PageDocsType } from '../plugins/PluginTypes'\nimport type { PageDocsPlugin } from '../plugins/types'\n\ninterface RegistryLike {\n addPlugin( type: string, plugin: unknown ): void\n}\n\nexport class PageDoc {\n static register( plg: RegistryLike, pageDoc: PageDocsPlugin ) {\n plg.addPlugin( PageDocsType, pageDoc )\n }\n}\n","import type { ComponentType } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport type { PageDocsPlugin } from '../plugins/types'\nimport { mdComponents, extractH2s, toTitleCase } from './mdComponents'\n\nexport class MarkdownPageDoc {\n static create( { path, markdown }: { path: string; markdown: string } ): PageDocsPlugin {\n const sections = extractH2s( markdown )\n\n const scrollTo = ( slug: string ) => {\n document.getElementById( slug )?.scrollIntoView( { behavior: 'smooth', block: 'start' } )\n }\n\n const Component: ComponentType = () => (\n <>\n {sections.length > 1 && (\n <div className=\"flex flex-wrap gap-1.5 mb-4\">\n {sections.map( ( { text, slug } ) => (\n <button\n key={slug}\n onClick={() => scrollTo( slug )}\n className=\"rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors\"\n >\n {toTitleCase( text )}\n </button>\n ) )}\n </div>\n )}\n <ReactMarkdown components={mdComponents}>{markdown}</ReactMarkdown>\n </>\n )\n\n return { path, component: Component }\n }\n}\n"],"names":["FilterCtx","createContext","registerInto","prev","incoming","next","t","arr","toggleIn","value","idx","_","i","FilterProvider","children","showDev","setShowDev","useState","hiddenTypes","setHiddenTypes","hiddenTags","setHiddenTags","knownTypes","setKnownTypes","knownTags","setKnownTags","filteredOutCount","setFilteredOutCount","toggleSystemConfigType","useCallback","type","toggleSystemConfigTag","tag","registerSystemConfigTypes","types","registerSystemConfigTags","tags","clearHidden","useMemo","jsx","useFilters","v","useContext","isDevConfig","c","name","url","applyConfigFilters","configs","filters","typeBlocked","tagBlocked","Ctx","SystemConfigsProvider","fetchJson","useImaginariumApi","apiPath","Config","queryKey","query","useQuery","res","filtered","a","b","useEffect","useSystemConfigs","PageDoc","plg","pageDoc","PageDocsType","MarkdownPageDoc","path","markdown","sections","extractH2s","scrollTo","slug","_a","jsxs","Fragment","text","ReactMarkdown","mdComponents"],"mappings":"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"}
@@ -1,19 +1,19 @@
1
1
  import { jsx as m, jsxs as M, Fragment as L } from "react/jsx-runtime";
2
- import { createContext as F, useState as d, useCallback as f, useMemo as l, useContext as P, useEffect as C } from "react";
3
- import { useQuery as A } from "@tanstack/react-query";
4
- import { Config as H } from "@leverege/plugin";
5
- import { a as q } from "./Card-D2LdIJwJ.js";
6
- import { b as B } from "./PluginTypes-mZ4TjxPV.js";
7
- import { e as K, t as N, M as j, m as J } from "./mdComponents-kPa8Rxqz.js";
8
- const k = F(null);
9
- function v(t, n) {
2
+ import { createContext as P, useState as u, useCallback as l, useMemo as f, useContext as k, useEffect as C } from "react";
3
+ import { useQuery as N } from "@tanstack/react-query";
4
+ import { Config as A } from "@leverege/plugin";
5
+ import { a as H } from "./Card-D2LdIJwJ.js";
6
+ import { b as q } from "./PluginTypes-mZ4TjxPV.js";
7
+ import { e as B, t as K, M as j, m as J } from "./mdComponents-kPa8Rxqz.js";
8
+ const D = P(null);
9
+ function b(t, n) {
10
10
  const s = new Set(t);
11
11
  for (const e of n)
12
12
  e && s.add(e);
13
13
  const o = Array.from(s).sort();
14
14
  return o.length === t.length && o.every((e, r) => e === t[r]) ? t : o;
15
15
  }
16
- function b(t, n) {
16
+ function F(t, n) {
17
17
  const s = t.indexOf(n);
18
18
  if (s === -1) {
19
19
  const o = [...t, n];
@@ -22,47 +22,47 @@ function b(t, n) {
22
22
  return t.filter((o, e) => e !== s);
23
23
  }
24
24
  function Z({ children: t }) {
25
- const [n, s] = d(!0), [o, e] = d([]), [r, i] = d([]), [a, y] = d([]), [g, E] = d([]), [p, O] = d(0), h = f((c) => {
26
- e((u) => b(u, c));
27
- }, []), S = f((c) => {
28
- i((u) => b(u, c));
29
- }, []), T = f((c) => {
30
- y((u) => v(u, c));
31
- }, []), w = f((c) => {
32
- E((u) => v(u, c));
33
- }, []), x = f(() => {
25
+ const [n, s] = u(!0), [o, e] = u([]), [r, i] = u([]), [c, y] = u([]), [a, p] = u([]), [h, O] = u(0), S = l((g) => {
26
+ e((d) => F(d, g));
27
+ }, []), T = l((g) => {
28
+ i((d) => F(d, g));
29
+ }, []), w = l((g) => {
30
+ y((d) => b(d, g));
31
+ }, []), x = l((g) => {
32
+ p((d) => b(d, g));
33
+ }, []), v = l(() => {
34
34
  e([]), i([]);
35
- }, []), I = l(() => ({
35
+ }, []), I = f(() => ({
36
36
  showDev: n,
37
37
  setShowDev: s,
38
38
  hiddenSystemConfigTypes: o,
39
- toggleSystemConfigType: h,
39
+ toggleSystemConfigType: S,
40
40
  hiddenSystemConfigTags: r,
41
- toggleSystemConfigTag: S,
42
- knownSystemConfigTypes: a,
43
- registerSystemConfigTypes: T,
44
- knownSystemConfigTags: g,
45
- registerSystemConfigTags: w,
46
- filteredOutCount: p,
41
+ toggleSystemConfigTag: T,
42
+ knownSystemConfigTypes: c,
43
+ registerSystemConfigTypes: w,
44
+ knownSystemConfigTags: a,
45
+ registerSystemConfigTags: x,
46
+ filteredOutCount: h,
47
47
  setFilteredOutCount: O,
48
- clearHidden: x
48
+ clearHidden: v
49
49
  }), [
50
50
  n,
51
51
  o,
52
- h,
53
- r,
54
52
  S,
55
- a,
53
+ r,
56
54
  T,
57
- g,
55
+ c,
58
56
  w,
59
- p,
60
- x
57
+ a,
58
+ x,
59
+ h,
60
+ v
61
61
  ]);
62
- return /* @__PURE__ */ m(k.Provider, { value: I, children: t });
62
+ return /* @__PURE__ */ m(D.Provider, { value: I, children: t });
63
63
  }
64
64
  function Q() {
65
- const t = P(k);
65
+ const t = k(D);
66
66
  if (!t)
67
67
  throw new Error("useFilters must be used inside FilterProvider");
68
68
  return t;
@@ -75,26 +75,29 @@ function V(t, n) {
75
75
  const s = new Set(n.hiddenSystemConfigTypes), o = new Set(n.hiddenSystemConfigTags);
76
76
  return t.filter((e) => !(!n.showDev && U(e) || e.type && s.has(e.type) || e.tags && e.tags.length > 0 && e.tags.every((r) => o.has(r))));
77
77
  }
78
- const D = F(null);
78
+ const E = P(null);
79
79
  function $({ children: t }) {
80
- const { fetchJson: n } = q(), s = H.get("ImagineSystemConfig", "apiPath", "/configs"), o = l(
80
+ const { fetchJson: n } = H(), s = A.get("ImagineSystemConfig", "apiPath", "/configs"), o = f(
81
81
  () => ["imaginarium", "system-configs", s],
82
82
  [s]
83
- ), e = Q(), r = A({
83
+ ), e = Q(), r = N({
84
84
  queryKey: o,
85
85
  queryFn: async () => {
86
- const g = await n(s);
87
- return Array.isArray(g) ? g : (g == null ? void 0 : g.items) ?? [];
86
+ const a = await n(s);
87
+ return Array.isArray(a) ? a : (a == null ? void 0 : a.items) ?? [];
88
88
  }
89
- }), i = l(() => r.data ?? [], [r.data]), a = l(() => V(i, e), [i, e]);
89
+ }), i = f(() => r.data ?? [], [r.data]), c = f(
90
+ () => V(i, e).slice().sort((a, p) => a.displayName.localeCompare(p.displayName, void 0, { sensitivity: "base" })),
91
+ [i, e]
92
+ );
90
93
  C(() => {
91
- e.registerSystemConfigTypes(i.map((g) => g.type)), e.registerSystemConfigTags(i.flatMap((g) => g.tags ?? []));
94
+ e.registerSystemConfigTypes(i.map((a) => a.type)), e.registerSystemConfigTags(i.flatMap((a) => a.tags ?? []));
92
95
  }, [i, e.registerSystemConfigTypes, e.registerSystemConfigTags]), C(() => {
93
- e.setFilteredOutCount(i.length - a.length);
94
- }, [i.length, a.length, e.setFilteredOutCount]), C(() => () => e.setFilteredOutCount(0), [e.setFilteredOutCount]);
95
- const y = l(() => ({
96
+ e.setFilteredOutCount(i.length - c.length);
97
+ }, [i.length, c.length, e.setFilteredOutCount]), C(() => () => e.setFilteredOutCount(0), [e.setFilteredOutCount]);
98
+ const y = f(() => ({
96
99
  configs: i,
97
- filtered: a,
100
+ filtered: c,
98
101
  isLoading: r.isLoading,
99
102
  isError: r.isError,
100
103
  error: r.error,
@@ -103,7 +106,7 @@ function $({ children: t }) {
103
106
  queryKey: o
104
107
  }), [
105
108
  i,
106
- a,
109
+ c,
107
110
  r.isLoading,
108
111
  r.isError,
109
112
  r.error,
@@ -111,34 +114,34 @@ function $({ children: t }) {
111
114
  s,
112
115
  o
113
116
  ]);
114
- return /* @__PURE__ */ m(D.Provider, { value: y, children: t });
117
+ return /* @__PURE__ */ m(E.Provider, { value: y, children: t });
115
118
  }
116
119
  function ee() {
117
- const t = P(D);
120
+ const t = k(E);
118
121
  if (!t)
119
122
  throw new Error("useSystemConfigs must be used inside SystemConfigsProvider");
120
123
  return t;
121
124
  }
122
125
  class te {
123
126
  static register(n, s) {
124
- n.addPlugin(B, s);
127
+ n.addPlugin(q, s);
125
128
  }
126
129
  }
127
130
  class se {
128
131
  static create({ path: n, markdown: s }) {
129
- const o = K(s), e = (i) => {
130
- var a;
131
- (a = document.getElementById(i)) == null || a.scrollIntoView({ behavior: "smooth", block: "start" });
132
+ const o = B(s), e = (i) => {
133
+ var c;
134
+ (c = document.getElementById(i)) == null || c.scrollIntoView({ behavior: "smooth", block: "start" });
132
135
  };
133
136
  return { path: n, component: () => /* @__PURE__ */ M(L, { children: [
134
- o.length > 1 && /* @__PURE__ */ m("div", { className: "flex flex-wrap gap-1.5 mb-4", children: o.map(({ text: i, slug: a }) => /* @__PURE__ */ m(
137
+ o.length > 1 && /* @__PURE__ */ m("div", { className: "flex flex-wrap gap-1.5 mb-4", children: o.map(({ text: i, slug: c }) => /* @__PURE__ */ m(
135
138
  "button",
136
139
  {
137
- onClick: () => e(a),
140
+ onClick: () => e(c),
138
141
  className: "rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors",
139
- children: N(i)
142
+ children: K(i)
140
143
  },
141
- a
144
+ c
142
145
  )) }),
143
146
  /* @__PURE__ */ m(j, { components: J, children: s })
144
147
  ] }) };
@@ -154,4 +157,4 @@ export {
154
157
  U as i,
155
158
  ee as u
156
159
  };
157
- //# sourceMappingURL=MarkdownPageDoc-DR1FmNpF.js.map
160
+ //# sourceMappingURL=MarkdownPageDoc-xK0hMx2S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownPageDoc-xK0hMx2S.js","sources":["../src/filters/FilterContext.tsx","../src/filters/applyConfigFilters.ts","../src/system/SystemConfigsContext.tsx","../src/docs/PageDoc.ts","../src/docs/MarkdownPageDoc.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from 'react'\n\nexport interface FilterContextValue {\n showDev : boolean\n setShowDev : ( v: boolean ) => void\n\n // Anything in this set is filtered out\n hiddenSystemConfigTypes : string[]\n toggleSystemConfigType : ( type: string ) => void\n\n hiddenSystemConfigTags : string[]\n toggleSystemConfigTag : ( tag: string ) => void\n\n // Known values, populated by pages as they fetch\n knownSystemConfigTypes : string[]\n registerSystemConfigTypes : ( types: ( string | null | undefined )[] ) => void\n\n knownSystemConfigTags : string[]\n registerSystemConfigTags : ( tags: ( string | null | undefined )[] ) => void\n\n // Number of system configs currently being filtered out, reported by the\n // page that owns the data (ImagineSystemView). The dropdown reads this to\n // render a badge next to the filter icon. Reset to 0 when the page unmounts.\n filteredOutCount : number\n setFilteredOutCount : ( n: number ) => void\n\n // Quick action — clears both hidden sets, leaves showDev untouched\n clearHidden : () => void\n}\n\nconst FilterCtx = createContext<FilterContextValue | null>( null )\n\nfunction registerInto( prev: string[], incoming: ( string | null | undefined )[] ): string[] {\n const next = new Set( prev )\n for ( const t of incoming ) {\n if ( t ) { next.add( t ) }\n }\n const arr = Array.from( next ).sort()\n if ( arr.length === prev.length && arr.every( ( t, i ) => t === prev[i] ) ) {\n return prev\n }\n return arr\n}\n\nfunction toggleIn( prev: string[], value: string ): string[] {\n const idx = prev.indexOf( value )\n if ( idx === -1 ) {\n const next = [ ...prev, value ]\n next.sort()\n return next\n }\n return prev.filter( ( _, i ) => i !== idx )\n}\n\nexport function FilterProvider( { children }: { children: ReactNode } ) {\n const [ showDev, setShowDev ] = useState( true )\n const [ hiddenTypes, setHiddenTypes ] = useState<string[]>( [] )\n const [ hiddenTags, setHiddenTags ] = useState<string[]>( [] )\n const [ knownTypes, setKnownTypes ] = useState<string[]>( [] )\n const [ knownTags, setKnownTags ] = useState<string[]>( [] )\n const [ filteredOutCount, setFilteredOutCount ] = useState( 0 )\n\n const toggleSystemConfigType = useCallback( ( type: string ) => {\n setHiddenTypes( ( prev ) => toggleIn( prev, type ) )\n }, [] )\n\n const toggleSystemConfigTag = useCallback( ( tag: string ) => {\n setHiddenTags( ( prev ) => toggleIn( prev, tag ) )\n }, [] )\n\n const registerSystemConfigTypes = useCallback( ( types: ( string | null | undefined )[] ) => {\n setKnownTypes( ( prev ) => registerInto( prev, types ) )\n }, [] )\n\n const registerSystemConfigTags = useCallback( ( tags: ( string | null | undefined )[] ) => {\n setKnownTags( ( prev ) => registerInto( prev, tags ) )\n }, [] )\n\n const clearHidden = useCallback( () => {\n setHiddenTypes( [] )\n setHiddenTags( [] )\n }, [] )\n\n const value = useMemo<FilterContextValue>( () => ( {\n showDev,\n setShowDev,\n hiddenSystemConfigTypes : hiddenTypes,\n toggleSystemConfigType,\n hiddenSystemConfigTags : hiddenTags,\n toggleSystemConfigTag,\n knownSystemConfigTypes : knownTypes,\n registerSystemConfigTypes,\n knownSystemConfigTags : knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n setFilteredOutCount,\n clearHidden,\n } ), [\n showDev,\n hiddenTypes,\n toggleSystemConfigType,\n hiddenTags,\n toggleSystemConfigTag,\n knownTypes,\n registerSystemConfigTypes,\n knownTags,\n registerSystemConfigTags,\n filteredOutCount,\n clearHidden,\n ] )\n\n return <FilterCtx.Provider value={value}>{children}</FilterCtx.Provider>\n}\n\nexport function useFilters(): FilterContextValue {\n const v = useContext( FilterCtx )\n if ( !v ) {\n throw new Error( 'useFilters must be used inside FilterProvider' )\n }\n return v\n}\n","export interface ImagineSystemConfigLike {\n displayName : string\n baseUrl : string\n type? : string | null\n tags? : string[]\n}\n\nexport function isDevConfig( c: ImagineSystemConfigLike ): boolean {\n const name = c.displayName.toLowerCase()\n const url = c.baseUrl.toLowerCase()\n return name.includes( 'dev' )\n || name.includes( 'staging' )\n || url.includes( 'dev-' )\n || url.includes( 'stg-' )\n}\n\nexport interface ConfigFilterOptions {\n showDev : boolean\n hiddenSystemConfigTypes : string[]\n hiddenSystemConfigTags : string[]\n}\n\nexport function applyConfigFilters<T extends ImagineSystemConfigLike>(\n configs: T[],\n filters: ConfigFilterOptions,\n): T[] {\n const typeBlocked = new Set( filters.hiddenSystemConfigTypes )\n const tagBlocked = new Set( filters.hiddenSystemConfigTags )\n\n return configs.filter( ( c ) => {\n if ( !filters.showDev && isDevConfig( c ) ) { return false }\n if ( c.type && typeBlocked.has( c.type ) ) { return false }\n // Tags: show if at least one tag is still visible. Hide only when the\n // config has tags and every one of them is in the hidden set.\n if ( c.tags && c.tags.length > 0 && c.tags.every( ( t ) => tagBlocked.has( t ) ) ) {\n return false\n }\n return true\n } )\n}\n","import { createContext, useContext, useEffect, useMemo, type ReactNode } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { Config } from '@leverege/plugin'\n\nimport { useImaginariumApi } from '../api/ImaginariumApiContext'\nimport { useFilters } from '../filters/FilterContext'\nimport { applyConfigFilters } from '../filters/applyConfigFilters'\nimport type { ImagineSystemConfig, ImagineSystemConfigListResponse } from './types'\n\nexport interface SystemConfigsContextValue {\n /** Raw list as returned by the server (before filters). */\n configs : ImagineSystemConfig[]\n /** Filter-applied view of `configs`. */\n filtered : ImagineSystemConfig[]\n isLoading : boolean\n isError : boolean\n error : unknown\n refetch : () => Promise<unknown>\n /** API path being polled (relative to apiBaseUrl). */\n apiPath : string\n /** React Query key — share this with mutations to invalidate the cache. */\n queryKey : readonly unknown[]\n}\n\nconst Ctx = createContext<SystemConfigsContextValue | null>( null )\n\nexport function SystemConfigsProvider( { children }: { children: ReactNode } ) {\n const { fetchJson } = useImaginariumApi()\n const apiPath = Config.get<string>( 'ImagineSystemConfig', 'apiPath', '/configs' )\n const queryKey = useMemo(\n () => [ 'imaginarium', 'system-configs', apiPath ] as const,\n [ apiPath ],\n )\n const filters = useFilters()\n\n const query = useQuery<ImagineSystemConfig[]>( {\n queryKey,\n queryFn: async () => {\n const res = await fetchJson<ImagineSystemConfigListResponse | ImagineSystemConfig[]>( apiPath )\n return Array.isArray( res ) ? res : ( res?.items ?? [] )\n },\n } )\n\n const configs = useMemo( () => query.data ?? [], [ query.data ] )\n const filtered = useMemo(\n () => applyConfigFilters( configs, filters )\n .slice()\n .sort( ( a, b ) => a.displayName.localeCompare( b.displayName, undefined, { sensitivity: 'base' } ) ),\n [ configs, filters ],\n )\n\n // Surface available types/tags so the global filter dropdown can render them.\n useEffect( () => {\n filters.registerSystemConfigTypes( configs.map( ( c ) => c.type ) )\n filters.registerSystemConfigTags( configs.flatMap( ( c ) => c.tags ?? [] ) )\n }, [ configs, filters.registerSystemConfigTypes, filters.registerSystemConfigTags ] )\n\n // Surface how many configs are currently being filtered out (badge on filter button).\n useEffect( () => {\n filters.setFilteredOutCount( configs.length - filtered.length )\n }, [ configs.length, filtered.length, filters.setFilteredOutCount ] )\n\n useEffect( () => {\n return () => filters.setFilteredOutCount( 0 )\n }, [ filters.setFilteredOutCount ] )\n\n const value = useMemo<SystemConfigsContextValue>( () => ( {\n configs,\n filtered,\n isLoading : query.isLoading,\n isError : query.isError,\n error : query.error,\n refetch : query.refetch,\n apiPath,\n queryKey,\n } ), [\n configs,\n filtered,\n query.isLoading,\n query.isError,\n query.error,\n query.refetch,\n apiPath,\n queryKey,\n ] )\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>\n}\n\nexport function useSystemConfigs(): SystemConfigsContextValue {\n const v = useContext( Ctx )\n if ( !v ) {\n throw new Error( 'useSystemConfigs must be used inside SystemConfigsProvider' )\n }\n return v\n}\n","import { PageDocsType } from '../plugins/PluginTypes'\nimport type { PageDocsPlugin } from '../plugins/types'\n\ninterface RegistryLike {\n addPlugin( type: string, plugin: unknown ): void\n}\n\nexport class PageDoc {\n static register( plg: RegistryLike, pageDoc: PageDocsPlugin ) {\n plg.addPlugin( PageDocsType, pageDoc )\n }\n}\n","import type { ComponentType } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport type { PageDocsPlugin } from '../plugins/types'\nimport { mdComponents, extractH2s, toTitleCase } from './mdComponents'\n\nexport class MarkdownPageDoc {\n static create( { path, markdown }: { path: string; markdown: string } ): PageDocsPlugin {\n const sections = extractH2s( markdown )\n\n const scrollTo = ( slug: string ) => {\n document.getElementById( slug )?.scrollIntoView( { behavior: 'smooth', block: 'start' } )\n }\n\n const Component: ComponentType = () => (\n <>\n {sections.length > 1 && (\n <div className=\"flex flex-wrap gap-1.5 mb-4\">\n {sections.map( ( { text, slug } ) => (\n <button\n key={slug}\n onClick={() => scrollTo( slug )}\n className=\"rounded-full border border-border bg-muted px-2.5 py-0.5 text-[11px] text-muted-foreground hover:border-primary/40 hover:text-foreground transition-colors\"\n >\n {toTitleCase( text )}\n </button>\n ) )}\n </div>\n )}\n <ReactMarkdown components={mdComponents}>{markdown}</ReactMarkdown>\n </>\n )\n\n return { path, component: Component }\n }\n}\n"],"names":["FilterCtx","createContext","registerInto","prev","incoming","next","t","arr","i","toggleIn","value","idx","_","FilterProvider","children","showDev","setShowDev","useState","hiddenTypes","setHiddenTypes","hiddenTags","setHiddenTags","knownTypes","setKnownTypes","knownTags","setKnownTags","filteredOutCount","setFilteredOutCount","toggleSystemConfigType","useCallback","type","toggleSystemConfigTag","tag","registerSystemConfigTypes","types","registerSystemConfigTags","tags","clearHidden","useMemo","jsx","useFilters","v","useContext","isDevConfig","c","name","url","applyConfigFilters","configs","filters","typeBlocked","tagBlocked","Ctx","SystemConfigsProvider","fetchJson","useImaginariumApi","apiPath","Config","queryKey","query","useQuery","res","filtered","b","useEffect","useSystemConfigs","PageDoc","plg","pageDoc","PageDocsType","MarkdownPageDoc","path","markdown","sections","extractH2s","scrollTo","slug","_a","jsxs","Fragment","text","ReactMarkdown","mdComponents"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- "use strict";const Me=require("./PluginTypes-BmYA5_B9.cjs"),ae=require("./MarkdownPageDoc-BZF02iL5.cjs"),e=require("react/jsx-runtime"),y=require("react"),g=require("./Card-CHVaz_7u.cjs"),K=require("@tanstack/react-query"),C=require("lucide-react"),be=require("@leverege/plugin"),T=require("./Label-BhnvyUcc.cjs"),xe=require("./Tooltip-DQn1fHhM.cjs"),bt=ae.MarkdownPageDoc.create({path:"/imp",markdown:`# imp
1
+ "use strict";const Me=require("./PluginTypes-BmYA5_B9.cjs"),ae=require("./MarkdownPageDoc-BrPfBSvd.cjs"),e=require("react/jsx-runtime"),y=require("react"),g=require("./Card-CHVaz_7u.cjs"),K=require("@tanstack/react-query"),C=require("lucide-react"),be=require("@leverege/plugin"),T=require("./Label-BhnvyUcc.cjs"),xe=require("./Tooltip-DQn1fHhM.cjs"),bt=ae.MarkdownPageDoc.create({path:"/imp",markdown:`# imp
2
2
 
3
3
  Manage cross-cluster releases for your Imagine project. A release captures a snapshot of entities from an origin cluster and lets you review diffs and push to one or more destination clusters.
4
4
 
@@ -113,4 +113,4 @@ After removing an ignore, refreshing an existing release draft will bring the it
113
113
  `).map((i,r)=>e.jsx("div",{className:n[r]?"bg-yellow-200/70 text-yellow-950 dark:bg-yellow-400/20 dark:text-yellow-100":void 0,children:i===""?" ":i},r))})]})}function Ke(t){return t===void 0?"null":JSON.stringify(t,null,2)}function We(t,s,n){let i=Ke(t);if(n&&n.length>0)for(const{replace:m,with:M}of n)m&&(i=i.split(m).join(M));const r=i.split(`
114
114
  `),d=Ke(s).split(`
115
115
  `),l=r.length,c=d.length,h=Array.from({length:l+1},()=>new Array(c+1).fill(0));for(let m=l-1;m>=0;m-=1)for(let M=c-1;M>=0;M-=1)h[m][M]=r[m]===d[M]?h[m+1][M+1]+1:Math.max(h[m+1][M],h[m][M+1]);const w=new Array(l).fill(!0);let v=0,o=0;for(;v<l&&o<c;)r[v]===d[o]?(w[v]=!1,v+=1,o+=1):h[v+1][o]>=h[v][o+1]?v+=1:o+=1;return w}function ge({title:t,values:s,excluded:n,editable:i,onToggle:r,formatLabel:d}){const[l,c]=y.useState(n.length>0);return y.useEffect(()=>{n.length>0&&c(!0)},[n.length]),e.jsxs("div",{className:"border-b p-2",children:[e.jsxs("button",{type:"button",className:"flex w-full items-center justify-between gap-2",onClick:()=>c(h=>!h),"aria-expanded":l,children:[e.jsxs("span",{className:"flex items-center gap-1 text-xs font-medium text-muted-foreground",children:[l?e.jsx(C.ChevronDown,{size:12}):e.jsx(C.ChevronRight,{size:12}),t," (",n.length,")"]}),i?null:e.jsx("span",{className:"text-[10px] text-muted-foreground",children:"read-only"})]}),l?e.jsx("div",{className:"mt-1 flex flex-col gap-1",children:s.map(h=>{const w=!n.includes(h);return e.jsxs("label",{className:"flex items-start gap-2 text-xs",children:[e.jsx("input",{type:"checkbox",className:"mt-0.5 shrink-0",checked:w,disabled:!i,onChange:v=>r==null?void 0:r(h,v.target.checked)}),e.jsx("span",{className:`min-w-0 break-all font-mono ${w?"":"text-muted-foreground line-through"}`,children:d?d(h):h})]},h)})}):null]})}function Xe({item:t,targets:s,onClose:n,unmetDependencyNames:i=[],tags:r=[],excludedTags:d=[],editable:l=!0,onToggleTag:c,metadataKeys:h=[],excludedMetadataKeys:w=[],onToggleMetadataKey:v,i18nPaths:o=[],excludedI18nPaths:m=[],onToggleI18nPath:M,permissionKeys:z=[],excludedPermissions:Q=[],onTogglePermission:U,formatPermissionLabel:_,replacementMaps:L}){var X,x,q,F;const B=((X=s[0])==null?void 0:X.id)??null,[J,f]=y.useState(B);y.useEffect(()=>{var R;f(((R=s[0])==null?void 0:R.id)??null)},[t==null?void 0:t.id]);const k=s.find(R=>R.id===J)??s[0]??null,S=(x=t==null?void 0:t.diff)==null?void 0:x.byTarget,p=S!=null,O=p?S[(k==null?void 0:k.id)??""]:(q=t==null?void 0:t.diff)==null?void 0:q.target,V=p&&k!=null&&!(k.id in S),G=y.useMemo(()=>{var R;return V?void 0:We((R=t==null?void 0:t.diff)==null?void 0:R.origin,O,L==null?void 0:L[(k==null?void 0:k.id)??""])},[t,O,V,L,k==null?void 0:k.id]);return t?e.jsxs("div",{className:"flex h-full flex-col rounded-md border bg-background",children:[e.jsxs("div",{className:"flex items-center justify-between border-b p-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate font-medium",children:t.itemName}),e.jsx("div",{className:"font-mono text-xs text-muted-foreground",children:t.itemType})]}),e.jsx(g.Button,{variant:"ghost",size:"icon",title:"Close",onClick:n,children:e.jsx(C.X,{})})]}),i.length>0?e.jsxs("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:[e.jsx(C.AlertTriangle,{size:14,className:"mt-0.5 shrink-0 text-amber-600 dark:text-amber-400"}),e.jsxs("span",{children:["Depends on excluded items: ",i.join(", "),". Push will fail for this item until they're included."]})]}):null,r.length>0?e.jsx(ge,{title:"Tag Overrides",values:r,excluded:d,editable:l,onToggle:c}):null,h.length>0?e.jsx(ge,{title:"Metadata Overrides",values:h,excluded:w,editable:l,onToggle:v}):null,o.length>0?e.jsx(ge,{title:"Translation Overrides",values:o,excluded:m,editable:l,onToggle:M}):null,z.length>0?e.jsx(ge,{title:"Permission Overrides",values:z,excluded:Q,editable:l,onToggle:U,formatLabel:_}):null,s.length>0?e.jsx("div",{className:"flex flex-wrap gap-1 border-b p-2",children:s.map(R=>{const H=p&&!(R.id in S);return e.jsxs("button",{type:"button",onClick:()=>f(R.id),className:`inline-flex items-center gap-1 rounded px-2 py-1 text-xs ${R.id===(k==null?void 0:k.id)?"bg-muted font-medium":"hover:bg-muted/50"}`,children:[H?e.jsx(C.Check,{size:12,className:"text-green-600"}):e.jsx("span",{className:"h-1.5 w-1.5 shrink-0 rounded-full bg-red-500","aria-hidden":!0}),R.name]},R.id)})}):null,e.jsxs("div",{className:"flex flex-1 gap-3 overflow-auto p-3",children:[e.jsx(pe,{label:"Origin",value:(F=t.diff)==null?void 0:F.origin,highlightLines:G}),V?e.jsxs("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:["Matches ",k==null?void 0:k.name," — no differences."]}):e.jsx(pe,{label:(k==null?void 0:k.name)??"Target",value:O})]})]}):null}function Nt({state:t}){switch(t.status){case"pushing":return e.jsxs("span",{className:"inline-flex items-center gap-1 text-sm text-muted-foreground",children:[e.jsx(C.Loader2,{className:"h-4 w-4 animate-spin"}),"Pushing…"]});case"success":return e.jsxs("span",{className:"inline-flex items-center gap-1 text-sm text-emerald-600",children:[e.jsx(C.Check,{className:"h-4 w-4"}),"Success"]});case"partial":return e.jsxs("span",{className:"inline-flex items-center gap-1 text-sm text-amber-600",children:[e.jsx(C.AlertTriangle,{className:"h-4 w-4"}),"Partial — ",t.failed??0," failed"]});case"failed":return e.jsxs("span",{className:"inline-flex items-center gap-1 text-sm text-destructive",title:t.error,children:[e.jsx(C.X,{className:"h-4 w-4"}),"Failed"]});default:return e.jsxs("span",{className:"inline-flex items-center gap-1 text-sm text-muted-foreground",children:[e.jsx(C.Circle,{className:"h-3 w-3"}),"Pending"]})}}function Ge({open:t,onOpenChange:s,releaseId:n,targetConfigIds:i,targetNames:r,apiPath:d="/releases",onComplete:l,dependencyWarnings:c=[]}){const{toast:h}=g.useToast(),{fetchJson:w}=g.useImaginariumApi(),v=K.useQueryClient(),[o,m]=y.useState(!1),[M,z]=y.useState({}),[Q,U]=y.useState(!1),_=f=>(r==null?void 0:r[f])??f,L=(f,k)=>z(S=>({...S,[f]:k})),B=async()=>{m(!0),U(!1),z(Object.fromEntries(i.map(S=>[S,{status:"idle"}])));let f=0,k=0;for(const S of i){L(S,{status:"pushing"});try{const p=await w(`${d}/${n}/push`,{method:"POST",body:JSON.stringify({destConfigId:S})}),O=(p.results??[]).filter(V=>!V.ok);p.status==="success"?(f+=1,L(S,{status:"success"})):p.status==="partial"?(k+=1,L(S,{status:"partial",failed:O.length,failures:O})):(k+=1,L(S,{status:"failed",failures:O}))}catch(p){k+=1;const O=p instanceof Error?p.message:String(p);L(S,{status:"failed",error:O})}}v.invalidateQueries({queryKey:["imaginarium","releases"]}),v.invalidateQueries({queryKey:["imaginarium","release",n]}),v.invalidateQueries({queryKey:["imaginarium","release-items",n]}),v.invalidateQueries({queryKey:["imaginarium","release-pushes",n]}),h(k===0?{title:"Push complete",description:`Pushed to ${f} target${f===1?"":"s"}.`}:{title:"Push finished with errors",description:`${k} target${k===1?"":"s"} did not fully succeed.`,variant:"destructive"}),m(!1),U(!0),l==null||l()},J=f=>{o||(f||(z({}),U(!1)),s(f))};return e.jsx(T.Dialog,{open:t,onOpenChange:J,children:e.jsxs(T.DialogContent,{children:[e.jsxs(T.DialogHeader,{children:[e.jsx(T.DialogTitle,{children:"Push release"}),e.jsx(T.DialogDescription,{children:"Pushes the included items to each target cluster, one at a time. Each target re-compares against the latest origin before applying."})]}),c.length>0?e.jsxs("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:[e.jsxs("div",{className:"flex items-center gap-2 font-medium",children:[e.jsx(C.AlertTriangle,{className:"h-4 w-4 shrink-0 text-amber-600 dark:text-amber-400"}),c.length," item",c.length===1?"":"s"," reference excluded dependencies"]}),e.jsx("ul",{className:"list-disc space-y-0.5 pl-8",children:c.map(f=>e.jsxs("li",{children:[f.itemName," → ",f.missing.join(", ")]},f.itemName))}),e.jsx("p",{className:"pl-8 text-amber-600",children:"Push may fail for these items. You can proceed anyway."})]}):null,e.jsx("div",{className:"space-y-2 py-2",children:i.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"This release has no targets."}):i.map(f=>{const k=M[f]??{status:"idle"},S=k.failures??[];return e.jsxs("div",{className:"rounded border px-3 py-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-sm font-medium",children:_(f)}),e.jsx(Nt,{state:k})]}),S.length>0?e.jsx("ul",{className:"mt-2 max-h-48 space-y-1 overflow-auto border-t pt-2 text-xs",children:S.map((p,O)=>e.jsxs("li",{className:"text-destructive",children:[e.jsxs("span",{className:"font-mono",children:[p.action?`${p.action} `:"",p.itemKey??"item"]}),p.error?e.jsxs("span",{className:"text-muted-foreground",children:[" — ",p.error]}):null]},`${p.itemKey??"item"}-${O}`))}):null]},f)})}),e.jsxs(T.DialogFooter,{children:[e.jsx(g.Button,{variant:"outline",onClick:()=>J(!1),disabled:o,children:"Close"}),e.jsxs(g.Button,{variant:"destructive",onClick:B,disabled:o||Q||i.length===0,children:[e.jsx(C.Send,{className:"w-4 h-4 mr-2"}),o?"Pushing…":"Confirm push"]})]})]})})}function vt(t){var s;return(((s=t.diff)==null?void 0:s.versions)??[]).filter(n=>!n.existsOnTarget)}function wt({item:t,disabled:s,onChange:n}){var r;const i=((r=t.diff)==null?void 0:r.versions)??[];return e.jsxs("select",{value:t.selectedVersion??"",disabled:s,onClick:d=>d.stopPropagation(),onChange:d=>n(d.target.value),className:"h-7 rounded-md border border-input bg-background px-2 py-0.5 text-xs disabled:cursor-not-allowed disabled:opacity-50","aria-label":"Rule version",children:[e.jsx("option",{value:"",disabled:!0,children:"Select a version"}),i.map(d=>{const l=String(d.version),c=d.existsOnTarget?`v${d.version} — already on target`:`v${d.version}${d.isPublished?" (published)":""}`;return e.jsx("option",{value:l,disabled:d.existsOnTarget,children:c},l)})]})}const Ct={blueprint:"bg-blue-100 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300",rule:"bg-orange-100 text-orange-700 dark:bg-orange-500/15 dark:text-orange-300",messageRoute:"bg-teal-100 text-teal-700 dark:bg-teal-500/15 dark:text-teal-300",role:"bg-purple-100 text-purple-700 dark:bg-purple-500/15 dark:text-purple-300",enum:"bg-yellow-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300",resourceEnum:"bg-yellow-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300",timer:"bg-slate-100 text-slate-600 dark:bg-slate-500/20 dark:text-slate-300",network:"bg-green-100 text-green-700 dark:bg-green-500/15 dark:text-green-300",module:"bg-indigo-100 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300",permission:"bg-pink-100 text-pink-700 dark:bg-pink-500/15 dark:text-pink-300",template:"bg-red-100 text-red-800 dark:bg-red-500/15 dark:text-red-300",script:"bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300",scenario:"bg-cyan-100 text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-300",system:"bg-gray-200 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300",attribute:"bg-violet-100 text-violet-700 dark:bg-violet-500/15 dark:text-violet-300",enumValue:"bg-violet-100 text-violet-700 dark:bg-violet-500/15 dark:text-violet-300",project:"bg-fuchsia-50 text-fuchsia-800 dark:bg-fuchsia-500/15 dark:text-fuchsia-300"};function re({type:t}){const s=Ct[t]??"bg-muted text-muted-foreground";return e.jsx("span",{className:`inline-flex items-center rounded px-1.5 py-0.5 text-xs font-semibold ${s}`,children:t})}function fe({checked:t,onChange:s,disabled:n=!1}){return e.jsxs("label",{className:`relative inline-block h-[18px] w-8 shrink-0 ${n?"cursor-not-allowed opacity-40":"cursor-pointer"}`,children:[e.jsx("input",{type:"checkbox",className:"peer sr-only",checked:t,disabled:n,onChange:i=>s(i.target.checked)}),e.jsx("span",{className:"absolute inset-0 rounded-full bg-input transition-colors peer-checked:bg-primary"}),e.jsx("span",{className:"absolute left-0.5 top-0.5 h-3.5 w-3.5 rounded-full bg-white transition-transform peer-checked:translate-x-3.5"})]})}function Ze(t){const s=new Map;for(const i of t){const r=s.get(i.destConfigId);(!r||i.createdAt>r.createdAt)&&s.set(i.destConfigId,i)}const n=new Map;for(const i of s.values())for(const r of i.results??[]){if(!r.itemKey)continue;let d=n.get(r.itemKey);d||(d=new Map,n.set(r.itemKey,d)),d.set(i.destConfigId,{ok:r.ok,error:r.error})}return n}function et(t,s,n){var i;return(i=t.get(s))==null?void 0:i.get(n)}function kt(t,s){return t.filter(n=>!(s.type!=="all"&&n.itemType!==s.type||s.included==="enabled"&&(!n.included||n.ignored)||s.included==="disabled"&&n.included&&!n.ignored))}function tt(t){const s={};for(const n of t)s[n.itemType]=(s[n.itemType]??0)+1;return s}function St(t){const s=t.indexOf(":"),n=s>=0?t.slice(0,s):t,i=s>=0?t.slice(s+1):t;return{id:"",releaseId:"",itemKey:t,itemType:n,itemName:i,parentKey:null,selectedVersion:null,status:"updated",included:!0,carriedOver:!1,ignored:!1,diff:null,createdAt:"",updatedAt:""}}function st(t){var d;const s=new Set(t.filter(l=>!l.parentKey).map(l=>l.itemKey)),n=[],i=new Map;for(const l of t){if(l.parentKey)continue;const c={item:l,children:[]};n.push(c),i.set(l.itemKey,c)}const r=new Map;for(const l of t){if(!l.parentKey)continue;if(s.has(l.parentKey)){(d=i.get(l.parentKey))==null||d.children.push(l);continue}let c=r.get(l.parentKey);c||(c={item:St(l.parentKey),children:[],synthetic:!0},r.set(l.parentKey,c),n.push(c)),c.children.push(l)}return n}function Tt(t){const s=t.indexOf(":"),n=s>=0?t.slice(0,s):t,i=s>=0?t.slice(s+1):t;return{itemKey:t,itemType:n,itemName:i,parentKey:null,cells:{}}}function nt(t){var d;const s=new Set(t.filter(l=>!l.parentKey).map(l=>l.itemKey)),n=[],i=new Map;for(const l of t){if(l.parentKey)continue;const c={row:l,children:[]};n.push(c),i.set(l.itemKey,c)}const r=new Map;for(const l of t){if(!l.parentKey)continue;if(s.has(l.parentKey)){(d=i.get(l.parentKey))==null||d.children.push(l);continue}let c=r.get(l.parentKey);c||(c={row:Tt(l.parentKey),children:[],synthetic:!0},r.set(l.parentKey,c),n.push(c)),c.children.push(l)}return n}function it(t){let s=0;for(const n of t.children)n.included&&!n.ignored&&(s+=1);return{included:s,total:t.children.length}}function at(t){var i,r;const s=[];for(const d of t){if(d.status!=="new")continue;const l=(i=d.diff)==null?void 0:i.origin,c=l==null?void 0:l.id;if(typeof c=="string"&&c&&s.push({token:c,depKey:d.itemKey}),d.itemType==="enum"){const h=l==null?void 0:l.type;typeof h=="string"&&h&&s.push({token:h,depKey:d.itemKey})}}const n=new Map;for(const d of t){const l=new Set,c=JSON.stringify(((r=d.diff)==null?void 0:r.origin)??null);for(const{token:h,depKey:w}of s)w!==d.itemKey&&c.includes(h)&&l.add(w);n.set(d.itemKey,l)}return n}function de(t,s,n){const i=s.get(t.itemKey);if(!i||i.size===0)return[];const r=[];for(const d of i){const l=n.get(d);l&&l.status==="new"&&(!l.included||l.ignored)&&r.push(l)}return r}const $e=["blueprint","system","network","enum","resourceEnum","timer","messageRoute","role","permission","module","scenario","template","project","rule","script"];function Re(t){const s=$e.indexOf(t);return s===-1?$e.length:s}function ye(t,s){const n=Re(t)-Re(s);return n!==0?n:t.localeCompare(s)}function Pt(t){return t.tags+t.metadataKeys+t.i18nPaths+t.permissions}function It(t){const s=[];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`}const Et=[{value:"all",label:"All"},{value:"enabled",label:"Enabled"},{value:"disabled",label:"Disabled"}];function De(t,s){return s==="all"?!0:s==="enabled"?t.included&&!t.ignored:!t.included||t.ignored}function Oe({status:t}){return e.jsx("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})}function Z(t){if(Array.isArray(t))return t.filter(s=>typeof s=="string");if(typeof t=="string"&&t.length>0)try{const s=JSON.parse(t);return Array.isArray(s)?s.filter(n=>typeof n=="string"):[]}catch{return[]}return[]}function Ae({item:t}){const s={tags:Z(t.excludedTags).length,metadataKeys:Z(t.excludedMetadataKeys).length,i18nPaths:Z(t.excludedI18nPaths).length,permissions:Z(t.excludedPermissions).length},n=Pt(s);return n<=0?null:e.jsxs("span",{title:It(s),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",children:[n," manual override",n===1?"":"s"]})}function Be({item:t,targetConfigIds:s,results:n,pushedDests:i,displayName:r}){const d=t.included&&!t.ignored,l=s.filter(c=>i.has(c)).map(c=>({id:c,result:et(n,t.itemKey,c)})).filter(c=>c.result!=null||d);return l.length===0?null:e.jsx("div",{className:"flex flex-wrap justify-end gap-1",children:l.map(({id:c,result:h})=>{const w=h?h.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=h?h.ok?"✓":"✗":"=",o=h?h.ok?void 0:h.error:"No change — already in sync";return e.jsxs("span",{title:o,className:`inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px] font-semibold ${w}`,children:[r(c)," ",v]},c)})})}function rt({releaseId:t,onBack:s}){var we,Ce,ke;const n=be.Config.get("Release","apiPath","/releases"),{toast:i}=g.useToast(),{fetchJson:r}=g.useImaginariumApi(),{configs:d}=ae.useSystemConfigs(),l=K.useQueryClient(),[c,h]=y.useState("all"),[w,v]=y.useState("all"),[o,m]=y.useState(null),[M,z]=y.useState(!1),[Q,U]=y.useState(()=>new Set),_=a=>U(N=>{const u=new Set(N);return u.has(a)?u.delete(a):u.add(a),u}),L=["imaginarium","release",t],B=["imaginarium","release-items",t],J=["imaginarium","release-pushes",t],{data:f,isLoading:k}=K.useQuery({queryKey:L,queryFn:()=>r(`${n}/${t}`)}),{data:S,isLoading:p}=K.useQuery({queryKey:B,queryFn:async()=>{const a=await r(`${n}/${t}/items`);return Array.isArray(a)?a:(a==null?void 0:a.items)??[]}}),{data:O}=K.useQuery({queryKey:J,queryFn:async()=>{const a=await r(`${n}/${t}/pushes`);return Array.isArray(a)?a:(a==null?void 0:a.items)??[]}}),V=y.useMemo(()=>Ze(O??[]),[O]),G=y.useMemo(()=>new Set((O??[]).map(a=>a.destConfigId)),[O]),X=(O??[]).length>0,x=y.useMemo(()=>(f==null?void 0:f.targetConfigIds)??[],[f]),q=y.useMemo(()=>{const a=new Map;return d.forEach(N=>a.set(String(N.id),N.displayName)),a},[d]),F=a=>q.get(a)??a,R=y.useMemo(()=>st(S??[]),[S]),H=y.useMemo(()=>R.map(a=>a.item),[R]),A=y.useMemo(()=>at(S??[]),[S]),j=y.useMemo(()=>new Map((S??[]).map(a=>[a.itemKey,a])),[S]),D=a=>{var u;let N;if(a.parentKey){const $=(u=j.get(a.parentKey))==null?void 0:u.itemName,P=a.parentKey.indexOf(":");N=$??(P>=0?a.parentKey.slice(P+1):void 0)}return`${N?N+" ":""}${a.itemType} "${a.itemName}"`},I=y.useMemo(()=>{var N,u;const a=new Map;for(const $ of S??[]){const P=(u=(N=$.diff)==null?void 0:N.origin)==null?void 0:u.id;typeof P=="string"&&P&&a.set(P,$.itemName)}return a},[S]),ie=y.useMemo(()=>(S??[]).filter(a=>a.included&&!a.ignored).map(a=>({itemName:a.itemName,missing:de(a,A,j).map(D)})).filter(a=>a.missing.length>0),[S,A,j]),le=y.useMemo(()=>tt(H),[H]),ce=y.useMemo(()=>Object.keys(le).sort(ye),[le]),Y=y.useMemo(()=>R.filter(a=>c==="all"||a.item.itemType===c).map(a=>{const N=w==="all"?a.children:a.children.filter(u=>De(u,w));return{node:a,renderChildren:N}}).filter(({node:a,renderChildren:N})=>w==="all"||De(a.item,w)||N.length>0).sort((a,N)=>{const u=ye(a.node.item.itemType,N.node.item.itemType);return u!==0?u:a.node.item.itemName.localeCompare(N.node.item.itemName)}),[R,c,w]),ee=K.useMutation({mutationFn:()=>r(`${n}/${t}/refresh`,{method:"POST"}),onSuccess:()=>{l.invalidateQueries({queryKey:B}),i({title:"Snapshot refreshed",description:"Items re-computed from origin."})},onError:a=>{i({title:"Error",description:a.message,variant:"destructive"})}}),ue=K.useMutation({mutationFn:({itemId:a,included:N})=>r(`${n}/${t}/items/${a}`,{method:"PATCH",body:JSON.stringify({included:N})}),onSuccess:()=>{l.invalidateQueries({queryKey:B})},onError:a=>{i({title:"Error",description:a.message,variant:"destructive"})}}),ve=K.useMutation({mutationFn:({itemId:a,selectedVersion:N})=>r(`${n}/${t}/items/${a}`,{method:"PATCH",body:JSON.stringify({selectedVersion:N})}),onSuccess:()=>{l.invalidateQueries({queryKey:B})},onError:a=>{i({title:"Error",description:a.message,variant:"destructive"})}}),me=a=>({mutationFn:({itemId:N,value:u})=>r(`${n}/${t}/items/${N}`,{method:"PATCH",body:JSON.stringify({[a]:u})}),onMutate:async({itemId:N,value:u})=>{await l.cancelQueries({queryKey:B});const $=l.getQueryData(B);return l.setQueryData(B,P=>(P??[]).map(se=>se.id===N?{...se,[a]:u}:se)),{prev:$}},onError:(N,u,$)=>{$!=null&&$.prev&&l.setQueryData(B,$.prev),i({title:"Error",description:N.message,variant:"destructive"})},onSettled:()=>{l.invalidateQueries({queryKey:B})}}),mt=K.useMutation(me("excludedTags")),ht=K.useMutation(me("excludedMetadataKeys")),xt=K.useMutation(me("excludedI18nPaths")),gt=K.useMutation(me("excludedPermissions")),pt=()=>l.invalidateQueries({queryKey:B}),te=(f==null?void 0:f.status)==="pushed",b=o?j.get(o.itemKey)??o:null;return k?e.jsx("div",{className:"text-center text-muted-foreground py-8",children:"Loading…"}):f?e.jsxs("div",{className:"space-y-4",children:[te&&e.jsx("div",{className:"bg-muted text-muted-foreground rounded-md px-3 py-2 text-sm",children:"This release was pushed and is read-only."}),e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs(g.Button,{variant:"ghost",size:"sm",onClick:s,children:[e.jsx(C.ArrowLeft,{}),"Back"]}),e.jsx("h3",{className:"text-lg font-semibold",children:f.name}),e.jsx(Ne,{status:f.status})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[!te&&e.jsx(Ye,{releaseId:t,apiPath:n,onReset:pt}),e.jsxs(g.Button,{variant:"outline",size:"sm",onClick:()=>ee.mutate(),disabled:te||ee.isPending,children:[e.jsx(C.RefreshCw,{}),ee.isPending?"Refreshing…":"Refresh"]}),te?e.jsx(g.Button,{size:"sm",disabled:!0,children:"Pushed ✓"}):e.jsx(g.Button,{size:"sm",onClick:()=>z(!0),disabled:(f.targetConfigIds??[]).length===0,children:"Push"})]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-sm text-muted-foreground",children:[e.jsx("span",{className:"inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs",children:F(f.originConfigId)}),e.jsx("span",{children:"→"}),(f.targetConfigIds??[]).map(a=>e.jsx("span",{className:"inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs",children:F(a)},a)),e.jsxs("span",{className:"ml-2",children:["Snapshot: ",f.snapshotAt?new Date(f.snapshotAt).toLocaleString():"—"]}),e.jsxs("span",{children:["Pushed: ",f.pushedAt?new Date(f.pushedAt).toLocaleString():"—"]})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-1",children:[e.jsxs(g.Button,{variant:c==="all"?"secondary":"ghost",size:"sm",onClick:()=>h("all"),children:["All types (",H.length,")"]}),ce.map(a=>e.jsxs(g.Button,{variant:c===a?"secondary":"ghost",size:"sm",onClick:()=>h(a),children:[a," (",le[a],")"]},a))]}),e.jsx("div",{className:"flex flex-wrap items-center gap-1",children:Et.map(a=>e.jsx(g.Button,{variant:w===a.value?"secondary":"outline",size:"sm",onClick:()=>v(a.value),children:a.label},a.value))})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"min-w-0 flex-1",children:p?e.jsx("div",{className:"text-center text-muted-foreground py-8",children:"Loading items…"}):Y.length===0?e.jsx(g.Card,{children:e.jsx(g.CardContent,{className:"py-12 text-center text-muted-foreground",children:H.length===0?"No items in this release yet.":"No items match the current filters."})}):e.jsx(g.Card,{children:e.jsx(g.CardContent,{className:"p-0",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b text-left text-muted-foreground",children:[e.jsx("th",{className:"p-3 font-medium w-10",children:"Inc."}),e.jsx("th",{className:"p-3 font-medium",children:"Type"}),e.jsx("th",{className:"p-3 font-medium",children:"Name"}),e.jsx("th",{className:"p-3 font-medium",children:"Status"}),e.jsx("th",{className:"p-3 font-medium"})]})}),e.jsx("tbody",{children:Y.map(({node:a,renderChildren:N})=>{var Ee;const u=a.item,$=N.length>0,P=Q.has(u.itemKey)||w!=="all",se=Q.has(u.itemKey),ne=it(a),Se=((Ee=u.diff)==null?void 0:Ee.versions)??[],oe=u.itemType==="rule"&&Se.length>0,Te=Se.some(E=>E.isPublished),ft=oe?vt(u):[],Pe=oe&&!Te,Ie=oe&&Te&&ft.length===0,he=Pe||Ie,yt=oe&&!he&&u.selectedVersion==null;return e.jsxs(y.Fragment,{children:[a.synthetic?e.jsxs("tr",{className:"border-b last:border-0 cursor-pointer hover:bg-muted/50",onClick:()=>_(u.itemKey),children:[e.jsx("td",{className:"p-3"}),e.jsx("td",{className:"p-3",children:e.jsx(re,{type:u.itemType})}),e.jsx("td",{className:"p-3",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",className:"text-muted-foreground hover:text-foreground",onClick:E=>{E.stopPropagation(),_(u.itemKey)},"aria-label":se?"Collapse":"Expand",children:se?e.jsx(C.ChevronDown,{size:14}):e.jsx(C.ChevronRight,{size:14})}),e.jsx("span",{className:"font-medium",children:u.itemName}),e.jsxs("span",{className:`inline-flex items-center rounded px-1.5 py-0.5 text-xs ${ne.included<ne.total?"bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300":"bg-muted text-muted-foreground"}`,children:[ne.included,"/",ne.total," changes included"]})]})}),e.jsx("td",{className:"p-3"}),e.jsx("td",{className:"p-3"})]}):e.jsxs("tr",{className:`border-b last:border-0 cursor-pointer hover:bg-muted/50 ${(o==null?void 0:o.id)===u.id?"bg-muted/50":""} ${he?"opacity-60":""}`,onClick:()=>m(u),children:[e.jsx("td",{className:"p-3",onClick:E=>E.stopPropagation(),children:e.jsx(fe,{checked:u.included,disabled:u.ignored||ue.isPending||te||he,onChange:E=>ue.mutate({itemId:u.id,included:E})})}),e.jsx("td",{className:"p-3",children:e.jsx(re,{type:u.itemType})}),e.jsx("td",{className:"p-3",children:e.jsxs("div",{className:"flex items-center gap-2",children:[$?e.jsx("button",{type:"button",className:"text-muted-foreground hover:text-foreground",onClick:E=>{E.stopPropagation(),_(u.itemKey)},"aria-label":se?"Collapse":"Expand",children:se?e.jsx(C.ChevronDown,{size:14}):e.jsx(C.ChevronRight,{size:14})}):null,e.jsx("span",{className:"font-medium",children:u.itemName}),(()=>{if(!u.included||u.ignored)return null;const E=de(u,A,j);return E.length===0?null:e.jsx("span",{title:`Depends on excluded: ${E.map(W=>W.itemName).join(", ")}`,children:e.jsx(C.AlertTriangle,{size:14,className:"shrink-0 text-amber-600"})})})(),e.jsx(Ae,{item:u}),$?e.jsxs("span",{className:`inline-flex items-center rounded px-1.5 py-0.5 text-xs ${ne.included<ne.total?"bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300":"bg-muted text-muted-foreground"}`,children:[ne.included,"/",ne.total," changes included"]}):null,u.carriedOver?e.jsx(He,{originName:F(f.originConfigId)}):null,u.ignored?e.jsx(Ue,{}):null,oe&&!he?e.jsx("span",{onClick:E=>E.stopPropagation(),children:e.jsx(wt,{item:u,disabled:te||ve.isPending,onChange:E=>ve.mutate({itemId:u.id,selectedVersion:E})})}):null,Pe?e.jsx("span",{className:"text-xs text-muted-foreground",children:"Rules without a published version cannot be pushed"}):null,Ie?e.jsx("span",{className:"text-xs text-muted-foreground",children:"Nothing to push — all versions exist on target"}):null,yt?e.jsx("span",{className:"text-xs text-amber-600",children:"Pushable version not selected"}):null]})}),e.jsx("td",{className:"p-3",children:e.jsx(Oe,{status:u.status})}),e.jsx("td",{className:"p-3 text-right",onClick:E=>E.stopPropagation(),children:e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[X?e.jsx(Be,{item:u,targetConfigIds:x,results:V,pushedDests:G,displayName:F}):null,!u.ignored&&!te&&e.jsx(_e,{createPayload:{originConfigId:f.originConfigId,itemKey:u.itemKey,itemType:u.itemType,itemName:u.itemName},onChange:()=>{l.setQueryData(B,E=>(E??[]).map(W=>W.id===u.id?{...W,ignored:!0,included:!1}:W)),ee.mutate()}})]})})]}),$&&P?N.map(E=>e.jsxs("tr",{className:`border-b last:border-0 cursor-pointer hover:bg-muted/50 ${(o==null?void 0:o.id)===E.id?"bg-muted/50":""}`,onClick:()=>m(E),children:[e.jsx("td",{className:"p-3 pl-8",onClick:W=>W.stopPropagation(),children:e.jsx(fe,{checked:E.included,disabled:E.ignored||ue.isPending||te,onChange:W=>ue.mutate({itemId:E.id,included:W})})}),e.jsx("td",{className:"p-3 pl-8",children:e.jsx(re,{type:E.itemType})}),e.jsx("td",{className:"p-3",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium",children:E.itemName}),(()=>{if(!E.included||E.ignored)return null;const W=de(E,A,j);return W.length===0?null:e.jsx("span",{title:`Depends on excluded: ${W.map(jt=>jt.itemName).join(", ")}`,children:e.jsx(C.AlertTriangle,{size:14,className:"shrink-0 text-amber-600"})})})(),e.jsx(Ae,{item:E})]})}),e.jsx("td",{className:"p-3",children:e.jsx(Oe,{status:E.status})}),e.jsx("td",{className:"p-3 text-right",onClick:W=>W.stopPropagation(),children:X?e.jsx(Be,{item:E,targetConfigIds:x,results:V,pushedDests:G,displayName:F}):null})]},E.id)):null]},a.synthetic?u.itemKey:u.id)})})]})})})}),o?e.jsx("div",{className:"w-[28rem] shrink-0 self-start sticky top-4 max-h-[calc(100vh-2rem)] overflow-auto",children:e.jsx(Xe,{item:b,targets:(f.targetConfigIds??[]).map(a=>({id:a,name:F(a)})),onClose:()=>m(null),unmetDependencyNames:b&&b.included&&!b.ignored?de(b,A,j).map(D):[],tags:Array.isArray((Ce=(we=b==null?void 0:b.diff)==null?void 0:we.origin)==null?void 0:Ce.tags)?((ke=b==null?void 0:b.diff)==null?void 0:ke.origin).tags??[]:[],excludedTags:Z(b==null?void 0:b.excludedTags),metadataKeys:(()=>{var N,u;const a=(u=(N=b==null?void 0:b.diff)==null?void 0:N.origin)==null?void 0:u.metadata;return a!=null&&typeof a=="object"&&!Array.isArray(a)?Object.keys(a):[]})(),excludedMetadataKeys:Z(b==null?void 0:b.excludedMetadataKeys),i18nPaths:(()=>{var u,$;const a=($=(u=b==null?void 0:b.diff)==null?void 0:u.origin)==null?void 0:$.i18n;if(!Array.isArray(a))return[];const N=a.map(P=>P==null?void 0:P.path).filter(P=>typeof P=="string");return Array.from(new Set(N))})(),excludedI18nPaths:Z(b==null?void 0:b.excludedI18nPaths),permissionKeys:(()=>{var u,$;if((b==null?void 0:b.itemType)!=="role")return[];const a=($=(u=b==null?void 0:b.diff)==null?void 0:u.origin)==null?void 0:$.permissions;if(!Array.isArray(a))return[];const N=a.map(P=>`${(P==null?void 0:P.module)??""}/${(P==null?void 0:P.name)??(P==null?void 0:P.id)??""}`).filter(P=>P!=="/");return Array.from(new Set(N))})(),excludedPermissions:Z(b==null?void 0:b.excludedPermissions),formatPermissionLabel:a=>a.split(/([/.])/).map(N=>{var u,$;return(($=(u=b==null?void 0:b.diff)==null?void 0:u.nameMap)==null?void 0:$[N])??I.get(N)??N}).join(""),replacementMaps:f.replacementMaps??void 0,editable:!te,onToggleTag:(a,N)=>{if(!b)return;const u=Z(b.excludedTags),$=N?u.filter(P=>P!==a):Array.from(new Set([...u,a]));mt.mutate({itemId:b.id,value:$})},onToggleMetadataKey:(a,N)=>{if(!b)return;const u=Z(b.excludedMetadataKeys),$=N?u.filter(P=>P!==a):Array.from(new Set([...u,a]));ht.mutate({itemId:b.id,value:$})},onToggleI18nPath:(a,N)=>{if(!b)return;const u=Z(b.excludedI18nPaths),$=N?u.filter(P=>P!==a):Array.from(new Set([...u,a]));xt.mutate({itemId:b.id,value:$})},onTogglePermission:(a,N)=>{if(!b)return;const u=Z(b.excludedPermissions),$=N?u.filter(P=>P!==a):Array.from(new Set([...u,a]));gt.mutate({itemId:b.id,value:$})}})}):null]}),e.jsx(Ge,{open:M,onOpenChange:z,releaseId:t,apiPath:n,targetConfigIds:f.targetConfigIds??[],targetNames:Object.fromEntries((f.targetConfigIds??[]).map(a=>[a,F(a)])),dependencyWarnings:ie})]}):e.jsxs("div",{className:"space-y-4",children:[e.jsxs(g.Button,{variant:"ghost",size:"sm",onClick:s,children:[e.jsx(C.ArrowLeft,{}),"Back"]}),e.jsx("p",{className:"text-muted-foreground",children:"Release not found."})]})}function je({value:t,onChange:s,configs:n,label:i}){const r=`cluster-select-${i.toLowerCase().replace(/\s+/g,"-")}`;return e.jsxs("div",{className:"space-y-2",children:[e.jsx(T.Label,{htmlFor:r,children:i}),e.jsxs("select",{id:r,value:t,onChange:d=>s(d.target.value),className:"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",children:[e.jsx("option",{value:"",children:"Select cluster…"}),n.map(d=>e.jsx("option",{value:d.id,children:d.displayName},d.id))]})]})}function lt({item:t,onClose:s}){var i,r;const n=y.useMemo(()=>{var d,l;return We((d=t==null?void 0:t.diff)==null?void 0:d.origin,(l=t==null?void 0:t.diff)==null?void 0:l.target)},[t]);return t?e.jsxs("div",{className:"flex h-full flex-col rounded-md border bg-background",children:[e.jsxs("div",{className:"flex items-center justify-between border-b p-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate font-medium",children:t.itemName}),e.jsx("div",{className:"font-mono text-xs text-muted-foreground",children:t.itemType})]}),e.jsx(g.Button,{variant:"ghost",size:"icon",title:"Close",onClick:s,children:e.jsx(C.X,{})})]}),e.jsxs("div",{className:"flex flex-1 gap-3 overflow-auto p-3",children:[e.jsx(pe,{label:"Origin",value:(i=t.diff)==null?void 0:i.origin,highlightLines:n}),e.jsx(pe,{label:"Target",value:(r=t.diff)==null?void 0:r.target})]})]}):null}const Fe={match:{symbol:"✓",className:"text-muted-foreground",label:"Match"},diff:{symbol:"≠",className:"text-red-500 dark:text-red-400 font-semibold",label:"Diff"},translated:{symbol:"≈",className:"text-blue-600 dark:text-blue-400 font-semibold",label:"Translated"},missing:{symbol:"✗",className:"text-red-500 dark:text-red-400 font-semibold",label:"Missing"},extra:{symbol:"+",className:"text-amber-600 font-semibold",label:"Extra"},skip:{symbol:"—",className:"text-muted-foreground/50",label:"Ignored"}};function qe({state:t,onClick:s,active:n}){const i=Fe[t]??Fe.match,r=t!=="match"&&t!=="skip"&&!!s;return e.jsx("button",{type:"button",onClick:r?s:void 0,disabled:!r,title:i.label,className:g.cn("w-full text-center text-sm py-1 rounded",i.className,r&&"hover:bg-muted cursor-pointer",!r&&"cursor-default",n&&"bg-muted ring-1 ring-ring"),children:i.symbol})}function Mt({stats:t,destConfigIds:s}){return e.jsx("div",{className:"flex gap-6 text-xs text-muted-foreground py-2 px-1",children:s.map(n=>{const i=t[n];if(!i)return null;const r=i.match+i.diff+i.missing+i.extra;return e.jsxs("span",{children:[e.jsxs("span",{className:"font-mono font-medium",children:[i.match,"/",r]})," match",i.diff>0&&e.jsxs("span",{className:"text-destructive ml-2",children:[i.diff," diff"]}),i.missing>0&&e.jsxs("span",{className:"text-destructive ml-2",children:[i.missing," missing"]}),i.extra>0&&e.jsxs("span",{className:"text-amber-600 ml-2",children:[i.extra," extra"]})]},n)})})}function Qe(t){return Object.values(t.cells).some(s=>s==="diff"||s==="missing"||s==="extra")}function ot({originConfigId:t,destConfigIds:s,apiPath:n="/release-status"}){const{toast:i}=g.useToast(),{fetchJson:r}=g.useImaginariumApi(),{configs:d}=ae.useSystemConfigs(),l=K.useQueryClient(),[c,h]=y.useState("issues"),[w,v]=y.useState(!1),[o,m]=y.useState(null),[M,z]=y.useState(new Set),[Q,U]=y.useState(()=>new Set),_=j=>U(D=>{const I=new Set(D);return I.has(j)?I.delete(j):I.add(j),I}),L=y.useMemo(()=>{const j=new Map;return d.forEach(D=>j.set(D.id,D.displayName)),j},[d]),B=j=>L.get(j)??j,J=s.filter(j=>!M.has(j)),f=new URLSearchParams;f.set("originConfigId",t),J.forEach(j=>f.append("destConfigIds[]",j));const k=["imaginarium","release-status",t,J],{data:S,isLoading:p,isError:O}=K.useQuery({queryKey:k,queryFn:()=>r(`${n}?${f.toString()}`),enabled:J.length>0}),V=K.useMutation({mutationFn:()=>r(`${n}/refresh`,{method:"POST",body:JSON.stringify({originConfigId:t,destConfigIds:J})}),onSuccess:()=>{l.invalidateQueries({queryKey:k}),i({title:"Cache cleared",description:"Refreshing comparison data…"})},onError:j=>{i({title:"Error",description:j.message,variant:"destructive"})}}),{data:G,isLoading:X,isError:x}=K.useQuery({queryKey:["imaginarium","release-status-diff",t,o==null?void 0:o.destConfigId,o==null?void 0:o.itemKey],queryFn:()=>r(`${n}/diff?originConfigId=${encodeURIComponent(t)}&destConfigId=${encodeURIComponent(o.destConfigId)}&itemKey=${encodeURIComponent(o.itemKey)}`),enabled:!!o}),q=j=>{z(D=>{const I=new Set(D);return I.has(j)?I.delete(j):I.add(j),I})},F=(j,D)=>{m(I=>(I==null?void 0:I.itemKey)===j&&I.destConfigId===D?null:{itemKey:j,destConfigId:D})},R=(S==null?void 0:S.rows)??[],H=(S==null?void 0:S.stats)??{},A=y.useMemo(()=>nt(R).map(D=>{const I=c==="issues"?D.children.filter(Qe):D.children;return{node:D,renderChildren:I}}).filter(({node:D,renderChildren:I})=>c==="all"||Qe(D.row)||I.length>0).sort((D,I)=>{const ie=ye(D.node.row.itemType,I.node.row.itemType);return ie!==0?ie:D.node.row.itemName.localeCompare(I.node.row.itemName)}),[R,c]);return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("div",{className:"flex rounded-md border text-sm overflow-hidden",children:[e.jsx("button",{className:g.cn("px-3 py-1.5",c==="issues"?"bg-muted font-medium":"hover:bg-muted/50"),onClick:()=>h("issues"),children:"Issues only"}),e.jsx("button",{className:g.cn("px-3 py-1.5 border-l",c==="all"?"bg-muted font-medium":"hover:bg-muted/50"),onClick:()=>h("all"),children:"All"})]}),e.jsxs(g.Button,{variant:"ghost",size:"sm",onClick:()=>v(j=>!j),children:[e.jsx(C.BarChart2,{}),"Stats"]}),e.jsxs(g.Button,{variant:"ghost",size:"sm",onClick:()=>V.mutate(),disabled:V.isPending,children:[e.jsx(C.RefreshCw,{className:g.cn(V.isPending&&"animate-spin")}),"Refresh"]}),[...M].map(j=>e.jsxs("button",{onClick:()=>q(j),className:"text-xs border rounded px-2 py-1 text-muted-foreground hover:bg-muted",children:["+ ",B(j)]},j))]}),w&&S&&e.jsx(Mt,{stats:H,destConfigIds:J}),p&&e.jsx("div",{className:"text-center text-muted-foreground py-8",children:"Loading…"}),O&&e.jsx("div",{className:"text-center text-destructive py-8",children:"Failed to load comparison data."}),!p&&!O&&e.jsxs("div",{className:"flex gap-4",children:[e.jsx("div",{className:"min-w-0 flex-1 rounded-md border overflow-auto max-h-[70vh]",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b bg-muted/50",children:[e.jsx("th",{className:"sticky top-0 z-10 bg-muted px-4 py-2 text-left font-medium min-w-[200px]",children:"Item"}),J.map(j=>e.jsx("th",{className:"sticky top-0 z-10 bg-muted px-2 py-2 text-center font-medium min-w-[80px]",children:e.jsxs("div",{className:"flex items-center justify-center gap-1",children:[e.jsx("span",{className:"truncate max-w-[120px]",title:B(j),children:B(j)}),e.jsx("button",{className:"text-muted-foreground hover:text-foreground",onClick:()=>q(j),title:"Hide column",children:"×"})]})},j))]})}),e.jsx("tbody",{children:A.length===0?e.jsx("tr",{children:e.jsx("td",{colSpan:J.length+1,className:"text-center text-muted-foreground py-8",children:c==="issues"?"No issues found — all clusters in sync.":"No items."})}):A.map(({node:j,renderChildren:D})=>{const I=j.row,ie=D.length>0,le=Q.has(I.itemKey)||c==="issues",ce=Q.has(I.itemKey);return e.jsxs(y.Fragment,{children:[e.jsxs("tr",{className:"border-b last:border-0 hover:bg-muted/25",children:[e.jsx("td",{className:"px-4 py-1.5",children:e.jsxs("div",{className:"flex items-center gap-2",children:[ie?e.jsx("button",{type:"button",className:"text-muted-foreground hover:text-foreground",onClick:()=>_(I.itemKey),"aria-label":ce?"Collapse":"Expand",children:ce?e.jsx(C.ChevronDown,{size:14}):e.jsx(C.ChevronRight,{size:14})}):null,e.jsx("span",{className:"inline-flex align-middle",children:e.jsx(re,{type:I.itemType})}),e.jsx("span",{className:"font-medium",children:I.itemName})]})}),J.map(Y=>e.jsx("td",{className:"px-2 py-1",children:e.jsx(qe,{state:I.cells[Y]??"match",active:(o==null?void 0:o.itemKey)===I.itemKey&&o.destConfigId===Y,onClick:()=>F(I.itemKey,Y)})},Y))]}),ie&&le?D.map(Y=>e.jsxs("tr",{className:"border-b last:border-0 hover:bg-muted/25",children:[e.jsx("td",{className:"px-4 py-1.5 pl-8",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"inline-flex align-middle",children:e.jsx(re,{type:Y.itemType})}),e.jsx("span",{className:"font-medium",children:Y.itemName})]})}),J.map(ee=>e.jsx("td",{className:"px-2 py-1",children:e.jsx(qe,{state:Y.cells[ee]??"match",active:(o==null?void 0:o.itemKey)===Y.itemKey&&o.destConfigId===ee,onClick:()=>F(Y.itemKey,ee)})},ee))]},Y.itemKey)):null]},I.itemKey)})})]})}),o?e.jsx("div",{className:"w-[28rem] shrink-0 self-start sticky top-4 max-h-[calc(100vh-2rem)] overflow-auto",children:X?e.jsx("div",{className:"flex h-full items-center justify-center rounded-md border bg-background p-4 text-sm text-muted-foreground",children:"Loading diff…"}):x||!G?e.jsx("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."}):e.jsx(lt,{item:{itemName:G.itemName,itemType:G.itemType,diff:{origin:G.origin,target:G.target}},onClose:()=>m(null)})}):null]})]})}const ze=t=>({name:"",description:"",values:Object.fromEntries(t.map(s=>[s,""]))});function dt({configIds:t,clusterNames:s={},apiPath:n="/release-translations"}){const{toast:i}=g.useToast(),{fetchJson:r}=g.useImaginariumApi(),d=K.useQueryClient(),[l,c]=y.useState(!1),[h,w]=y.useState(null),[v,o]=y.useState(ze(t)),[m,M]=y.useState(()=>new Set),z=x=>{M(q=>{const F=new Set(q);return F.has(x)?F.delete(x):F.add(x),F})},Q=["imaginarium","release-translations"],{data:U,isLoading:_}=K.useQuery({queryKey:Q,queryFn:async()=>{const x=await r(n);return(x==null?void 0:x.items)??[]}}),L=K.useMutation({mutationFn:async x=>{const q=await r(n,{method:"POST",body:JSON.stringify({name:x.name.trim(),description:x.description.trim()||null})});await f(q.id,x.values)},onSuccess:()=>{d.invalidateQueries({queryKey:Q}),i({title:"Translation created"}),p()},onError:x=>i({title:"Error",description:x.message,variant:"destructive"})}),B=K.useMutation({mutationFn:async x=>{await r(`${n}/${h.id}`,{method:"PATCH",body:JSON.stringify({name:x.name.trim(),description:x.description.trim()||null})}),await f(h.id,x.values)},onSuccess:()=>{d.invalidateQueries({queryKey:Q}),i({title:"Translation updated"}),p()},onError:x=>i({title:"Error",description:x.message,variant:"destructive"})}),J=K.useMutation({mutationFn:x=>r(`${n}/${x}`,{method:"DELETE"}),onSuccess:()=>{d.invalidateQueries({queryKey:Q}),i({title:"Translation deleted"})},onError:x=>i({title:"Error",description:x.message,variant:"destructive"})});async function f(x,q){var R;const F=(h==null?void 0:h.values)??[];for(const H of t){const A=(R=q[H])==null?void 0:R.trim(),j=F.find(I=>I.configId===H),D=`${n}/${x}/values`;j&&A?await r(`${D}/${j.id}`,{method:"PATCH",body:JSON.stringify({value:A})}):j&&!A?await r(`${D}/${j.id}`,{method:"DELETE"}):!j&&A&&await r(D,{method:"POST",body:JSON.stringify({translationId:x,configId:H,value:A})})}}const k=()=>{w(null),o(ze(t)),c(!0)},S=x=>{w(x);const q=x.values??[],F=Object.fromEntries(t.map(R=>{var H;return[R,((H=q.find(A=>A.configId===R))==null?void 0:H.value)??""]}));o({name:x.name,description:x.description??"",values:F}),c(!0)},p=()=>{c(!1),w(null)},O=()=>{h?B.mutate(v):L.mutate(v)},V=L.isPending||B.isPending,G=!!v.name.trim();if(_)return e.jsx("div",{className:"text-center text-muted-foreground py-8",children:"Loading…"});const X=[...U??[]].sort((x,q)=>x.name.localeCompare(q.name,void 0,{sensitivity:"base"}));return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:X.length===0?"No translation rules yet.":`${X.length} translation rule${X.length===1?"":"s"}.`}),e.jsxs(g.Button,{size:"sm",onClick:k,children:[e.jsx(C.Plus,{}),"Add translation"]})]}),X.length>0&&e.jsx("div",{className:"rounded-md border divide-y text-sm",children:X.map(x=>{const q=m.has(x.id),F=x.values??[],R=A=>{var j;return((j=F.find(D=>D.configId===A))==null?void 0:j.value)??""},H=t.filter(A=>R(A)).length;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-3 px-4 py-2 hover:bg-muted/25",children:[e.jsxs("button",{type:"button",onClick:()=>z(x.id),"aria-expanded":q,className:"flex flex-1 min-w-0 items-center gap-3 text-left",children:[q?e.jsx(C.ChevronDown,{className:"size-4 shrink-0 text-muted-foreground"}):e.jsx(C.ChevronRight,{className:"size-4 shrink-0 text-muted-foreground"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"font-medium",children:x.name}),x.description&&e.jsx("div",{className:"truncate text-xs text-muted-foreground",children:x.description})]}),e.jsxs("div",{className:"shrink-0 whitespace-nowrap text-xs text-muted-foreground",children:[H," of ",t.length," set"]})]}),e.jsxs("div",{className:"flex shrink-0 gap-1",children:[e.jsx(g.Button,{variant:"ghost",size:"icon",onClick:()=>S(x),children:e.jsx(C.Pencil,{})}),e.jsx(g.Button,{variant:"ghost",size:"icon",onClick:()=>{window.confirm(`Delete translation "${x.name}"?`)&&J.mutate(x.id)},children:e.jsx(C.Trash2,{})})]})]}),q&&e.jsx("div",{className:"space-y-1 px-4 pb-3 pl-11",children:t.map(A=>e.jsxs("div",{className:"grid grid-cols-[10rem_1fr] gap-2 text-xs",children:[e.jsx("span",{className:"text-muted-foreground",children:s[A]??A}),e.jsx("span",{className:"break-all font-mono",children:R(A)||e.jsx("span",{className:"text-muted-foreground",children:"—"})})]},A))})]},x.id)})}),e.jsx(T.Dialog,{open:l,onOpenChange:c,children:e.jsxs(T.DialogContent,{className:"max-w-lg",children:[e.jsxs(T.DialogHeader,{children:[e.jsx(T.DialogTitle,{children:h?`Edit ${h.name}`:"New Translation Rule"}),e.jsx(T.DialogDescription,{children:"Set the equivalent values for each cluster. Rules with values on only one side of a pair are silently skipped for that comparison."})]}),e.jsxs("div",{className:"space-y-4 py-2",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsx(T.Label,{htmlFor:"tr-name",children:"Name"}),e.jsx(T.Input,{id:"tr-name",value:v.name,onChange:x=>o({...v,name:x.target.value}),placeholder:"key (ex. molten-url)"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx(T.Label,{htmlFor:"tr-desc",children:"Description (optional)"}),e.jsx(T.Input,{id:"tr-desc",value:v.description,onChange:x=>o({...v,description:x.target.value}),placeholder:"Explain what this value represents"})]}),e.jsxs("div",{className:"space-y-3 pt-1",children:[e.jsx("p",{className:"text-sm font-medium",children:"Values per cluster"}),t.map(x=>e.jsxs("div",{className:"space-y-1",children:[e.jsx(T.Label,{htmlFor:`tr-val-${x}`,className:"text-xs text-muted-foreground",children:s[x]??x}),e.jsx(T.Input,{id:`tr-val-${x}`,value:v.values[x]??"",onChange:q=>o({...v,values:{...v.values,[x]:q.target.value}}),placeholder:"Leave blank to remove",className:"font-mono text-xs"})]},x))]})]}),e.jsxs(T.DialogFooter,{children:[e.jsxs(g.Button,{variant:"outline",onClick:p,children:[e.jsx(C.X,{}),"Cancel"]}),e.jsxs(g.Button,{onClick:O,disabled:!G||V,children:[e.jsx(C.Save,{}),V?"Saving…":"Save"]})]})]})})]})}function ct({originConfigId:t,apiPath:s="/release-ignores"}){const{toast:n}=g.useToast(),{fetchJson:i}=g.useImaginariumApi(),r=K.useQueryClient(),d=["imaginarium","release-ignores",t],{data:l,isLoading:c}=K.useQuery({queryKey:d,queryFn:async()=>{const m=await i(`${s}?where[originConfigId]=${encodeURIComponent(t)}`);return(m==null?void 0:m.items)??[]}}),h=K.useMutation({mutationFn:m=>i(`${s}/${m}`,{method:"DELETE"}),onSuccess:()=>{r.invalidateQueries({queryKey:d}),n({title:"Item removed from ignore list"})},onError:m=>{n({title:"Error",description:m.message,variant:"destructive"})}}),w=K.useMutation({mutationFn:()=>i(`${s}?originConfigId=${encodeURIComponent(t)}`,{method:"DELETE"}),onSuccess:()=>{r.invalidateQueries({queryKey:d}),n({title:"All ignore rules cleared"})},onError:m=>{n({title:"Error",description:m.message,variant:"destructive"})}}),v=()=>{window.confirm("Remove all ignore rules for this cluster? Items will appear normally in future snapshots.")&&w.mutate()};if(c)return e.jsx("div",{className:"text-center text-muted-foreground py-8",children:"Loading…"});const o=l??[];return e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("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.`}),o.length>0&&e.jsxs(g.Button,{variant:"outline",size:"sm",onClick:v,disabled:w.isPending,children:[e.jsx(C.Ban,{}),w.isPending?"Clearing…":"Clear all"]})]}),o.length>0&&e.jsx("div",{className:"rounded-md border",children:e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b bg-muted/50",children:[e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Type"}),e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Name"}),e.jsx("th",{className:"px-4 py-2 text-left font-medium",children:"Reason"}),e.jsx("th",{className:"px-4 py-2 text-right font-medium"})]})}),e.jsx("tbody",{children:o.map(m=>e.jsxs("tr",{className:"border-b last:border-0 hover:bg-muted/25",children:[e.jsx("td",{className:"px-4 py-2 text-muted-foreground font-mono text-xs",children:m.itemType}),e.jsx("td",{className:"px-4 py-2 font-medium",children:m.itemName}),e.jsx("td",{className:"px-4 py-2 text-muted-foreground",children:m.reason??e.jsx("span",{className:"italic text-xs",children:"—"})}),e.jsx("td",{className:"px-4 py-2 text-right",children:e.jsx(g.Button,{variant:"ghost",size:"icon",title:"Remove from ignore list",onClick:()=>h.mutate(m.id),disabled:h.isPending,children:e.jsx(C.Trash2,{})})})]},m.id))})]})})]})}function Kt(t,s){return[...t].sort((n,i)=>(s[n]??n).localeCompare(s[i]??i,void 0,{sensitivity:"base"}))}const Le=["dev","stg","prd"];function $t(t){const s=(t.tags??[]).map(i=>i.toLowerCase()),n=Le.findIndex(i=>s.includes(i));return n===-1?Le.length:n}function Rt(t){const s=Object.fromEntries(t.map(r=>[r.id,r.displayName])),n=new Map;for(const r of t){const d=$t(r);n.has(d)||n.set(d,[]),n.get(d).push(r.id)}return[...n.keys()].sort((r,d)=>r-d).flatMap(r=>Kt(n.get(r),s))}const Dt=[{id:"releases",label:"Releases"},{id:"status",label:"Status"},{id:"translations",label:"Translations"},{id:"ignored",label:"Ignored"}];function ut(){var o;const[t,s]=y.useState("releases"),[n,i]=y.useState(null),{configs:r}=ae.useSystemConfigs(),[d,l]=y.useState("");y.useEffect(()=>{!d&&r.length>0&&l(r[0].id)},[d,r]);const c=y.useMemo(()=>{const m={};return r.forEach(M=>{m[M.id]=M.displayName}),m},[r]),h=d||((o=r[0])==null?void 0:o.id)||"",w=y.useMemo(()=>Rt(r),[r]),v=w.filter(m=>m!==h);return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-2xl font-semibold",children:"imp"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Manage releases across clusters"})]}),e.jsx("div",{className:"flex items-center gap-1 border-b pb-2",children:Dt.map(({id:m,label:M})=>e.jsx(g.Button,{variant:t===m?"secondary":"ghost",size:"sm",onClick:()=>s(m),children:M},m))}),t==="releases"&&(n==null?e.jsx(Ve,{onOpen:i}):e.jsx(rt,{releaseId:n,onBack:()=>i(null)})),t==="status"&&(r.length===0?e.jsx("div",{className:"text-muted-foreground",children:"No clusters configured."}):e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"max-w-xs",children:e.jsx(je,{label:"Reference",value:h,onChange:l,configs:r})}),h?e.jsx(ot,{originConfigId:h,destConfigIds:v}):e.jsx("div",{className:"text-muted-foreground",children:"Select a reference cluster."})]})),t==="translations"&&(r.length===0?e.jsx("div",{className:"text-muted-foreground",children:"No clusters configured."}):e.jsx(dt,{configIds:w,clusterNames:c})),t==="ignored"&&(r.length===0?e.jsx("div",{className:"text-muted-foreground",children:"No clusters configured."}):e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"max-w-xs",children:e.jsx(je,{label:"Cluster",value:h,onChange:l,configs:r})}),h?e.jsx(ct,{originConfigId:h}):e.jsx("div",{className:"text-muted-foreground",children:"Select a cluster."})]}))]})}const Ot={id:"imaginarium.ui.ImpPage",path:"/imp",element:ut},At={id:"imaginarium.ui.ImpNavItem",path:"/imp",label:"imp",icon:C.Bot,sort:150},Bt={install(t){t.addPlugin(Me.PageType,Ot),t.addPlugin(Me.NavItemType,At),ae.PageDoc.register(t,bt)}};exports.ClusterSelect=je;exports.CreateReleaseModal=Je;exports.DiffPanel=lt;exports.EntityTag=re;exports.IgnoreButton=_e;exports.IgnoredPill=Ue;exports.IgnoredTab=ct;exports.PreviouslySkippedBadge=He;exports.PushDialog=Ge;exports.ReleaseDetail=rt;exports.ReleaseDiffPanel=Xe;exports.ReleaseList=Ve;exports.ReleaseSetup=Bt;exports.ReleaseStatusBadge=Ne;exports.ReleaseView=ut;exports.ResetExclusionsButton=Ye;exports.StatusMatrix=ot;exports.Toggle=fe;exports.TranslationsTab=dt;exports.buildItemTree=st;exports.buildPushResultMap=Ze;exports.computeDependsOn=at;exports.filterItems=kt;exports.groupStatusRows=nt;exports.includedChildCounts=it;exports.pushResultFor=et;exports.typeCounts=tt;exports.unmetDependencies=de;
116
- //# sourceMappingURL=PluginSetup-XhNP-74n.cjs.map
116
+ //# sourceMappingURL=PluginSetup-6y-Q93AW.cjs.map