@leverege/imaginarium-ui 1.2.0 → 1.2.2

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 +0,0 @@
1
- {"version":3,"file":"PluginSetup-RmtTRKtb.js","sources":["../src/imp/release/CreateReleaseModal.tsx","../src/imp/release/StatusBadge.tsx","../src/imp/release/ReleaseList.tsx","../src/imp/release/PreviouslySkippedBadge.tsx","../src/imp/release/IgnoredPill.tsx","../src/imp/release/IgnoreButton.tsx","../src/imp/release/ResetExclusionsButton.tsx","../src/imp/release/DiffColumn.tsx","../src/imp/release/jsonLineDiff.ts","../src/imp/release/ReleaseDiffPanel.tsx","../src/imp/release/PushDialog.tsx","../src/imp/release/RuleVersionSelect.tsx","../src/imp/release/EntityTag.tsx","../src/imp/release/Toggle.tsx","../src/imp/release/pushResults.ts","../src/imp/release/itemFilters.ts","../src/imp/release/itemTree.ts","../src/imp/release/dependencies.ts","../src/imp/release/typeOrder.ts","../src/imp/release/exclusionSummary.ts","../src/imp/release/ReleaseDetail.tsx","../src/imp/release/ClusterSelect.tsx","../src/imp/release/DiffPanel.tsx","../src/imp/release/StatusMatrix.tsx","../src/imp/release/TranslationsTab.tsx","../src/imp/release/IgnoredTab.tsx","../src/imp/release/ReleaseView.tsx","../src/imp/release/ReleasePage.tsx","../src/imp/release/ReleaseNavItem.ts","../src/imp/release/PluginSetup.ts"],"sourcesContent":["import { useMemo, useState } from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Loader2, Save, X } from 'lucide-react'\nimport { Config } from '@leverege/plugin'\n\nimport { Button } from '../../components/ui/Button'\nimport {\n Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle,\n} from '../../components/ui/Dialog'\nimport { Input } from '../../components/ui/Input'\nimport { Label } from '../../components/ui/Label'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport { useSystemConfigs } from '../../system/SystemConfigsContext'\nimport type { Release } from './types'\n\nexport interface CreateReleaseModalProps {\n open: boolean\n onOpenChange: ( open: boolean ) => void\n /** Called with the new release id after create + snapshot succeed. */\n onCreated: ( id: string ) => void\n}\n\nexport default function CreateReleaseModal( { open, onOpenChange, onCreated }: CreateReleaseModalProps ) {\n const apiPath = Config.get<string>( 'Release', 'apiPath', '/releases' )\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const queryClient = useQueryClient()\n const { configs } = useSystemConfigs()\n\n const [ name, setName ] = useState( '' )\n const [ description, setDescription ] = useState( '' )\n const [ originConfigId, setOriginConfigId ] = useState( '' )\n const [ targetConfigIds, setTargetConfigIds ] = useState<string[]>( [] )\n\n const queryKey = [ 'imaginarium', 'releases', apiPath ] as const\n\n const reset = () => {\n setName( '' )\n setDescription( '' )\n setOriginConfigId( '' )\n setTargetConfigIds( [] )\n }\n\n // Targets exclude the chosen origin cluster.\n const targetOptions = useMemo(\n () => configs.filter( ( c ) => c.id !== originConfigId ),\n [ configs, originConfigId ],\n )\n\n const handleOriginChange = ( id: string ) => {\n setOriginConfigId( id )\n // Drop the origin from selected targets if it was previously chosen.\n setTargetConfigIds( ( prev ) => prev.filter( ( t ) => t !== id ) )\n }\n\n const toggleTarget = ( id: string ) => {\n setTargetConfigIds( ( prev ) =>\n prev.includes( id ) ? prev.filter( ( t ) => t !== id ) : [ ...prev, id ],\n )\n }\n\n // Sequenced create → snapshot: POST the release, then POST snapshot-from-compare\n // (the server uses the release's stored targetConfigIds for the union diff).\n const createMutation = useMutation( {\n mutationFn: async () => {\n const created = await fetchJson<Release>( apiPath, {\n method: 'POST',\n body: JSON.stringify( {\n name: name.trim(),\n description: description.trim() || null,\n originConfigId,\n targetConfigIds,\n } ),\n } )\n await fetchJson( `${apiPath}/${created.id}/snapshot-from-compare`, {\n method: 'POST',\n body: JSON.stringify( {} ),\n } )\n return created\n },\n onSuccess: ( created ) => {\n queryClient.invalidateQueries( { queryKey } )\n toast( { title: 'Success', description: 'Release created and snapshotted' } )\n onOpenChange( false )\n reset()\n onCreated( created.id )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n // Refetch regardless of outcome: if create succeeds but snapshot fails, the\n // new release would otherwise be orphaned and missing from the list.\n onSettled: () => {\n queryClient.invalidateQueries( { queryKey } )\n },\n } )\n\n const handleOpenChange = ( next: boolean ) => {\n if ( !next ) { reset() }\n onOpenChange( next )\n }\n\n const isValid = Boolean( name.trim() && originConfigId && targetConfigIds.length > 0 )\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>New Release</DialogTitle>\n <DialogDescription>\n Create a release from an origin cluster and snapshot the diff against its targets.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"release-name\">Name</Label>\n <Input\n id=\"release-name\"\n value={name}\n onChange={( e ) => setName( e.target.value )}\n placeholder=\"2026.05 Release\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"release-description\">Description (Optional)</Label>\n <Input\n id=\"release-description\"\n value={description}\n onChange={( e ) => setDescription( e.target.value )}\n placeholder=\"What this release contains\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"release-origin\">Origin Cluster</Label>\n <select\n id=\"release-origin\"\n value={originConfigId}\n onChange={( e ) => handleOriginChange( e.target.value )}\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n >\n <option value=\"\">Select origin…</option>\n {configs.map( ( c ) => (\n <option key={c.id} value={c.id}>{c.displayName}</option>\n ) )}\n </select>\n </div>\n\n <div className=\"space-y-2\">\n <Label>Target Clusters</Label>\n {targetOptions.length > 0 ? (\n <div className=\"space-y-1 rounded-md border border-input p-2 max-h-48 overflow-y-auto\">\n {targetOptions.map( ( c ) => (\n <label key={c.id} className=\"flex items-center gap-2 text-sm cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={targetConfigIds.includes( c.id )}\n onChange={() => toggleTarget( c.id )}\n />\n {c.displayName}\n </label>\n ) )}\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {originConfigId ? 'No other clusters available as targets.' : 'Select an origin first.'}\n </p>\n )}\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => handleOpenChange( false )} disabled={createMutation.isPending}>\n <X className=\"w-4 h-4 mr-2\" />\n Cancel\n </Button>\n <Button onClick={() => createMutation.mutate()} disabled={!isValid || createMutation.isPending}>\n {createMutation.isPending ? (\n <>\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\n Snapshotting…\n </>\n ) : (\n <>\n <Save className=\"w-4 h-4 mr-2\" />\n Create &amp; snapshot\n </>\n )}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","import type { Release } from './types'\n\nexport interface ReleaseStatusBadgeProps {\n status: Release['status']\n}\n\nexport default function ReleaseStatusBadge( { status }: ReleaseStatusBadgeProps ) {\n // 'pushed' = success; use an emerald that stays readable in both themes\n // ( text-primary on a faint primary fill was too dark to read in dark mode ).\n const styles = status === 'pushed'\n ? 'bg-emerald-500/15 text-emerald-700 dark:text-emerald-300 border-emerald-500/30'\n : 'bg-muted text-muted-foreground border-border'\n return (\n <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium border ${styles}`}>\n {status}\n </span>\n )\n}\n","import { useMemo, useState } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { Plus } from 'lucide-react'\nimport { Config } from '@leverege/plugin'\n\nimport { Button } from '../../components/ui/Button'\nimport { Card, CardContent } from '../../components/ui/Card'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport { useSystemConfigs } from '../../system/SystemConfigsContext'\nimport CreateReleaseModal from './CreateReleaseModal'\nimport StatusBadge from './StatusBadge'\nimport type { Release, ReleaseListResponse } from './types'\n\nexport interface ReleaseListProps {\n onOpen: ( id: string ) => void\n}\n\nexport default function ReleaseList( { onOpen }: ReleaseListProps ) {\n const apiPath = Config.get<string>( 'Release', 'apiPath', '/releases' )\n const { fetchJson } = useImaginariumApi()\n const { configs } = useSystemConfigs()\n const [ isModalOpen, setIsModalOpen ] = useState( false )\n\n const queryKey = [ 'imaginarium', 'releases', apiPath ] as const\n\n const { data: releases, isLoading } = useQuery<Release[]>( {\n queryKey,\n queryFn: async () => {\n const res = await fetchJson<ReleaseListResponse | Release[]>( apiPath )\n const items = Array.isArray( res ) ? res : ( res?.items ?? [] )\n // Newest first.\n return [ ...items ].sort( ( a, b ) => ( b.createdAt ?? '' ).localeCompare( a.createdAt ?? '' ) )\n },\n } )\n\n // cluster id → displayName lookup.\n const nameById = useMemo( () => {\n const map = new Map<string, string>()\n configs.forEach( ( c ) => map.set( c.id, c.displayName ) )\n return map\n }, [ configs ] )\n\n const displayName = ( id: string ) => nameById.get( id ) ?? id\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-end\">\n <Button onClick={() => setIsModalOpen( true )}>\n <Plus className=\"w-4 h-4 mr-2\" />\n New Release\n </Button>\n </div>\n\n {isLoading ? (\n <div className=\"text-center text-muted-foreground\">Loading…</div>\n ) : releases && releases.length > 0 ? (\n <Card>\n <CardContent className=\"p-0\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-muted-foreground\">\n <th className=\"p-3 font-medium\">Name</th>\n <th className=\"p-3 font-medium\">Origin</th>\n <th className=\"p-3 font-medium\">Targets</th>\n <th className=\"p-3 font-medium\">Status</th>\n <th className=\"p-3 font-medium\">Snapshot</th>\n <th className=\"p-3 font-medium\">Pushed</th>\n <th className=\"p-3 font-medium\" />\n </tr>\n </thead>\n <tbody>\n {/* Per-status change counts (e.g. \"33 new\") deferred for Phase 1 — would require fetching each release's items. */}\n {releases.map( ( r ) => (\n <tr\n key={r.id}\n className=\"border-b last:border-0 cursor-pointer hover:bg-muted/50\"\n onClick={() => onOpen( r.id )}\n >\n <td className=\"p-3\">\n <div className=\"font-medium\">{r.name}</div>\n {r.description ? (\n <div className=\"text-xs text-muted-foreground\">{r.description}</div>\n ) : null}\n </td>\n <td className=\"p-3\">{displayName( r.originConfigId )}</td>\n <td className=\"p-3\">\n <div className=\"flex flex-wrap gap-1\">\n {( r.targetConfigIds ?? [] ).map( ( id ) => (\n <span\n key={id}\n className=\"inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs\"\n >\n {displayName( id )}\n </span>\n ) )}\n </div>\n </td>\n <td className=\"p-3\"><StatusBadge status={r.status} /></td>\n <td className=\"p-3 text-muted-foreground\">\n {r.snapshotAt ? new Date( r.snapshotAt ).toLocaleString() : '—'}\n </td>\n <td className=\"p-3 text-muted-foreground\">\n {r.pushedAt ? new Date( r.pushedAt ).toLocaleString() : '—'}\n </td>\n <td className=\"p-3 text-right\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={( e ) => { e.stopPropagation(); onOpen( r.id ) }}\n >\n Open →\n </Button>\n </td>\n </tr>\n ) )}\n </tbody>\n </table>\n </CardContent>\n </Card>\n ) : (\n <Card>\n <CardContent className=\"py-12 text-center\">\n <p className=\"text-muted-foreground mb-4\">No releases yet</p>\n <Button onClick={() => setIsModalOpen( true )}>\n <Plus className=\"w-4 h-4 mr-2\" />\n Create Your First Release\n </Button>\n </CardContent>\n </Card>\n )}\n\n <CreateReleaseModal\n open={isModalOpen}\n onOpenChange={setIsModalOpen}\n onCreated={onOpen}\n />\n </div>\n )\n}\n","import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../components/ui/Tooltip'\nimport { cn } from '../../lib/utils'\n\nexport interface PreviouslySkippedBadgeProps {\n originName?: string\n className?: string\n}\n\n/**\n * Informational badge shown on release items that were auto-excluded by\n * carry-over from the most recent previous release.\n *\n * Disappears once the user manually toggles the item (server clears carriedOver).\n */\nexport default function PreviouslySkippedBadge( {\n originName,\n className,\n}: PreviouslySkippedBadgeProps ) {\n const tooltip = originName\n ? `Skipped in your last release from ${originName}.`\n : 'Skipped in your last release.'\n\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n className={cn(\n 'inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium',\n 'bg-muted text-muted-foreground cursor-default select-none',\n className,\n )}\n >\n previously skipped\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n {tooltip}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )\n}\n","import { cn } from '../../lib/utils'\n\nexport interface IgnoredPillProps {\n className?: string\n}\n\n/**\n * Inline badge displayed below the item name when an item is on the ignore list.\n * The include/exclude toggle is disabled separately by the parent; this badge\n * is purely informational.\n */\nexport default function IgnoredPill( { className }: IgnoredPillProps ) {\n return (\n <span\n className={cn(\n 'inline-flex items-center rounded px-1.5 py-0.5 text-xs font-medium',\n 'bg-red-500/10 text-red-600 dark:text-red-400 border border-red-500/25',\n className,\n )}\n >\n ignored\n </span>\n )\n}\n","import { useState } from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Ban } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport {\n Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle,\n} from '../../components/ui/Dialog'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport { cn } from '../../lib/utils'\nimport type { InsertReleaseIgnore, ReleaseIgnore } from './types'\n\nexport interface IgnoreButtonProps {\n /** When set, this item is currently ignored and the button acts as un-ignore. */\n ignoreRule?: ReleaseIgnore | null\n /** Required when ignoreRule is null — payload for creating the ignore rule. */\n createPayload?: InsertReleaseIgnore\n apiPath?: string\n /** Called after the ignore state changes so the parent can refresh. */\n onChange?: () => void\n className?: string\n}\n\n/**\n * ⊘ toggle button that adds or removes an item from the permanent ignore list.\n *\n * - Active (item IS ignored): clicking sends DELETE /api/release-ignores/:id\n * - Inactive (item is NOT ignored): clicking sends POST /api/release-ignores\n */\nexport default function IgnoreButton( {\n ignoreRule,\n createPayload,\n apiPath = '/release-ignores',\n onChange,\n className,\n}: IgnoreButtonProps ) {\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const queryClient = useQueryClient()\n\n const [ confirmOpen, setConfirmOpen ] = useState( false )\n\n const isIgnored = Boolean( ignoreRule )\n\n const invalidate = () => {\n queryClient.invalidateQueries( { queryKey: [ 'imaginarium', 'release-ignores' ] } )\n onChange?.()\n }\n\n const ignoreMutation = useMutation( {\n mutationFn: () =>\n fetchJson<ReleaseIgnore>( apiPath, {\n method: 'POST',\n body: JSON.stringify( createPayload ),\n } ),\n onSuccess: () => {\n toast( { title: 'Item ignored', description: 'Will be excluded from all future snapshots.' } )\n setConfirmOpen( false )\n invalidate()\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n const unignoreMutation = useMutation( {\n mutationFn: () =>\n fetchJson( `${apiPath}/${ignoreRule!.id}`, { method: 'DELETE' } ),\n onSuccess: () => {\n toast( { title: 'Item un-ignored', description: 'Will appear normally in future snapshots.' } )\n invalidate()\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n const isPending = ignoreMutation.isPending || unignoreMutation.isPending\n\n return (\n <>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title={isIgnored ? 'Remove from ignore list' : 'Ignore this item'}\n disabled={isPending}\n onClick={() => isIgnored ? unignoreMutation.mutate() : setConfirmOpen( true )}\n className={cn( isIgnored && 'text-red-500 hover:text-red-500 dark:text-red-400 dark:hover:text-red-400', className )}\n >\n <Ban />\n </Button>\n\n <Dialog open={confirmOpen} onOpenChange={setConfirmOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Ignore this item?</DialogTitle>\n <DialogDescription>\n Ignoring excludes this item from <strong>this and all future releases</strong> for\n this origin cluster — it will never be pushed to any destination. You can un-ignore it\n later from the Ignored tab.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setConfirmOpen( false )}\n disabled={ignoreMutation.isPending}\n >\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n onClick={() => ignoreMutation.mutate()}\n disabled={ignoreMutation.isPending}\n >\n <Ban className=\"w-4 h-4 mr-2\" />\n Ignore item\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n}\n","import { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { RotateCcw } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\n\nexport interface ResetExclusionsButtonProps {\n releaseId: string\n apiPath?: string\n /** Called after a successful reset so the parent can refresh item data. */\n onReset?: ( count: number ) => void\n}\n\n/**\n * Secondary button in the filter bar that re-enables all items whose excluded\n * state was carried over from a previous release.\n *\n * Only touches items where carriedOver = true; items the user manually toggled\n * in this session are left alone.\n */\nexport default function ResetExclusionsButton( {\n releaseId,\n apiPath = '/releases',\n onReset,\n}: ResetExclusionsButtonProps ) {\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const queryClient = useQueryClient()\n\n const mutation = useMutation( {\n mutationFn: () =>\n fetchJson<{ reset: number }>( `${apiPath}/${releaseId}/reset-exclusions`, {\n method: 'POST',\n } ),\n onSuccess: ( data ) => {\n queryClient.invalidateQueries( { queryKey: [ 'imaginarium', 'release-items', releaseId ] } )\n toast( {\n title: 'Exclusions reset',\n description: `${data.reset} item${data.reset === 1 ? '' : 's'} re-enabled.`,\n } )\n onReset?.( data.reset )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n return (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => mutation.mutate()}\n disabled={mutation.isPending}\n >\n <RotateCcw />\n {mutation.isPending ? 'Resetting…' : 'Reset exclusions'}\n </Button>\n )\n}\n","export interface DiffColumnProps {\n label: string\n value: unknown\n /** When provided, each origin line is rendered separately and lines marked `true` get a yellow highlight. */\n highlightLines?: boolean[]\n}\n\n/** Single column rendering a value as pretty-printed JSON. Shared by the diff panels. */\nexport default function DiffColumn( { label, value, highlightLines }: DiffColumnProps ) {\n return (\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <div className=\"mb-1 text-xs font-medium text-muted-foreground\">{label}</div>\n <pre className=\"flex-1 overflow-auto rounded border bg-muted/30 p-3 text-xs\">\n {highlightLines === undefined ? (\n value === undefined ? 'null' : JSON.stringify( value, null, 2 )\n ) : (\n ( value === undefined ? 'null' : JSON.stringify( value, null, 2 ) )\n .split( '\\n' )\n .map( ( line, i ) => (\n // eslint-disable-next-line react/no-array-index-key\n <div\n key={i}\n className={highlightLines[ i ]\n ? 'bg-yellow-200/70 text-yellow-950 dark:bg-yellow-400/20 dark:text-yellow-100'\n : undefined}\n >\n {line === '' ? ' ' : line}\n </div>\n ) )\n )}\n </pre>\n </div>\n )\n}\n","/** Pretty-prints a value the same way the diff columns do. */\nfunction stringify( value: unknown ): string {\n return value === undefined ? 'null' : JSON.stringify( value, null, 2 )\n}\n\n/**\n * Returns, for each line of the pretty-printed `originValue`, whether that line\n * differs from `targetValue` — i.e. is NOT part of the longest common\n * subsequence (LCS) of the two stringified line arrays. `true` = changed.\n *\n * When `rMap` is provided and non-empty, api-copy's replacement map is applied\n * to the ORIGIN text before diffing (the target text is left untouched). Each\n * `{ replace, with }` is a plain (non-regex) global substring swap, applied in\n * the given order — the map is pre-sorted longest-`replace`-first so longer ids\n * are replaced before any shorter substrings of them. This masks cluster-specific\n * id/translation differences ( which the push remaps ) so they don't highlight,\n * while genuine diffs remain flagged. Because `replace` only swaps values and\n * never adds/removes lines, the result still maps 1:1 onto the displayed origin.\n *\n * Identical inputs yield all `false`; a target that shares no lines flags every\n * origin line. Runs in O(n*m), which is fine for these snapshot sizes.\n */\nexport function changedOriginLines(\n originValue: unknown,\n targetValue: unknown,\n rMap?: { replace: string; with: string }[],\n): boolean[] {\n let originText = stringify( originValue )\n if ( rMap && rMap.length > 0 ) {\n for ( const { replace, with: withValue } of rMap ) {\n if ( replace ) { originText = originText.split( replace ).join( withValue ) }\n }\n }\n const o = originText.split( '\\n' )\n const t = stringify( targetValue ).split( '\\n' )\n const n = o.length\n const m = t.length\n\n // dp[i][j] = LCS length of o[i:] and t[j:].\n const dp: number[][] = Array.from( { length: n + 1 }, () => new Array( m + 1 ).fill( 0 ) )\n for ( let i = n - 1; i >= 0; i -= 1 ) {\n for ( let j = m - 1; j >= 0; j -= 1 ) {\n dp[ i ][ j ] = o[ i ] === t[ j ]\n ? dp[ i + 1 ][ j + 1 ] + 1\n : Math.max( dp[ i + 1 ][ j ], dp[ i ][ j + 1 ] )\n }\n }\n\n // Backtrack: lines on the LCS path are unchanged; everything else is changed.\n const changed = new Array<boolean>( n ).fill( true )\n let i = 0\n let j = 0\n while ( i < n && j < m ) {\n if ( o[ i ] === t[ j ] ) {\n changed[ i ] = false\n i += 1\n j += 1\n } else if ( dp[ i + 1 ][ j ] >= dp[ i ][ j + 1 ] ) {\n i += 1\n } else {\n j += 1\n }\n }\n\n return changed\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport { Check, X, AlertTriangle, ChevronRight, ChevronDown } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport DiffColumn from './DiffColumn'\nimport { changedOriginLines } from './jsonLineDiff'\nimport type { ReleaseItem } from './types'\n\nexport interface ReleaseDiffPanelProps {\n item: ReleaseItem | null\n targets: { id: string; name: string }[]\n onClose: () => void\n /** Names of new dependencies that are excluded/ignored; push will fail until included. */\n unmetDependencyNames?: string[]\n /** The item's full origin tag list. */\n tags?: string[]\n /** Tag values currently excluded from the push. */\n excludedTags?: string[]\n /** The metadata object's top-level keys. */\n metadataKeys?: string[]\n /** Metadata keys currently excluded from the push. */\n excludedMetadataKeys?: string[]\n /** Called when a metadata-key checkbox flips. push=true includes it, push=false excludes it. */\n onToggleMetadataKey?: ( key: string, push: boolean ) => void\n /** The i18n entries' resource paths. */\n i18nPaths?: string[]\n /** i18n paths currently excluded from the push. */\n excludedI18nPaths?: string[]\n /** Called when an i18n-path checkbox flips. push=true includes it, push=false excludes it. */\n onToggleI18nPath?: ( path: string, push: boolean ) => void\n /** The role's permission keys (`module/name`). Only populated for role items. */\n permissionKeys?: string[]\n /** Permission keys currently excluded from the push. */\n excludedPermissions?: string[]\n /** Called when a permission checkbox flips. push=true includes it, push=false excludes it. */\n onTogglePermission?: ( key: string, push: boolean ) => void\n /** Render a friendly label for a permission key (e.g. resolve blueprint ids → names). */\n formatPermissionLabel?: ( key: string ) => string\n /** False when the release is pushed (read-only). */\n editable?: boolean\n /** Called when a tag checkbox flips. push=true includes it, push=false excludes it. */\n onToggleTag?: ( tag: string, push: boolean ) => void\n /** Per-destination api-copy replacement maps, keyed by destConfigId. Applied to\n * the origin text before the line diff so cluster-specific id/translation\n * differences ( which the push remaps ) don't highlight. */\n replacementMaps?: Record<string, { replace: string; with: string }[]> | null\n}\n\n/**\n * A labeled checklist of values that may be excluded from the push. Checked =\n * will push (not excluded); unchecked = muted + struck through. Disabled (with a\n * read-only hint) when not editable.\n *\n * Collapsible: collapsed by default but auto-opens when the section has any\n * excluded ( \"override\" ) entries, so existing overrides are always visible. A\n * `useEffect` keeps it open if `excluded` later becomes non-empty without\n * forcing it closed otherwise.\n */\nfunction ExclusionChecklist( {\n title, values, excluded, editable, onToggle, formatLabel,\n}: {\n title: string\n values: string[]\n excluded: string[]\n editable: boolean\n onToggle?: ( value: string, push: boolean ) => void\n formatLabel?: ( value: string ) => string\n} ) {\n const [ open, setOpen ] = useState( excluded.length > 0 )\n\n useEffect( () => {\n if ( excluded.length > 0 ) { setOpen( true ) }\n }, [ excluded.length ] )\n\n return (\n <div className=\"border-b p-2\">\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-2\"\n onClick={() => setOpen( ( o ) => !o )}\n aria-expanded={open}\n >\n <span className=\"flex items-center gap-1 text-xs font-medium text-muted-foreground\">\n {open ? <ChevronDown size={12} /> : <ChevronRight size={12} />}\n {title} ({excluded.length})\n </span>\n {!editable ? (\n <span className=\"text-[10px] text-muted-foreground\">read-only</span>\n ) : null}\n </button>\n {open ? (\n <div className=\"mt-1 flex flex-col gap-1\">\n {values.map( ( value ) => {\n const push = !excluded.includes( value )\n return (\n <label\n key={value}\n className=\"flex items-start gap-2 text-xs\"\n >\n <input\n type=\"checkbox\"\n className=\"mt-0.5 shrink-0\"\n checked={push}\n disabled={!editable}\n onChange={( e ) => onToggle?.( value, e.target.checked )}\n />\n <span className={`min-w-0 break-all font-mono ${push ? '' : 'text-muted-foreground line-through'}`}>\n {formatLabel ? formatLabel( value ) : value}\n </span>\n </label>\n )\n } )}\n </div>\n ) : null}\n </div>\n )\n}\n\n/**\n * Read-only side panel showing an item's origin snapshot against each\n * destination cluster via tabs. A target present in `diff.byTarget` differs on\n * that cluster; an absent key means the item already matches there.\n */\nexport default function ReleaseDiffPanel( {\n item, targets, onClose, unmetDependencyNames = [],\n tags = [], excludedTags = [], editable = true, onToggleTag,\n metadataKeys = [], excludedMetadataKeys = [], onToggleMetadataKey,\n i18nPaths = [], excludedI18nPaths = [], onToggleI18nPath,\n permissionKeys = [], excludedPermissions = [], onTogglePermission, formatPermissionLabel,\n replacementMaps,\n}: ReleaseDiffPanelProps ) {\n const firstId = targets[ 0 ]?.id ?? null\n const [ activeId, setActiveId ] = useState<string | null>( firstId )\n\n // Reset to the first target whenever the selected row changes, so switching\n // rows never leaves a stale tab active.\n useEffect( () => {\n setActiveId( targets[ 0 ]?.id ?? null )\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [ item?.id ] )\n\n const active = targets.find( ( t ) => t.id === activeId ) ?? targets[ 0 ] ?? null\n const byTarget = item?.diff?.byTarget\n const hasByTarget = byTarget != null\n // Legacy snapshots predate byTarget — fall back to the single target value.\n const targetValue = hasByTarget ? byTarget[ active?.id ?? '' ] : item?.diff?.target\n const matches = hasByTarget && active != null && !( active.id in byTarget )\n\n // Highlight origin lines that differ from the shown target — only when a real\n // target value is rendered (not the \"Matches …\" box). Origin column only.\n const originHighlight = useMemo(\n () => ( matches\n ? undefined\n : changedOriginLines( item?.diff?.origin, targetValue, replacementMaps?.[ active?.id ?? '' ] ) ),\n [ item, targetValue, matches, replacementMaps, active?.id ],\n )\n\n if ( !item ) { return null }\n\n return (\n <div className=\"flex h-full flex-col rounded-md border bg-background\">\n <div className=\"flex items-center justify-between border-b p-3\">\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium\">{item.itemName}</div>\n <div className=\"font-mono text-xs text-muted-foreground\">{item.itemType}</div>\n </div>\n <Button variant=\"ghost\" size=\"icon\" title=\"Close\" onClick={onClose}>\n <X />\n </Button>\n </div>\n\n {unmetDependencyNames.length > 0 ? (\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\">\n <AlertTriangle size={14} className=\"mt-0.5 shrink-0 text-amber-600 dark:text-amber-400\" />\n <span>\n Depends on excluded items: {unmetDependencyNames.join( ', ' )}. Push will fail for this\n item until they&apos;re included.\n </span>\n </div>\n ) : null}\n\n {tags.length > 0 ? (\n <ExclusionChecklist\n title=\"Tag Overrides\"\n values={tags}\n excluded={excludedTags}\n editable={editable}\n onToggle={onToggleTag}\n />\n ) : null}\n\n {metadataKeys.length > 0 ? (\n <ExclusionChecklist\n title=\"Metadata Overrides\"\n values={metadataKeys}\n excluded={excludedMetadataKeys}\n editable={editable}\n onToggle={onToggleMetadataKey}\n />\n ) : null}\n\n {i18nPaths.length > 0 ? (\n <ExclusionChecklist\n title=\"Translation Overrides\"\n values={i18nPaths}\n excluded={excludedI18nPaths}\n editable={editable}\n onToggle={onToggleI18nPath}\n />\n ) : null}\n\n {permissionKeys.length > 0 ? (\n <ExclusionChecklist\n title=\"Permission Overrides\"\n values={permissionKeys}\n excluded={excludedPermissions}\n editable={editable}\n onToggle={onTogglePermission}\n formatLabel={formatPermissionLabel}\n />\n ) : null}\n\n {targets.length > 0 ? (\n <div className=\"flex flex-wrap gap-1 border-b p-2\">\n {targets.map( ( t ) => {\n // Matches this cluster when byTarget exists and has no entry for it.\n const tMatches = hasByTarget && !( t.id in byTarget )\n return (\n <button\n key={t.id}\n type=\"button\"\n onClick={() => setActiveId( t.id )}\n className={`inline-flex items-center gap-1 rounded px-2 py-1 text-xs ${\n t.id === active?.id ? 'bg-muted font-medium' : 'hover:bg-muted/50'\n }`}\n >\n {tMatches ? (\n <Check size={12} className=\"text-green-600\" />\n ) : (\n <span className=\"h-1.5 w-1.5 shrink-0 rounded-full bg-red-500\" aria-hidden />\n )}\n {t.name}\n </button>\n )\n } )}\n </div>\n ) : null}\n\n <div className=\"flex flex-1 gap-3 overflow-auto p-3\">\n <DiffColumn label=\"Origin\" value={item.diff?.origin} highlightLines={originHighlight} />\n {matches ? (\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\">\n Matches {active?.name} — no differences.\n </div>\n ) : (\n <DiffColumn label={active?.name ?? 'Target'} value={targetValue} />\n )}\n </div>\n </div>\n )\n}\n","import { useState } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { Send, Check, AlertTriangle, X, Loader2, Circle } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport {\n Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle,\n} from '../../components/ui/Dialog'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport type { ReleasePush, ReleasePushResultItem } from './types'\n\nexport interface PushDialogProps {\n open: boolean\n onOpenChange: ( open: boolean ) => void\n releaseId: string\n targetConfigIds: string[]\n targetNames?: Record<string, string>\n apiPath?: string\n onComplete?: () => void\n /** Included items that reference new, excluded/ignored dependencies. Warning only. */\n dependencyWarnings?: { itemName: string; missing: string[] }[]\n}\n\ntype TargetStatus = 'idle' | 'pushing' | 'success' | 'partial' | 'failed'\n\ninterface TargetState {\n status: TargetStatus\n failed?: number\n error?: string\n /** Per-item failures from the push result, surfaced explicitly under the target. */\n failures?: ReleasePushResultItem[]\n}\n\nfunction StatusIndicator( { state }: { state: TargetState } ) {\n switch ( state.status ) {\n case 'pushing':\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Pushing…\n </span>\n )\n case 'success':\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-emerald-600\">\n <Check className=\"h-4 w-4\" />\n Success\n </span>\n )\n case 'partial':\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-amber-600\">\n <AlertTriangle className=\"h-4 w-4\" />\n Partial — {state.failed ?? 0} failed\n </span>\n )\n case 'failed':\n return (\n <span\n className=\"inline-flex items-center gap-1 text-sm text-destructive\"\n title={state.error}\n >\n <X className=\"h-4 w-4\" />\n Failed\n </span>\n )\n default:\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-muted-foreground\">\n <Circle className=\"h-3 w-3\" />\n Pending\n </span>\n )\n }\n}\n\n/**\n * Confirm dialog that pushes a release to each target cluster sequentially\n * (one request per target) and shows a per-target result. A single failed\n * target does not abort the rest.\n */\nexport default function PushDialog( {\n open,\n onOpenChange,\n releaseId,\n targetConfigIds,\n targetNames,\n apiPath = '/releases',\n onComplete,\n dependencyWarnings = [],\n}: PushDialogProps ) {\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const queryClient = useQueryClient()\n\n const [ isPushing, setIsPushing ] = useState( false )\n const [ states, setStates ] = useState<Record<string, TargetState>>( {} )\n const [ done, setDone ] = useState( false )\n\n const label = ( id: string ) => targetNames?.[ id ] ?? id\n\n const setTarget = ( id: string, state: TargetState ) =>\n setStates( ( prev ) => ( { ...prev, [ id ]: state } ) )\n\n const handleConfirm = async () => {\n setIsPushing( true )\n setDone( false )\n // Reset all rows to a fresh idle state for this run.\n setStates( Object.fromEntries( targetConfigIds.map( ( id ) => [ id, { status: 'idle' } as TargetState ] ) ) )\n\n let succeeded = 0\n let withErrors = 0\n\n for ( const destConfigId of targetConfigIds ) {\n setTarget( destConfigId, { status: 'pushing' } )\n try {\n const push = await fetchJson<ReleasePush>( `${apiPath}/${releaseId}/push`, {\n method: 'POST',\n body: JSON.stringify( { destConfigId } ),\n } )\n const failures = ( push.results ?? [] ).filter( ( r ) => !r.ok )\n if ( push.status === 'success' ) {\n succeeded += 1\n setTarget( destConfigId, { status: 'success' } )\n } else if ( push.status === 'partial' ) {\n withErrors += 1\n setTarget( destConfigId, { status: 'partial', failed: failures.length, failures } )\n } else {\n withErrors += 1\n setTarget( destConfigId, { status: 'failed', failures } )\n }\n } catch ( err ) {\n withErrors += 1\n const message = err instanceof Error ? err.message : String( err )\n setTarget( destConfigId, { status: 'failed', error: message } )\n }\n }\n\n // Refresh release status / item counts now that pushes are applied.\n queryClient.invalidateQueries( { queryKey: [ 'imaginarium', 'releases' ] } )\n queryClient.invalidateQueries( { queryKey: [ 'imaginarium', 'release', releaseId ] } )\n queryClient.invalidateQueries( { queryKey: [ 'imaginarium', 'release-items', releaseId ] } )\n queryClient.invalidateQueries( { queryKey: [ 'imaginarium', 'release-pushes', releaseId ] } )\n\n if ( withErrors === 0 ) {\n toast( { title: 'Push complete', description: `Pushed to ${succeeded} target${succeeded === 1 ? '' : 's'}.` } )\n } else {\n toast( {\n title: 'Push finished with errors',\n description: `${withErrors} target${withErrors === 1 ? '' : 's'} did not fully succeed.`,\n variant: 'destructive',\n } )\n }\n\n setIsPushing( false )\n setDone( true )\n onComplete?.()\n }\n\n const handleOpenChange = ( next: boolean ) => {\n if ( isPushing ) { return }\n if ( !next ) {\n // Reset transient state when the dialog closes.\n setStates( {} )\n setDone( false )\n }\n onOpenChange( next )\n }\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Push release</DialogTitle>\n <DialogDescription>\n Pushes the included items to each target cluster, one at a time. Each target re-compares\n against the latest origin before applying.\n </DialogDescription>\n </DialogHeader>\n\n {dependencyWarnings.length > 0 ? (\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\">\n <div className=\"flex items-center gap-2 font-medium\">\n <AlertTriangle className=\"h-4 w-4 shrink-0 text-amber-600 dark:text-amber-400\" />\n {dependencyWarnings.length} item{dependencyWarnings.length === 1 ? '' : 's'} reference excluded dependencies\n </div>\n <ul className=\"list-disc space-y-0.5 pl-8\">\n {dependencyWarnings.map( ( w ) => (\n <li key={w.itemName}>\n {w.itemName} → {w.missing.join( ', ' )}\n </li>\n ) )}\n </ul>\n <p className=\"pl-8 text-amber-600\">Push may fail for these items. You can proceed anyway.</p>\n </div>\n ) : null}\n\n <div className=\"space-y-2 py-2\">\n {targetConfigIds.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">This release has no targets.</p>\n ) : (\n targetConfigIds.map( ( id ) => {\n const state = states[ id ] ?? { status: 'idle' as TargetStatus }\n const failures = state.failures ?? []\n return (\n <div key={id} className=\"rounded border px-3 py-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium\">{label( id )}</span>\n <StatusIndicator state={state} />\n </div>\n {failures.length > 0 ? (\n <ul className=\"mt-2 max-h-48 space-y-1 overflow-auto border-t pt-2 text-xs\">\n {failures.map( ( f, i ) => (\n <li key={`${f.itemKey ?? 'item'}-${i}`} className=\"text-destructive\">\n <span className=\"font-mono\">{f.action ? `${f.action} ` : ''}{f.itemKey ?? 'item'}</span>\n {f.error ? <span className=\"text-muted-foreground\"> — {f.error}</span> : null}\n </li>\n ) )}\n </ul>\n ) : null}\n </div>\n )\n } )\n )}\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => handleOpenChange( false )} disabled={isPushing}>\n Close\n </Button>\n <Button\n variant=\"destructive\"\n onClick={handleConfirm}\n disabled={isPushing || done || targetConfigIds.length === 0}\n >\n <Send className=\"w-4 h-4 mr-2\" />\n {isPushing ? 'Pushing…' : 'Confirm push'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","import type { ReleaseItem } from './types'\n\ntype RuleVersion = NonNullable<NonNullable<ReleaseItem[ 'diff' ]>[ 'versions' ]>[ number ]\n\n/**\n * Versions that can be pushed: a version is pushable iff it does not already\n * exist on the target. Pure helper so it can be unit-tested in isolation.\n */\nexport function pushableVersions( item: ReleaseItem ): RuleVersion[] {\n return ( item.diff?.versions ?? [] ).filter( ( v ) => !v.existsOnTarget )\n}\n\nexport interface RuleVersionSelectProps {\n item: ReleaseItem\n disabled?: boolean\n onChange: ( selectedVersion: string ) => void\n}\n\n/**\n * Inline version picker for a rule row. Native <select> styled with Tailwind,\n * matching the established ClusterSelect / CreateReleaseModal pattern.\n *\n * Options: one per `diff.versions` entry. Versions that already exist on the\n * target are disabled (they can't be pushed). The placeholder \"Select a\n * version\" shows when `selectedVersion` is null.\n */\nexport default function RuleVersionSelect( { item, disabled, onChange }: RuleVersionSelectProps ) {\n const versions = item.diff?.versions ?? []\n return (\n <select\n value={item.selectedVersion ?? ''}\n disabled={disabled}\n onClick={( e ) => e.stopPropagation()}\n onChange={( e ) => onChange( e.target.value )}\n className=\"h-7 rounded-md border border-input bg-background px-2 py-0.5 text-xs disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label=\"Rule version\"\n >\n <option value=\"\" disabled>Select a version</option>\n {versions.map( ( v ) => {\n const value = String( v.version )\n const label = v.existsOnTarget\n ? `v${v.version} — already on target`\n : `v${v.version}${v.isPublished ? ' (published)' : ''}`\n return (\n <option key={value} value={value} disabled={v.existsOnTarget}>\n {label}\n </option>\n )\n } )}\n </select>\n )\n}\n","export interface EntityTagProps {\n type: string\n}\n\n// Ported from the prototype's `.entity-tag` + `.e-*` palette. Hex colours were\n// mapped to their nearest Tailwind bg/text utilities. Unknown types fall back\n// to the neutral muted token.\n// Each type carries a dark-mode variant ( subtle translucent fill + lighter\n// text ) so the pills aren't harsh bright chips on a dark theme.\nconst TYPE_CLASSES: Record<string, string> = {\n blueprint: 'bg-blue-100 text-blue-700 dark:bg-blue-500/15 dark:text-blue-300',\n rule: 'bg-orange-100 text-orange-700 dark:bg-orange-500/15 dark:text-orange-300',\n messageRoute: 'bg-teal-100 text-teal-700 dark:bg-teal-500/15 dark:text-teal-300',\n role: 'bg-purple-100 text-purple-700 dark:bg-purple-500/15 dark:text-purple-300',\n enum: 'bg-yellow-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300',\n resourceEnum: 'bg-yellow-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300',\n timer: 'bg-slate-100 text-slate-600 dark:bg-slate-500/20 dark:text-slate-300',\n network: 'bg-green-100 text-green-700 dark:bg-green-500/15 dark:text-green-300',\n module: 'bg-indigo-100 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300',\n permission: 'bg-pink-100 text-pink-700 dark:bg-pink-500/15 dark:text-pink-300',\n template: 'bg-red-100 text-red-800 dark:bg-red-500/15 dark:text-red-300',\n script: 'bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-300',\n scenario: 'bg-cyan-100 text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-300',\n system: 'bg-gray-200 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300',\n attribute: 'bg-violet-100 text-violet-700 dark:bg-violet-500/15 dark:text-violet-300',\n enumValue: 'bg-violet-100 text-violet-700 dark:bg-violet-500/15 dark:text-violet-300',\n project: 'bg-fuchsia-50 text-fuchsia-800 dark:bg-fuchsia-500/15 dark:text-fuchsia-300',\n}\n\nexport default function EntityTag( { type }: EntityTagProps ) {\n const classes = TYPE_CLASSES[ type ] ?? 'bg-muted text-muted-foreground'\n return (\n <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-xs font-semibold ${classes}`}>\n {type}\n </span>\n )\n}\n","export interface ToggleProps {\n checked: boolean\n onChange: ( checked: boolean ) => void\n disabled?: boolean\n}\n\n// Styled on/off switch ported from the prototype `.toggle` (≈ 32×18 track with a\n// sliding 14px thumb). A real visually-hidden checkbox keeps it accessible and\n// focusable; the track/thumb are purely presentational.\nexport default function Toggle( { checked, onChange, disabled = false }: ToggleProps ) {\n return (\n <label\n className={`relative inline-block h-[18px] w-8 shrink-0 ${\n disabled ? 'cursor-not-allowed opacity-40' : 'cursor-pointer'\n }`}\n >\n <input\n type=\"checkbox\"\n className=\"peer sr-only\"\n checked={checked}\n disabled={disabled}\n onChange={( e ) => onChange( e.target.checked )}\n />\n <span className=\"absolute inset-0 rounded-full bg-input transition-colors peer-checked:bg-primary\" />\n <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\" />\n </label>\n )\n}\n","import type { ReleasePush } from './types'\n\nexport interface PushResult {\n ok: boolean\n error?: string\n}\n\n/**\n * Per-row, per-target push outcomes keyed by `itemKey`, then by `destConfigId`.\n * Only the LATEST push per destConfigId contributes (a target can be pushed\n * more than once), so re-pushes overwrite prior results for that target.\n */\nexport type PushResultMap = Map<string, Map<string, PushResult>>\n\n/**\n * Build a `(itemKey → destConfigId → PushResult)` lookup from a release's\n * pushes. Pushes are grouped by `destConfigId` and only the most recent one\n * (by `createdAt`) is used per target; each of its `results` entries is recorded\n * under its `itemKey`. Entries without an `itemKey` are skipped.\n */\nexport function buildPushResultMap( pushes: ReleasePush[] ): PushResultMap {\n // Latest push per destConfigId.\n const latestByDest = new Map<string, ReleasePush>()\n for ( const push of pushes ) {\n const current = latestByDest.get( push.destConfigId )\n if ( !current || push.createdAt > current.createdAt ) {\n latestByDest.set( push.destConfigId, push )\n }\n }\n\n const map: PushResultMap = new Map()\n for ( const push of latestByDest.values() ) {\n for ( const result of push.results ?? [] ) {\n if ( !result.itemKey ) { continue }\n let byDest = map.get( result.itemKey )\n if ( !byDest ) {\n byDest = new Map()\n map.set( result.itemKey, byDest )\n }\n byDest.set( push.destConfigId, { ok: result.ok, error: result.error } )\n }\n }\n return map\n}\n\n/** Look up a single row's outcome for a single target. */\nexport function pushResultFor(\n map: PushResultMap,\n itemKey: string,\n destConfigId: string,\n): PushResult | undefined {\n return map.get( itemKey )?.get( destConfigId )\n}\n","import type { ReleaseItem } from './types'\n\nexport type TypeFilter = string | 'all'\nexport type IncludedFilter = 'all' | 'enabled' | 'disabled'\n\nexport interface ItemFilters {\n type: TypeFilter\n included: IncludedFilter\n}\n\n/**\n * Pure filter over release items. `type` matches a specific value or passes\n * everything when set to 'all'; `included` narrows to enabled or disabled items.\n */\nexport function filterItems( items: ReleaseItem[], filters: ItemFilters ): ReleaseItem[] {\n return items.filter( ( item ) => {\n if ( filters.type !== 'all' && item.itemType !== filters.type ) { return false }\n if ( filters.included === 'enabled' && ( !item.included || item.ignored ) ) { return false }\n if ( filters.included === 'disabled' && item.included && !item.ignored ) { return false }\n return true\n } )\n}\n\n/** Count items by itemType — drives the type filter chip counts. */\nexport function typeCounts( items: ReleaseItem[] ): Record<string, number> {\n const counts: Record<string, number> = {}\n for ( const item of items ) {\n counts[ item.itemType ] = ( counts[ item.itemType ] ?? 0 ) + 1\n }\n return counts\n}\n","import type { ReleaseItem, StatusMatrixRow } from './types'\n\nexport interface TreeNode {\n item: ReleaseItem\n children: ReleaseItem[]\n synthetic?: boolean\n}\n\nexport interface StatusRowNode {\n row: StatusMatrixRow\n children: StatusMatrixRow[]\n synthetic?: boolean\n}\n\n/**\n * Fabricate a grouping parent for an orphan `parentKey` of the form\n * `\"<type>:<name>\"` (split on the first `:`). The result is a display-only\n * container: `id: ''` signals \"no real row\" (not toggleable), and we mark the\n * item updated/included so it passes the same root filters as a real blueprint\n * whose attributes changed.\n */\nfunction syntheticParent( parentKey: string ): ReleaseItem {\n const idx = parentKey.indexOf( ':' )\n const type = idx >= 0 ? parentKey.slice( 0, idx ) : parentKey\n const name = idx >= 0 ? parentKey.slice( idx + 1 ) : parentKey\n return {\n id: '',\n releaseId: '',\n itemKey: parentKey,\n itemType: type,\n itemName: name,\n parentKey: null,\n selectedVersion: null,\n status: 'updated',\n included: true,\n carriedOver: false,\n ignored: false,\n diff: null,\n createdAt: '',\n updatedAt: '',\n }\n}\n\n/**\n * Group flat release items into a parent/child tree. Roots are items with no\n * `parentKey`; each root's children are items whose `parentKey` matches the\n * root's `itemKey`. Orphan children (a `parentKey` with no matching real root)\n * are grouped under one synthesized parent per distinct `parentKey`, so e.g. a\n * blueprint that itself is unchanged but whose attributes changed still groups\n * those attributes. Real roots come first in input order; synthetic roots are\n * appended after, in first-appearance order of their `parentKey`. Input order\n * is preserved within each root's children.\n */\nexport function buildItemTree( items: ReleaseItem[] ): TreeNode[] {\n const rootKeys = new Set(\n items.filter( ( i ) => !i.parentKey ).map( ( i ) => i.itemKey ),\n )\n\n const nodes: TreeNode[] = []\n const byKey = new Map<string, TreeNode>()\n\n for ( const item of items ) {\n if ( item.parentKey ) { continue }\n const node: TreeNode = { item, children: [] }\n nodes.push( node )\n byKey.set( item.itemKey, node )\n }\n\n // Synthetic roots, created lazily on first orphan child, appended after reals.\n const synthByKey = new Map<string, TreeNode>()\n\n for ( const item of items ) {\n if ( !item.parentKey ) { continue }\n if ( rootKeys.has( item.parentKey ) ) {\n byKey.get( item.parentKey )?.children.push( item )\n continue\n }\n let synth = synthByKey.get( item.parentKey )\n if ( !synth ) {\n synth = { item: syntheticParent( item.parentKey ), children: [], synthetic: true }\n synthByKey.set( item.parentKey, synth )\n nodes.push( synth )\n }\n synth.children.push( item )\n }\n\n return nodes\n}\n\n/**\n * Synthesize a display-only parent row for an orphan `parentKey` of the form\n * `\"<type>:<name>\"` ( split on the first `:` ). Mirrors `syntheticParent` for\n * the status matrix: the row has no own cells ( nothing to compare ), so it is\n * never clickable.\n */\nfunction syntheticRow( parentKey: string ): StatusMatrixRow {\n const idx = parentKey.indexOf( ':' )\n const type = idx >= 0 ? parentKey.slice( 0, idx ) : parentKey\n const name = idx >= 0 ? parentKey.slice( idx + 1 ) : parentKey\n return { itemKey: parentKey, itemType: type, itemName: name, parentKey: null, cells: {} }\n}\n\n/**\n * Group flat status-matrix rows into a parent/child tree by `parentKey`, mirroring\n * `buildItemTree`. Roots are rows without a `parentKey`; each root's children are\n * rows whose `parentKey` matches the root's `itemKey`. Orphan children ( a\n * `parentKey` with no matching real root ) are grouped under one synthesized\n * parent per distinct `parentKey`. Real roots come first in input order;\n * synthetic roots are appended after, in first-appearance order. Input order is\n * preserved within each root's children.\n */\nexport function groupStatusRows( rows: StatusMatrixRow[] ): StatusRowNode[] {\n const rootKeys = new Set(\n rows.filter( ( r ) => !r.parentKey ).map( ( r ) => r.itemKey ),\n )\n\n const nodes: StatusRowNode[] = []\n const byKey = new Map<string, StatusRowNode>()\n\n for ( const row of rows ) {\n if ( row.parentKey ) { continue }\n const node: StatusRowNode = { row, children: [] }\n nodes.push( node )\n byKey.set( row.itemKey, node )\n }\n\n const synthByKey = new Map<string, StatusRowNode>()\n\n for ( const row of rows ) {\n if ( !row.parentKey ) { continue }\n if ( rootKeys.has( row.parentKey ) ) {\n byKey.get( row.parentKey )?.children.push( row )\n continue\n }\n let synth = synthByKey.get( row.parentKey )\n if ( !synth ) {\n synth = { row: syntheticRow( row.parentKey ), children: [], synthetic: true }\n synthByKey.set( row.parentKey, synth )\n nodes.push( synth )\n }\n synth.children.push( row )\n }\n\n return nodes\n}\n\n/** Count children that are included and not ignored, over the total children. */\nexport function includedChildCounts( node: TreeNode ): { included: number, total: number } {\n let included = 0\n for ( const child of node.children ) {\n if ( child.included && !child.ignored ) { included += 1 }\n }\n return { included, total: node.children.length }\n}\n","import type { ReleaseItem } from './types'\n\n/**\n * Computes a client-side dependency graph over release items, restricted to NEW\n * items. A release pushes items in dependency order automatically, but the\n * per-item include/exclude model lets a user include an item while excluding (or\n * ignoring) a NEW item it depends on — which makes the push fail. This map lets\n * the UI surface a soft warning.\n *\n * Approach: build a token → itemKey map over NEW items (using `diff.origin.id`,\n * plus `diff.origin.type` for enums, which are referenced by type string rather\n * than id). For each item, substring-match those tokens against the JSON of its\n * own `diff.origin`. Long base62 ids and enum types are distinctive enough that\n * a substring hit is a strong signal — but this is intentionally a soft warning,\n * not a guarantee.\n *\n * @returns itemKey → set of itemKeys it depends on (every item gets an entry).\n */\nexport function computeDependsOn( items: ReleaseItem[] ): Map<string, Set<string>> {\n // token → depKey, over NEW items only.\n const tokenToKey: { token: string; depKey: string }[] = []\n for ( const it of items ) {\n if ( it.status !== 'new' ) { continue }\n const origin = it.diff?.origin as { id?: unknown; type?: unknown } | null | undefined\n const id = origin?.id\n if ( typeof id === 'string' && id ) {\n tokenToKey.push( { token: id, depKey: it.itemKey } )\n }\n if ( it.itemType === 'enum' ) {\n const type = origin?.type\n if ( typeof type === 'string' && type ) {\n tokenToKey.push( { token: type, depKey: it.itemKey } )\n }\n }\n }\n\n const result = new Map<string, Set<string>>()\n for ( const it of items ) {\n const deps = new Set<string>()\n const hay = JSON.stringify( it.diff?.origin ?? null )\n for ( const { token, depKey } of tokenToKey ) {\n if ( depKey === it.itemKey ) { continue }\n if ( hay.includes( token ) ) {\n deps.add( depKey )\n }\n }\n result.set( it.itemKey, deps )\n }\n return result\n}\n\n/**\n * Resolves the unmet dependencies for a single item: dependency items that are\n * still NEW and either excluded or ignored, so pushing `item` would fail.\n *\n * Pure — does not gate on `item`'s own include/ignore state; callers decide when\n * a warning is meaningful (e.g. only for included, non-ignored items).\n *\n * @returns the dependency items that are unmet (so callers can show names).\n */\nexport function unmetDependencies(\n item: ReleaseItem,\n dependsOn: Map<string, Set<string>>,\n byKey: Map<string, ReleaseItem>,\n): ReleaseItem[] {\n const deps = dependsOn.get( item.itemKey )\n if ( !deps || deps.size === 0 ) { return [] }\n const unmet: ReleaseItem[] = []\n for ( const depKey of deps ) {\n const dep = byKey.get( depKey )\n if ( !dep ) { continue }\n if ( dep.status === 'new' && ( !dep.included || dep.ignored ) ) {\n unmet.push( dep )\n }\n }\n return unmet\n}\n","// Canonical item-type order, matching the Imagine nav menu grouping\n// (Device Control → Flow → Permissions → Application Controls → Project).\nexport const TYPE_ORDER: string[] = [\n 'blueprint', 'system', 'network', 'enum', 'resourceEnum', // Device Control\n 'timer', 'messageRoute', // Flow\n 'role', 'permission', 'module', // Permissions\n 'scenario', 'template', // Application Controls\n 'project', 'rule', 'script', // Project\n]\n\nexport function typeRank( type: string ): number {\n const i = TYPE_ORDER.indexOf( type )\n return i === -1 ? TYPE_ORDER.length : i\n}\n\n/** Sort by canonical type order; unknown types sort last, then alphabetically. */\nexport function compareTypes( a: string, b: string ): number {\n const r = typeRank( a ) - typeRank( b )\n return r !== 0 ? r : a.localeCompare( b )\n}\n","export interface ExclusionCounts {\n tags: number\n metadataKeys: number\n i18nPaths: number\n permissions: number\n}\n\n/** Total number of excluded entries across all categories. */\nexport function exclusionTotal( counts: ExclusionCounts ): number {\n return counts.tags + counts.metadataKeys + counts.i18nPaths + counts.permissions\n}\n\n/**\n * Title text breaking the excluded count down by category, e.g.\n * \"2 tags, 1 metadata key, 1 translation excluded from push\". Categories with a\n * zero count are omitted. Returns an empty string when nothing is excluded.\n */\nexport function exclusionTitle( counts: ExclusionCounts ): string {\n const parts: string[] = []\n if ( counts.tags > 0 ) {\n parts.push( `${counts.tags} tag${counts.tags === 1 ? '' : 's'}` )\n }\n if ( counts.metadataKeys > 0 ) {\n parts.push( `${counts.metadataKeys} metadata key${counts.metadataKeys === 1 ? '' : 's'}` )\n }\n if ( counts.i18nPaths > 0 ) {\n parts.push( `${counts.i18nPaths} translation${counts.i18nPaths === 1 ? '' : 's'}` )\n }\n if ( counts.permissions > 0 ) {\n parts.push( `${counts.permissions} permission${counts.permissions === 1 ? '' : 's'}` )\n }\n if ( parts.length === 0 ) { return '' }\n return `${parts.join( ', ' )} excluded from push`\n}\n","import { Fragment, useMemo, useState } from 'react'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { ArrowLeft, ChevronDown, ChevronRight, RefreshCw, AlertTriangle } from 'lucide-react'\nimport { Config } from '@leverege/plugin'\n\nimport { Button } from '../../components/ui/Button'\nimport { Card, CardContent } from '../../components/ui/Card'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport { useSystemConfigs } from '../../system/SystemConfigsContext'\nimport PreviouslySkippedBadge from './PreviouslySkippedBadge'\nimport IgnoredPill from './IgnoredPill'\nimport IgnoreButton from './IgnoreButton'\nimport ResetExclusionsButton from './ResetExclusionsButton'\nimport ReleaseStatusBadge from './StatusBadge'\nimport ReleaseDiffPanel from './ReleaseDiffPanel'\nimport PushDialog from './PushDialog'\nimport RuleVersionSelect, { pushableVersions } from './RuleVersionSelect'\nimport EntityTag from './EntityTag'\nimport Toggle from './Toggle'\nimport { buildPushResultMap, pushResultFor } from './pushResults'\nimport { typeCounts, type ItemFilters, type IncludedFilter } from './itemFilters'\nimport { buildItemTree, includedChildCounts } from './itemTree'\nimport { computeDependsOn, unmetDependencies } from './dependencies'\nimport { compareTypes } from './typeOrder'\nimport { exclusionTotal, exclusionTitle } from './exclusionSummary'\nimport type { Release, ReleaseItem, ReleasePush } from './types'\n\nexport interface ReleaseDetailProps {\n releaseId: string\n onBack: () => void\n}\n\nconst INCLUDED_OPTIONS: { value: IncludedFilter; label: string }[] = [\n { value: 'all', label: 'All' },\n { value: 'enabled', label: 'Enabled' },\n { value: 'disabled', label: 'Disabled' },\n]\n\n/** Narrows to enabled ( included + not ignored ) or disabled ( excluded or ignored ) items. */\nfunction matchesIncluded( item: ReleaseItem, f: IncludedFilter ): boolean {\n if ( f === 'all' ) { return true }\n if ( f === 'enabled' ) { return item.included && !item.ignored }\n return !item.included || item.ignored\n}\n\nfunction StatusBadge( { status }: { status: ReleaseItem['status'] } ) {\n return (\n <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\">\n {status}\n </span>\n )\n}\n\n/**\n * Coerce a persisted exclusion list to a string[]. The values can arrive as a\n * raw JSON string ( sandbox columns added via a TEXT ALTER may not parse ); this\n * normalizes to an array so a string is never spread char-by-char or `.filter`ed.\n */\nfunction toStringArray( v: unknown ): string[] {\n if ( Array.isArray( v ) ) { return v.filter( ( x ): x is string => typeof x === 'string' ) }\n if ( typeof v === 'string' && v.length > 0 ) {\n try {\n const parsed = JSON.parse( v )\n return Array.isArray( parsed ) ? parsed.filter( ( x ): x is string => typeof x === 'string' ) : []\n } catch {\n return []\n }\n }\n return []\n}\n\nfunction ExclusionsBadge( { item }: { item: ReleaseItem } ) {\n const counts = {\n tags: toStringArray( item.excludedTags ).length,\n metadataKeys: toStringArray( item.excludedMetadataKeys ).length,\n i18nPaths: toStringArray( item.excludedI18nPaths ).length,\n permissions: toStringArray( item.excludedPermissions ).length,\n }\n const total = exclusionTotal( counts )\n if ( total <= 0 ) { return null }\n return (\n <span\n title={exclusionTitle( counts )}\n 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\"\n >\n {total} manual override{total === 1 ? '' : 's'}\n </span>\n )\n}\n\nfunction PushTargets( {\n item,\n targetConfigIds,\n results,\n pushedDests,\n displayName,\n}: {\n item: ReleaseItem\n targetConfigIds: string[]\n results: ReturnType<typeof buildPushResultMap>\n pushedDests: Set<string>\n displayName: ( id: string ) => string\n} ) {\n // One chip per target that has been pushed: ✓ ok / ✗ failed / \"no change\"\n // ( included but nothing to send — already in sync ). Excluded/ignored items\n // weren't pushed, so they get no chip for that target.\n const included = item.included && !item.ignored\n const chips = targetConfigIds\n .filter( ( id ) => pushedDests.has( id ) )\n .map( ( id ) => ( { id, result: pushResultFor( results, item.itemKey, id ) } ) )\n .filter( ( c ) => c.result != null || included )\n if ( chips.length === 0 ) { return null }\n return (\n <div className=\"flex flex-wrap justify-end gap-1\">\n {chips.map( ( { id, result } ) => {\n const style = result\n ? ( result.ok\n ? 'bg-green-100 text-green-700 dark:bg-green-500/15 dark:text-green-300'\n : 'bg-red-100 text-red-700 dark:bg-red-500/15 dark:text-red-300' )\n : 'bg-muted text-muted-foreground'\n const glyph = result ? ( result.ok ? '✓' : '✗' ) : '='\n const title = result\n ? ( result.ok ? undefined : result.error )\n : 'No change — already in sync'\n return (\n <span\n key={id}\n title={title}\n className={`inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px] font-semibold ${style}`}\n >\n {displayName( id )} {glyph}\n </span>\n )\n } )}\n </div>\n )\n}\n\nexport default function ReleaseDetail( { releaseId, onBack }: ReleaseDetailProps ) {\n const apiPath = Config.get<string>( 'Release', 'apiPath', '/releases' )\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const { configs } = useSystemConfigs()\n const queryClient = useQueryClient()\n\n const [ typeFilter, setTypeFilter ] = useState<ItemFilters[ 'type' ]>( 'all' )\n const [ includedFilter, setIncludedFilter ] = useState<IncludedFilter>( 'all' )\n const [ selected, setSelected ] = useState<ReleaseItem | null>( null )\n const [ pushOpen, setPushOpen ] = useState( false )\n const [ expanded, setExpanded ] = useState<Set<string>>( () => new Set() )\n\n const toggleExpanded = ( itemKey: string ) =>\n setExpanded( ( prev ) => {\n const next = new Set( prev )\n if ( next.has( itemKey ) ) { next.delete( itemKey ) } else { next.add( itemKey ) }\n return next\n } )\n\n const releaseKey = [ 'imaginarium', 'release', releaseId ] as const\n const itemsKey = [ 'imaginarium', 'release-items', releaseId ] as const\n const pushesKey = [ 'imaginarium', 'release-pushes', releaseId ] as const\n\n const { data: release, isLoading: releaseLoading } = useQuery<Release>( {\n queryKey: releaseKey,\n queryFn: () => fetchJson<Release>( `${apiPath}/${releaseId}` ),\n } )\n\n const { data: items, isLoading: itemsLoading } = useQuery<ReleaseItem[]>( {\n queryKey: itemsKey,\n queryFn: async () => {\n const res = await fetchJson<{ items: ReleaseItem[] } | ReleaseItem[]>( `${apiPath}/${releaseId}/items` )\n return Array.isArray( res ) ? res : ( res?.items ?? [] )\n },\n } )\n\n const { data: pushes } = useQuery<ReleasePush[]>( {\n queryKey: pushesKey,\n queryFn: async () => {\n const res = await fetchJson<{ items: ReleasePush[] } | ReleasePush[]>( `${apiPath}/${releaseId}/pushes` )\n return Array.isArray( res ) ? res : ( res?.items ?? [] )\n },\n } )\n\n const pushResults = useMemo( () => buildPushResultMap( pushes ?? [] ), [ pushes ] )\n // Targets that have been pushed at least once — lets a row show a neutral\n // \"no change\" chip for a pushed target it had nothing to send to, vs. nothing\n // at all ( which reads as \"did it even try?\" ).\n const pushedDests = useMemo(\n () => new Set( ( pushes ?? [] ).map( ( p ) => p.destConfigId ) ),\n [ pushes ],\n )\n const hasPushes = ( pushes ?? [] ).length > 0\n const targetConfigIds = useMemo( () => release?.targetConfigIds ?? [], [ release ] )\n\n const nameById = useMemo( () => {\n const map = new Map<string, string>()\n configs.forEach( ( c ) => map.set( c.id, c.displayName ) )\n return map\n }, [ configs ] )\n const displayName = ( id: string ) => nameById.get( id ) ?? id\n\n // Group items into roots + children. Filtering decision: type/status/included\n // filters apply to ROOTS only (by their `.item`); a root's children always\n // show when the root is expanded. Simplest behavior — children are not\n // independently filtered.\n const roots = useMemo( () => buildItemTree( items ?? [] ), [ items ] )\n const rootItems = useMemo( () => roots.map( ( n ) => n.item ), [ roots ] )\n\n // Client-side dependency graph over NEW items. Recomputes whenever items\n // change (include/exclude toggles invalidate the items query), so warnings\n // stay live without extra wiring.\n const dependsOn = useMemo( () => computeDependsOn( items ?? [] ), [ items ] )\n const byKey = useMemo(\n () => new Map( ( items ?? [] ).map( ( it ) => [ it.itemKey, it ] ) ),\n [ items ],\n )\n\n // Describe a dependency with its type and parent context, e.g.\n // `Location attribute \"tracker\"` or `enum \"vehicleStatus\"`. Resolves the parent\n // display name from `byKey` when possible, else falls back to the part after the\n // first \":\" in `parentKey` ( e.g. `blueprint:Location` → `Location` ).\n const describeDep = ( dep: ReleaseItem ): string => {\n let parent: string | undefined\n if ( dep.parentKey ) {\n const fromKey = byKey.get( dep.parentKey )?.itemName\n const idx = dep.parentKey.indexOf( ':' )\n parent = fromKey ?? ( idx >= 0 ? dep.parentKey.slice( idx + 1 ) : undefined )\n }\n return `${parent ? parent + ' ' : ''}${dep.itemType} \"${dep.itemName}\"`\n }\n\n // Map every in-release item's origin db id → its display name, so permission\n // keys ( which encode blueprint ids like \"<bpId>/create\" ) can be shown with\n // readable names. Ids of items not in the release are resolved per-role from\n // diff.nameMap ( see formatPermissionLabel at the panel ); anything still\n // unresolved stays as the raw token.\n const idToName = useMemo( () => {\n const map = new Map<string, string>()\n for ( const it of items ?? [] ) {\n const id = ( it.diff?.origin as { id?: unknown } | null | undefined )?.id\n if ( typeof id === 'string' && id ) { map.set( id, it.itemName ) }\n }\n return map\n }, [ items ] )\n\n // Soft pre-push warnings: every included, non-ignored item whose new\n // dependencies are excluded/ignored.\n const dependencyWarnings = useMemo(\n () =>\n ( items ?? [] )\n .filter( ( it ) => it.included && !it.ignored )\n .map( ( it ) => ( {\n itemName: it.itemName,\n missing: unmetDependencies( it, dependsOn, byKey ).map( describeDep ),\n } ) )\n .filter( ( w ) => w.missing.length > 0 ),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [ items, dependsOn, byKey ],\n )\n\n const counts = useMemo( () => typeCounts( rootItems ), [ rootItems ] )\n const types = useMemo( () => Object.keys( counts ).sort( compareTypes ), [ counts ] )\n\n // Compute, per shown root, the children to render under it. The type chip\n // filters roots by `itemType`; the included filter narrows children ( so e.g.\n // disabled attributes surface under \"Disabled\" ) and keeps a root when it\n // matches OR has any matching children. Children remain in their existing\n // order; only the top-level node order changes ( canonical type, then name ).\n const visible = useMemo( () => {\n return roots\n .filter( ( n ) => typeFilter === 'all' || n.item.itemType === typeFilter )\n .map( ( node ) => {\n const renderChildren = includedFilter === 'all'\n ? node.children\n : node.children.filter( ( c ) => matchesIncluded( c, includedFilter ) )\n return { node, renderChildren }\n } )\n .filter( ( { node, renderChildren } ) =>\n includedFilter === 'all'\n || matchesIncluded( node.item, includedFilter )\n || renderChildren.length > 0,\n )\n .sort( ( a, b ) => {\n const r = compareTypes( a.node.item.itemType, b.node.item.itemType )\n return r !== 0 ? r : a.node.item.itemName.localeCompare( b.node.item.itemName )\n } )\n }, [ roots, typeFilter, includedFilter ] )\n\n const refreshMutation = useMutation( {\n mutationFn: () => fetchJson( `${apiPath}/${releaseId}/refresh`, { method: 'POST' } ),\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey: itemsKey } )\n toast( { title: 'Snapshot refreshed', description: 'Items re-computed from origin.' } )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n const toggleMutation = useMutation( {\n mutationFn: ( { itemId, included }: { itemId: string; included: boolean } ) =>\n fetchJson( `${apiPath}/${releaseId}/items/${itemId}`, {\n method: 'PATCH',\n body: JSON.stringify( { included } ),\n } ),\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey: itemsKey } )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n const versionMutation = useMutation( {\n mutationFn: ( { itemId, selectedVersion }: { itemId: string; selectedVersion: string | null } ) =>\n fetchJson( `${apiPath}/${releaseId}/items/${itemId}`, {\n method: 'PATCH',\n body: JSON.stringify( { selectedVersion } ),\n } ),\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey: itemsKey } )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n // The four exclusion lists are full-array PATCHes computed from the current\n // item state. Without an optimistic cache update, a second toggle ( or a quick\n // re-check ) fires before the refetch lands and recomputes from the stale\n // pre-toggle array, clobbering the first change. So optimistically write the\n // new array into the items cache on mutate; roll back on error; reconcile on settle.\n type ExclusionField = 'excludedTags' | 'excludedMetadataKeys' | 'excludedI18nPaths' | 'excludedPermissions'\n const exclusionMutationOptions = ( field: ExclusionField ) => ( {\n mutationFn: ( { itemId, value }: { itemId: string; value: string[] } ) =>\n fetchJson( `${apiPath}/${releaseId}/items/${itemId}`, {\n method: 'PATCH',\n body: JSON.stringify( { [field]: value } ),\n } ),\n onMutate: async ( { itemId, value }: { itemId: string; value: string[] } ) => {\n await queryClient.cancelQueries( { queryKey: itemsKey } )\n const prev = queryClient.getQueryData<ReleaseItem[]>( itemsKey )\n queryClient.setQueryData<ReleaseItem[]>( itemsKey, ( old ) =>\n ( old ?? [] ).map( ( it ) => ( it.id === itemId ? { ...it, [field]: value } : it ) ),\n )\n return { prev }\n },\n onError: ( error: Error, _vars: { itemId: string; value: string[] }, ctx?: { prev?: ReleaseItem[] } ) => {\n if ( ctx?.prev ) { queryClient.setQueryData( itemsKey, ctx.prev ) }\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n onSettled: () => { queryClient.invalidateQueries( { queryKey: itemsKey } ) },\n } )\n\n const excludedTagsMutation = useMutation( exclusionMutationOptions( 'excludedTags' ) )\n const excludedMetadataKeysMutation = useMutation( exclusionMutationOptions( 'excludedMetadataKeys' ) )\n const excludedI18nPathsMutation = useMutation( exclusionMutationOptions( 'excludedI18nPaths' ) )\n const excludedPermissionsMutation = useMutation( exclusionMutationOptions( 'excludedPermissions' ) )\n\n const invalidateItems = () => queryClient.invalidateQueries( { queryKey: itemsKey } )\n\n const isPushed = release?.status === 'pushed'\n\n // `selected` is a snapshot captured at click time, so it goes stale after a\n // mutation refetch. Derive the live item from the freshly-fetched list by key\n // so the tag checklist reflects saved state immediately after a toggle.\n const selectedLive = selected ? ( byKey.get( selected.itemKey ) ?? selected ) : null\n\n if ( releaseLoading ) {\n return <div className=\"text-center text-muted-foreground py-8\">Loading…</div>\n }\n\n if ( !release ) {\n return (\n <div className=\"space-y-4\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onBack}>\n <ArrowLeft />\n Back\n </Button>\n <p className=\"text-muted-foreground\">Release not found.</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {isPushed && (\n <div className=\"bg-muted text-muted-foreground rounded-md px-3 py-2 text-sm\">\n This release was pushed and is read-only.\n </div>\n )}\n\n {/* Header */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button variant=\"ghost\" size=\"sm\" onClick={onBack}>\n <ArrowLeft />\n Back\n </Button>\n <h3 className=\"text-lg font-semibold\">{release.name}</h3>\n <ReleaseStatusBadge status={release.status} />\n </div>\n <div className=\"flex items-center gap-2\">\n {!isPushed && (\n <ResetExclusionsButton\n releaseId={releaseId}\n apiPath={apiPath}\n onReset={invalidateItems}\n />\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => refreshMutation.mutate()}\n disabled={isPushed || refreshMutation.isPending}\n >\n <RefreshCw />\n {refreshMutation.isPending ? 'Refreshing…' : 'Refresh'}\n </Button>\n {isPushed ? (\n <Button size=\"sm\" disabled>\n Pushed ✓\n </Button>\n ) : (\n <Button\n size=\"sm\"\n onClick={() => setPushOpen( true )}\n disabled={( release.targetConfigIds ?? [] ).length === 0}\n >\n Push\n </Button>\n )}\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2 text-sm text-muted-foreground\">\n <span className=\"inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs\">\n {displayName( release.originConfigId )}\n </span>\n <span>→</span>\n {( release.targetConfigIds ?? [] ).map( ( id ) => (\n <span key={id} className=\"inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-xs\">\n {displayName( id )}\n </span>\n ) )}\n <span className=\"ml-2\">\n Snapshot: {release.snapshotAt ? new Date( release.snapshotAt ).toLocaleString() : '—'}\n </span>\n <span>\n Pushed: {release.pushedAt ? new Date( release.pushedAt ).toLocaleString() : '—'}\n </span>\n </div>\n </div>\n\n {/* Filter bar */}\n <div className=\"space-y-2\">\n <div className=\"flex flex-wrap items-center gap-1\">\n <Button\n variant={typeFilter === 'all' ? 'secondary' : 'ghost'}\n size=\"sm\"\n onClick={() => setTypeFilter( 'all' )}\n >\n All types ({rootItems.length})\n </Button>\n {types.map( ( t ) => (\n <Button\n key={t}\n variant={typeFilter === t ? 'secondary' : 'ghost'}\n size=\"sm\"\n onClick={() => setTypeFilter( t )}\n >\n {t} ({counts[ t ]})\n </Button>\n ) )}\n </div>\n\n <div className=\"flex flex-wrap items-center gap-1\">\n {INCLUDED_OPTIONS.map( ( o ) => (\n <Button\n key={o.value}\n variant={includedFilter === o.value ? 'secondary' : 'outline'}\n size=\"sm\"\n onClick={() => setIncludedFilter( o.value )}\n >\n {o.label}\n </Button>\n ) )}\n </div>\n </div>\n\n {/* Items + diff */}\n <div className=\"flex gap-4\">\n <div className=\"min-w-0 flex-1\">\n {itemsLoading ? (\n <div className=\"text-center text-muted-foreground py-8\">Loading items…</div>\n ) : visible.length === 0 ? (\n <Card>\n <CardContent className=\"py-12 text-center text-muted-foreground\">\n {rootItems.length === 0 ? 'No items in this release yet.' : 'No items match the current filters.'}\n </CardContent>\n </Card>\n ) : (\n <Card>\n <CardContent className=\"p-0\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b text-left text-muted-foreground\">\n <th className=\"p-3 font-medium w-10\">Inc.</th>\n <th className=\"p-3 font-medium\">Type</th>\n <th className=\"p-3 font-medium\">Name</th>\n <th className=\"p-3 font-medium\">Status</th>\n <th className=\"p-3 font-medium\" />\n </tr>\n </thead>\n <tbody>\n {visible.map( ( { node, renderChildren } ) => {\n const it = node.item\n const hasChildren = renderChildren.length > 0\n // Surface matching children without manual expand when a\n // non-\"all\" included filter is active.\n const showChildren = expanded.has( it.itemKey ) || includedFilter !== 'all'\n const isExpanded = expanded.has( it.itemKey )\n const childCounts = includedChildCounts( node )\n const ruleVersions = it.diff?.versions ?? []\n const isRuleWithVersions = it.itemType === 'rule' && ruleVersions.length > 0\n const hasPublished = ruleVersions.some( ( v ) => v.isPublished )\n const pushable = isRuleWithVersions ? pushableVersions( it ) : []\n // A rule with no published version ( draft only ) can't be pushed at all.\n const noPublished = isRuleWithVersions && !hasPublished\n // Every pushable version already exists on the target.\n const allExist = isRuleWithVersions && hasPublished && pushable.length === 0\n const ruleBlocked = noPublished || allExist\n const needsVersion = isRuleWithVersions && !ruleBlocked && it.selectedVersion == null\n return (\n <Fragment key={node.synthetic ? it.itemKey : it.id}>\n {node.synthetic ? (\n <tr\n className=\"border-b last:border-0 cursor-pointer hover:bg-muted/50\"\n onClick={() => toggleExpanded( it.itemKey )}\n >\n <td className=\"p-3\" />\n <td className=\"p-3\"><EntityTag type={it.itemType} /></td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={( e ) => { e.stopPropagation(); toggleExpanded( it.itemKey ) }}\n aria-label={isExpanded ? 'Collapse' : 'Expand'}\n >\n {isExpanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </button>\n <span className=\"font-medium\">{it.itemName}</span>\n <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-xs ${\n childCounts.included < childCounts.total\n ? 'bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300'\n : 'bg-muted text-muted-foreground'\n }`}>\n {childCounts.included}/{childCounts.total} changes included\n </span>\n </div>\n </td>\n <td className=\"p-3\" />\n <td className=\"p-3\" />\n </tr>\n ) : (\n <tr\n className={`border-b last:border-0 cursor-pointer hover:bg-muted/50 ${\n selected?.id === it.id ? 'bg-muted/50' : ''\n } ${ruleBlocked ? 'opacity-60' : ''}`}\n onClick={() => setSelected( it )}\n >\n <td className=\"p-3\" onClick={( e ) => e.stopPropagation()}>\n <Toggle\n checked={it.included}\n disabled={it.ignored || toggleMutation.isPending || isPushed || ruleBlocked}\n onChange={( included ) =>\n toggleMutation.mutate( { itemId: it.id, included } )\n }\n />\n </td>\n <td className=\"p-3\"><EntityTag type={it.itemType} /></td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-2\">\n {hasChildren ? (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={( e ) => { e.stopPropagation(); toggleExpanded( it.itemKey ) }}\n aria-label={isExpanded ? 'Collapse' : 'Expand'}\n >\n {isExpanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </button>\n ) : null}\n <span className=\"font-medium\">{it.itemName}</span>\n {( () => {\n if ( !it.included || it.ignored ) { return null }\n const unmet = unmetDependencies( it, dependsOn, byKey )\n if ( unmet.length === 0 ) { return null }\n return (\n <span title={`Depends on excluded: ${unmet.map( ( d ) => d.itemName ).join( ', ' )}`}>\n <AlertTriangle size={14} className=\"shrink-0 text-amber-600\" />\n </span>\n )\n } )()}\n <ExclusionsBadge item={it} />\n {hasChildren ? (\n <span className={`inline-flex items-center rounded px-1.5 py-0.5 text-xs ${\n childCounts.included < childCounts.total\n ? 'bg-amber-100 text-amber-700 font-medium dark:bg-amber-500/15 dark:text-amber-300'\n : 'bg-muted text-muted-foreground'\n }`}>\n {childCounts.included}/{childCounts.total} changes included\n </span>\n ) : null}\n {it.carriedOver ? (\n <PreviouslySkippedBadge originName={displayName( release.originConfigId )} />\n ) : null}\n {it.ignored ? <IgnoredPill /> : null}\n {isRuleWithVersions && !ruleBlocked ? (\n <span onClick={( e ) => e.stopPropagation()}>\n <RuleVersionSelect\n item={it}\n disabled={isPushed || versionMutation.isPending}\n onChange={( selectedVersion ) =>\n versionMutation.mutate( { itemId: it.id, selectedVersion } )\n }\n />\n </span>\n ) : null}\n {noPublished ? (\n <span className=\"text-xs text-muted-foreground\">\n Rules without a published version cannot be pushed\n </span>\n ) : null}\n {allExist ? (\n <span className=\"text-xs text-muted-foreground\">\n Nothing to push — all versions exist on target\n </span>\n ) : null}\n {needsVersion ? (\n <span className=\"text-xs text-amber-600\">\n Pushable version not selected\n </span>\n ) : null}\n </div>\n </td>\n <td className=\"p-3\"><StatusBadge status={it.status} /></td>\n <td className=\"p-3 text-right\" onClick={( e ) => e.stopPropagation()}>\n <div className=\"flex items-center justify-end gap-2\">\n {hasPushes ? (\n <PushTargets\n item={it}\n targetConfigIds={targetConfigIds}\n results={pushResults}\n pushedDests={pushedDests}\n displayName={displayName}\n />\n ) : null}\n {!it.ignored && !isPushed && (\n <IgnoreButton\n createPayload={{\n originConfigId: release.originConfigId,\n itemKey: it.itemKey,\n itemType: it.itemType,\n itemName: it.itemName,\n }}\n onChange={() => {\n queryClient.setQueryData<ReleaseItem[]>( itemsKey, ( old ) =>\n ( old ?? [] ).map( ( i ) => ( i.id === it.id ? { ...i, ignored: true, included: false } : i ) ),\n )\n refreshMutation.mutate()\n }}\n />\n )}\n </div>\n </td>\n </tr>\n )}\n {hasChildren && showChildren\n ? renderChildren.map( ( child ) => (\n <tr\n key={child.id}\n className={`border-b last:border-0 cursor-pointer hover:bg-muted/50 ${\n selected?.id === child.id ? 'bg-muted/50' : ''\n }`}\n onClick={() => setSelected( child )}\n >\n <td className=\"p-3 pl-8\" onClick={( e ) => e.stopPropagation()}>\n <Toggle\n checked={child.included}\n disabled={child.ignored || toggleMutation.isPending || isPushed}\n onChange={( included ) =>\n toggleMutation.mutate( { itemId: child.id, included } )\n }\n />\n </td>\n <td className=\"p-3 pl-8\"><EntityTag type={child.itemType} /></td>\n <td className=\"p-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{child.itemName}</span>\n {( () => {\n if ( !child.included || child.ignored ) { return null }\n const unmet = unmetDependencies( child, dependsOn, byKey )\n if ( unmet.length === 0 ) { return null }\n return (\n <span title={`Depends on excluded: ${unmet.map( ( d ) => d.itemName ).join( ', ' )}`}>\n <AlertTriangle size={14} className=\"shrink-0 text-amber-600\" />\n </span>\n )\n } )()}\n <ExclusionsBadge item={child} />\n </div>\n </td>\n <td className=\"p-3\"><StatusBadge status={child.status} /></td>\n <td className=\"p-3 text-right\" onClick={( e ) => e.stopPropagation()}>\n {hasPushes ? (\n <PushTargets\n item={child}\n targetConfigIds={targetConfigIds}\n results={pushResults}\n pushedDests={pushedDests}\n displayName={displayName}\n />\n ) : null}\n </td>\n </tr>\n ) )\n : null}\n </Fragment>\n )\n } )}\n </tbody>\n </table>\n </CardContent>\n </Card>\n )}\n </div>\n\n {selected ? (\n <div className=\"w-[28rem] shrink-0 self-start sticky top-4 max-h-[calc(100vh-2rem)] overflow-auto\">\n <ReleaseDiffPanel\n item={selectedLive}\n targets={( release.targetConfigIds ?? [] ).map( ( id ) => ( { id, name: displayName( id ) } ) )}\n onClose={() => setSelected( null )}\n unmetDependencyNames={\n selectedLive && selectedLive.included && !selectedLive.ignored\n ? unmetDependencies( selectedLive, dependsOn, byKey ).map( describeDep )\n : []\n }\n tags={\n Array.isArray( ( selectedLive?.diff?.origin as { tags?: unknown } | null | undefined )?.tags )\n ? ( ( selectedLive?.diff?.origin as { tags?: string[] } ).tags ?? [] )\n : []\n }\n excludedTags={toStringArray( selectedLive?.excludedTags )}\n metadataKeys={( () => {\n const md = ( selectedLive?.diff?.origin as { metadata?: unknown } | null | undefined )?.metadata\n return md != null && typeof md === 'object' && !Array.isArray( md )\n ? Object.keys( md as Record<string, unknown> )\n : []\n } )()}\n excludedMetadataKeys={toStringArray( selectedLive?.excludedMetadataKeys )}\n i18nPaths={( () => {\n const i18n = ( selectedLive?.diff?.origin as { i18n?: unknown } | null | undefined )?.i18n\n if ( !Array.isArray( i18n ) ) { return [] }\n const paths = ( i18n as { path?: unknown }[] )\n .map( ( e ) => e?.path )\n .filter( ( p ): p is string => typeof p === 'string' )\n return Array.from( new Set( paths ) )\n } )()}\n excludedI18nPaths={toStringArray( selectedLive?.excludedI18nPaths )}\n permissionKeys={( () => {\n if ( selectedLive?.itemType !== 'role' ) { return [] }\n const perms = ( selectedLive?.diff?.origin as { permissions?: unknown } | null | undefined )?.permissions\n if ( !Array.isArray( perms ) ) { return [] }\n const keys = ( perms as { module?: unknown; name?: unknown; id?: unknown }[] )\n .map( ( p ) => `${p?.module ?? ''}/${p?.name ?? p?.id ?? ''}` )\n .filter( ( k ) => k !== '/' )\n return Array.from( new Set( keys ) )\n } )()}\n excludedPermissions={toStringArray( selectedLive?.excludedPermissions )}\n formatPermissionLabel={( key ) =>\n key.split( /([/.])/ )\n .map( ( tok ) => selectedLive?.diff?.nameMap?.[tok] ?? idToName.get( tok ) ?? tok )\n .join( '' )}\n replacementMaps={release.replacementMaps ?? undefined}\n editable={!isPushed}\n onToggleTag={( tag, push ) => {\n if ( !selectedLive ) { return }\n const cur = toStringArray( selectedLive.excludedTags )\n const next = push ? cur.filter( ( t ) => t !== tag ) : Array.from( new Set( [ ...cur, tag ] ) )\n excludedTagsMutation.mutate( { itemId: selectedLive.id, value: next } )\n }}\n onToggleMetadataKey={( key, push ) => {\n if ( !selectedLive ) { return }\n const cur = toStringArray( selectedLive.excludedMetadataKeys )\n const next = push ? cur.filter( ( k ) => k !== key ) : Array.from( new Set( [ ...cur, key ] ) )\n excludedMetadataKeysMutation.mutate( { itemId: selectedLive.id, value: next } )\n }}\n onToggleI18nPath={( path, push ) => {\n if ( !selectedLive ) { return }\n const cur = toStringArray( selectedLive.excludedI18nPaths )\n const next = push ? cur.filter( ( p ) => p !== path ) : Array.from( new Set( [ ...cur, path ] ) )\n excludedI18nPathsMutation.mutate( { itemId: selectedLive.id, value: next } )\n }}\n onTogglePermission={( key, push ) => {\n if ( !selectedLive ) { return }\n const cur = toStringArray( selectedLive.excludedPermissions )\n const next = push ? cur.filter( ( k ) => k !== key ) : Array.from( new Set( [ ...cur, key ] ) )\n excludedPermissionsMutation.mutate( { itemId: selectedLive.id, value: next } )\n }}\n />\n </div>\n ) : null}\n </div>\n\n <PushDialog\n open={pushOpen}\n onOpenChange={setPushOpen}\n releaseId={releaseId}\n apiPath={apiPath}\n targetConfigIds={release.targetConfigIds ?? []}\n targetNames={Object.fromEntries(\n ( release.targetConfigIds ?? [] ).map( ( id ) => [ id, displayName( id ) ] ),\n )}\n dependencyWarnings={dependencyWarnings}\n />\n </div>\n )\n}\n","import { Label } from '../../components/ui/Label'\nimport type { ImagineSystemConfig } from '../../system/types'\n\nexport interface ClusterSelectProps {\n value: string\n onChange: ( id: string ) => void\n configs: ImagineSystemConfig[]\n label: string\n}\n\n/**\n * Labeled native <select> over system configs. Native select styled with Tailwind\n * is the established pattern (see CreateReleaseModal); there is no Select primitive.\n */\nexport default function ClusterSelect( { value, onChange, configs, label }: ClusterSelectProps ) {\n const id = `cluster-select-${label.toLowerCase().replace( /\\s+/g, '-' )}`\n return (\n <div className=\"space-y-2\">\n <Label htmlFor={id}>{label}</Label>\n <select\n id={id}\n value={value}\n onChange={( e ) => onChange( e.target.value )}\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm\"\n >\n <option value=\"\">Select cluster…</option>\n {configs.map( ( c ) => (\n <option key={c.id} value={c.id}>{c.displayName}</option>\n ) )}\n </select>\n </div>\n )\n}\n","import { useMemo } from 'react'\nimport { X } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport DiffColumn from './DiffColumn'\nimport { changedOriginLines } from './jsonLineDiff'\nimport type { ReleaseItem } from './types'\n\nexport interface DiffPanelProps {\n item: ReleaseItem | null\n onClose: () => void\n}\n\n/**\n * Read-only side panel showing an item's origin/target snapshots as JSON.\n * The rich tree / rule-logic / enum views are Phase 4 — this stays plain.\n */\nexport default function DiffPanel( { item, onClose }: DiffPanelProps ) {\n // Highlight the origin lines that differ from the target. Origin column only.\n const originHighlight = useMemo(\n () => changedOriginLines( item?.diff?.origin, item?.diff?.target ),\n [ item ],\n )\n\n if ( !item ) { return null }\n\n return (\n <div className=\"flex h-full flex-col rounded-md border bg-background\">\n <div className=\"flex items-center justify-between border-b p-3\">\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium\">{item.itemName}</div>\n <div className=\"font-mono text-xs text-muted-foreground\">{item.itemType}</div>\n </div>\n <Button variant=\"ghost\" size=\"icon\" title=\"Close\" onClick={onClose}>\n <X />\n </Button>\n </div>\n <div className=\"flex flex-1 gap-3 overflow-auto p-3\">\n <DiffColumn label=\"Origin\" value={item.diff?.origin} highlightLines={originHighlight} />\n <DiffColumn label=\"Target\" value={item.diff?.target} />\n </div>\n </div>\n )\n}\n","import { Fragment, useMemo, useState } from 'react'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { RefreshCw, BarChart2, ChevronDown, ChevronRight } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport { useSystemConfigs } from '../../system/SystemConfigsContext'\nimport { cn } from '../../lib/utils'\nimport DiffPanel from './DiffPanel'\nimport EntityTag from './EntityTag'\nimport { groupStatusRows } from './itemTree'\nimport { compareTypes } from './typeOrder'\nimport type {\n StatusMatrix as StatusMatrixData,\n StatusMatrixRow,\n CellState,\n ClusterStats,\n ReleaseItem,\n} from './types'\n\n/** Shape returned by the `/diff` endpoint for a single matrix cell. */\ninterface CellDiff {\n itemKey: string\n itemType: string\n itemName: string\n origin: unknown\n target: unknown\n}\n\n// ── Cell rendering ────────────────────────────────────────────────\n\nconst CELL_CONFIG: Record<CellState, { symbol: string; className: string; label: string }> = {\n match: { symbol: '✓', className: 'text-muted-foreground', label: 'Match' },\n diff: { symbol: '≠', className: 'text-red-500 dark:text-red-400 font-semibold', label: 'Diff' },\n translated: { symbol: '≈', className: 'text-blue-600 dark:text-blue-400 font-semibold', label: 'Translated' },\n missing: { symbol: '✗', className: 'text-red-500 dark:text-red-400 font-semibold', label: 'Missing' },\n extra: { symbol: '+', className: 'text-amber-600 font-semibold', label: 'Extra' },\n skip: { symbol: '—', className: 'text-muted-foreground/50', label: 'Ignored' },\n}\n\nfunction Cell( {\n state,\n onClick,\n active,\n}: {\n state: CellState\n onClick?: () => void\n active?: boolean\n} ) {\n const cfg = CELL_CONFIG[state] ?? CELL_CONFIG.match\n const clickable = state !== 'match' && state !== 'skip' && Boolean( onClick )\n\n return (\n <button\n type=\"button\"\n onClick={clickable ? onClick : undefined}\n disabled={!clickable}\n title={cfg.label}\n className={cn(\n 'w-full text-center text-sm py-1 rounded',\n cfg.className,\n clickable && 'hover:bg-muted cursor-pointer',\n !clickable && 'cursor-default',\n active && 'bg-muted ring-1 ring-ring',\n )}\n >\n {cfg.symbol}\n </button>\n )\n}\n\n// ── Stats bar ────────────────────────────────────────────────────\n\nfunction StatsBar( { stats, destConfigIds }: { stats: Record<string, ClusterStats>; destConfigIds: string[] } ) {\n return (\n <div className=\"flex gap-6 text-xs text-muted-foreground py-2 px-1\">\n {destConfigIds.map( ( id ) => {\n const s = stats[id]\n if ( !s ) { return null }\n const total = s.match + s.diff + s.missing + s.extra\n return (\n <span key={id}>\n <span className=\"font-mono font-medium\">{s.match}/{total}</span> match\n {s.diff > 0 && <span className=\"text-destructive ml-2\">{s.diff} diff</span>}\n {s.missing > 0 && <span className=\"text-destructive ml-2\">{s.missing} missing</span>}\n {s.extra > 0 && <span className=\"text-amber-600 ml-2\">{s.extra} extra</span>}\n </span>\n )\n } )}\n </div>\n )\n}\n\n// ── Filter ────────────────────────────────────────────────────────\n\ntype RowFilter = 'issues' | 'all'\n\nfunction isIssueRow( row: StatusMatrixRow ): boolean {\n return Object.values( row.cells ).some( s => s === 'diff' || s === 'missing' || s === 'extra' )\n}\n\n// translated counts as matching in the stats bar — same colour bucket as match\n\n// ── Main component ────────────────────────────────────────────────\n\nexport interface StatusMatrixProps {\n originConfigId: string\n destConfigIds: string[]\n apiPath?: string\n}\n\ninterface ActiveCell {\n itemKey: string\n destConfigId: string\n}\n\nexport default function StatusMatrix( {\n originConfigId,\n destConfigIds,\n apiPath = '/release-status',\n}: StatusMatrixProps ) {\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const { configs } = useSystemConfigs()\n const queryClient = useQueryClient()\n\n const [ filter, setFilter ] = useState<RowFilter>( 'issues' )\n const [ showStats, setShowStats ] = useState( false )\n const [ activeCell, setActiveCell ] = useState<ActiveCell | null>( null )\n const [ hiddenDests, setHiddenDests ] = useState<Set<string>>( new Set() )\n const [ expanded, setExpanded ] = useState<Set<string>>( () => new Set() )\n\n const toggleExpanded = ( itemKey: string ) =>\n setExpanded( ( prev ) => {\n const next = new Set( prev )\n if ( next.has( itemKey ) ) { next.delete( itemKey ) } else { next.add( itemKey ) }\n return next\n } )\n\n // Cluster id → display name, mirroring ReleaseDetail's nameById/displayName.\n const nameById = useMemo( () => {\n const map = new Map<string, string>()\n configs.forEach( ( c ) => map.set( c.id, c.displayName ) )\n return map\n }, [ configs ] )\n const displayName = ( id: string ) => nameById.get( id ) ?? id\n\n const visibleDests = destConfigIds.filter( id => !hiddenDests.has( id ) )\n\n const params = new URLSearchParams()\n params.set( 'originConfigId', originConfigId )\n visibleDests.forEach( id => params.append( 'destConfigIds[]', id ) )\n\n const queryKey = [ 'imaginarium', 'release-status', originConfigId, visibleDests ] as const\n\n const { data, isLoading, isError } = useQuery<StatusMatrixData>( {\n queryKey,\n queryFn: () => fetchJson<StatusMatrixData>( `${apiPath}?${params.toString()}` ),\n enabled: visibleDests.length > 0,\n } )\n\n const refreshMutation = useMutation( {\n mutationFn: () =>\n fetchJson( `${apiPath}/refresh`, {\n method : 'POST',\n body : JSON.stringify( { originConfigId, destConfigIds : visibleDests } ),\n } ),\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey } )\n toast( { title: 'Cache cleared', description: 'Refreshing comparison data…' } )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n // Fetch the diff for the active cell on demand. 404 → no diff available.\n const {\n data: cellDiff,\n isLoading: diffLoading,\n isError: diffError,\n } = useQuery<CellDiff>( {\n queryKey: [ 'imaginarium', 'release-status-diff', originConfigId, activeCell?.destConfigId, activeCell?.itemKey ],\n queryFn: () => fetchJson<CellDiff>(\n `${apiPath}/diff?originConfigId=${encodeURIComponent( originConfigId )}&destConfigId=${encodeURIComponent( activeCell!.destConfigId )}&itemKey=${encodeURIComponent( activeCell!.itemKey )}`,\n ),\n enabled: Boolean( activeCell ),\n } )\n\n const toggleDest = ( id: string ) => {\n setHiddenDests( prev => {\n const next = new Set( prev )\n next.has( id ) ? next.delete( id ) : next.add( id )\n return next\n } )\n }\n\n const handleCellClick = ( itemKey: string, destConfigId: string ) => {\n setActiveCell( prev =>\n prev?.itemKey === itemKey && prev.destConfigId === destConfigId ? null : { itemKey, destConfigId }\n )\n }\n\n const rows = data?.rows ?? []\n const stats = data?.stats ?? {}\n\n // Group rows into roots + children by `parentKey`, then apply the issues/all\n // filter tree-aware ( mirroring ReleaseDetail's `visible` ): under Issues only,\n // a root shows if it OR any child is an issue, and only its issue children\n // render; under All, every root shows with all of its children. Top-level node\n // order is canonical type then name; child order is preserved.\n const visible = useMemo( () => {\n const tree = groupStatusRows( rows )\n return tree\n .map( ( node ) => {\n const renderChildren = filter === 'issues'\n ? node.children.filter( isIssueRow )\n : node.children\n return { node, renderChildren }\n } )\n .filter( ( { node, renderChildren } ) =>\n filter === 'all'\n || isIssueRow( node.row )\n || renderChildren.length > 0,\n )\n .sort( ( a, b ) => {\n const r = compareTypes( a.node.row.itemType, b.node.row.itemType )\n return r !== 0 ? r : a.node.row.itemName.localeCompare( b.node.row.itemName )\n } )\n }, [ rows, filter ] )\n\n return (\n <div className=\"space-y-3\">\n {/* Toolbar */}\n <div className=\"flex items-center gap-2 flex-wrap\">\n <div className=\"flex rounded-md border text-sm overflow-hidden\">\n <button\n className={cn( 'px-3 py-1.5', filter === 'issues' ? 'bg-muted font-medium' : 'hover:bg-muted/50' )}\n onClick={() => setFilter( 'issues' )}\n >\n Issues only\n </button>\n <button\n className={cn( 'px-3 py-1.5 border-l', filter === 'all' ? 'bg-muted font-medium' : 'hover:bg-muted/50' )}\n onClick={() => setFilter( 'all' )}\n >\n All\n </button>\n </div>\n\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setShowStats( s => !s )}>\n <BarChart2 />\n Stats\n </Button>\n\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => refreshMutation.mutate()}\n disabled={refreshMutation.isPending}\n >\n <RefreshCw className={cn( refreshMutation.isPending && 'animate-spin' )} />\n Refresh\n </Button>\n\n {/* Hidden cluster re-add chips */}\n {[ ...hiddenDests ].map( id => (\n <button\n key={id}\n onClick={() => toggleDest( id )}\n className=\"text-xs border rounded px-2 py-1 text-muted-foreground hover:bg-muted\"\n >\n + {displayName( id )}\n </button>\n ) )}\n </div>\n\n {showStats && data && (\n <StatsBar stats={stats} destConfigIds={visibleDests} />\n )}\n\n {isLoading && <div className=\"text-center text-muted-foreground py-8\">Loading…</div>}\n {isError && <div className=\"text-center text-destructive py-8\">Failed to load comparison data.</div>}\n\n {!isLoading && !isError && (\n <div className=\"flex gap-4\">\n <div className=\"min-w-0 flex-1 rounded-md border overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-muted/50\">\n <th className=\"px-4 py-2 text-left font-medium min-w-[200px]\">Item</th>\n {visibleDests.map( id => (\n <th key={id} className=\"px-2 py-2 text-center font-medium min-w-[80px]\">\n <div className=\"flex items-center justify-center gap-1\">\n <span className=\"truncate max-w-[120px]\" title={displayName( id )}>{displayName( id )}</span>\n <button\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={() => toggleDest( id )}\n title=\"Hide column\"\n >\n ×\n </button>\n </div>\n </th>\n ) )}\n </tr>\n </thead>\n <tbody>\n {visible.length === 0 ? (\n <tr>\n <td colSpan={visibleDests.length + 1} className=\"text-center text-muted-foreground py-8\">\n {filter === 'issues' ? 'No issues found — all clusters in sync.' : 'No items.'}\n </td>\n </tr>\n ) : (\n visible.map( ( { node, renderChildren } ) => {\n const row = node.row\n const hasChildren = renderChildren.length > 0\n // Surface matching children without manual expand under Issues only.\n const showChildren = expanded.has( row.itemKey ) || filter === 'issues'\n const isExpanded = expanded.has( row.itemKey )\n return (\n <Fragment key={row.itemKey}>\n <tr className=\"border-b last:border-0 hover:bg-muted/25\">\n <td className=\"px-4 py-1.5\">\n <div className=\"flex items-center gap-2\">\n {hasChildren ? (\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={() => toggleExpanded( row.itemKey )}\n aria-label={isExpanded ? 'Collapse' : 'Expand'}\n >\n {isExpanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n </button>\n ) : null}\n <span className=\"inline-flex align-middle\"><EntityTag type={row.itemType} /></span>\n <span className=\"font-medium\">{row.itemName}</span>\n </div>\n </td>\n {visibleDests.map( destId => (\n <td key={destId} className=\"px-2 py-1\">\n <Cell\n state={row.cells[destId] ?? 'match'}\n active={activeCell?.itemKey === row.itemKey && activeCell.destConfigId === destId}\n onClick={() => handleCellClick( row.itemKey, destId )}\n />\n </td>\n ) )}\n </tr>\n {hasChildren && showChildren\n ? renderChildren.map( ( child ) => (\n <tr key={child.itemKey} className=\"border-b last:border-0 hover:bg-muted/25\">\n <td className=\"px-4 py-1.5 pl-8\">\n <div className=\"flex items-center gap-2\">\n <span className=\"inline-flex align-middle\"><EntityTag type={child.itemType} /></span>\n <span className=\"font-medium\">{child.itemName}</span>\n </div>\n </td>\n {visibleDests.map( destId => (\n <td key={destId} className=\"px-2 py-1\">\n <Cell\n state={child.cells[destId] ?? 'match'}\n active={activeCell?.itemKey === child.itemKey && activeCell.destConfigId === destId}\n onClick={() => handleCellClick( child.itemKey, destId )}\n />\n </td>\n ) )}\n </tr>\n ) )\n : null}\n </Fragment>\n )\n } )\n )}\n </tbody>\n </table>\n </div>\n\n {activeCell ? (\n <div className=\"w-[28rem] shrink-0 self-start sticky top-4 max-h-[calc(100vh-2rem)] overflow-auto\">\n {diffLoading ? (\n <div className=\"flex h-full items-center justify-center rounded-md border bg-background p-4 text-sm text-muted-foreground\">\n Loading diff…\n </div>\n ) : diffError || !cellDiff ? (\n <div className=\"flex h-full items-center justify-center rounded-md border bg-background p-4 text-sm text-muted-foreground\">\n No diff available.\n </div>\n ) : (\n <DiffPanel\n // DiffPanel only reads itemName/itemType/diff, so a minimal\n // object built from the /diff response is sufficient here.\n item={{\n itemName: cellDiff.itemName,\n itemType: cellDiff.itemType,\n diff: { origin: cellDiff.origin, target: cellDiff.target },\n } as unknown as ReleaseItem}\n onClose={() => setActiveCell( null )}\n />\n )}\n </div>\n ) : null}\n </div>\n )}\n </div>\n )\n}\n","import { useState } from 'react'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Plus, Pencil, Trash2, Save, X } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport { Input } from '../../components/ui/Input'\nimport { Label } from '../../components/ui/Label'\nimport {\n Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle,\n} from '../../components/ui/Dialog'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport type { ReleaseTranslation, ReleaseTranslationValue } from './types'\n\nexport interface TranslationsTabProps {\n /** All cluster config IDs to show value columns for */\n configIds: string[]\n /** Optional display names for each cluster ID */\n clusterNames?: Record<string, string>\n apiPath?: string\n}\n\ninterface TranslationWithValues extends ReleaseTranslation {\n values: ReleaseTranslationValue[]\n}\n\ninterface FormState {\n name: string\n description: string\n values: Record<string, string>\n}\n\nconst EMPTY_FORM = ( configIds: string[] ): FormState => ( {\n name : '',\n description : '',\n values : Object.fromEntries( configIds.map( id => [ id, '' ] ) ),\n} )\n\nexport default function TranslationsTab( {\n configIds,\n clusterNames = {},\n apiPath = '/release-translations',\n}: TranslationsTabProps ) {\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const queryClient = useQueryClient()\n\n const [ isOpen, setIsOpen ] = useState( false )\n const [ editing, setEditing ] = useState<TranslationWithValues | null>( null )\n const [ form, setForm ] = useState<FormState>( EMPTY_FORM( configIds ) )\n\n const queryKey = [ 'imaginarium', 'release-translations' ] as const\n\n const { data: translations, isLoading } = useQuery<TranslationWithValues[]>( {\n queryKey,\n queryFn: async () => {\n const res = await fetchJson<{ items: TranslationWithValues[] }>( apiPath )\n return res?.items ?? []\n },\n } )\n\n const createMutation = useMutation( {\n mutationFn: async ( f: FormState ) => {\n const t = await fetchJson<ReleaseTranslation>( apiPath, {\n method : 'POST',\n body : JSON.stringify( { name : f.name.trim(), description : f.description.trim() || null } ),\n } )\n await saveValues( t.id, f.values )\n },\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey } )\n toast( { title: 'Translation created' } )\n close()\n },\n onError: ( e: Error ) => toast( { title: 'Error', description: e.message, variant: 'destructive' } ),\n } )\n\n const updateMutation = useMutation( {\n mutationFn: async ( f: FormState ) => {\n await fetchJson( `${apiPath}/${editing!.id}`, {\n method : 'PATCH',\n body : JSON.stringify( { name : f.name.trim(), description : f.description.trim() || null } ),\n } )\n await saveValues( editing!.id, f.values )\n },\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey } )\n toast( { title: 'Translation updated' } )\n close()\n },\n onError: ( e: Error ) => toast( { title: 'Error', description: e.message, variant: 'destructive' } ),\n } )\n\n const deleteMutation = useMutation( {\n mutationFn: ( id: string ) => fetchJson( `${apiPath}/${id}`, { method : 'DELETE' } ),\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey } )\n toast( { title: 'Translation deleted' } )\n },\n onError: ( e: Error ) => toast( { title: 'Error', description: e.message, variant: 'destructive' } ),\n } )\n\n async function saveValues( translationId: string, values: Record<string, string> ) {\n const existing = editing?.values ?? []\n for ( const configId of configIds ) {\n const val = values[configId]?.trim()\n const prev = existing.find( v => v.configId === configId )\n const valuesPath = `${apiPath}/${translationId}/values`\n\n if ( prev && val ) {\n await fetchJson( `${valuesPath}/${prev.id}`, {\n method : 'PATCH',\n body : JSON.stringify( { value : val } ),\n } )\n } else if ( prev && !val ) {\n await fetchJson( `${valuesPath}/${prev.id}`, { method : 'DELETE' } )\n } else if ( !prev && val ) {\n await fetchJson( valuesPath, {\n method : 'POST',\n body : JSON.stringify( { translationId, configId, value : val } ),\n } )\n }\n }\n }\n\n const openCreate = () => {\n setEditing( null )\n setForm( EMPTY_FORM( configIds ) )\n setIsOpen( true )\n }\n\n const openEdit = ( t: TranslationWithValues ) => {\n setEditing( t )\n const vals = t.values ?? []\n const values = Object.fromEntries(\n configIds.map( id => [ id, vals.find( v => v.configId === id )?.value ?? '' ] )\n )\n setForm( { name : t.name, description : t.description ?? '', values } )\n setIsOpen( true )\n }\n\n const close = () => { setIsOpen( false ); setEditing( null ) }\n\n const handleSubmit = () => {\n if ( editing ) { updateMutation.mutate( form ) } else { createMutation.mutate( form ) }\n }\n\n const isPending = createMutation.isPending || updateMutation.isPending\n const isValid = Boolean( form.name.trim() )\n\n if ( isLoading ) {\n return <div className=\"text-center text-muted-foreground py-8\">Loading…</div>\n }\n\n const list = translations ?? []\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {list.length === 0\n ? 'No translation rules yet.'\n : `${list.length} translation rule${list.length === 1 ? '' : 's'}.`}\n </p>\n <Button size=\"sm\" onClick={openCreate}>\n <Plus />\n Add translation\n </Button>\n </div>\n\n {list.length > 0 && (\n <div className=\"rounded-md border overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-muted/50\">\n <th className=\"px-4 py-2 text-left font-medium\">Name</th>\n {configIds.map( id => (\n <th key={id} className=\"px-4 py-2 text-left font-medium\">\n {clusterNames[id] ?? id}\n </th>\n ) )}\n <th className=\"px-4 py-2 text-right font-medium\"></th>\n </tr>\n </thead>\n <tbody>\n {list.map( ( t ) => (\n <tr key={t.id} className=\"border-b last:border-0 hover:bg-muted/25\">\n <td className=\"px-4 py-2\">\n <div className=\"font-medium\">{t.name}</div>\n {t.description && (\n <div className=\"text-xs text-muted-foreground\">{t.description}</div>\n )}\n </td>\n {configIds.map( id => {\n const v = t.values?.find( val => val.configId === id )\n return (\n <td key={id} className=\"px-4 py-2 font-mono text-xs\">\n {v ? v.value : <span className=\"text-muted-foreground\">—</span>}\n </td>\n )\n } )}\n <td className=\"px-4 py-2 text-right\">\n <div className=\"flex gap-1 justify-end\">\n <Button variant=\"ghost\" size=\"icon\" onClick={() => openEdit( t )}>\n <Pencil />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if ( window.confirm( `Delete translation \"${t.name}\"?` ) ) {\n deleteMutation.mutate( t.id )\n }\n }}\n >\n <Trash2 />\n </Button>\n </div>\n </td>\n </tr>\n ) )}\n </tbody>\n </table>\n </div>\n )}\n\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle>{editing ? `Edit ${editing.name}` : 'New Translation Rule'}</DialogTitle>\n <DialogDescription>\n Set the equivalent values for each cluster. Rules with values on only one side of a\n pair are silently skipped for that comparison.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"tr-name\">Name</Label>\n <Input\n id=\"tr-name\"\n value={form.name}\n onChange={( e ) => setForm( { ...form, name : e.target.value } )}\n placeholder=\"API Base URL\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tr-desc\">Description (optional)</Label>\n <Input\n id=\"tr-desc\"\n value={form.description}\n onChange={( e ) => setForm( { ...form, description : e.target.value } )}\n placeholder=\"Explain what this value represents\"\n />\n </div>\n\n <div className=\"space-y-3 pt-1\">\n <p className=\"text-sm font-medium\">Values per cluster</p>\n {configIds.map( id => (\n <div key={id} className=\"space-y-1\">\n <Label htmlFor={`tr-val-${id}`} className=\"text-xs text-muted-foreground\">\n {clusterNames[id] ?? id}\n </Label>\n <Input\n id={`tr-val-${id}`}\n value={form.values[id] ?? ''}\n onChange={( e ) => setForm( {\n ...form,\n values : { ...form.values, [id] : e.target.value },\n } )}\n placeholder=\"Leave blank to remove\"\n className=\"font-mono text-xs\"\n />\n </div>\n ) )}\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={close}>\n <X />\n Cancel\n </Button>\n <Button onClick={handleSubmit} disabled={!isValid || isPending}>\n <Save />\n {isPending ? 'Saving…' : 'Save'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </div>\n )\n}\n","import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport { Trash2, Ban } from 'lucide-react'\n\nimport { Button } from '../../components/ui/Button'\nimport { useToast } from '../../hooks/useToast'\nimport { useImaginariumApi } from '../../api/ImaginariumApiContext'\nimport type { ReleaseIgnore, ReleaseIgnoreListResponse } from './types'\n\nexport interface IgnoredTabProps {\n originConfigId: string\n apiPath?: string\n}\n\n/**\n * Tab listing all permanently-ignored items for an origin cluster.\n *\n * Provides per-row Remove and a Clear all toolbar button.\n */\nexport default function IgnoredTab( {\n originConfigId,\n apiPath = '/release-ignores',\n}: IgnoredTabProps ) {\n const { toast } = useToast()\n const { fetchJson } = useImaginariumApi()\n const queryClient = useQueryClient()\n\n const queryKey = [ 'imaginarium', 'release-ignores', originConfigId ] as const\n\n const { data: ignoreRules, isLoading } = useQuery<ReleaseIgnore[]>( {\n queryKey,\n queryFn: async () => {\n const res = await fetchJson<ReleaseIgnoreListResponse>(\n `${apiPath}?where[originConfigId]=${encodeURIComponent( originConfigId )}`\n )\n return res?.items ?? []\n },\n } )\n\n const removeMutation = useMutation( {\n mutationFn: ( id: string ) => fetchJson( `${apiPath}/${id}`, { method: 'DELETE' } ),\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey } )\n toast( { title: 'Item removed from ignore list' } )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n const clearAllMutation = useMutation( {\n mutationFn: () =>\n fetchJson( `${apiPath}?originConfigId=${encodeURIComponent( originConfigId )}`, {\n method: 'DELETE',\n } ),\n onSuccess: () => {\n queryClient.invalidateQueries( { queryKey } )\n toast( { title: 'All ignore rules cleared' } )\n },\n onError: ( error: Error ) => {\n toast( { title: 'Error', description: error.message, variant: 'destructive' } )\n },\n } )\n\n const handleClearAll = () => {\n if ( !window.confirm( 'Remove all ignore rules for this cluster? Items will appear normally in future snapshots.' ) ) {\n return\n }\n clearAllMutation.mutate()\n }\n\n if ( isLoading ) {\n return <div className=\"text-center text-muted-foreground py-8\">Loading…</div>\n }\n\n const rules = ignoreRules ?? []\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {rules.length === 0\n ? 'No items are permanently ignored.'\n : `${rules.length} item${rules.length === 1 ? '' : 's'} permanently ignored for this cluster.`}\n </p>\n {rules.length > 0 && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleClearAll}\n disabled={clearAllMutation.isPending}\n >\n <Ban />\n {clearAllMutation.isPending ? 'Clearing…' : 'Clear all'}\n </Button>\n )}\n </div>\n\n {rules.length > 0 && (\n <div className=\"rounded-md border\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b bg-muted/50\">\n <th className=\"px-4 py-2 text-left font-medium\">Type</th>\n <th className=\"px-4 py-2 text-left font-medium\">Name</th>\n <th className=\"px-4 py-2 text-left font-medium\">Reason</th>\n <th className=\"px-4 py-2 text-right font-medium\"></th>\n </tr>\n </thead>\n <tbody>\n {rules.map( ( rule ) => (\n <tr key={rule.id} className=\"border-b last:border-0 hover:bg-muted/25\">\n <td className=\"px-4 py-2 text-muted-foreground font-mono text-xs\">\n {rule.itemType}\n </td>\n <td className=\"px-4 py-2 font-medium\">{rule.itemName}</td>\n <td className=\"px-4 py-2 text-muted-foreground\">\n {rule.reason ?? <span className=\"italic text-xs\">—</span>}\n </td>\n <td className=\"px-4 py-2 text-right\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n title=\"Remove from ignore list\"\n onClick={() => removeMutation.mutate( rule.id )}\n disabled={removeMutation.isPending}\n >\n <Trash2 />\n </Button>\n </td>\n </tr>\n ) )}\n </tbody>\n </table>\n </div>\n )}\n </div>\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\n\nimport { Button } from '../../components/ui/Button'\nimport { useSystemConfigs } from '../../system/SystemConfigsContext'\nimport ReleaseList from './ReleaseList'\nimport ReleaseDetail from './ReleaseDetail'\nimport ClusterSelect from './ClusterSelect'\nimport StatusMatrix from './StatusMatrix'\nimport TranslationsTab from './TranslationsTab'\nimport IgnoredTab from './IgnoredTab'\n\ntype ReleaseTab = 'releases' | 'status' | 'translations' | 'ignored'\n\nconst TABS: { id: ReleaseTab; label: string }[] = [\n { id: 'releases', label: 'Releases' },\n { id: 'status', label: 'Status' },\n { id: 'translations', label: 'Translations' },\n { id: 'ignored', label: 'Ignored' },\n]\n\nexport default function ReleaseView() {\n // TODO: sync tab to URL — plain useState for Phase 1 (see U2 decision note).\n const [ tab, setTab ] = useState<ReleaseTab>( 'releases' )\n const [ openReleaseId, setOpenReleaseId ] = useState<string | null>( null )\n\n const { configs } = useSystemConfigs()\n\n // App-level reference/origin cluster shared by the Status and Ignored tabs.\n const [ originConfigId, setOriginConfigId ] = useState<string>( '' )\n\n // Default to the first config once loaded and nothing is selected.\n useEffect( () => {\n if ( !originConfigId && configs.length > 0 ) {\n setOriginConfigId( configs[0].id )\n }\n }, [ originConfigId, configs ] )\n\n // cluster id → displayName lookup (same idiom as ReleaseList/ReleaseDetail).\n const nameMap = useMemo( () => {\n const map: Record<string, string> = {}\n configs.forEach( ( c ) => { map[c.id] = c.displayName } )\n return map\n }, [ configs ] )\n\n const effectiveOrigin = originConfigId || configs[0]?.id || ''\n const destIds = configs.map( ( c ) => c.id ).filter( ( id ) => id !== effectiveOrigin )\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h2 className=\"text-2xl font-semibold\">imp</h2>\n <p className=\"text-sm text-muted-foreground\">Manage releases across clusters</p>\n </div>\n\n <div className=\"flex items-center gap-1 border-b pb-2\">\n {TABS.map( ( { id, label } ) => (\n <Button\n key={id}\n variant={tab === id ? 'secondary' : 'ghost'}\n size=\"sm\"\n onClick={() => setTab( id )}\n >\n {label}\n </Button>\n ) )}\n </div>\n\n {tab === 'releases' && (\n openReleaseId == null ? (\n <ReleaseList onOpen={setOpenReleaseId} />\n ) : (\n <ReleaseDetail releaseId={openReleaseId} onBack={() => setOpenReleaseId( null )} />\n )\n )}\n\n {tab === 'status' && (\n configs.length === 0 ? (\n <div className=\"text-muted-foreground\">No clusters configured.</div>\n ) : (\n <div className=\"space-y-4\">\n <div className=\"max-w-xs\">\n <ClusterSelect\n label=\"Reference\"\n value={effectiveOrigin}\n onChange={setOriginConfigId}\n configs={configs}\n />\n </div>\n {effectiveOrigin ? (\n <StatusMatrix originConfigId={effectiveOrigin} destConfigIds={destIds} />\n ) : (\n <div className=\"text-muted-foreground\">Select a reference cluster.</div>\n )}\n </div>\n )\n )}\n\n {tab === 'translations' && (\n configs.length === 0 ? (\n <div className=\"text-muted-foreground\">No clusters configured.</div>\n ) : (\n <TranslationsTab configIds={configs.map( ( c ) => c.id )} clusterNames={nameMap} />\n )\n )}\n\n {tab === 'ignored' && (\n configs.length === 0 ? (\n <div className=\"text-muted-foreground\">No clusters configured.</div>\n ) : (\n <div className=\"space-y-4\">\n <div className=\"max-w-xs\">\n <ClusterSelect\n label=\"Cluster\"\n value={effectiveOrigin}\n onChange={setOriginConfigId}\n configs={configs}\n />\n </div>\n {effectiveOrigin ? (\n <IgnoredTab originConfigId={effectiveOrigin} />\n ) : (\n <div className=\"text-muted-foreground\">Select a cluster.</div>\n )}\n </div>\n )\n )}\n </div>\n )\n}\n","import ReleaseView from './ReleaseView'\n\nexport default {\n id : 'imaginarium.ui.ImpPage',\n path : '/imp',\n element : ReleaseView,\n}\n","import { Bot } from 'lucide-react'\n\nexport default {\n id : 'imaginarium.ui.ImpNavItem',\n path : '/imp',\n label : 'imp',\n icon : Bot,\n sort : 150,\n}\n","import { PageType, NavItemType } from '../../plugins/PluginTypes'\n\nimport ReleasePage from './ReleasePage'\nimport ReleaseNavItem from './ReleaseNavItem'\n\nexport const ReleaseSetup = {\n install( plg: { addPlugin: ( type: string, p: unknown ) => void } ) {\n plg.addPlugin( PageType, ReleasePage )\n plg.addPlugin( NavItemType, ReleaseNavItem )\n },\n}\n\nexport default ReleaseSetup\n"],"names":["CreateReleaseModal","open","onOpenChange","onCreated","apiPath","Config","toast","useToast","fetchJson","useImaginariumApi","queryClient","useQueryClient","configs","useSystemConfigs","name","setName","useState","description","setDescription","originConfigId","setOriginConfigId","targetConfigIds","setTargetConfigIds","queryKey","reset","targetOptions","useMemo","c","handleOriginChange","id","prev","t","toggleTarget","createMutation","useMutation","created","error","handleOpenChange","next","isValid","Dialog","DialogContent","jsxs","DialogHeader","jsx","DialogTitle","DialogDescription","Label","Input","e","DialogFooter","Button","X","Fragment","Loader2","Save","ReleaseStatusBadge","status","ReleaseList","onOpen","isModalOpen","setIsModalOpen","releases","isLoading","useQuery","res","a","b","nameById","map","displayName","Plus","Card","CardContent","r","StatusBadge","PreviouslySkippedBadge","originName","className","tooltip","TooltipProvider","Tooltip","TooltipTrigger","cn","TooltipContent","IgnoredPill","IgnoreButton","ignoreRule","createPayload","onChange","confirmOpen","setConfirmOpen","isIgnored","invalidate","ignoreMutation","unignoreMutation","isPending","Ban","ResetExclusionsButton","releaseId","onReset","mutation","data","RotateCcw","DiffColumn","label","value","highlightLines","line","i","stringify","changedOriginLines","originValue","targetValue","rMap","originText","replace","withValue","o","n","m","dp","j","changed","ExclusionChecklist","title","values","excluded","editable","onToggle","formatLabel","setOpen","useEffect","ChevronDown","ChevronRight","push","ReleaseDiffPanel","item","targets","onClose","unmetDependencyNames","tags","excludedTags","onToggleTag","metadataKeys","excludedMetadataKeys","onToggleMetadataKey","i18nPaths","excludedI18nPaths","onToggleI18nPath","permissionKeys","excludedPermissions","onTogglePermission","formatPermissionLabel","replacementMaps","firstId","_a","activeId","setActiveId","active","byTarget","_b","hasByTarget","_c","matches","originHighlight","AlertTriangle","tMatches","Check","_d","StatusIndicator","state","Circle","PushDialog","targetNames","onComplete","dependencyWarnings","isPushing","setIsPushing","states","setStates","done","setDone","setTarget","handleConfirm","succeeded","withErrors","destConfigId","failures","err","message","w","f","Send","pushableVersions","v","RuleVersionSelect","disabled","versions","TYPE_CLASSES","EntityTag","type","classes","Toggle","checked","buildPushResultMap","pushes","latestByDest","current","result","byDest","pushResultFor","itemKey","filterItems","items","filters","typeCounts","counts","syntheticParent","parentKey","idx","buildItemTree","rootKeys","nodes","byKey","node","synthByKey","synth","syntheticRow","groupStatusRows","rows","row","includedChildCounts","included","child","computeDependsOn","tokenToKey","it","origin","deps","hay","token","depKey","unmetDependencies","dependsOn","unmet","dep","TYPE_ORDER","typeRank","compareTypes","exclusionTotal","exclusionTitle","parts","INCLUDED_OPTIONS","matchesIncluded","toStringArray","x","parsed","ExclusionsBadge","total","PushTargets","results","pushedDests","chips","style","glyph","ReleaseDetail","onBack","typeFilter","setTypeFilter","includedFilter","setIncludedFilter","selected","setSelected","pushOpen","setPushOpen","expanded","setExpanded","toggleExpanded","releaseKey","itemsKey","pushesKey","release","releaseLoading","itemsLoading","pushResults","p","hasPushes","roots","rootItems","describeDep","parent","fromKey","idToName","types","visible","renderChildren","refreshMutation","toggleMutation","itemId","versionMutation","selectedVersion","exclusionMutationOptions","field","old","_vars","ctx","excludedTagsMutation","excludedMetadataKeysMutation","excludedI18nPathsMutation","excludedPermissionsMutation","invalidateItems","isPushed","selectedLive","ArrowLeft","RefreshCw","hasChildren","showChildren","isExpanded","childCounts","ruleVersions","isRuleWithVersions","hasPublished","pushable","noPublished","allExist","ruleBlocked","needsVersion","d","md","i18n","paths","perms","keys","k","key","tok","tag","cur","path","ClusterSelect","DiffPanel","CELL_CONFIG","Cell","onClick","cfg","clickable","StatsBar","stats","destConfigIds","s","isIssueRow","StatusMatrix","filter","setFilter","showStats","setShowStats","activeCell","setActiveCell","hiddenDests","setHiddenDests","visibleDests","params","isError","cellDiff","diffLoading","diffError","toggleDest","handleCellClick","BarChart2","destId","EMPTY_FORM","configIds","TranslationsTab","clusterNames","isOpen","setIsOpen","editing","setEditing","form","setForm","translations","saveValues","close","updateMutation","deleteMutation","translationId","existing","configId","val","valuesPath","openCreate","openEdit","vals","handleSubmit","list","Pencil","Trash2","IgnoredTab","ignoreRules","removeMutation","clearAllMutation","handleClearAll","rules","rule","TABS","ReleaseView","tab","setTab","openReleaseId","setOpenReleaseId","nameMap","effectiveOrigin","destIds","ReleasePage","ReleaseNavItem","Bot","ReleaseSetup","plg","PageType","NavItemType"],"mappings":"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"}