claude-code-workflow 7.2.27 → 7.2.28
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.
- package/.ccw/specs/architecture-constraints.md +5 -0
- package/.claude/skills/_shared/SKILL-DESIGN-SPEC.md +140 -0
- package/.claude/skills/investigate/SKILL.md +110 -0
- package/.claude/skills/investigate/phases/01-root-cause-investigation.md +132 -0
- package/.claude/skills/investigate/phases/02-pattern-analysis.md +126 -0
- package/.claude/skills/investigate/phases/03-hypothesis-testing.md +177 -0
- package/.claude/skills/investigate/phases/04-implementation.md +139 -0
- package/.claude/skills/investigate/phases/05-verification-report.md +153 -0
- package/.claude/skills/investigate/specs/debug-report-format.md +226 -0
- package/.claude/skills/investigate/specs/iron-law.md +101 -0
- package/.claude/skills/security-audit/SKILL.md +125 -0
- package/.claude/skills/security-audit/phases/01-supply-chain-scan.md +139 -0
- package/.claude/skills/security-audit/phases/02-owasp-review.md +156 -0
- package/.claude/skills/security-audit/phases/03-threat-modeling.md +180 -0
- package/.claude/skills/security-audit/phases/04-report-tracking.md +177 -0
- package/.claude/skills/security-audit/specs/owasp-checklist.md +442 -0
- package/.claude/skills/security-audit/specs/scoring-gates.md +141 -0
- package/.claude/skills/ship/SKILL.md +105 -0
- package/.claude/skills/ship/phases/01-preflight-checks.md +121 -0
- package/.claude/skills/ship/phases/02-code-review.md +137 -0
- package/.claude/skills/ship/phases/03-version-bump.md +171 -0
- package/.claude/skills/ship/phases/04-changelog-commit.md +167 -0
- package/.claude/skills/ship/phases/05-pr-creation.md +163 -0
- package/.claude/skills/skill-generator/templates/sequential-phase.md +10 -0
- package/.claude/skills/skill-generator/templates/skill-md.md +4 -0
- package/.claude/skills/team-interactive-craft/SKILL.md +127 -0
- package/.claude/skills/team-interactive-craft/roles/a11y-tester/role.md +159 -0
- package/.claude/skills/team-interactive-craft/roles/builder/role.md +216 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/commands/analyze.md +71 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/commands/dispatch.md +192 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/commands/monitor.md +183 -0
- package/.claude/skills/team-interactive-craft/roles/coordinator/role.md +166 -0
- package/.claude/skills/team-interactive-craft/roles/interaction-designer/role.md +144 -0
- package/.claude/skills/team-interactive-craft/roles/researcher/role.md +131 -0
- package/.claude/skills/team-interactive-craft/specs/interaction-patterns.md +362 -0
- package/.claude/skills/team-interactive-craft/specs/pipelines.md +85 -0
- package/.claude/skills/team-interactive-craft/specs/team-config.json +105 -0
- package/.claude/skills/team-interactive-craft/specs/vanilla-constraints.md +83 -0
- package/.claude/skills/team-motion-design/SKILL.md +129 -0
- package/.claude/skills/team-motion-design/roles/animator/role.md +194 -0
- package/.claude/skills/team-motion-design/roles/choreographer/role.md +164 -0
- package/.claude/skills/team-motion-design/roles/coordinator/commands/analyze.md +64 -0
- package/.claude/skills/team-motion-design/roles/coordinator/commands/dispatch.md +203 -0
- package/.claude/skills/team-motion-design/roles/coordinator/commands/monitor.md +184 -0
- package/.claude/skills/team-motion-design/roles/coordinator/role.md +167 -0
- package/.claude/skills/team-motion-design/roles/motion-researcher/role.md +115 -0
- package/.claude/skills/team-motion-design/roles/motion-tester/role.md +175 -0
- package/.claude/skills/team-motion-design/specs/gpu-constraints.md +114 -0
- package/.claude/skills/team-motion-design/specs/motion-tokens.md +128 -0
- package/.claude/skills/team-motion-design/specs/pipelines.md +74 -0
- package/.claude/skills/team-motion-design/specs/reduced-motion.md +129 -0
- package/.claude/skills/team-motion-design/specs/team-config.json +99 -0
- package/.claude/skills/team-ui-polish/SKILL.md +127 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/commands/analyze.md +77 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/commands/dispatch.md +194 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/commands/monitor.md +180 -0
- package/.claude/skills/team-ui-polish/roles/coordinator/role.md +170 -0
- package/.claude/skills/team-ui-polish/roles/diagnostician/role.md +160 -0
- package/.claude/skills/team-ui-polish/roles/optimizer/role.md +225 -0
- package/.claude/skills/team-ui-polish/roles/scanner/role.md +356 -0
- package/.claude/skills/team-ui-polish/roles/verifier/role.md +142 -0
- package/.claude/skills/team-ui-polish/specs/anti-patterns.md +141 -0
- package/.claude/skills/team-ui-polish/specs/design-standards.md +356 -0
- package/.claude/skills/team-ui-polish/specs/fix-strategies.md +235 -0
- package/.claude/skills/team-ui-polish/specs/pipelines.md +81 -0
- package/.claude/skills/team-ui-polish/specs/scoring-guide.md +162 -0
- package/.claude/skills/team-ui-polish/specs/team-config.json +73 -0
- package/.claude/skills/team-uidesign/SKILL.md +6 -1
- package/.claude/skills/team-uidesign/roles/designer/role.md +28 -4
- package/.claude/skills/team-uidesign/roles/implementer/role.md +25 -3
- package/.claude/skills/team-uidesign/roles/researcher/role.md +21 -2
- package/.claude/skills/team-uidesign/roles/reviewer/role.md +19 -17
- package/.claude/skills/team-uidesign/specs/anti-patterns.md +211 -0
- package/.claude/skills/team-uidesign/specs/design-standards.md +329 -0
- package/.claude/skills/team-uidesign/specs/scoring-guide.md +114 -0
- package/.claude/skills/team-uidesign/specs/team-config.json +1 -1
- package/.claude/skills/team-uidesign/specs/ux-writing.md +86 -0
- package/.claude/skills/team-ux-improve/SKILL.md +3 -0
- package/.claude/skills/team-ux-improve/roles/designer/role.md +30 -0
- package/.claude/skills/team-ux-improve/roles/diagnoser/role.md +16 -1
- package/.claude/skills/team-ux-improve/roles/scanner/role.md +43 -1
- package/.claude/skills/team-ux-improve/specs/anti-patterns.md +103 -0
- package/.claude/skills/team-ux-improve/specs/design-standards.md +54 -0
- package/.claude/skills/team-ux-improve/specs/heuristics.md +88 -0
- package/.claude/skills/team-ux-improve/wisdom/anti-patterns/common-ux-pitfalls.md +40 -8
- package/.claude/skills/team-ux-improve/wisdom/patterns/state-management.md +32 -12
- package/.claude/skills/team-ux-improve/wisdom/patterns/ui-feedback.md +35 -11
- package/.claude/skills/team-ux-improve/wisdom/principles/general-ux.md +36 -9
- package/.claude/skills/team-visual-a11y/SKILL.md +143 -0
- package/.claude/skills/team-visual-a11y/roles/color-auditor/role.md +178 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/commands/analyze.md +72 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/commands/dispatch.md +250 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/commands/monitor.md +204 -0
- package/.claude/skills/team-visual-a11y/roles/coordinator/role.md +169 -0
- package/.claude/skills/team-visual-a11y/roles/fix-implementer/role.md +246 -0
- package/.claude/skills/team-visual-a11y/roles/focus-auditor/role.md +222 -0
- package/.claude/skills/team-visual-a11y/roles/remediation-planner/role.md +206 -0
- package/.claude/skills/team-visual-a11y/roles/typo-auditor/role.md +185 -0
- package/.claude/skills/team-visual-a11y/specs/focus-patterns.md +325 -0
- package/.claude/skills/team-visual-a11y/specs/oklch-standards.md +130 -0
- package/.claude/skills/team-visual-a11y/specs/pipelines.md +98 -0
- package/.claude/skills/team-visual-a11y/specs/team-config.json +109 -0
- package/.claude/skills/team-visual-a11y/specs/typography-scale.md +165 -0
- package/.claude/skills/team-visual-a11y/specs/wcag-matrix.md +133 -0
- package/.codex/skills/investigate/agents/investigator.md +392 -0
- package/.codex/skills/investigate/orchestrator.md +362 -0
- package/.codex/skills/investigate/phases/01-root-cause-investigation.md +212 -0
- package/.codex/skills/investigate/phases/02-pattern-analysis.md +181 -0
- package/.codex/skills/investigate/phases/03-hypothesis-testing.md +214 -0
- package/.codex/skills/investigate/phases/04-implementation.md +195 -0
- package/.codex/skills/investigate/phases/05-verification-report.md +240 -0
- package/.codex/skills/security-audit/agents/security-auditor.md +341 -0
- package/.codex/skills/security-audit/orchestrator.md +384 -0
- package/.codex/skills/security-audit/phases/01-supply-chain-scan.md +226 -0
- package/.codex/skills/security-audit/phases/02-owasp-review.md +232 -0
- package/.codex/skills/security-audit/phases/03-threat-modeling.md +249 -0
- package/.codex/skills/security-audit/phases/04-report-tracking.md +300 -0
- package/.codex/skills/ship/agents/ship-operator.md +318 -0
- package/.codex/skills/ship/orchestrator.md +426 -0
- package/.codex/skills/ship/phases/01-preflight-checks.md +198 -0
- package/.codex/skills/ship/phases/02-code-review.md +228 -0
- package/.codex/skills/ship/phases/03-version-bump.md +259 -0
- package/.codex/skills/ship/phases/04-changelog-commit.md +263 -0
- package/.codex/skills/ship/phases/05-pr-creation.md +280 -0
- package/.codex/skills/team-interactive-craft/SKILL.md +220 -0
- package/.codex/skills/team-interactive-craft/roles/a11y-tester/role.md +159 -0
- package/.codex/skills/team-interactive-craft/roles/builder/role.md +216 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/commands/analyze.md +71 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/commands/dispatch.md +162 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/commands/monitor.md +233 -0
- package/.codex/skills/team-interactive-craft/roles/coordinator/role.md +209 -0
- package/.codex/skills/team-interactive-craft/roles/interaction-designer/role.md +144 -0
- package/.codex/skills/team-interactive-craft/roles/researcher/role.md +131 -0
- package/.codex/skills/team-interactive-craft/specs/interaction-patterns.md +362 -0
- package/.codex/skills/team-interactive-craft/specs/pipelines.md +85 -0
- package/.codex/skills/team-interactive-craft/specs/team-config.json +105 -0
- package/.codex/skills/team-interactive-craft/specs/vanilla-constraints.md +83 -0
- package/.codex/skills/team-motion-design/SKILL.md +222 -0
- package/.codex/skills/team-motion-design/roles/animator/role.md +194 -0
- package/.codex/skills/team-motion-design/roles/choreographer/role.md +164 -0
- package/.codex/skills/team-motion-design/roles/coordinator/commands/analyze.md +64 -0
- package/.codex/skills/team-motion-design/roles/coordinator/commands/dispatch.md +168 -0
- package/.codex/skills/team-motion-design/roles/coordinator/commands/monitor.md +242 -0
- package/.codex/skills/team-motion-design/roles/coordinator/role.md +210 -0
- package/.codex/skills/team-motion-design/roles/motion-researcher/role.md +115 -0
- package/.codex/skills/team-motion-design/roles/motion-tester/role.md +175 -0
- package/.codex/skills/team-motion-design/specs/gpu-constraints.md +114 -0
- package/.codex/skills/team-motion-design/specs/motion-tokens.md +128 -0
- package/.codex/skills/team-motion-design/specs/pipelines.md +74 -0
- package/.codex/skills/team-motion-design/specs/reduced-motion.md +129 -0
- package/.codex/skills/team-motion-design/specs/team-config.json +99 -0
- package/.codex/skills/team-ui-polish/SKILL.md +218 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/commands/analyze.md +77 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/commands/dispatch.md +167 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/commands/monitor.md +230 -0
- package/.codex/skills/team-ui-polish/roles/coordinator/role.md +213 -0
- package/.codex/skills/team-ui-polish/roles/diagnostician/role.md +164 -0
- package/.codex/skills/team-ui-polish/roles/optimizer/role.md +229 -0
- package/.codex/skills/team-ui-polish/roles/scanner/role.md +360 -0
- package/.codex/skills/team-ui-polish/roles/verifier/role.md +142 -0
- package/.codex/skills/team-ui-polish/specs/anti-patterns.md +141 -0
- package/.codex/skills/team-ui-polish/specs/design-standards.md +356 -0
- package/.codex/skills/team-ui-polish/specs/fix-strategies.md +235 -0
- package/.codex/skills/team-ui-polish/specs/pipelines.md +81 -0
- package/.codex/skills/team-ui-polish/specs/scoring-guide.md +162 -0
- package/.codex/skills/team-ui-polish/specs/team-config.json +73 -0
- package/.codex/skills/team-visual-a11y/SKILL.md +319 -0
- package/.codex/skills/team-visual-a11y/roles/color-auditor/role.md +178 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/commands/analyze.md +72 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/commands/dispatch.md +188 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/commands/monitor.md +281 -0
- package/.codex/skills/team-visual-a11y/roles/coordinator/role.md +213 -0
- package/.codex/skills/team-visual-a11y/roles/fix-implementer/role.md +246 -0
- package/.codex/skills/team-visual-a11y/roles/focus-auditor/role.md +222 -0
- package/.codex/skills/team-visual-a11y/roles/remediation-planner/role.md +206 -0
- package/.codex/skills/team-visual-a11y/roles/typo-auditor/role.md +185 -0
- package/.codex/skills/team-visual-a11y/specs/focus-patterns.md +325 -0
- package/.codex/skills/team-visual-a11y/specs/oklch-standards.md +130 -0
- package/.codex/skills/team-visual-a11y/specs/pipelines.md +98 -0
- package/.codex/skills/team-visual-a11y/specs/team-config.json +109 -0
- package/.codex/skills/team-visual-a11y/specs/typography-scale.md +165 -0
- package/.codex/skills/team-visual-a11y/specs/wcag-matrix.md +133 -0
- package/README.md +8 -0
- package/ccw/dist/core/hooks/hook-templates.d.ts.map +1 -1
- package/ccw/dist/core/hooks/hook-templates.js +114 -1
- package/ccw/dist/core/hooks/hook-templates.js.map +1 -1
- package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js +34 -0
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +2 -2
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/frontend/dist/assets/{AlertDialog-Bf1jdqax.js → AlertDialog-BjP1ydDR.js} +2 -2
- package/ccw/frontend/dist/assets/{AlertDialog-Bf1jdqax.js.map → AlertDialog-BjP1ydDR.js.map} +1 -1
- package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js → AnalysisPage-CAX3xqMf.js} +2 -2
- package/ccw/frontend/dist/assets/{AnalysisPage-C8niKdp4.js.map → AnalysisPage-CAX3xqMf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js → ApiSettingsPage-CtWlmztq.js} +2 -2
- package/ccw/frontend/dist/assets/{ApiSettingsPage-BL2c3UNS.js.map → ApiSettingsPage-CtWlmztq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js → CliModeToggle-hR4a-eLX.js} +2 -2
- package/ccw/frontend/dist/assets/{CliModeToggle-BePBFynD.js.map → CliModeToggle-hR4a-eLX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js → CliSessionSharePage-DzNPkFN9.js} +2 -2
- package/ccw/frontend/dist/assets/{CliSessionSharePage-7cYtX6FT.js.map → CliSessionSharePage-DzNPkFN9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js → CliViewerPage-BPEGN4TT.js} +2 -2
- package/ccw/frontend/dist/assets/{CliViewerPage-CBwg1mPL.js.map → CliViewerPage-BPEGN4TT.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js → CodexLensPage-Cf0r2RHY.js} +2 -2
- package/ccw/frontend/dist/assets/{CodexLensPage-Bt74xORP.js.map → CodexLensPage-Cf0r2RHY.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js → Collapsible-DEm1rJ4h.js} +2 -2
- package/ccw/frontend/dist/assets/{Collapsible-Wrs87QT7.js.map → Collapsible-DEm1rJ4h.js.map} +1 -1
- package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js → CommandsManagerPage-BpeWw8HO.js} +2 -2
- package/ccw/frontend/dist/assets/{CommandsManagerPage-ChQjmPWZ.js.map → CommandsManagerPage-BpeWw8HO.js.map} +1 -1
- package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js → DeepWikiPage-BEsmh2vF.js} +2 -2
- package/ccw/frontend/dist/assets/{DeepWikiPage-dEO5wi6X.js.map → DeepWikiPage-BEsmh2vF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js → EndpointsPage-B30SFdtU.js} +2 -2
- package/ccw/frontend/dist/assets/{EndpointsPage-4zq269xY.js.map → EndpointsPage-B30SFdtU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js → ExplorerPage-BVvMpg1O.js} +2 -2
- package/ccw/frontend/dist/assets/{ExplorerPage-B0YTENhA.js.map → ExplorerPage-BVvMpg1O.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js → FixSessionPage-CL73dHbh.js} +2 -2
- package/ccw/frontend/dist/assets/{FixSessionPage-CwGs6dhz.js.map → FixSessionPage-CL73dHbh.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js → FloatingFileBrowser-BL-28lMZ.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingFileBrowser-COZRBslc.js.map → FloatingFileBrowser-BL-28lMZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js → FloatingPanel-BzZDciHZ.js} +2 -2
- package/ccw/frontend/dist/assets/{FloatingPanel-DYvgQZRD.js.map → FloatingPanel-BzZDciHZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js → GraphExplorerPage-CDp6-d8P.js} +2 -2
- package/ccw/frontend/dist/assets/{GraphExplorerPage-ewMHQGem.js.map → GraphExplorerPage-CDp6-d8P.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js → HistoryPage-fZY_7O9n.js} +2 -2
- package/ccw/frontend/dist/assets/{HistoryPage-BMeR0PrK.js.map → HistoryPage-fZY_7O9n.js.map} +1 -1
- package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js → HookManagerPage-4LJeC9bq.js} +2 -2
- package/ccw/frontend/dist/assets/{HookManagerPage-DBW2LnRm.js.map → HookManagerPage-4LJeC9bq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js → InstallationsPage-Bpigrbhw.js} +2 -2
- package/ccw/frontend/dist/assets/{InstallationsPage--pMj0QEH.js.map → InstallationsPage-Bpigrbhw.js.map} +1 -1
- package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js → IssueHubPage-BP0zJc1R.js} +2 -2
- package/ccw/frontend/dist/assets/{IssueHubPage-C_QMpQSR.js.map → IssueHubPage-BP0zJc1R.js.map} +1 -1
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js → LiteTasksPage-CSt2oVKQ.js} +2 -2
- package/ccw/frontend/dist/assets/{LiteTasksPage-CSWFdQ2-.js.map → LiteTasksPage-CSt2oVKQ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js → McpManagerPage-B-xaMA0w.js} +2 -2
- package/ccw/frontend/dist/assets/{McpManagerPage-Dvv8NtGy.js.map → McpManagerPage-B-xaMA0w.js.map} +1 -1
- package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js → MemoryPage-CJqo_7DY.js} +2 -2
- package/ccw/frontend/dist/assets/{MemoryPage-YO8WZzZO.js.map → MemoryPage-CJqo_7DY.js.map} +1 -1
- package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js → NotFoundPage-ibZeQA-Y.js} +2 -2
- package/ccw/frontend/dist/assets/{NotFoundPage-quUJw0CD.js.map → NotFoundPage-ibZeQA-Y.js.map} +1 -1
- package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js → OrchestratorPage-DgJ4ctPQ.js} +2 -2
- package/ccw/frontend/dist/assets/{OrchestratorPage-tuThWPID.js.map → OrchestratorPage-DgJ4ctPQ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js → ProjectOverviewPage-Cit0Yq0D.js} +2 -2
- package/ccw/frontend/dist/assets/{ProjectOverviewPage-shTilwiT.js.map → ProjectOverviewPage-Cit0Yq0D.js.map} +1 -1
- package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js → PromptHistoryPage-Ce1HDIK0.js} +2 -2
- package/ccw/frontend/dist/assets/{PromptHistoryPage-6rQnsI8l.js.map → PromptHistoryPage-Ce1HDIK0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js → ReviewSessionPage-J1KikNrk.js} +2 -2
- package/ccw/frontend/dist/assets/{ReviewSessionPage-JOmzjVbT.js.map → ReviewSessionPage-J1KikNrk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js → RulesManagerPage-CdBjTmth.js} +2 -2
- package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js.map → RulesManagerPage-CdBjTmth.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js → SessionDetailPage-B9ZK7LvX.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js.map → SessionDetailPage-B9ZK7LvX.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js → SessionsPage-CW_nS5UR.js} +2 -2
- package/ccw/frontend/dist/assets/{SessionsPage-Ciqjy9kz.js.map → SessionsPage-CW_nS5UR.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SettingsPage-BPDbXPSM.js → SettingsPage-B2PYzSoO.js} +35 -35
- package/ccw/frontend/dist/assets/SettingsPage-B2PYzSoO.js.map +1 -0
- package/ccw/frontend/dist/assets/{SkillsManagerPage-D3LzbpJY.js → SkillsManagerPage-CTnWrrwp.js} +2 -2
- package/ccw/frontend/dist/assets/{SkillsManagerPage-D3LzbpJY.js.map → SkillsManagerPage-CTnWrrwp.js.map} +1 -1
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js → SpecsSettingsPage-DJpi9XQL.js} +2 -2
- package/ccw/frontend/dist/assets/{SpecsSettingsPage-BpkJctzo.js.map → SpecsSettingsPage-DJpi9XQL.js.map} +1 -1
- package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js → Switch-Ac6Ov7uy.js} +2 -2
- package/ccw/frontend/dist/assets/{Switch-BpB9h__9.js.map → Switch-Ac6Ov7uy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js → TabsNavigation-DZAAspqR.js} +2 -2
- package/ccw/frontend/dist/assets/{TabsNavigation-BGsKy7DO.js.map → TabsNavigation-DZAAspqR.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js → TaskDrawer-BJkwfhIZ.js} +2 -2
- package/ccw/frontend/dist/assets/{TaskDrawer-bYIlbM0Q.js.map → TaskDrawer-BJkwfhIZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js → TeamPage-BJgjxBgb.js} +2 -2
- package/ccw/frontend/dist/assets/{TeamPage-CihtQ6LQ.js.map → TeamPage-BJgjxBgb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js → TerminalDashboardPage-D1WekoOy.js} +2 -2
- package/ccw/frontend/dist/assets/{TerminalDashboardPage-BDnNF_ud.js.map → TerminalDashboardPage-D1WekoOy.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js → archive-DxemgIhF.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-CQJ86bQp.js.map → archive-DxemgIhF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js → archive-restore-CjS83f1V.js} +2 -2
- package/ccw/frontend/dist/assets/{archive-restore-BhTfDbPU.js.map → archive-restore-CjS83f1V.js.map} +1 -1
- package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js → arrow-right-B5PUcn8I.js} +2 -2
- package/ccw/frontend/dist/assets/{arrow-right-eUAZnT9C.js.map → arrow-right-B5PUcn8I.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js → bookmark-plus-DCc9aPbb.js} +2 -2
- package/ccw/frontend/dist/assets/{bookmark-plus-ilF5-V-k.js.map → bookmark-plus-DCc9aPbb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{bot-BLkaQscs.js → bot-DOwFtzak.js} +2 -2
- package/ccw/frontend/dist/assets/{bot-BLkaQscs.js.map → bot-DOwFtzak.js.map} +1 -1
- package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js → braces-96qH3aFh.js} +2 -2
- package/ccw/frontend/dist/assets/{braces-D9HdgsO6.js.map → braces-96qH3aFh.js.map} +1 -1
- package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js → circle-stop-CCxSuil1.js} +2 -2
- package/ccw/frontend/dist/assets/{circle-stop-C3ZF1okQ.js.map → circle-stop-CCxSuil1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js → cpu-CZNSJFdq.js} +2 -2
- package/ccw/frontend/dist/assets/{cpu-B-QjaSjm.js.map → cpu-CZNSJFdq.js.map} +1 -1
- package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js → ellipsis-vertical-h8xtvw2_.js} +2 -2
- package/ccw/frontend/dist/assets/{ellipsis-vertical-CbNlw2gS.js.map → ellipsis-vertical-h8xtvw2_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js → eye-D3NY0bm6.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-yAy69Cnn.js.map → eye-D3NY0bm6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js → eye-off-Cy2vkc8p.js} +2 -2
- package/ccw/frontend/dist/assets/{eye-off-D5uzLZyP.js.map → eye-off-Cy2vkc8p.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js → file-json-Bzq3U1Mx.js} +2 -2
- package/ccw/frontend/dist/assets/{file-json-rwo1NowL.js.map → file-json-Bzq3U1Mx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js → file-text-DwuwPDPi.js} +2 -2
- package/ccw/frontend/dist/assets/{file-text-DRkrjie9.js.map → file-text-DwuwPDPi.js.map} +1 -1
- package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js → filter-q9g-bknU.js} +2 -2
- package/ccw/frontend/dist/assets/{filter-BOe-OTu1.js.map → filter-q9g-bknU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js → folder-CL6vb42J.js} +2 -2
- package/ccw/frontend/dist/assets/{folder-BaWZWn_r.js.map → folder-CL6vb42J.js.map} +1 -1
- package/ccw/frontend/dist/assets/{gauge-kazFexTr.js → gauge-BkrcQBly.js} +2 -2
- package/ccw/frontend/dist/assets/{gauge-kazFexTr.js.map → gauge-BkrcQBly.js.map} +1 -1
- package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js → globe-BQbwyNeV.js} +2 -2
- package/ccw/frontend/dist/assets/{globe-BuHeEjxd.js.map → globe-BQbwyNeV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js → grid-3x3-x5_7DrN7.js} +2 -2
- package/ccw/frontend/dist/assets/{grid-3x3-DbhuUu4V.js.map → grid-3x3-x5_7DrN7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js → hard-drive-DTyWXwzf.js} +2 -2
- package/ccw/frontend/dist/assets/{hard-drive-AoLGL0z4.js.map → hard-drive-DTyWXwzf.js.map} +1 -1
- package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js → hash-80O0kJO7.js} +2 -2
- package/ccw/frontend/dist/assets/{hash-Dpo1exMB.js.map → hash-80O0kJO7.js.map} +1 -1
- package/ccw/frontend/dist/assets/{history-ujQnmMC9.js → history-DDlN2Bwa.js} +2 -2
- package/ccw/frontend/dist/assets/{history-ujQnmMC9.js.map → history-DDlN2Bwa.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-CxzXz6o1.js → index-B9A3Hnrk.js} +2 -2
- package/ccw/frontend/dist/assets/{index-CxzXz6o1.js.map → index-B9A3Hnrk.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-B76AGix5.js → index-Bs80iCX0.js} +2 -2
- package/ccw/frontend/dist/assets/{index-B76AGix5.js.map → index-Bs80iCX0.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js → index-mbeo62f8.js} +2 -2
- package/ccw/frontend/dist/assets/{index-C_Yf5fZ4.js.map → index-mbeo62f8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{index-Dff4bg3u.js → index-rLgoBCfV.js} +3 -3
- package/ccw/frontend/dist/assets/{index-Dff4bg3u.js.map → index-rLgoBCfV.js.map} +1 -1
- package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js → layout-grid-C1niOWJx.js} +2 -2
- package/ccw/frontend/dist/assets/{layout-grid-CBdE4K8h.js.map → layout-grid-C1niOWJx.js.map} +1 -1
- package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js → lightbulb-BTmI7SUg.js} +2 -2
- package/ccw/frontend/dist/assets/{lightbulb-B9K6ZgRp.js.map → lightbulb-BTmI7SUg.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js → link-2-CB9HKeuZ.js} +2 -2
- package/ccw/frontend/dist/assets/{link-2-Oea4xHJl.js.map → link-2-CB9HKeuZ.js.map} +1 -1
- package/ccw/frontend/dist/assets/{link-5yXdZBch.js → link-koEYiemK.js} +2 -2
- package/ccw/frontend/dist/assets/{link-5yXdZBch.js.map → link-koEYiemK.js.map} +1 -1
- package/ccw/frontend/dist/assets/{list-9lHhC_U_.js → list-v2_GaLdC.js} +2 -2
- package/ccw/frontend/dist/assets/{list-9lHhC_U_.js.map → list-v2_GaLdC.js.map} +1 -1
- package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js → map-pin-BQNfAqG_.js} +2 -2
- package/ccw/frontend/dist/assets/{map-pin-B6Io5kmB.js.map → map-pin-BQNfAqG_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js → messages-square-Dzq5LGg9.js} +2 -2
- package/ccw/frontend/dist/assets/{messages-square-BT000aD3.js.map → messages-square-Dzq5LGg9.js.map} +1 -1
- package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js → minimize-2-CtkoJXcz.js} +2 -2
- package/ccw/frontend/dist/assets/{minimize-2-DO-zbT3a.js.map → minimize-2-CtkoJXcz.js.map} +1 -1
- package/ccw/frontend/dist/assets/{package-BjOw1ldU.js → package-CH3smL37.js} +2 -2
- package/ccw/frontend/dist/assets/{package-BjOw1ldU.js.map → package-CH3smL37.js.map} +1 -1
- package/ccw/frontend/dist/assets/{plug-9dAARpE1.js → plug-CZ0aL_yF.js} +2 -2
- package/ccw/frontend/dist/assets/{plug-9dAARpE1.js.map → plug-CZ0aL_yF.js.map} +1 -1
- package/ccw/frontend/dist/assets/{power-K2S39x7f.js → power-F2A_J4l6.js} +2 -2
- package/ccw/frontend/dist/assets/{power-K2S39x7f.js.map → power-F2A_J4l6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{save-D9-CoT3x.js → save-Byxot0YU.js} +2 -2
- package/ccw/frontend/dist/assets/{save-D9-CoT3x.js.map → save-Byxot0YU.js.map} +1 -1
- package/ccw/frontend/dist/assets/{send-Bunw9NtC.js → send-JjqhUkpw.js} +2 -2
- package/ccw/frontend/dist/assets/{send-Bunw9NtC.js.map → send-JjqhUkpw.js.map} +1 -1
- package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js → settings-2--SuN9rAt.js} +2 -2
- package/ccw/frontend/dist/assets/{settings-2-osl4EXFf.js.map → settings-2--SuN9rAt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js → square-check-big-BbngGB2h.js} +2 -2
- package/ccw/frontend/dist/assets/{square-check-big-Dl5gYkjR.js.map → square-check-big-BbngGB2h.js.map} +1 -1
- package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js → square-pen-CgrHgZSl.js} +2 -2
- package/ccw/frontend/dist/assets/{square-pen-Bue1chJR.js.map → square-pen-CgrHgZSl.js.map} +1 -1
- package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js → star-BU3TQr7Z.js} +2 -2
- package/ccw/frontend/dist/assets/{star-Bk7EC7FB.js.map → star-BU3TQr7Z.js.map} +1 -1
- package/ccw/frontend/dist/assets/{style-BbREPmRj.js → style-CKs7nnn3.js} +2 -2
- package/ccw/frontend/dist/assets/{style-BbREPmRj.js.map → style-CKs7nnn3.js.map} +1 -1
- package/ccw/frontend/dist/assets/{target-CElrCVhR.js → target-DW5tsDW6.js} +2 -2
- package/ccw/frontend/dist/assets/{target-CElrCVhR.js.map → target-DW5tsDW6.js.map} +1 -1
- package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js → test-tube-BHm7w3ON.js} +2 -2
- package/ccw/frontend/dist/assets/{test-tube-wciJaoas.js.map → test-tube-BHm7w3ON.js.map} +1 -1
- package/ccw/frontend/dist/assets/{upload-BD1F07wG.js → upload-DYR7PWwt.js} +2 -2
- package/ccw/frontend/dist/assets/{upload-BD1F07wG.js.map → upload-DYR7PWwt.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js → useApiSettings-D0TVgQD_.js} +2 -2
- package/ccw/frontend/dist/assets/{useApiSettings-D23HVEt8.js.map → useApiSettings-D0TVgQD_.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js → useCli-DfY8mAP8.js} +2 -2
- package/ccw/frontend/dist/assets/{useCli-BGDd_lXD.js.map → useCli-DfY8mAP8.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js → useCommands-CGusDp0F.js} +2 -2
- package/ccw/frontend/dist/assets/{useCommands-B-m_HxPB.js.map → useCommands-CGusDp0F.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js → useDebounce-CIwh0fF1.js} +2 -2
- package/ccw/frontend/dist/assets/{useDebounce-Z18-PHZr.js.map → useDebounce-CIwh0fF1.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js → useFileExplorer-FMyFv39K.js} +2 -2
- package/ccw/frontend/dist/assets/{useFileExplorer-D4gPp-LB.js.map → useFileExplorer-FMyFv39K.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js → useLocale-B2qhsoTb.js} +2 -2
- package/ccw/frontend/dist/assets/{useLocale-DJ62jjFa.js.map → useLocale-B2qhsoTb.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js → useSkills-cxKXMBm3.js} +3 -3
- package/ccw/frontend/dist/assets/{useSkills-B8NPs9__.js.map → useSkills-cxKXMBm3.js.map} +1 -1
- package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js → useSystemSettings-B-xUT_z-.js} +2 -2
- package/ccw/frontend/dist/assets/{useSystemSettings-CVi7nKGJ.js.map → useSystemSettings-B-xUT_z-.js.map} +1 -1
- package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js → wand-sparkles-DZV_3lPr.js} +2 -2
- package/ccw/frontend/dist/assets/{wand-sparkles-CLjPiU5w.js.map → wand-sparkles-DZV_3lPr.js.map} +1 -1
- package/ccw/frontend/dist/index.html +1 -1
- package/package.json +105 -105
- package/ccw/frontend/dist/assets/SettingsPage-BPDbXPSM.js.map +0 -1
package/ccw/frontend/dist/assets/{RulesManagerPage-Cayfywqi.js → RulesManagerPage-CdBjTmth.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e,C as re,a as ne,c as R,u as V,aS as oe,B as y,D as ce,d as de,e as x,f as me,g as L,h as q,T as Te,af as ue,av as Ee,aw as Ie,m as xe,aF as Le,r as d,aH as X,x as he,y as ge,z as fe,A as pe,E as je,I as S,aq as Y,ar as J,as as Z,at as ee,au as se,G as ve,dx as Pe,dy as Ae,o as ae,s as qe,R as Oe,a7 as te,a2 as Ve,a3 as ze,a4 as A,b as Qe,X as T,v as Ue}from"./index-Dff4bg3u.js";import{r as le,l as $e,m as Ge,n as Ke,o as Be}from"./useCli-BGDd_lXD.js";import{S as _e}from"./Switch-BpB9h__9.js";import{F as O}from"./folder-BaWZWn_r.js";import{E as He}from"./ellipsis-vertical-CbNlw2gS.js";import{S as We}from"./square-pen-Bue1chJR.js";import{T as Xe}from"./TabsNavigation-BGsKy7DO.js";import{M as Ye,a as Je}from"./minimize-2-DO-zbT3a.js";import{G as Ze}from"./globe-BuHeEjxd.js";import{F as es}from"./filter-BOe-OTu1.js";import"./useLocale-DJ62jjFa.js";import"./errorSanitizer-IY9pf5g4.js";const ss={error:{variant:"destructive",icon:e.jsx(xe,{className:"h-3 w-3"})},warning:{variant:"warning",icon:e.jsx(Ie,{className:"h-3 w-3"})},info:{variant:"info",icon:e.jsx(Ee,{className:"h-3 w-3"})}},as={error:"rules.severity.error",warning:"rules.severity.warning",info:"rules.severity.info"};function ts({rule:s,onEdit:r,onDelete:h,onToggle:m,className:u,showActions:i=!0,actionsDisabled:p=!1}){const{formatMessage:l}=V(),{variant:g,icon:c}=ss[s.severity||"info"]||{variant:"default",icon:null},b=s.severity?l({id:as[s.severity]}):null,k=s.location==="user"?e.jsx(oe,{className:"h-3 w-3"}):e.jsx(O,{className:"h-3 w-3"}),j=o=>{m==null||m(s.id,o)},v=(o,D)=>{switch(o.stopPropagation(),D){case"edit":r==null||r(s);break;case"delete":h==null||h(s.id);break}};return e.jsx(re,{className:R("group transition-all duration-200 hover:shadow-md hover:border-primary/30 hover-glow",!s.enabled&&"opacity-60",u),children:e.jsxs(ne,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-medium text-card-foreground truncate",children:s.name}),e.jsx("div",{className:"flex items-center gap-1 text-muted-foreground",title:l({id:s.location==="user"?"rules.location.user":"rules.location.project"}),children:k})]}),s.category&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:s.category})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[s.enabled&&s.severity&&e.jsxs(y,{variant:g,className:"gap-1",children:[c,b]}),e.jsx(_e,{checked:s.enabled,onCheckedChange:j,disabled:p,className:"data-[state=checked]:bg-primary"}),i&&e.jsxs(ce,{children:[e.jsx(de,{asChild:!0,children:e.jsxs(x,{variant:"ghost",size:"icon",className:"h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity",onClick:o=>o.stopPropagation(),disabled:p,children:[e.jsx(He,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:l({id:"common.aria.actions"})})]})}),e.jsxs(me,{align:"end",children:[e.jsxs(L,{onClick:o=>v(o,"edit"),children:[e.jsx(We,{className:"mr-2 h-4 w-4"}),l({id:"rules.actions.edit"})]}),e.jsx(q,{}),e.jsxs(L,{onClick:o=>v(o,"delete"),className:"text-destructive focus:text-destructive",children:[e.jsx(Te,{className:"mr-2 h-4 w-4"}),l({id:"rules.actions.delete"})]})]})]})]})]}),s.description&&e.jsx("p",{className:"mt-3 text-sm text-muted-foreground line-clamp-2",children:s.description}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground",children:[s.pattern&&e.jsxs("span",{className:"flex items-center gap-1 font-mono",children:[e.jsx(ue,{className:"h-3.5 w-3.5"}),s.pattern]}),s.subdirectory&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(O,{className:"h-3.5 w-3.5"}),s.subdirectory]})]})]})})}function ls({className:s}){return e.jsx(re,{className:R("animate-pulse",s),children:e.jsxs(ne,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"h-5 w-32 rounded bg-muted"}),e.jsx("div",{className:"mt-1 h-3 w-24 rounded bg-muted"})]}),e.jsx("div",{className:"h-5 w-8 rounded-full bg-muted"}),e.jsx("div",{className:"h-8 w-8 rounded bg-muted"})]}),e.jsx("div",{className:"mt-3 h-4 w-full rounded bg-muted"}),e.jsxs("div",{className:"mt-2 flex gap-4",children:[e.jsx("div",{className:"h-3 w-20 rounded bg-muted"}),e.jsx("div",{className:"h-3 w-16 rounded bg-muted"})]})]})})}const is=["coding","testing","security","architecture","documentation","performance","workflow","tooling","general"],rs=["error","warning","info"];function ie({mode:s,rule:r,open:h,onClose:m,onSave:u}){const{formatMessage:i}=V(),p=Le(),[l,g]=d.useState({name:"",description:"",enabled:!0,category:"general",severity:"info",fileName:"",location:"project",subdirectory:"",content:"",pattern:""}),[c,b]=d.useState({});d.useEffect(()=>{var t;g(r&&s==="edit"?{name:r.name,description:r.description||"",enabled:r.enabled,category:r.category||"general",severity:r.severity||"info",fileName:((t=r.path)==null?void 0:t.split(/[/\\]/).pop())||`${r.name.toLowerCase().replace(/\s+/g,"-")}.md`,location:r.location||"project",subdirectory:r.subdirectory||"",content:"",pattern:r.pattern||""}:{name:"",description:"",enabled:!0,category:"general",severity:"info",fileName:"",location:"project",subdirectory:"",content:"",pattern:""}),b({})},[r,s,h]);const k=X({mutationFn:t=>Pe(t),onSuccess:()=>{p.invalidateQueries({queryKey:le.all}),v(),u==null||u()}}),j=X({mutationFn:({ruleId:t,config:N})=>Ae(t,N),onSuccess:()=>{p.invalidateQueries({queryKey:le.all}),v(),u==null||u()}}),v=()=>{b({}),m()},o=(t,N)=>{g(w=>({...w,[t]:N})),c[t]&&b(w=>({...w,[t]:void 0}))};d.useEffect(()=>{if(l.name&&!l.fileName){const t=`${l.name.toLowerCase().replace(/\s+/g,"-")}.md`;g(N=>({...N,fileName:t}))}},[l.name,l.fileName]);const D=()=>{const t={};return l.name.trim()||(t.name=i({id:"rules.dialog.validation.nameRequired"})),l.fileName.trim()||(t.fileName=i({id:"rules.dialog.validation.fileNameRequired"})),l.fileName&&!l.fileName.endsWith(".md")&&(t.fileName=i({id:"rules.dialog.validation.fileNameMd"})),l.location||(t.location=i({id:"rules.dialog.validation.locationRequired"})),s==="add"&&!l.content.trim()&&(t.content=i({id:"rules.dialog.validation.contentRequired"})),b(t),Object.keys(t).length===0},F=async()=>{if(D())if(s==="add"){const t={name:l.name.trim(),description:l.description.trim()||void 0,enabled:l.enabled,category:l.category||void 0,severity:l.severity,fileName:l.fileName.trim(),location:l.location,subdirectory:l.subdirectory.trim()||void 0,content:l.content.trim(),pattern:l.pattern.trim()||void 0};k.mutate(t)}else j.mutate({ruleId:r.id,config:{name:l.name.trim(),description:l.description.trim()||void 0,enabled:l.enabled,category:l.category||void 0,severity:l.severity,pattern:l.pattern.trim()||void 0}})},M=k.isPending||j.isPending;return e.jsx(he,{open:h,onOpenChange:v,children:e.jsxs(ge,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(fe,{children:[e.jsx(pe,{children:s==="add"?i({id:"rules.dialog.addTitle"}):i({id:"rules.dialog.editTitle"},{name:r==null?void 0:r.name})}),e.jsx(je,{children:i({id:"rules.dialog.description"})})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.name"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsx(S,{value:l.name,onChange:t=>o("name",t.target.value),placeholder:i({id:"rules.dialog.form.namePlaceholder"}),error:!!c.name}),c.name&&e.jsx("p",{className:"text-sm text-destructive",children:c.name})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.description"})}),e.jsx(S,{value:l.description,onChange:t=>o("description",t.target.value),placeholder:i({id:"rules.dialog.form.descriptionPlaceholder"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.category"})}),e.jsxs(Y,{value:l.category,onValueChange:t=>o("category",t),children:[e.jsx(J,{children:e.jsx(Z,{})}),e.jsx(ee,{children:is.map(t=>e.jsx(se,{value:t,children:t.charAt(0).toUpperCase()+t.slice(1)},t))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.severity"})}),e.jsxs(Y,{value:l.severity,onValueChange:t=>o("severity",t),children:[e.jsx(J,{children:e.jsx(Z,{})}),e.jsx(ee,{children:rs.map(t=>e.jsx(se,{value:t,children:i({id:`rules.severity.${t}`})},t))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.fileName"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsx(S,{value:l.fileName,onChange:t=>o("fileName",t.target.value),placeholder:"rule-name.md",error:!!c.fileName}),c.fileName&&e.jsx("p",{className:"text-sm text-destructive",children:c.fileName})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.location"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"location",value:"project",checked:l.location==="project",onChange:t=>o("location",t.target.value),className:"w-4 h-4"}),e.jsx("span",{className:"text-sm",children:i({id:"rules.location.project"})})]}),e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"location",value:"user",checked:l.location==="user",onChange:t=>o("location",t.target.value),className:"w-4 h-4"}),e.jsx("span",{className:"text-sm",children:i({id:"rules.location.user"})})]})]}),c.location&&e.jsx("p",{className:"text-sm text-destructive",children:c.location})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.subdirectory"})}),e.jsx(S,{value:l.subdirectory,onChange:t=>o("subdirectory",t.target.value),placeholder:i({id:"rules.dialog.form.subdirectoryPlaceholder"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.pattern"})}),e.jsx(S,{value:l.pattern,onChange:t=>o("pattern",t.target.value),placeholder:i({id:"rules.dialog.form.patternPlaceholder"})})]}),s==="add"&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.content"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsx("textarea",{value:l.content,onChange:t=>o("content",t.target.value),placeholder:i({id:"rules.dialog.form.contentPlaceholder"}),className:R("flex min-h-[150px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",c.content&&"border-destructive focus-visible:ring-destructive")}),c.content&&e.jsx("p",{className:"text-sm text-destructive",children:c.content})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"checkbox",id:"enabled",checked:l.enabled,onChange:t=>o("enabled",t.target.checked),className:"w-4 h-4"}),e.jsx("label",{htmlFor:"enabled",className:"text-sm font-medium text-foreground cursor-pointer",children:i({id:"rules.dialog.form.enabled"})})]})]}),e.jsxs(ve,{children:[e.jsx(x,{variant:"outline",onClick:v,disabled:M,children:i({id:"common.actions.cancel"})}),e.jsx(x,{onClick:F,disabled:M,children:i(M?{id:"rules.dialog.actions.saving"}:{id:"common.actions.save"})})]})]})})}function vs(){const{formatMessage:s}=V(),[r,h]=d.useState("all"),[m,u]=d.useState("all"),[i,p]=d.useState(""),[l,g]=d.useState([]),c=ae(qe),b=ae(a=>a.toggleImmersiveMode),[k,j]=d.useState(!1),[v,o]=d.useState(!1),[D,F]=d.useState(!1),[M,t]=d.useState(null),[N,w]=d.useState(null),{rules:f,isLoading:Ne,isFetching:z,error:Q,refetch:U}=$e(),{isCreating:ye}=Ge(),{deleteRule:be,isDeleting:P}=Ke(),{toggleRule:we,isToggling:Ce}=Be(),E=ye||P||Ce,$=d.useMemo(()=>{let a=f;if(r==="enabled"?a=a.filter(n=>n.enabled):r==="disabled"&&(a=a.filter(n=>!n.enabled)),m==="project"?a=a.filter(n=>n.location==="project"):m==="user"&&(a=a.filter(n=>n.location==="user")),l.length>0&&(a=a.filter(n=>n.category?l.includes(n.category):!1)),i){const n=i.toLowerCase();a=a.filter(C=>{var H,W;return C.name.toLowerCase().includes(n)||((H=C.description)==null?void 0:H.toLowerCase().includes(n))||((W=C.category)==null?void 0:W.toLowerCase().includes(n))})}return a},[f,r,m,l,i]),G=d.useMemo(()=>{const a=new Set;return f.forEach(n=>{n.category&&a.add(n.category)}),Array.from(a).sort()},[f]),ke=d.useMemo(()=>f.filter(a=>a.location==="project").length,[f]),Fe=d.useMemo(()=>f.filter(a=>a.location==="user").length,[f]),Se=a=>{t(a),o(!0)},Re=a=>{w(a),F(!0)},De=async()=>{if(N)try{const a=f.find(n=>n.id===N);await be(N,a==null?void 0:a.location),F(!1),w(null)}catch(a){console.error("Failed to delete rule:",a)}},Me=async(a,n)=>{try{await we(a,n)}catch(C){console.error("Failed to toggle rule:",C)}},K=()=>{p("")},B=a=>{g(n=>n.includes(a)?n.filter(C=>C!==a):[...n,a])},_=()=>{h("all"),u("all"),g([]),p("")},I=r!=="all"||m!=="all"||l.length>0||i.length>0;return e.jsxs("div",{className:R("space-y-6",c&&"h-screen overflow-hidden"),children:[e.jsxs("div",{className:"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:s({id:"rules.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:s({id:"rules.description"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:b,className:R("p-2 rounded-md transition-colors",c?"bg-primary/10 text-primary":"text-muted-foreground hover:text-foreground hover:bg-muted"),title:c?"Exit Fullscreen":"Fullscreen",children:c?e.jsx(Ye,{className:"w-4 h-4"}):e.jsx(Je,{className:"w-4 h-4"})}),e.jsxs(x,{variant:"outline",size:"sm",onClick:()=>U(),disabled:z,children:[e.jsx(Oe,{className:R("h-4 w-4 mr-2",z&&"animate-spin")}),s({id:"common.actions.refresh"})]}),e.jsxs(x,{size:"sm",onClick:()=>j(!0),children:[e.jsx(te,{className:"h-4 w-4 mr-2"}),s({id:"common.actions.new"})]})]})]}),Q&&e.jsxs("div",{className:"flex items-center gap-2 p-4 rounded-lg bg-destructive/10 border border-destructive/30 text-destructive",children:[e.jsx(xe,{className:"h-5 w-5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-sm font-medium",children:s({id:"common.errors.loadFailed"})}),e.jsx("p",{className:"text-xs mt-0.5",children:Q.message})]}),e.jsx(x,{variant:"outline",size:"sm",onClick:()=>U(),children:s({id:"home.errors.retry"})})]}),e.jsx(Xe,{value:m,onValueChange:a=>u(a),tabs:[{value:"all",label:s({id:"rules.filters.all"}),icon:e.jsx(Ze,{className:"h-4 w-4"}),badge:e.jsx(y,{variant:"secondary",className:"ml-2",children:f.length}),disabled:E},{value:"project",label:s({id:"rules.location.project"}),icon:e.jsx(O,{className:"h-4 w-4"}),badge:e.jsx(y,{variant:"secondary",className:"ml-2",children:ke}),disabled:E},{value:"user",label:s({id:"rules.location.user"}),icon:e.jsx(oe,{className:"h-4 w-4"}),badge:e.jsx(y,{variant:"secondary",className:"ml-2",children:Fe}),disabled:E}]}),e.jsxs("div",{className:"flex flex-col gap-4 sm:flex-row sm:items-center",children:[e.jsx(Ve,{value:r,onValueChange:a=>h(a),children:e.jsxs(ze,{children:[e.jsx(A,{value:"all",children:s({id:"rules.filters.all"})}),e.jsx(A,{value:"enabled",children:s({id:"rules.filters.enabled"})}),e.jsx(A,{value:"disabled",children:s({id:"rules.filters.disabled"})})]})}),e.jsxs("div",{className:"flex-1 max-w-sm relative",children:[e.jsx(Qe,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(S,{placeholder:s({id:"rules.searchPlaceholder"}),value:i,onChange:a=>p(a.target.value),className:"pl-9 pr-9"}),i&&e.jsx("button",{onClick:K,className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",children:e.jsx(T,{className:"h-4 w-4"})})]}),G.length>0&&e.jsxs(ce,{children:[e.jsx(de,{asChild:!0,children:e.jsxs(x,{variant:"outline",size:"sm",className:"gap-2",children:[e.jsx(es,{className:"h-4 w-4"}),s({id:"rules.filters.category"}),l.length>0&&e.jsx(y,{variant:"secondary",className:"ml-1 h-5 min-w-5 px-1",children:l.length})]})}),e.jsxs(me,{align:"end",className:"w-48",children:[e.jsx(Ue,{children:s({id:"rules.dialog.form.category"})}),e.jsx(q,{}),G.map(a=>e.jsxs(L,{onClick:()=>B(a),className:"justify-between",children:[e.jsx("span",{children:a.charAt(0).toUpperCase()+a.slice(1)}),l.includes(a)&&e.jsx("span",{className:"text-primary",children:"✓"})]},a)),l.length>0&&e.jsxs(e.Fragment,{children:[e.jsx(q,{}),e.jsx(L,{onClick:()=>g([]),className:"text-destructive",children:s({id:"common.actions.clearFilters"})})]})]})]})]}),I&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[s({id:"common.actions.filters"}),":"]}),r!=="all"&&e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:()=>h("all"),children:[s({id:`rules.filters.${r}`}),e.jsx(T,{className:"ml-1 h-3 w-3"})]}),m!=="all"&&e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:()=>u("all"),children:[s({id:`rules.location.${m}`}),e.jsx(T,{className:"ml-1 h-3 w-3"})]}),l.map(a=>e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:()=>B(a),children:[a.charAt(0).toUpperCase()+a.slice(1),e.jsx(T,{className:"ml-1 h-3 w-3"})]},a)),i&&e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:K,children:[s({id:"common.actions.search"}),": ",i,e.jsx(T,{className:"ml-1 h-3 w-3"})]}),e.jsx(x,{variant:"ghost",size:"sm",onClick:_,className:"h-6 text-xs",children:s({id:"common.actions.clearAll"})})]}),Ne?e.jsx("div",{className:"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3",children:Array.from({length:9}).map((a,n)=>e.jsx(ls,{},n))}):$.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg",children:[e.jsx(ue,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium text-foreground mb-1",children:s(I?{id:"rules.emptyState.title"}:{id:"rules.emptyState.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground text-center max-w-sm mb-4",children:s(I?{id:"rules.emptyState.message"}:{id:"rules.emptyState.createFirst"})}),I?e.jsx(x,{variant:"outline",onClick:_,children:s({id:"common.actions.clearFilters"})}):e.jsxs(x,{onClick:()=>j(!0),children:[e.jsx(te,{className:"h-4 w-4 mr-2"}),s({id:"common.actions.new"})]})]}):e.jsx("div",{className:"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3",children:$.map(a=>e.jsx(ts,{rule:a,onEdit:Se,onDelete:Re,onToggle:Me,actionsDisabled:E},a.id))}),e.jsx(ie,{mode:"add",open:k,onClose:()=>j(!1),onSave:()=>j(!1)}),e.jsx(ie,{mode:"edit",rule:M||void 0,open:v,onClose:()=>{o(!1),t(null)},onSave:()=>{o(!1),t(null)}}),e.jsx(he,{open:D,onOpenChange:F,children:e.jsxs(ge,{children:[e.jsxs(fe,{children:[e.jsx(pe,{children:s({id:"rules.dialog.deleteTitle"})}),e.jsx(je,{children:s({id:"rules.dialog.deleteConfirm"})})]}),e.jsxs(ve,{children:[e.jsx(x,{variant:"outline",onClick:()=>{F(!1),w(null)},children:s({id:"common.actions.cancel"})}),e.jsx(x,{variant:"destructive",onClick:De,disabled:P,children:s(P?{id:"rules.status.deleting"}:{id:"common.actions.delete"})})]})]})})]})}export{vs as RulesManagerPage,vs as default};
|
|
2
|
-
//# sourceMappingURL=RulesManagerPage-
|
|
1
|
+
import{j as e,C as re,a as ne,c as R,u as V,aS as oe,B as y,D as ce,d as de,e as x,f as me,g as L,h as q,T as Te,af as ue,av as Ee,aw as Ie,m as xe,aF as Le,r as d,aH as X,x as he,y as ge,z as fe,A as pe,E as je,I as S,aq as Y,ar as J,as as Z,at as ee,au as se,G as ve,dx as Pe,dy as Ae,o as ae,s as qe,R as Oe,a7 as te,a2 as Ve,a3 as ze,a4 as A,b as Qe,X as T,v as Ue}from"./index-rLgoBCfV.js";import{r as le,l as $e,m as Ge,n as Ke,o as Be}from"./useCli-DfY8mAP8.js";import{S as _e}from"./Switch-Ac6Ov7uy.js";import{F as O}from"./folder-CL6vb42J.js";import{E as He}from"./ellipsis-vertical-h8xtvw2_.js";import{S as We}from"./square-pen-CgrHgZSl.js";import{T as Xe}from"./TabsNavigation-DZAAspqR.js";import{M as Ye,a as Je}from"./minimize-2-CtkoJXcz.js";import{G as Ze}from"./globe-BQbwyNeV.js";import{F as es}from"./filter-q9g-bknU.js";import"./useLocale-B2qhsoTb.js";import"./errorSanitizer-IY9pf5g4.js";const ss={error:{variant:"destructive",icon:e.jsx(xe,{className:"h-3 w-3"})},warning:{variant:"warning",icon:e.jsx(Ie,{className:"h-3 w-3"})},info:{variant:"info",icon:e.jsx(Ee,{className:"h-3 w-3"})}},as={error:"rules.severity.error",warning:"rules.severity.warning",info:"rules.severity.info"};function ts({rule:s,onEdit:r,onDelete:h,onToggle:m,className:u,showActions:i=!0,actionsDisabled:p=!1}){const{formatMessage:l}=V(),{variant:g,icon:c}=ss[s.severity||"info"]||{variant:"default",icon:null},b=s.severity?l({id:as[s.severity]}):null,k=s.location==="user"?e.jsx(oe,{className:"h-3 w-3"}):e.jsx(O,{className:"h-3 w-3"}),j=o=>{m==null||m(s.id,o)},v=(o,D)=>{switch(o.stopPropagation(),D){case"edit":r==null||r(s);break;case"delete":h==null||h(s.id);break}};return e.jsx(re,{className:R("group transition-all duration-200 hover:shadow-md hover:border-primary/30 hover-glow",!s.enabled&&"opacity-60",u),children:e.jsxs(ne,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h3",{className:"font-medium text-card-foreground truncate",children:s.name}),e.jsx("div",{className:"flex items-center gap-1 text-muted-foreground",title:l({id:s.location==="user"?"rules.location.user":"rules.location.project"}),children:k})]}),s.category&&e.jsx("p",{className:"text-xs text-muted-foreground mt-0.5",children:s.category})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-shrink-0",children:[s.enabled&&s.severity&&e.jsxs(y,{variant:g,className:"gap-1",children:[c,b]}),e.jsx(_e,{checked:s.enabled,onCheckedChange:j,disabled:p,className:"data-[state=checked]:bg-primary"}),i&&e.jsxs(ce,{children:[e.jsx(de,{asChild:!0,children:e.jsxs(x,{variant:"ghost",size:"icon",className:"h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity",onClick:o=>o.stopPropagation(),disabled:p,children:[e.jsx(He,{className:"h-4 w-4"}),e.jsx("span",{className:"sr-only",children:l({id:"common.aria.actions"})})]})}),e.jsxs(me,{align:"end",children:[e.jsxs(L,{onClick:o=>v(o,"edit"),children:[e.jsx(We,{className:"mr-2 h-4 w-4"}),l({id:"rules.actions.edit"})]}),e.jsx(q,{}),e.jsxs(L,{onClick:o=>v(o,"delete"),className:"text-destructive focus:text-destructive",children:[e.jsx(Te,{className:"mr-2 h-4 w-4"}),l({id:"rules.actions.delete"})]})]})]})]})]}),s.description&&e.jsx("p",{className:"mt-3 text-sm text-muted-foreground line-clamp-2",children:s.description}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground",children:[s.pattern&&e.jsxs("span",{className:"flex items-center gap-1 font-mono",children:[e.jsx(ue,{className:"h-3.5 w-3.5"}),s.pattern]}),s.subdirectory&&e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsx(O,{className:"h-3.5 w-3.5"}),s.subdirectory]})]})]})})}function ls({className:s}){return e.jsx(re,{className:R("animate-pulse",s),children:e.jsxs(ne,{className:"p-4",children:[e.jsxs("div",{className:"flex items-start justify-between",children:[e.jsxs("div",{className:"flex-1",children:[e.jsx("div",{className:"h-5 w-32 rounded bg-muted"}),e.jsx("div",{className:"mt-1 h-3 w-24 rounded bg-muted"})]}),e.jsx("div",{className:"h-5 w-8 rounded-full bg-muted"}),e.jsx("div",{className:"h-8 w-8 rounded bg-muted"})]}),e.jsx("div",{className:"mt-3 h-4 w-full rounded bg-muted"}),e.jsxs("div",{className:"mt-2 flex gap-4",children:[e.jsx("div",{className:"h-3 w-20 rounded bg-muted"}),e.jsx("div",{className:"h-3 w-16 rounded bg-muted"})]})]})})}const is=["coding","testing","security","architecture","documentation","performance","workflow","tooling","general"],rs=["error","warning","info"];function ie({mode:s,rule:r,open:h,onClose:m,onSave:u}){const{formatMessage:i}=V(),p=Le(),[l,g]=d.useState({name:"",description:"",enabled:!0,category:"general",severity:"info",fileName:"",location:"project",subdirectory:"",content:"",pattern:""}),[c,b]=d.useState({});d.useEffect(()=>{var t;g(r&&s==="edit"?{name:r.name,description:r.description||"",enabled:r.enabled,category:r.category||"general",severity:r.severity||"info",fileName:((t=r.path)==null?void 0:t.split(/[/\\]/).pop())||`${r.name.toLowerCase().replace(/\s+/g,"-")}.md`,location:r.location||"project",subdirectory:r.subdirectory||"",content:"",pattern:r.pattern||""}:{name:"",description:"",enabled:!0,category:"general",severity:"info",fileName:"",location:"project",subdirectory:"",content:"",pattern:""}),b({})},[r,s,h]);const k=X({mutationFn:t=>Pe(t),onSuccess:()=>{p.invalidateQueries({queryKey:le.all}),v(),u==null||u()}}),j=X({mutationFn:({ruleId:t,config:N})=>Ae(t,N),onSuccess:()=>{p.invalidateQueries({queryKey:le.all}),v(),u==null||u()}}),v=()=>{b({}),m()},o=(t,N)=>{g(w=>({...w,[t]:N})),c[t]&&b(w=>({...w,[t]:void 0}))};d.useEffect(()=>{if(l.name&&!l.fileName){const t=`${l.name.toLowerCase().replace(/\s+/g,"-")}.md`;g(N=>({...N,fileName:t}))}},[l.name,l.fileName]);const D=()=>{const t={};return l.name.trim()||(t.name=i({id:"rules.dialog.validation.nameRequired"})),l.fileName.trim()||(t.fileName=i({id:"rules.dialog.validation.fileNameRequired"})),l.fileName&&!l.fileName.endsWith(".md")&&(t.fileName=i({id:"rules.dialog.validation.fileNameMd"})),l.location||(t.location=i({id:"rules.dialog.validation.locationRequired"})),s==="add"&&!l.content.trim()&&(t.content=i({id:"rules.dialog.validation.contentRequired"})),b(t),Object.keys(t).length===0},F=async()=>{if(D())if(s==="add"){const t={name:l.name.trim(),description:l.description.trim()||void 0,enabled:l.enabled,category:l.category||void 0,severity:l.severity,fileName:l.fileName.trim(),location:l.location,subdirectory:l.subdirectory.trim()||void 0,content:l.content.trim(),pattern:l.pattern.trim()||void 0};k.mutate(t)}else j.mutate({ruleId:r.id,config:{name:l.name.trim(),description:l.description.trim()||void 0,enabled:l.enabled,category:l.category||void 0,severity:l.severity,pattern:l.pattern.trim()||void 0}})},M=k.isPending||j.isPending;return e.jsx(he,{open:h,onOpenChange:v,children:e.jsxs(ge,{className:"max-w-2xl max-h-[90vh] overflow-y-auto",children:[e.jsxs(fe,{children:[e.jsx(pe,{children:s==="add"?i({id:"rules.dialog.addTitle"}):i({id:"rules.dialog.editTitle"},{name:r==null?void 0:r.name})}),e.jsx(je,{children:i({id:"rules.dialog.description"})})]}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.name"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsx(S,{value:l.name,onChange:t=>o("name",t.target.value),placeholder:i({id:"rules.dialog.form.namePlaceholder"}),error:!!c.name}),c.name&&e.jsx("p",{className:"text-sm text-destructive",children:c.name})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.description"})}),e.jsx(S,{value:l.description,onChange:t=>o("description",t.target.value),placeholder:i({id:"rules.dialog.form.descriptionPlaceholder"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.category"})}),e.jsxs(Y,{value:l.category,onValueChange:t=>o("category",t),children:[e.jsx(J,{children:e.jsx(Z,{})}),e.jsx(ee,{children:is.map(t=>e.jsx(se,{value:t,children:t.charAt(0).toUpperCase()+t.slice(1)},t))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.severity"})}),e.jsxs(Y,{value:l.severity,onValueChange:t=>o("severity",t),children:[e.jsx(J,{children:e.jsx(Z,{})}),e.jsx(ee,{children:rs.map(t=>e.jsx(se,{value:t,children:i({id:`rules.severity.${t}`})},t))})]})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.fileName"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsx(S,{value:l.fileName,onChange:t=>o("fileName",t.target.value),placeholder:"rule-name.md",error:!!c.fileName}),c.fileName&&e.jsx("p",{className:"text-sm text-destructive",children:c.fileName})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.location"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"location",value:"project",checked:l.location==="project",onChange:t=>o("location",t.target.value),className:"w-4 h-4"}),e.jsx("span",{className:"text-sm",children:i({id:"rules.location.project"})})]}),e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"radio",name:"location",value:"user",checked:l.location==="user",onChange:t=>o("location",t.target.value),className:"w-4 h-4"}),e.jsx("span",{className:"text-sm",children:i({id:"rules.location.user"})})]})]}),c.location&&e.jsx("p",{className:"text-sm text-destructive",children:c.location})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.subdirectory"})}),e.jsx(S,{value:l.subdirectory,onChange:t=>o("subdirectory",t.target.value),placeholder:i({id:"rules.dialog.form.subdirectoryPlaceholder"})})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"text-sm font-medium text-foreground",children:i({id:"rules.dialog.form.pattern"})}),e.jsx(S,{value:l.pattern,onChange:t=>o("pattern",t.target.value),placeholder:i({id:"rules.dialog.form.patternPlaceholder"})})]}),s==="add"&&e.jsxs("div",{className:"space-y-2",children:[e.jsxs("label",{className:"text-sm font-medium text-foreground",children:[i({id:"rules.dialog.form.content"}),e.jsx("span",{className:"text-destructive ml-1",children:"*"})]}),e.jsx("textarea",{value:l.content,onChange:t=>o("content",t.target.value),placeholder:i({id:"rules.dialog.form.contentPlaceholder"}),className:R("flex min-h-[150px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",c.content&&"border-destructive focus-visible:ring-destructive")}),c.content&&e.jsx("p",{className:"text-sm text-destructive",children:c.content})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"checkbox",id:"enabled",checked:l.enabled,onChange:t=>o("enabled",t.target.checked),className:"w-4 h-4"}),e.jsx("label",{htmlFor:"enabled",className:"text-sm font-medium text-foreground cursor-pointer",children:i({id:"rules.dialog.form.enabled"})})]})]}),e.jsxs(ve,{children:[e.jsx(x,{variant:"outline",onClick:v,disabled:M,children:i({id:"common.actions.cancel"})}),e.jsx(x,{onClick:F,disabled:M,children:i(M?{id:"rules.dialog.actions.saving"}:{id:"common.actions.save"})})]})]})})}function vs(){const{formatMessage:s}=V(),[r,h]=d.useState("all"),[m,u]=d.useState("all"),[i,p]=d.useState(""),[l,g]=d.useState([]),c=ae(qe),b=ae(a=>a.toggleImmersiveMode),[k,j]=d.useState(!1),[v,o]=d.useState(!1),[D,F]=d.useState(!1),[M,t]=d.useState(null),[N,w]=d.useState(null),{rules:f,isLoading:Ne,isFetching:z,error:Q,refetch:U}=$e(),{isCreating:ye}=Ge(),{deleteRule:be,isDeleting:P}=Ke(),{toggleRule:we,isToggling:Ce}=Be(),E=ye||P||Ce,$=d.useMemo(()=>{let a=f;if(r==="enabled"?a=a.filter(n=>n.enabled):r==="disabled"&&(a=a.filter(n=>!n.enabled)),m==="project"?a=a.filter(n=>n.location==="project"):m==="user"&&(a=a.filter(n=>n.location==="user")),l.length>0&&(a=a.filter(n=>n.category?l.includes(n.category):!1)),i){const n=i.toLowerCase();a=a.filter(C=>{var H,W;return C.name.toLowerCase().includes(n)||((H=C.description)==null?void 0:H.toLowerCase().includes(n))||((W=C.category)==null?void 0:W.toLowerCase().includes(n))})}return a},[f,r,m,l,i]),G=d.useMemo(()=>{const a=new Set;return f.forEach(n=>{n.category&&a.add(n.category)}),Array.from(a).sort()},[f]),ke=d.useMemo(()=>f.filter(a=>a.location==="project").length,[f]),Fe=d.useMemo(()=>f.filter(a=>a.location==="user").length,[f]),Se=a=>{t(a),o(!0)},Re=a=>{w(a),F(!0)},De=async()=>{if(N)try{const a=f.find(n=>n.id===N);await be(N,a==null?void 0:a.location),F(!1),w(null)}catch(a){console.error("Failed to delete rule:",a)}},Me=async(a,n)=>{try{await we(a,n)}catch(C){console.error("Failed to toggle rule:",C)}},K=()=>{p("")},B=a=>{g(n=>n.includes(a)?n.filter(C=>C!==a):[...n,a])},_=()=>{h("all"),u("all"),g([]),p("")},I=r!=="all"||m!=="all"||l.length>0||i.length>0;return e.jsxs("div",{className:R("space-y-6",c&&"h-screen overflow-hidden"),children:[e.jsxs("div",{className:"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:s({id:"rules.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground mt-1",children:s({id:"rules.description"})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:b,className:R("p-2 rounded-md transition-colors",c?"bg-primary/10 text-primary":"text-muted-foreground hover:text-foreground hover:bg-muted"),title:c?"Exit Fullscreen":"Fullscreen",children:c?e.jsx(Ye,{className:"w-4 h-4"}):e.jsx(Je,{className:"w-4 h-4"})}),e.jsxs(x,{variant:"outline",size:"sm",onClick:()=>U(),disabled:z,children:[e.jsx(Oe,{className:R("h-4 w-4 mr-2",z&&"animate-spin")}),s({id:"common.actions.refresh"})]}),e.jsxs(x,{size:"sm",onClick:()=>j(!0),children:[e.jsx(te,{className:"h-4 w-4 mr-2"}),s({id:"common.actions.new"})]})]})]}),Q&&e.jsxs("div",{className:"flex items-center gap-2 p-4 rounded-lg bg-destructive/10 border border-destructive/30 text-destructive",children:[e.jsx(xe,{className:"h-5 w-5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-sm font-medium",children:s({id:"common.errors.loadFailed"})}),e.jsx("p",{className:"text-xs mt-0.5",children:Q.message})]}),e.jsx(x,{variant:"outline",size:"sm",onClick:()=>U(),children:s({id:"home.errors.retry"})})]}),e.jsx(Xe,{value:m,onValueChange:a=>u(a),tabs:[{value:"all",label:s({id:"rules.filters.all"}),icon:e.jsx(Ze,{className:"h-4 w-4"}),badge:e.jsx(y,{variant:"secondary",className:"ml-2",children:f.length}),disabled:E},{value:"project",label:s({id:"rules.location.project"}),icon:e.jsx(O,{className:"h-4 w-4"}),badge:e.jsx(y,{variant:"secondary",className:"ml-2",children:ke}),disabled:E},{value:"user",label:s({id:"rules.location.user"}),icon:e.jsx(oe,{className:"h-4 w-4"}),badge:e.jsx(y,{variant:"secondary",className:"ml-2",children:Fe}),disabled:E}]}),e.jsxs("div",{className:"flex flex-col gap-4 sm:flex-row sm:items-center",children:[e.jsx(Ve,{value:r,onValueChange:a=>h(a),children:e.jsxs(ze,{children:[e.jsx(A,{value:"all",children:s({id:"rules.filters.all"})}),e.jsx(A,{value:"enabled",children:s({id:"rules.filters.enabled"})}),e.jsx(A,{value:"disabled",children:s({id:"rules.filters.disabled"})})]})}),e.jsxs("div",{className:"flex-1 max-w-sm relative",children:[e.jsx(Qe,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground"}),e.jsx(S,{placeholder:s({id:"rules.searchPlaceholder"}),value:i,onChange:a=>p(a.target.value),className:"pl-9 pr-9"}),i&&e.jsx("button",{onClick:K,className:"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",children:e.jsx(T,{className:"h-4 w-4"})})]}),G.length>0&&e.jsxs(ce,{children:[e.jsx(de,{asChild:!0,children:e.jsxs(x,{variant:"outline",size:"sm",className:"gap-2",children:[e.jsx(es,{className:"h-4 w-4"}),s({id:"rules.filters.category"}),l.length>0&&e.jsx(y,{variant:"secondary",className:"ml-1 h-5 min-w-5 px-1",children:l.length})]})}),e.jsxs(me,{align:"end",className:"w-48",children:[e.jsx(Ue,{children:s({id:"rules.dialog.form.category"})}),e.jsx(q,{}),G.map(a=>e.jsxs(L,{onClick:()=>B(a),className:"justify-between",children:[e.jsx("span",{children:a.charAt(0).toUpperCase()+a.slice(1)}),l.includes(a)&&e.jsx("span",{className:"text-primary",children:"✓"})]},a)),l.length>0&&e.jsxs(e.Fragment,{children:[e.jsx(q,{}),e.jsx(L,{onClick:()=>g([]),className:"text-destructive",children:s({id:"common.actions.clearFilters"})})]})]})]})]}),I&&e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsxs("span",{className:"text-sm text-muted-foreground",children:[s({id:"common.actions.filters"}),":"]}),r!=="all"&&e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:()=>h("all"),children:[s({id:`rules.filters.${r}`}),e.jsx(T,{className:"ml-1 h-3 w-3"})]}),m!=="all"&&e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:()=>u("all"),children:[s({id:`rules.location.${m}`}),e.jsx(T,{className:"ml-1 h-3 w-3"})]}),l.map(a=>e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:()=>B(a),children:[a.charAt(0).toUpperCase()+a.slice(1),e.jsx(T,{className:"ml-1 h-3 w-3"})]},a)),i&&e.jsxs(y,{variant:"secondary",className:"cursor-pointer",onClick:K,children:[s({id:"common.actions.search"}),": ",i,e.jsx(T,{className:"ml-1 h-3 w-3"})]}),e.jsx(x,{variant:"ghost",size:"sm",onClick:_,className:"h-6 text-xs",children:s({id:"common.actions.clearAll"})})]}),Ne?e.jsx("div",{className:"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3",children:Array.from({length:9}).map((a,n)=>e.jsx(ls,{},n))}):$.length===0?e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg",children:[e.jsx(ue,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium text-foreground mb-1",children:s(I?{id:"rules.emptyState.title"}:{id:"rules.emptyState.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground text-center max-w-sm mb-4",children:s(I?{id:"rules.emptyState.message"}:{id:"rules.emptyState.createFirst"})}),I?e.jsx(x,{variant:"outline",onClick:_,children:s({id:"common.actions.clearFilters"})}):e.jsxs(x,{onClick:()=>j(!0),children:[e.jsx(te,{className:"h-4 w-4 mr-2"}),s({id:"common.actions.new"})]})]}):e.jsx("div",{className:"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3",children:$.map(a=>e.jsx(ts,{rule:a,onEdit:Se,onDelete:Re,onToggle:Me,actionsDisabled:E},a.id))}),e.jsx(ie,{mode:"add",open:k,onClose:()=>j(!1),onSave:()=>j(!1)}),e.jsx(ie,{mode:"edit",rule:M||void 0,open:v,onClose:()=>{o(!1),t(null)},onSave:()=>{o(!1),t(null)}}),e.jsx(he,{open:D,onOpenChange:F,children:e.jsxs(ge,{children:[e.jsxs(fe,{children:[e.jsx(pe,{children:s({id:"rules.dialog.deleteTitle"})}),e.jsx(je,{children:s({id:"rules.dialog.deleteConfirm"})})]}),e.jsxs(ve,{children:[e.jsx(x,{variant:"outline",onClick:()=>{F(!1),w(null)},children:s({id:"common.actions.cancel"})}),e.jsx(x,{variant:"destructive",onClick:De,disabled:P,children:s(P?{id:"rules.status.deleting"}:{id:"common.actions.delete"})})]})]})})]})}export{vs as RulesManagerPage,vs as default};
|
|
2
|
+
//# sourceMappingURL=RulesManagerPage-CdBjTmth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RulesManagerPage-Cayfywqi.js","sources":["../../src/components/shared/RuleCard.tsx","../../src/components/shared/RuleDialog.tsx","../../src/pages/RulesManagerPage.tsx"],"sourcesContent":["// ========================================\r\n// RuleCard Component\r\n// ========================================\r\n// Rule card with status badge and action menu\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Switch } from '@/components/ui/Switch';\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuSeparator,\r\n} from '@/components/ui/Dropdown';\r\nimport {\r\n FileCode,\r\n MoreVertical,\r\n Edit,\r\n Trash2,\r\n Folder,\r\n User,\r\n AlertCircle,\r\n AlertTriangle,\r\n Info,\r\n} from 'lucide-react';\r\nimport type { Rule } from '@/types/store';\r\n\r\nexport interface RuleCardProps {\r\n /** Rule data */\r\n rule: Rule;\r\n /** Called when edit action is triggered */\r\n onEdit?: (rule: Rule) => void;\r\n /** Called when delete action is triggered */\r\n onDelete?: (ruleId: string) => void;\r\n /** Called when toggle enabled is triggered */\r\n onToggle?: (ruleId: string, enabled: boolean) => void;\r\n /** Optional className */\r\n className?: string;\r\n /** Show actions dropdown */\r\n showActions?: boolean;\r\n /** Disabled state for actions */\r\n actionsDisabled?: boolean;\r\n}\r\n\r\n// Severity variant configuration (without labels for i18n)\r\nconst severityVariantConfig: Record<\r\n string,\r\n { variant: 'default' | 'secondary' | 'destructive' | 'success' | 'warning' | 'info'; icon: React.ReactNode }\r\n> = {\r\n error: { variant: 'destructive' as const, icon: <AlertCircle className=\"h-3 w-3\" /> },\r\n warning: { variant: 'warning' as const, icon: <AlertTriangle className=\"h-3 w-3\" /> },\r\n info: { variant: 'info' as const, icon: <Info className=\"h-3 w-3\" /> },\r\n};\r\n\r\n// Severity label keys for i18n\r\nconst severityLabelKeys: Record<string, string> = {\r\n error: 'rules.severity.error',\r\n warning: 'rules.severity.warning',\r\n info: 'rules.severity.info',\r\n};\r\n\r\n/**\r\n * RuleCard component for displaying rule information\r\n */\r\nexport function RuleCard({\r\n rule,\r\n onEdit,\r\n onDelete,\r\n onToggle,\r\n className,\r\n showActions = true,\r\n actionsDisabled = false,\r\n}: RuleCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const { variant: severityVariant, icon: severityIcon } = severityVariantConfig[rule.severity || 'info'] || {\r\n variant: 'default' as const,\r\n icon: null,\r\n };\r\n const severityLabel = rule.severity\r\n ? formatMessage({ id: severityLabelKeys[rule.severity] })\r\n : null;\r\n\r\n const locationIcon = rule.location === 'user' ? <User className=\"h-3 w-3\" /> : <Folder className=\"h-3 w-3\" />;\r\n\r\n const handleToggle = (enabled: boolean) => {\r\n onToggle?.(rule.id, enabled);\r\n };\r\n\r\n const handleAction = (e: React.MouseEvent, action: 'edit' | 'delete') => {\r\n e.stopPropagation();\r\n switch (action) {\r\n case 'edit':\r\n onEdit?.(rule);\r\n break;\r\n case 'delete':\r\n onDelete?.(rule.id);\r\n break;\r\n }\r\n };\r\n\r\n return (\r\n <Card\r\n className={cn(\r\n 'group transition-all duration-200 hover:shadow-md hover:border-primary/30 hover-glow',\r\n !rule.enabled && 'opacity-60',\r\n className\r\n )}\r\n >\r\n <CardContent className=\"p-4\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between gap-2\">\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"font-medium text-card-foreground truncate\">\r\n {rule.name}\r\n </h3>\r\n <div className=\"flex items-center gap-1 text-muted-foreground\" title={formatMessage({ id: rule.location === 'user' ? 'rules.location.user' : 'rules.location.project' })}>\r\n {locationIcon}\r\n </div>\r\n </div>\r\n {rule.category && (\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">\r\n {rule.category}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2 flex-shrink-0\">\r\n {rule.enabled && rule.severity && (\r\n <Badge variant={severityVariant} className=\"gap-1\">\r\n {severityIcon}\r\n {severityLabel}\r\n </Badge>\r\n )}\r\n <Switch\r\n checked={rule.enabled}\r\n onCheckedChange={handleToggle}\r\n disabled={actionsDisabled}\r\n className=\"data-[state=checked]:bg-primary\"\r\n />\r\n {showActions && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity\"\r\n onClick={(e) => e.stopPropagation()}\r\n disabled={actionsDisabled}\r\n >\r\n <MoreVertical className=\"h-4 w-4\" />\r\n <span className=\"sr-only\">{formatMessage({ id: 'common.aria.actions' })}</span>\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\">\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'edit')}>\r\n <Edit className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'rules.actions.edit' })}\r\n </DropdownMenuItem>\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem\r\n onClick={(e) => handleAction(e, 'delete')}\r\n className=\"text-destructive focus:text-destructive\"\r\n >\r\n <Trash2 className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'rules.actions.delete' })}\r\n </DropdownMenuItem>\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Description */}\r\n {rule.description && (\r\n <p className=\"mt-3 text-sm text-muted-foreground line-clamp-2\">\r\n {rule.description}\r\n </p>\r\n )}\r\n\r\n {/* Meta info */}\r\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\r\n {rule.pattern && (\r\n <span className=\"flex items-center gap-1 font-mono\">\r\n <FileCode className=\"h-3.5 w-3.5\" />\r\n {rule.pattern}\r\n </span>\r\n )}\r\n {rule.subdirectory && (\r\n <span className=\"flex items-center gap-1\">\r\n <Folder className=\"h-3.5 w-3.5\" />\r\n {rule.subdirectory}\r\n </span>\r\n )}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Skeleton loader for RuleCard\r\n */\r\nexport function RuleCardSkeleton({ className }: { className?: string }) {\r\n return (\r\n <Card className={cn('animate-pulse', className)}>\r\n <CardContent className=\"p-4\">\r\n <div className=\"flex items-start justify-between\">\r\n <div className=\"flex-1\">\r\n <div className=\"h-5 w-32 rounded bg-muted\" />\r\n <div className=\"mt-1 h-3 w-24 rounded bg-muted\" />\r\n </div>\r\n <div className=\"h-5 w-8 rounded-full bg-muted\" />\r\n <div className=\"h-8 w-8 rounded bg-muted\" />\r\n </div>\r\n <div className=\"mt-3 h-4 w-full rounded bg-muted\" />\r\n <div className=\"mt-2 flex gap-4\">\r\n <div className=\"h-3 w-20 rounded bg-muted\" />\r\n <div className=\"h-3 w-16 rounded bg-muted\" />\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n","// ========================================\r\n// RuleDialog Component\r\n// ========================================\r\n// Add/Edit dialog for rule configuration\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogDescription,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Button } from '@/components/ui/Button';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n createRule,\r\n updateRule,\r\n type Rule,\r\n type RuleCreateInput,\r\n} from '@/lib/api';\r\nimport { rulesKeys } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface RuleDialogProps {\r\n mode: 'add' | 'edit';\r\n rule?: Rule;\r\n open: boolean;\r\n onClose: () => void;\r\n onSave?: () => void;\r\n}\r\n\r\ninterface RuleFormData {\r\n name: string;\r\n description: string;\r\n enabled: boolean;\r\n category: string;\r\n severity: Rule['severity'];\r\n fileName: string;\r\n location: 'project' | 'user';\r\n subdirectory: string;\r\n content: string;\r\n pattern: string;\r\n}\r\n\r\ninterface FormErrors {\r\n name?: string;\r\n fileName?: string;\r\n content?: string;\r\n location?: string;\r\n}\r\n\r\n// ========== Categories ==========\r\n\r\nconst RULE_CATEGORIES = [\r\n 'coding',\r\n 'testing',\r\n 'security',\r\n 'architecture',\r\n 'documentation',\r\n 'performance',\r\n 'workflow',\r\n 'tooling',\r\n 'general',\r\n];\r\n\r\nconst SEVERITY_LEVELS: Exclude<Rule['severity'], undefined>[] = ['error', 'warning', 'info'];\r\n\r\n// ========== Component ==========\r\n\r\nexport function RuleDialog({\r\n mode,\r\n rule,\r\n open,\r\n onClose,\r\n onSave,\r\n}: RuleDialogProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n\r\n // Form state\r\n const [formData, setFormData] = useState<RuleFormData>({\r\n name: '',\r\n description: '',\r\n enabled: true,\r\n category: 'general',\r\n severity: 'info',\r\n fileName: '',\r\n location: 'project',\r\n subdirectory: '',\r\n content: '',\r\n pattern: '',\r\n });\r\n\r\n const [errors, setErrors] = useState<FormErrors>({});\r\n\r\n // Initialize form from rule prop (edit mode)\r\n useEffect(() => {\r\n if (rule && mode === 'edit') {\r\n setFormData({\r\n name: rule.name,\r\n description: rule.description || '',\r\n enabled: rule.enabled,\r\n category: rule.category || 'general',\r\n severity: rule.severity || 'info',\r\n fileName: rule.path?.split(/[/\\\\]/).pop() || `${rule.name.toLowerCase().replace(/\\s+/g, '-')}.md`,\r\n location: rule.location || 'project',\r\n subdirectory: rule.subdirectory || '',\r\n content: '',\r\n pattern: rule.pattern || '',\r\n });\r\n } else {\r\n // Reset form for add mode\r\n setFormData({\r\n name: '',\r\n description: '',\r\n enabled: true,\r\n category: 'general',\r\n severity: 'info',\r\n fileName: '',\r\n location: 'project',\r\n subdirectory: '',\r\n content: '',\r\n pattern: '',\r\n });\r\n }\r\n setErrors({});\r\n }, [rule, mode, open]);\r\n\r\n // Mutations\r\n const createMutation = useMutation({\r\n mutationFn: (data: RuleCreateInput) => createRule(data),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: rulesKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n const updateMutation = useMutation({\r\n mutationFn: ({ ruleId, config }: { ruleId: string; config: Partial<Rule> }) =>\r\n updateRule(ruleId, config),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: rulesKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n // Handlers\r\n const handleClose = () => {\r\n setErrors({});\r\n onClose();\r\n };\r\n\r\n const handleFieldChange = (\r\n field: keyof RuleFormData,\r\n value: string | boolean | Rule['severity']\r\n ) => {\r\n setFormData((prev) => ({ ...prev, [field]: value }));\r\n // Clear error for this field\r\n if (errors[field as keyof FormErrors]) {\r\n setErrors((prev) => ({ ...prev, [field]: undefined }));\r\n }\r\n };\r\n\r\n // Auto-generate fileName from name if not set\r\n useEffect(() => {\r\n if (formData.name && !formData.fileName) {\r\n const generatedFileName = `${formData.name.toLowerCase().replace(/\\s+/g, '-')}.md`;\r\n setFormData((prev) => ({ ...prev, fileName: generatedFileName }));\r\n }\r\n }, [formData.name, formData.fileName]);\r\n\r\n const validateForm = (): boolean => {\r\n const newErrors: FormErrors = {};\r\n\r\n // Name required\r\n if (!formData.name.trim()) {\r\n newErrors.name = formatMessage({ id: 'rules.dialog.validation.nameRequired' });\r\n }\r\n\r\n // File name required\r\n if (!formData.fileName.trim()) {\r\n newErrors.fileName = formatMessage({ id: 'rules.dialog.validation.fileNameRequired' });\r\n }\r\n\r\n // File name must end with .md\r\n if (formData.fileName && !formData.fileName.endsWith('.md')) {\r\n newErrors.fileName = formatMessage({ id: 'rules.dialog.validation.fileNameMd' });\r\n }\r\n\r\n // Location required\r\n if (!formData.location) {\r\n newErrors.location = formatMessage({ id: 'rules.dialog.validation.locationRequired' });\r\n }\r\n\r\n // Content required for new rules\r\n if (mode === 'add' && !formData.content.trim()) {\r\n newErrors.content = formatMessage({ id: 'rules.dialog.validation.contentRequired' });\r\n }\r\n\r\n setErrors(newErrors);\r\n return Object.keys(newErrors).length === 0;\r\n };\r\n\r\n const handleSubmit = async () => {\r\n if (!validateForm()) {\r\n return;\r\n }\r\n\r\n if (mode === 'add') {\r\n const input: RuleCreateInput = {\r\n name: formData.name.trim(),\r\n description: formData.description.trim() || undefined,\r\n enabled: formData.enabled,\r\n category: formData.category || undefined,\r\n severity: formData.severity,\r\n fileName: formData.fileName.trim(),\r\n location: formData.location,\r\n subdirectory: formData.subdirectory.trim() || undefined,\r\n content: formData.content.trim(),\r\n pattern: formData.pattern.trim() || undefined,\r\n };\r\n createMutation.mutate(input);\r\n } else {\r\n updateMutation.mutate({\r\n ruleId: rule!.id,\r\n config: {\r\n name: formData.name.trim(),\r\n description: formData.description.trim() || undefined,\r\n enabled: formData.enabled,\r\n category: formData.category || undefined,\r\n severity: formData.severity,\r\n pattern: formData.pattern.trim() || undefined,\r\n },\r\n });\r\n }\r\n };\r\n\r\n const isPending = createMutation.isPending || updateMutation.isPending;\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleClose}>\r\n <DialogContent className=\"max-w-2xl max-h-[90vh] overflow-y-auto\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {mode === 'add'\r\n ? formatMessage({ id: 'rules.dialog.addTitle' })\r\n : formatMessage({ id: 'rules.dialog.editTitle' }, { name: rule?.name })}\r\n </DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'rules.dialog.description' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n\r\n <div className=\"space-y-4\">\r\n {/* Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.name' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.name}\r\n onChange={(e) => handleFieldChange('name', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.namePlaceholder' })}\r\n error={!!errors.name}\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n </div>\r\n\r\n {/* Description */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.description' })}\r\n </label>\r\n <Input\r\n value={formData.description}\r\n onChange={(e) => handleFieldChange('description', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.descriptionPlaceholder' })}\r\n />\r\n </div>\r\n\r\n {/* Category */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.category' })}\r\n </label>\r\n <Select value={formData.category} onValueChange={(v) => handleFieldChange('category', v)}>\r\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {RULE_CATEGORIES.map((cat) => (\r\n <SelectItem key={cat} value={cat}>\r\n {cat.charAt(0).toUpperCase() + cat.slice(1)}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Severity */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.severity' })}\r\n </label>\r\n <Select\r\n value={formData.severity}\r\n onValueChange={(v) => handleFieldChange('severity', v as Rule['severity'])}\r\n >\r\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {SEVERITY_LEVELS.map((sev) => (\r\n <SelectItem key={sev} value={sev}>\r\n {formatMessage({ id: `rules.severity.${sev}` })}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* File Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.fileName' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.fileName}\r\n onChange={(e) => handleFieldChange('fileName', e.target.value)}\r\n placeholder=\"rule-name.md\"\r\n error={!!errors.fileName}\r\n />\r\n {errors.fileName && (\r\n <p className=\"text-sm text-destructive\">{errors.fileName}</p>\r\n )}\r\n </div>\r\n\r\n {/* Location */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.location' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"location\"\r\n value=\"project\"\r\n checked={formData.location === 'project'}\r\n onChange={(e) => handleFieldChange('location', e.target.value as 'project' | 'user')}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'rules.location.project' })}\r\n </span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"location\"\r\n value=\"user\"\r\n checked={formData.location === 'user'}\r\n onChange={(e) => handleFieldChange('location', e.target.value as 'project' | 'user')}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'rules.location.user' })}\r\n </span>\r\n </label>\r\n </div>\r\n {errors.location && (\r\n <p className=\"text-sm text-destructive\">{errors.location}</p>\r\n )}\r\n </div>\r\n\r\n {/* Subdirectory */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.subdirectory' })}\r\n </label>\r\n <Input\r\n value={formData.subdirectory}\r\n onChange={(e) => handleFieldChange('subdirectory', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.subdirectoryPlaceholder' })}\r\n />\r\n </div>\r\n\r\n {/* Pattern */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.pattern' })}\r\n </label>\r\n <Input\r\n value={formData.pattern}\r\n onChange={(e) => handleFieldChange('pattern', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.patternPlaceholder' })}\r\n />\r\n </div>\r\n\r\n {/* Content (only for new rules) */}\r\n {mode === 'add' && (\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.content' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <textarea\r\n value={formData.content}\r\n onChange={(e) => handleFieldChange('content', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.contentPlaceholder' })}\r\n className={cn(\r\n 'flex min-h-[150px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\r\n errors.content && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n />\r\n {errors.content && (\r\n <p className=\"text-sm text-destructive\">{errors.content}</p>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Enabled */}\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"enabled\"\r\n checked={formData.enabled}\r\n onChange={(e) => handleFieldChange('enabled', e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <label htmlFor=\"enabled\" className=\"text-sm font-medium text-foreground cursor-pointer\">\r\n {formatMessage({ id: 'rules.dialog.form.enabled' })}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleClose}\r\n disabled={isPending}\r\n >\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleSubmit}\r\n disabled={isPending}\r\n >\r\n {isPending\r\n ? formatMessage({ id: 'rules.dialog.actions.saving' })\r\n : formatMessage({ id: 'common.actions.save' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default RuleDialog;\r\n","// ========================================\r\n// RulesManagerPage Component\r\n// ========================================\r\n// Rules list page with CRUD operations\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Plus,\r\n RefreshCw,\r\n Search,\r\n Filter,\r\n AlertCircle,\r\n FileCode,\r\n X,\r\n Folder,\r\n User,\r\n Globe,\r\n Maximize2,\r\n Minimize2,\r\n} from 'lucide-react';\r\nimport { useAppStore, selectIsImmersiveMode } from '@/stores/appStore';\r\nimport {\r\n useRules,\r\n useCreateRule,\r\n useDeleteRule,\r\n useToggleRule,\r\n} from '@/hooks';\r\nimport { RuleCard, RuleCardSkeleton } from '@/components/shared/RuleCard';\r\nimport { RuleDialog } from '@/components/shared/RuleDialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogDescription,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuSeparator,\r\n DropdownMenuLabel,\r\n} from '@/components/ui/Dropdown';\r\nimport { Tabs, TabsList, TabsTrigger } from '@/components/ui/Tabs';\r\nimport { cn } from '@/lib/utils';\r\nimport type { Rule } from '@/types/store';\r\n\r\ntype StatusFilter = 'all' | 'enabled' | 'disabled';\r\ntype LocationFilter = 'all' | 'project' | 'user';\r\n\r\n/**\r\n * RulesManagerPage component - Rules list with CRUD operations\r\n */\r\nexport function RulesManagerPage() {\r\n const { formatMessage } = useIntl();\r\n\r\n // Filter state\r\n const [statusFilter, setStatusFilter] = React.useState<StatusFilter>('all');\r\n const [locationFilter, setLocationFilter] = React.useState<LocationFilter>('all');\r\n const [searchQuery, setSearchQuery] = React.useState('');\r\n const [categoryFilter, setCategoryFilter] = React.useState<string[]>([]);\r\n\r\n // Immersive mode state\r\n const isImmersiveMode = useAppStore(selectIsImmersiveMode);\r\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\r\n\r\n // Dialog state\r\n const [createDialogOpen, setCreateDialogOpen] = React.useState(false);\r\n const [editDialogOpen, setEditDialogOpen] = React.useState(false);\r\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);\r\n const [selectedRule, setSelectedRule] = React.useState<Rule | null>(null);\r\n const [ruleToDelete, setRuleToDelete] = React.useState<string | null>(null);\r\n\r\n // Fetch rules\r\n const {\r\n rules,\r\n isLoading,\r\n isFetching,\r\n error,\r\n refetch,\r\n } = useRules();\r\n\r\n // Mutations\r\n const { isCreating } = useCreateRule();\r\n const { deleteRule, isDeleting } = useDeleteRule();\r\n const { toggleRule, isToggling } = useToggleRule();\r\n\r\n const isMutating = isCreating || isDeleting || isToggling;\r\n\r\n // Filter rules\r\n const filteredRules = React.useMemo(() => {\r\n let filtered = rules;\r\n\r\n // Status filter\r\n if (statusFilter === 'enabled') {\r\n filtered = filtered.filter((r) => r.enabled);\r\n } else if (statusFilter === 'disabled') {\r\n filtered = filtered.filter((r) => !r.enabled);\r\n }\r\n\r\n // Location filter\r\n if (locationFilter === 'project') {\r\n filtered = filtered.filter((r) => r.location === 'project');\r\n } else if (locationFilter === 'user') {\r\n filtered = filtered.filter((r) => r.location === 'user');\r\n }\r\n\r\n // Category filter\r\n if (categoryFilter.length > 0) {\r\n filtered = filtered.filter((r) =>\r\n r.category ? categoryFilter.includes(r.category) : false\r\n );\r\n }\r\n\r\n // Search filter\r\n if (searchQuery) {\r\n const query = searchQuery.toLowerCase();\r\n filtered = filtered.filter((r) =>\r\n r.name.toLowerCase().includes(query) ||\r\n r.description?.toLowerCase().includes(query) ||\r\n r.category?.toLowerCase().includes(query)\r\n );\r\n }\r\n\r\n return filtered;\r\n }, [rules, statusFilter, locationFilter, categoryFilter, searchQuery]);\r\n\r\n // Get all unique categories\r\n const categories = React.useMemo(() => {\r\n const cats = new Set<string>();\r\n rules.forEach((r) => {\r\n if (r.category) cats.add(r.category);\r\n });\r\n return Array.from(cats).sort();\r\n }, [rules]);\r\n\r\n // Count rules by location\r\n const projectRulesCount = React.useMemo(() =>\r\n rules.filter((r) => r.location === 'project').length, [rules]);\r\n const userRulesCount = React.useMemo(() =>\r\n rules.filter((r) => r.location === 'user').length, [rules]);\r\n\r\n // Handlers\r\n const handleEditClick = (rule: Rule) => {\r\n setSelectedRule(rule);\r\n setEditDialogOpen(true);\r\n };\r\n\r\n const handleDeleteClick = (ruleId: string) => {\r\n setRuleToDelete(ruleId);\r\n setDeleteDialogOpen(true);\r\n };\r\n\r\n const handleConfirmDelete = async () => {\r\n if (!ruleToDelete) return;\r\n\r\n try {\r\n const rule = rules.find((r) => r.id === ruleToDelete);\r\n await deleteRule(ruleToDelete, rule?.location);\r\n setDeleteDialogOpen(false);\r\n setRuleToDelete(null);\r\n } catch (err) {\r\n console.error('Failed to delete rule:', err);\r\n }\r\n };\r\n\r\n const handleToggle = async (ruleId: string, enabled: boolean) => {\r\n try {\r\n await toggleRule(ruleId, enabled);\r\n } catch (err) {\r\n console.error('Failed to toggle rule:', err);\r\n }\r\n };\r\n\r\n const handleClearSearch = () => {\r\n setSearchQuery('');\r\n };\r\n\r\n const toggleCategoryFilter = (category: string) => {\r\n setCategoryFilter((prev) =>\r\n prev.includes(category) ? prev.filter((c) => c !== category) : [...prev, category]\r\n );\r\n };\r\n\r\n const clearFilters = () => {\r\n setStatusFilter('all');\r\n setLocationFilter('all');\r\n setCategoryFilter([]);\r\n setSearchQuery('');\r\n };\r\n\r\n const hasActiveFilters = statusFilter !== 'all' || locationFilter !== 'all' ||\r\n categoryFilter.length > 0 || searchQuery.length > 0;\r\n\r\n return (\r\n <div className={cn(\"space-y-6\", isImmersiveMode && \"h-screen overflow-hidden\")}>\r\n {/* Header */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-semibold text-foreground\">{formatMessage({ id: 'rules.title' })}</h1>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'rules.description' })}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={toggleImmersiveMode}\r\n className={cn(\r\n 'p-2 rounded-md transition-colors',\r\n isImmersiveMode\r\n ? 'bg-primary/10 text-primary'\r\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\r\n )}\r\n title={isImmersiveMode ? 'Exit Fullscreen' : 'Fullscreen'}\r\n >\r\n {isImmersiveMode ? <Minimize2 className=\"w-4 h-4\" /> : <Maximize2 className=\"w-4 h-4\" />}\r\n </button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => refetch()}\r\n disabled={isFetching}\r\n >\r\n <RefreshCw className={cn('h-4 w-4 mr-2', isFetching && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n <Button size=\"sm\" onClick={() => setCreateDialogOpen(true)}>\r\n <Plus className=\"h-4 w-4 mr-2\" />\r\n {formatMessage({ id: 'common.actions.new' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Error alert */}\r\n {error && (\r\n <div className=\"flex items-center gap-2 p-4 rounded-lg bg-destructive/10 border border-destructive/30 text-destructive\">\r\n <AlertCircle className=\"h-5 w-5 flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'common.errors.loadFailed' })}</p>\r\n <p className=\"text-xs mt-0.5\">{error.message}</p>\r\n </div>\r\n <Button variant=\"outline\" size=\"sm\" onClick={() => refetch()}>\r\n {formatMessage({ id: 'home.errors.retry' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* Location Tabs - styled like LiteTasksPage */}\r\n <TabsNavigation\r\n value={locationFilter}\r\n onValueChange={(v) => setLocationFilter(v as LocationFilter)}\r\n tabs={[\r\n {\r\n value: 'all',\r\n label: formatMessage({ id: 'rules.filters.all' }),\r\n icon: <Globe className=\"h-4 w-4\" />,\r\n badge: <Badge variant=\"secondary\" className=\"ml-2\">{rules.length}</Badge>,\r\n disabled: isMutating,\r\n },\r\n {\r\n value: 'project',\r\n label: formatMessage({ id: 'rules.location.project' }),\r\n icon: <Folder className=\"h-4 w-4\" />,\r\n badge: <Badge variant=\"secondary\" className=\"ml-2\">{projectRulesCount}</Badge>,\r\n disabled: isMutating,\r\n },\r\n {\r\n value: 'user',\r\n label: formatMessage({ id: 'rules.location.user' }),\r\n icon: <User className=\"h-4 w-4\" />,\r\n badge: <Badge variant=\"secondary\" className=\"ml-2\">{userRulesCount}</Badge>,\r\n disabled: isMutating,\r\n },\r\n ]}\r\n />\r\n\r\n {/* Filters */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\r\n {/* Status tabs */}\r\n <Tabs value={statusFilter} onValueChange={(v) => setStatusFilter(v as StatusFilter)}>\r\n <TabsList>\r\n <TabsTrigger value=\"all\">{formatMessage({ id: 'rules.filters.all' })}</TabsTrigger>\r\n <TabsTrigger value=\"enabled\">{formatMessage({ id: 'rules.filters.enabled' })}</TabsTrigger>\r\n <TabsTrigger value=\"disabled\">{formatMessage({ id: 'rules.filters.disabled' })}</TabsTrigger>\r\n </TabsList>\r\n </Tabs>\r\n\r\n {/* Search input */}\r\n <div className=\"flex-1 max-w-sm relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\r\n <Input\r\n placeholder={formatMessage({ id: 'rules.searchPlaceholder' })}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n className=\"pl-9 pr-9\"\r\n />\r\n {searchQuery && (\r\n <button\r\n onClick={handleClearSearch}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\r\n >\r\n <X className=\"h-4 w-4\" />\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Category filter dropdown */}\r\n {categories.length > 0 && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button variant=\"outline\" size=\"sm\" className=\"gap-2\">\r\n <Filter className=\"h-4 w-4\" />\r\n {formatMessage({ id: 'rules.filters.category' })}\r\n {categoryFilter.length > 0 && (\r\n <Badge variant=\"secondary\" className=\"ml-1 h-5 min-w-5 px-1\">\r\n {categoryFilter.length}\r\n </Badge>\r\n )}\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\" className=\"w-48\">\r\n <DropdownMenuLabel>{formatMessage({ id: 'rules.dialog.form.category' })}</DropdownMenuLabel>\r\n <DropdownMenuSeparator />\r\n {categories.map((cat) => (\r\n <DropdownMenuItem\r\n key={cat}\r\n onClick={() => toggleCategoryFilter(cat)}\r\n className=\"justify-between\"\r\n >\r\n <span>{cat.charAt(0).toUpperCase() + cat.slice(1)}</span>\r\n {categoryFilter.includes(cat) && (\r\n <span className=\"text-primary\">✓</span>\r\n )}\r\n </DropdownMenuItem>\r\n ))}\r\n {categoryFilter.length > 0 && (\r\n <>\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem onClick={() => setCategoryFilter([])} className=\"text-destructive\">\r\n {formatMessage({ id: 'common.actions.clearFilters' })}\r\n </DropdownMenuItem>\r\n </>\r\n )}\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </div>\r\n\r\n {/* Active filters display */}\r\n {hasActiveFilters && (\r\n <div className=\"flex flex-wrap items-center gap-2\">\r\n <span className=\"text-sm text-muted-foreground\">{formatMessage({ id: 'common.actions.filters' })}:</span>\r\n {statusFilter !== 'all' && (\r\n <Badge\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={() => setStatusFilter('all')}\r\n >\r\n {formatMessage({ id: `rules.filters.${statusFilter}` })}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n )}\r\n {locationFilter !== 'all' && (\r\n <Badge\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={() => setLocationFilter('all')}\r\n >\r\n {formatMessage({ id: `rules.location.${locationFilter}` })}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n )}\r\n {categoryFilter.map((cat) => (\r\n <Badge\r\n key={cat}\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={() => toggleCategoryFilter(cat)}\r\n >\r\n {cat.charAt(0).toUpperCase() + cat.slice(1)}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n ))}\r\n {searchQuery && (\r\n <Badge\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={handleClearSearch}\r\n >\r\n {formatMessage({ id: 'common.actions.search' })}: {searchQuery}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n )}\r\n <Button variant=\"ghost\" size=\"sm\" onClick={clearFilters} className=\"h-6 text-xs\">\r\n {formatMessage({ id: 'common.actions.clearAll' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* Rules grid */}\r\n {isLoading ? (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {Array.from({ length: 9 }).map((_, i) => (\r\n <RuleCardSkeleton key={i} />\r\n ))}\r\n </div>\r\n ) : filteredRules.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg\">\r\n <FileCode className=\"h-12 w-12 text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-1\">\r\n {hasActiveFilters ? formatMessage({ id: 'rules.emptyState.title' }) : formatMessage({ id: 'rules.emptyState.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground text-center max-w-sm mb-4\">\r\n {hasActiveFilters\r\n ? formatMessage({ id: 'rules.emptyState.message' })\r\n : formatMessage({ id: 'rules.emptyState.createFirst' })}\r\n </p>\r\n {hasActiveFilters ? (\r\n <Button variant=\"outline\" onClick={clearFilters}>\r\n {formatMessage({ id: 'common.actions.clearFilters' })}\r\n </Button>\r\n ) : (\r\n <Button onClick={() => setCreateDialogOpen(true)}>\r\n <Plus className=\"h-4 w-4 mr-2\" />\r\n {formatMessage({ id: 'common.actions.new' })}\r\n </Button>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {filteredRules.map((rule) => (\r\n <RuleCard\r\n key={rule.id}\r\n rule={rule}\r\n onEdit={handleEditClick}\r\n onDelete={handleDeleteClick}\r\n onToggle={handleToggle}\r\n actionsDisabled={isMutating}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Create Rule Dialog */}\r\n <RuleDialog\r\n mode=\"add\"\r\n open={createDialogOpen}\r\n onClose={() => setCreateDialogOpen(false)}\r\n onSave={() => setCreateDialogOpen(false)}\r\n />\r\n\r\n {/* Edit Rule Dialog */}\r\n <RuleDialog\r\n mode=\"edit\"\r\n rule={selectedRule || undefined}\r\n open={editDialogOpen}\r\n onClose={() => {\r\n setEditDialogOpen(false);\r\n setSelectedRule(null);\r\n }}\r\n onSave={() => {\r\n setEditDialogOpen(false);\r\n setSelectedRule(null);\r\n }}\r\n />\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\r\n <DialogContent>\r\n <DialogHeader>\r\n <DialogTitle>{formatMessage({ id: 'rules.dialog.deleteTitle' })}</DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'rules.dialog.deleteConfirm' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n setDeleteDialogOpen(false);\r\n setRuleToDelete(null);\r\n }}\r\n >\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n onClick={handleConfirmDelete}\r\n disabled={isDeleting}\r\n >\r\n {isDeleting ? formatMessage({ id: 'rules.status.deleting' }) : formatMessage({ id: 'common.actions.delete' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n </div>\r\n );\r\n}\r\n\r\nexport default RulesManagerPage;\r\n"],"names":["severityVariantConfig","jsx","AlertCircle","AlertTriangle","Info","severityLabelKeys","RuleCard","rule","onEdit","onDelete","onToggle","className","showActions","actionsDisabled","formatMessage","useIntl","severityVariant","severityIcon","severityLabel","locationIcon","User","Folder","handleToggle","enabled","handleAction","e","action","Card","cn","jsxs","CardContent","Badge","Switch","DropdownMenu","DropdownMenuTrigger","Button","MoreVertical","DropdownMenuContent","DropdownMenuItem","Edit","DropdownMenuSeparator","Trash2","FileCode","RuleCardSkeleton","RULE_CATEGORIES","SEVERITY_LEVELS","RuleDialog","mode","open","onClose","onSave","queryClient","useQueryClient","formData","setFormData","useState","errors","setErrors","useEffect","_a","createMutation","useMutation","data","createRule","rulesKeys","handleClose","updateMutation","ruleId","config","updateRule","handleFieldChange","field","value","prev","generatedFileName","validateForm","newErrors","handleSubmit","input","isPending","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Input","Select","v","SelectTrigger","SelectValue","SelectContent","cat","SelectItem","sev","DialogFooter","RulesManagerPage","statusFilter","setStatusFilter","React.useState","locationFilter","setLocationFilter","searchQuery","setSearchQuery","categoryFilter","setCategoryFilter","isImmersiveMode","useAppStore","selectIsImmersiveMode","toggleImmersiveMode","s","createDialogOpen","setCreateDialogOpen","editDialogOpen","setEditDialogOpen","deleteDialogOpen","setDeleteDialogOpen","selectedRule","setSelectedRule","ruleToDelete","setRuleToDelete","rules","isLoading","isFetching","error","refetch","useRules","isCreating","useCreateRule","deleteRule","isDeleting","useDeleteRule","toggleRule","isToggling","useToggleRule","isMutating","filteredRules","React.useMemo","filtered","r","query","_b","categories","cats","projectRulesCount","userRulesCount","handleEditClick","handleDeleteClick","handleConfirmDelete","err","handleClearSearch","toggleCategoryFilter","category","c","clearFilters","hasActiveFilters","Minimize2","Maximize2","RefreshCw","Plus","TabsNavigation","Globe","Tabs","TabsList","TabsTrigger","Search","X","Filter","DropdownMenuLabel","Fragment","_","i"],"mappings":"24BAkDA,MAAMA,GAGF,CACF,MAAO,CAAE,QAAS,cAAwB,KAAMC,MAACC,GAAA,CAAY,UAAU,SAAA,CAAU,CAAA,EACjF,QAAS,CAAE,QAAS,UAAoB,KAAMD,MAACE,GAAA,CAAc,UAAU,SAAA,CAAU,CAAA,EACjF,KAAM,CAAE,QAAS,OAAiB,KAAMF,EAAAA,IAACG,GAAA,CAAK,UAAU,UAAU,CAAA,CACpE,EAGMC,GAA4C,CAChD,MAAO,uBACP,QAAS,yBACT,KAAM,qBACR,EAKO,SAASC,GAAS,CACvB,KAAAC,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,UAAAC,EACA,YAAAC,EAAc,GACd,gBAAAC,EAAkB,EACpB,EAAkB,CAChB,KAAM,CAAE,cAAAC,CAAA,EAAkBC,EAAA,EAEpB,CAAE,QAASC,EAAiB,KAAMC,GAAiBjB,GAAsBO,EAAK,UAAY,MAAM,GAAK,CACzG,QAAS,UACT,KAAM,IAAA,EAEFW,EAAgBX,EAAK,SACvBO,EAAc,CAAE,GAAIT,GAAkBE,EAAK,QAAQ,CAAA,CAAG,EACtD,KAEEY,EAAeZ,EAAK,WAAa,OAASN,EAAAA,IAACmB,GAAA,CAAK,UAAU,SAAA,CAAU,EAAKnB,EAAAA,IAACoB,EAAA,CAAO,UAAU,UAAU,EAErGC,EAAgBC,GAAqB,CACzCb,GAAA,MAAAA,EAAWH,EAAK,GAAIgB,EACtB,EAEMC,EAAe,CAACC,EAAqBC,IAA8B,CAEvE,OADAD,EAAE,gBAAA,EACMC,EAAA,CACN,IAAK,OACHlB,GAAA,MAAAA,EAASD,GACT,MACF,IAAK,SACHE,GAAA,MAAAA,EAAWF,EAAK,IAChB,KAAA,CAEN,EAEA,OACEN,EAAAA,IAAC0B,GAAA,CACC,UAAWC,EACT,uFACA,CAACrB,EAAK,SAAW,aACjBI,CAAA,EAGF,SAAAkB,EAAAA,KAACC,GAAA,CAAY,UAAU,MAErB,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,yCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,iBACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAA5B,EAAAA,IAAC,KAAA,CAAG,UAAU,4CACX,SAAAM,EAAK,KACR,EACAN,EAAAA,IAAC,MAAA,CAAI,UAAU,gDAAgD,MAAOa,EAAc,CAAE,GAAIP,EAAK,WAAa,OAAS,sBAAwB,wBAAA,CAA0B,EACpK,SAAAY,CAAA,CACH,CAAA,EACF,EACCZ,EAAK,UACJN,EAAAA,IAAC,KAAE,UAAU,uCACV,WAAK,QAAA,CACR,CAAA,EAEJ,EACA4B,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACZ,SAAA,CAAAtB,EAAK,SAAWA,EAAK,UACpBsB,EAAAA,KAACE,GAAM,QAASf,EAAiB,UAAU,QACxC,SAAA,CAAAC,EACAC,CAAA,EACH,EAEFjB,EAAAA,IAAC+B,GAAA,CACC,QAASzB,EAAK,QACd,gBAAiBe,EACjB,SAAUT,EACV,UAAU,iCAAA,CAAA,EAEXD,UACEqB,GAAA,CACC,SAAA,CAAAhC,EAAAA,IAACiC,GAAA,CAAoB,QAAO,GAC1B,SAAAL,EAAAA,KAACM,EAAA,CACC,QAAQ,QACR,KAAK,OACL,UAAU,+DACV,QAAUV,GAAMA,EAAE,gBAAA,EAClB,SAAUZ,EAEV,SAAA,CAAAZ,EAAAA,IAACmC,GAAA,CAAa,UAAU,SAAA,CAAU,EAClCnC,MAAC,QAAK,UAAU,UAAW,WAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAAE,CAAA,CAAA,CAAA,EAE5E,EACA4B,EAAAA,KAACQ,GAAA,CAAoB,MAAM,MACzB,SAAA,CAAAR,OAACS,GAAiB,QAAUb,GAAMD,EAAaC,EAAG,MAAM,EACtD,SAAA,CAAAxB,EAAAA,IAACsC,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BzB,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,EAC7C,QACC0B,EAAA,EAAsB,EACvBX,EAAAA,KAACS,EAAA,CACC,QAAUb,GAAMD,EAAaC,EAAG,QAAQ,EACxC,UAAU,0CAEV,SAAA,CAAAxB,EAAAA,IAACwC,GAAA,CAAO,UAAU,cAAA,CAAe,EAChC3B,EAAc,CAAE,GAAI,sBAAA,CAAwB,CAAA,CAAA,CAAA,CAC/C,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,EACF,EAGCP,EAAK,aACJN,EAAAA,IAAC,KAAE,UAAU,kDACV,WAAK,YACR,EAIF4B,EAAAA,KAAC,MAAA,CAAI,UAAU,iFACZ,SAAA,CAAAtB,EAAK,SACJsB,OAAC,OAAA,CAAK,UAAU,oCACd,SAAA,CAAA5B,EAAAA,IAACyC,GAAA,CAAS,UAAU,aAAA,CAAc,EACjCnC,EAAK,OAAA,EACR,EAEDA,EAAK,cACJsB,OAAC,OAAA,CAAK,UAAU,0BACd,SAAA,CAAA5B,EAAAA,IAACoB,EAAA,CAAO,UAAU,aAAA,CAAc,EAC/Bd,EAAK,YAAA,CAAA,CACR,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,CAAA,CAGN,CAKO,SAASoC,GAAiB,CAAE,UAAAhC,GAAqC,CACtE,OACEV,EAAAA,IAAC0B,GAAA,CAAK,UAAWC,EAAG,gBAAiBjB,CAAS,EAC5C,SAAAkB,EAAAA,KAACC,GAAA,CAAY,UAAU,MACrB,SAAA,CAAAD,EAAAA,KAAC,MAAA,CAAI,UAAU,mCACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,SACb,SAAA,CAAA5B,EAAAA,IAAC,MAAA,CAAI,UAAU,2BAAA,CAA4B,EAC3CA,EAAAA,IAAC,MAAA,CAAI,UAAU,gCAAA,CAAiC,CAAA,EAClD,EACAA,EAAAA,IAAC,MAAA,CAAI,UAAU,+BAAA,CAAgC,EAC/CA,EAAAA,IAAC,MAAA,CAAI,UAAU,0BAAA,CAA2B,CAAA,EAC5C,EACAA,EAAAA,IAAC,MAAA,CAAI,UAAU,kCAAA,CAAmC,EAClD4B,EAAAA,KAAC,MAAA,CAAI,UAAU,kBACb,SAAA,CAAA5B,EAAAA,IAAC,MAAA,CAAI,UAAU,2BAAA,CAA4B,EAC3CA,EAAAA,IAAC,MAAA,CAAI,UAAU,2BAAA,CAA4B,CAAA,CAAA,CAC7C,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CClKA,MAAM2C,GAAkB,CACtB,SACA,UACA,WACA,eACA,gBACA,cACA,WACA,UACA,SACF,EAEMC,GAA0D,CAAC,QAAS,UAAW,MAAM,EAIpF,SAASC,GAAW,CACzB,KAAAC,EACA,KAAAxC,EACA,KAAAyC,EACA,QAAAC,EACA,OAAAC,CACF,EAAoB,CAClB,KAAM,CAAE,cAAApC,CAAA,EAAkBC,EAAA,EACpBoC,EAAcC,GAAA,EAGd,CAACC,EAAUC,CAAW,EAAIC,WAAuB,CACrD,KAAM,GACN,YAAa,GACb,QAAS,GACT,SAAU,UACV,SAAU,OACV,SAAU,GACV,SAAU,UACV,aAAc,GACd,QAAS,GACT,QAAS,EAAA,CACV,EAEK,CAACC,EAAQC,CAAS,EAAIF,EAAAA,SAAqB,CAAA,CAAE,EAGnDG,EAAAA,UAAU,IAAM,OAEZJ,EADE/C,GAAQwC,IAAS,OACP,CACV,KAAMxC,EAAK,KACX,YAAaA,EAAK,aAAe,GACjC,QAASA,EAAK,QACd,SAAUA,EAAK,UAAY,UAC3B,SAAUA,EAAK,UAAY,OAC3B,WAAUoD,EAAApD,EAAK,OAAL,YAAAoD,EAAW,MAAM,SAAS,QAAS,GAAGpD,EAAK,KAAK,cAAc,QAAQ,OAAQ,GAAG,CAAC,MAC5F,SAAUA,EAAK,UAAY,UAC3B,aAAcA,EAAK,cAAgB,GACnC,QAAS,GACT,QAASA,EAAK,SAAW,EAAA,EAIf,CACV,KAAM,GACN,YAAa,GACb,QAAS,GACT,SAAU,UACV,SAAU,OACV,SAAU,GACV,SAAU,UACV,aAAc,GACd,QAAS,GACT,QAAS,EAAA,CAbV,EAgBHkD,EAAU,CAAA,CAAE,CACd,EAAG,CAAClD,EAAMwC,EAAMC,CAAI,CAAC,EAGrB,MAAMY,EAAiBC,EAAY,CACjC,WAAaC,GAA0BC,GAAWD,CAAI,EACtD,UAAW,IAAM,CACfX,EAAY,kBAAkB,CAAE,SAAUa,GAAU,IAAK,EACzDC,EAAA,EACAf,GAAA,MAAAA,GACF,CAAA,CACD,EAEKgB,EAAiBL,EAAY,CACjC,WAAY,CAAC,CAAE,OAAAM,EAAQ,OAAAC,KACrBC,GAAWF,EAAQC,CAAM,EAC3B,UAAW,IAAM,CACfjB,EAAY,kBAAkB,CAAE,SAAUa,GAAU,IAAK,EACzDC,EAAA,EACAf,GAAA,MAAAA,GACF,CAAA,CACD,EAGKe,EAAc,IAAM,CACxBR,EAAU,CAAA,CAAE,EACZR,EAAA,CACF,EAEMqB,EAAoB,CACxBC,EACAC,IACG,CACHlB,EAAamB,IAAU,CAAE,GAAGA,EAAM,CAACF,CAAK,EAAGC,CAAA,EAAQ,EAE/ChB,EAAOe,CAAyB,GAClCd,EAAWgB,IAAU,CAAE,GAAGA,EAAM,CAACF,CAAK,EAAG,MAAA,EAAY,CAEzD,EAGAb,EAAAA,UAAU,IAAM,CACd,GAAIL,EAAS,MAAQ,CAACA,EAAS,SAAU,CACvC,MAAMqB,EAAoB,GAAGrB,EAAS,KAAK,cAAc,QAAQ,OAAQ,GAAG,CAAC,MAC7EC,EAAamB,IAAU,CAAE,GAAGA,EAAM,SAAUC,GAAoB,CAClE,CACF,EAAG,CAACrB,EAAS,KAAMA,EAAS,QAAQ,CAAC,EAErC,MAAMsB,EAAe,IAAe,CAClC,MAAMC,EAAwB,CAAA,EAG9B,OAAKvB,EAAS,KAAK,SACjBuB,EAAU,KAAO9D,EAAc,CAAE,GAAI,uCAAwC,GAI1EuC,EAAS,SAAS,SACrBuB,EAAU,SAAW9D,EAAc,CAAE,GAAI,2CAA4C,GAInFuC,EAAS,UAAY,CAACA,EAAS,SAAS,SAAS,KAAK,IACxDuB,EAAU,SAAW9D,EAAc,CAAE,GAAI,qCAAsC,GAI5EuC,EAAS,WACZuB,EAAU,SAAW9D,EAAc,CAAE,GAAI,2CAA4C,GAInFiC,IAAS,OAAS,CAACM,EAAS,QAAQ,SACtCuB,EAAU,QAAU9D,EAAc,CAAE,GAAI,0CAA2C,GAGrF2C,EAAUmB,CAAS,EACZ,OAAO,KAAKA,CAAS,EAAE,SAAW,CAC3C,EAEMC,EAAe,SAAY,CAC/B,GAAKF,IAIL,GAAI5B,IAAS,MAAO,CAClB,MAAM+B,EAAyB,CAC7B,KAAMzB,EAAS,KAAK,KAAA,EACpB,YAAaA,EAAS,YAAY,KAAA,GAAU,OAC5C,QAASA,EAAS,QAClB,SAAUA,EAAS,UAAY,OAC/B,SAAUA,EAAS,SACnB,SAAUA,EAAS,SAAS,KAAA,EAC5B,SAAUA,EAAS,SACnB,aAAcA,EAAS,aAAa,KAAA,GAAU,OAC9C,QAASA,EAAS,QAAQ,KAAA,EAC1B,QAASA,EAAS,QAAQ,QAAU,MAAA,EAEtCO,EAAe,OAAOkB,CAAK,CAC7B,MACEZ,EAAe,OAAO,CACpB,OAAQ3D,EAAM,GACd,OAAQ,CACN,KAAM8C,EAAS,KAAK,KAAA,EACpB,YAAaA,EAAS,YAAY,KAAA,GAAU,OAC5C,QAASA,EAAS,QAClB,SAAUA,EAAS,UAAY,OAC/B,SAAUA,EAAS,SACnB,QAASA,EAAS,QAAQ,QAAU,MAAA,CACtC,CACD,CAEL,EAEM0B,EAAYnB,EAAe,WAAaM,EAAe,UAE7D,OACEjE,EAAAA,IAAC+E,IAAO,KAAAhC,EAAY,aAAciB,EAChC,SAAApC,EAAAA,KAACoD,GAAA,CAAc,UAAU,yCACvB,SAAA,CAAApD,OAACqD,GAAA,CACC,SAAA,CAAAjF,MAACkF,IACE,SAAApC,IAAS,MACNjC,EAAc,CAAE,GAAI,wBAAyB,EAC7CA,EAAc,CAAE,GAAI,0BAA4B,CAAE,KAAMP,GAAA,YAAAA,EAAM,IAAA,CAAM,EAC1E,QACC6E,GAAA,CACE,SAAAtE,EAAc,CAAE,GAAI,0BAAA,CAA4B,CAAA,CACnD,CAAA,EACF,EAEAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YAEb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,yBAA0B,EAC/Cb,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAACoF,EAAA,CACC,MAAOhC,EAAS,KAChB,SAAW5B,GAAM6C,EAAkB,OAAQ7C,EAAE,OAAO,KAAK,EACzD,YAAaX,EAAc,CAAE,GAAI,oCAAqC,EACtE,MAAO,CAAC,CAAC0C,EAAO,IAAA,CAAA,EAEjBA,EAAO,MACNvD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,IAAA,CAAK,CAAA,EAEzD,EAGA4B,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAa,EAAc,CAAE,GAAI,+BAAA,CAAiC,EACxD,EACAb,EAAAA,IAACoF,EAAA,CACC,MAAOhC,EAAS,YAChB,SAAW5B,GAAM6C,EAAkB,cAAe7C,EAAE,OAAO,KAAK,EAChE,YAAaX,EAAc,CAAE,GAAI,2CAA4C,CAAA,CAAA,CAC/E,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAa,EAAc,CAAE,GAAI,4BAAA,CAA8B,EACrD,EACAe,EAAAA,KAACyD,EAAA,CAAO,MAAOjC,EAAS,SAAU,cAAgBkC,GAAMjB,EAAkB,WAAYiB,CAAC,EACrF,SAAA,CAAAtF,EAAAA,IAACuF,EAAA,CACC,SAAAvF,EAAAA,IAACwF,EAAA,CAAA,CAAY,EACf,EACAxF,EAAAA,IAACyF,IACE,SAAA9C,GAAgB,IAAK+C,GACpB1F,EAAAA,IAAC2F,GAAA,CAAqB,MAAOD,EAC1B,SAAAA,EAAI,OAAO,CAAC,EAAE,cAAgBA,EAAI,MAAM,CAAC,GAD3BA,CAEjB,CACD,CAAA,CACH,CAAA,CAAA,CACF,CAAA,EACF,EAGA9D,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAa,EAAc,CAAE,GAAI,4BAAA,CAA8B,EACrD,EACAe,EAAAA,KAACyD,EAAA,CACC,MAAOjC,EAAS,SAChB,cAAgBkC,GAAMjB,EAAkB,WAAYiB,CAAqB,EAEzE,SAAA,CAAAtF,EAAAA,IAACuF,EAAA,CACC,SAAAvF,EAAAA,IAACwF,EAAA,CAAA,CAAY,EACf,EACAxF,MAACyF,IACE,SAAA7C,GAAgB,IAAKgD,GACpB5F,EAAAA,IAAC2F,IAAqB,MAAOC,EAC1B,WAAc,CAAE,GAAI,kBAAkBA,CAAG,GAAI,CAAA,EAD/BA,CAEjB,CACD,CAAA,CACH,CAAA,CAAA,CAAA,CACF,EACF,EAGAhE,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,6BAA8B,EACnDb,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAACoF,EAAA,CACC,MAAOhC,EAAS,SAChB,SAAW5B,GAAM6C,EAAkB,WAAY7C,EAAE,OAAO,KAAK,EAC7D,YAAY,eACZ,MAAO,CAAC,CAAC+B,EAAO,QAAA,CAAA,EAEjBA,EAAO,UACNvD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,QAAA,CAAS,CAAA,EAE7D,EAGA4B,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,6BAA8B,EACnDb,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACA4B,EAAAA,KAAC,MAAA,CAAI,UAAU,aACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,WACL,MAAM,UACN,QAASoD,EAAS,WAAa,UAC/B,SAAW5B,GAAM6C,EAAkB,WAAY7C,EAAE,OAAO,KAA2B,EACnF,UAAU,SAAA,CAAA,EAEZxB,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CACjD,CAAA,EACF,EACA4B,EAAAA,KAAC,QAAA,CAAM,UAAU,yCACf,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CACC,KAAK,QACL,KAAK,WACL,MAAM,OACN,QAASoD,EAAS,WAAa,OAC/B,SAAW5B,GAAM6C,EAAkB,WAAY7C,EAAE,OAAO,KAA2B,EACnF,UAAU,SAAA,CAAA,EAEZxB,MAAC,QAAK,UAAU,UACb,WAAc,CAAE,GAAI,qBAAA,CAAuB,CAAA,CAC9C,CAAA,CAAA,CACF,CAAA,EACF,EACCuD,EAAO,UACNvD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,QAAA,CAAS,CAAA,EAE7D,EAGA4B,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAa,EAAc,CAAE,GAAI,gCAAA,CAAkC,EACzD,EACAb,EAAAA,IAACoF,EAAA,CACC,MAAOhC,EAAS,aAChB,SAAW5B,GAAM6C,EAAkB,eAAgB7C,EAAE,OAAO,KAAK,EACjE,YAAaX,EAAc,CAAE,GAAI,4CAA6C,CAAA,CAAA,CAChF,EACF,EAGAe,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CAAM,UAAU,sCACd,SAAAa,EAAc,CAAE,GAAI,2BAAA,CAA6B,EACpD,EACAb,EAAAA,IAACoF,EAAA,CACC,MAAOhC,EAAS,QAChB,SAAW5B,GAAM6C,EAAkB,UAAW7C,EAAE,OAAO,KAAK,EAC5D,YAAaX,EAAc,CAAE,GAAI,uCAAwC,CAAA,CAAA,CAC3E,EACF,EAGCiC,IAAS,OACRlB,OAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAA,EAAAA,KAAC,QAAA,CAAM,UAAU,sCACd,SAAA,CAAAf,EAAc,CAAE,GAAI,4BAA6B,EAClDb,EAAAA,IAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,GAAA,CAAC,CAAA,EAC3C,EACAA,EAAAA,IAAC,WAAA,CACC,MAAOoD,EAAS,QAChB,SAAW5B,GAAM6C,EAAkB,UAAW7C,EAAE,OAAO,KAAK,EAC5D,YAAaX,EAAc,CAAE,GAAI,uCAAwC,EACzE,UAAWc,EACT,wSACA4B,EAAO,SAAW,mDAAA,CACpB,CAAA,EAEDA,EAAO,SACNvD,EAAAA,IAAC,KAAE,UAAU,2BAA4B,WAAO,OAAA,CAAQ,CAAA,EAE5D,EAIF4B,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAA5B,EAAAA,IAAC,QAAA,CACC,KAAK,WACL,GAAG,UACH,QAASoD,EAAS,QAClB,SAAW5B,GAAM6C,EAAkB,UAAW7C,EAAE,OAAO,OAAO,EAC9D,UAAU,SAAA,CAAA,EAEZxB,EAAAA,IAAC,QAAA,CAAM,QAAQ,UAAU,UAAU,qDAChC,SAAAa,EAAc,CAAE,GAAI,2BAAA,CAA6B,CAAA,CACpD,CAAA,CAAA,CACF,CAAA,EACF,SAECgF,GAAA,CACC,SAAA,CAAA7F,EAAAA,IAACkC,EAAA,CACC,QAAQ,UACR,QAAS8B,EACT,SAAUc,EAET,SAAAjE,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAA,EAEhDb,EAAAA,IAACkC,EAAA,CACC,QAAS0C,EACT,SAAUE,EAET,SACGjE,EADHiE,EACiB,CAAE,GAAI,6BAAA,EACN,CAAE,GAAI,qBAAA,CAD+B,CACR,CAAA,CACjD,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAEJ,CChaO,SAASgB,IAAmB,CACjC,KAAM,CAAE,cAAAjF,CAAA,EAAkBC,EAAA,EAGpB,CAACiF,EAAcC,CAAe,EAAIC,EAAAA,SAA6B,KAAK,EACpE,CAACC,EAAgBC,CAAiB,EAAIF,EAAAA,SAA+B,KAAK,EAC1E,CAACG,EAAaC,CAAc,EAAIJ,EAAAA,SAAe,EAAE,EACjD,CAACK,EAAgBC,CAAiB,EAAIN,EAAAA,SAAyB,CAAA,CAAE,EAGjEO,EAAkBC,GAAYC,EAAqB,EACnDC,EAAsBF,GAAaG,GAAMA,EAAE,mBAAmB,EAG9D,CAACC,EAAkBC,CAAmB,EAAIb,EAAAA,SAAe,EAAK,EAC9D,CAACc,EAAgBC,CAAiB,EAAIf,EAAAA,SAAe,EAAK,EAC1D,CAACgB,EAAkBC,CAAmB,EAAIjB,EAAAA,SAAe,EAAK,EAC9D,CAACkB,EAAcC,CAAe,EAAInB,EAAAA,SAA4B,IAAI,EAClE,CAACoB,EAAcC,CAAe,EAAIrB,EAAAA,SAA8B,IAAI,EAGpE,CACJ,MAAAsB,EACA,UAAAC,GACA,WAAAC,EACA,MAAAC,EACA,QAAAC,CAAA,EACEC,GAAA,EAGE,CAAE,WAAAC,EAAA,EAAeC,GAAA,EACjB,CAAE,WAAAC,GAAY,WAAAC,CAAA,EAAeC,GAAA,EAC7B,CAAE,WAAAC,GAAY,WAAAC,EAAA,EAAeC,GAAA,EAE7BC,EAAaR,IAAcG,GAAcG,GAGzCG,EAAgBC,EAAAA,QAAc,IAAM,CACxC,IAAIC,EAAWjB,EAwBf,GArBIxB,IAAiB,UACnByC,EAAWA,EAAS,OAAQC,GAAMA,EAAE,OAAO,EAClC1C,IAAiB,aAC1ByC,EAAWA,EAAS,OAAQC,GAAM,CAACA,EAAE,OAAO,GAI1CvC,IAAmB,UACrBsC,EAAWA,EAAS,OAAQC,GAAMA,EAAE,WAAa,SAAS,EACjDvC,IAAmB,SAC5BsC,EAAWA,EAAS,OAAQC,GAAMA,EAAE,WAAa,MAAM,GAIrDnC,EAAe,OAAS,IAC1BkC,EAAWA,EAAS,OAAQC,GAC1BA,EAAE,SAAWnC,EAAe,SAASmC,EAAE,QAAQ,EAAI,EAAA,GAKnDrC,EAAa,CACf,MAAMsC,EAAQtC,EAAY,YAAA,EAC1BoC,EAAWA,EAAS,OAAQC,YAC1B,OAAAA,EAAE,KAAK,cAAc,SAASC,CAAK,KACnChF,EAAA+E,EAAE,cAAF,YAAA/E,EAAe,cAAc,SAASgF,OACtCC,EAAAF,EAAE,WAAF,YAAAE,EAAY,cAAc,SAASD,IAAK,CAE5C,CAEA,OAAOF,CACT,EAAG,CAACjB,EAAOxB,EAAcG,EAAgBI,EAAgBF,CAAW,CAAC,EAG/DwC,EAAaL,EAAAA,QAAc,IAAM,CACrC,MAAMM,MAAW,IACjB,OAAAtB,EAAM,QAASkB,GAAM,CACfA,EAAE,UAAUI,EAAK,IAAIJ,EAAE,QAAQ,CACrC,CAAC,EACM,MAAM,KAAKI,CAAI,EAAE,KAAA,CAC1B,EAAG,CAACtB,CAAK,CAAC,EAGJuB,GAAoBP,EAAAA,QAAc,IACtChB,EAAM,OAAQkB,GAAMA,EAAE,WAAa,SAAS,EAAE,OAAQ,CAAClB,CAAK,CAAC,EACzDwB,GAAiBR,EAAAA,QAAc,IACnChB,EAAM,OAAQkB,GAAMA,EAAE,WAAa,MAAM,EAAE,OAAQ,CAAClB,CAAK,CAAC,EAGtDyB,GAAmB1I,GAAe,CACtC8G,EAAgB9G,CAAI,EACpB0G,EAAkB,EAAI,CACxB,EAEMiC,GAAqB/E,GAAmB,CAC5CoD,EAAgBpD,CAAM,EACtBgD,EAAoB,EAAI,CAC1B,EAEMgC,GAAsB,SAAY,CACtC,GAAK7B,EAEL,GAAI,CACF,MAAM/G,EAAOiH,EAAM,KAAMkB,GAAMA,EAAE,KAAOpB,CAAY,EACpD,MAAMU,GAAWV,EAAc/G,GAAA,YAAAA,EAAM,QAAQ,EAC7C4G,EAAoB,EAAK,EACzBI,EAAgB,IAAI,CACtB,OAAS6B,EAAK,CACZ,QAAQ,MAAM,yBAA0BA,CAAG,CAC7C,CACF,EAEM9H,GAAe,MAAO6C,EAAgB5C,IAAqB,CAC/D,GAAI,CACF,MAAM4G,GAAWhE,EAAQ5C,CAAO,CAClC,OAAS6H,EAAK,CACZ,QAAQ,MAAM,yBAA0BA,CAAG,CAC7C,CACF,EAEMC,EAAoB,IAAM,CAC9B/C,EAAe,EAAE,CACnB,EAEMgD,EAAwBC,GAAqB,CACjD/C,EAAmB/B,GACjBA,EAAK,SAAS8E,CAAQ,EAAI9E,EAAK,OAAQ+E,GAAMA,IAAMD,CAAQ,EAAI,CAAC,GAAG9E,EAAM8E,CAAQ,CAAA,CAErF,EAEME,EAAe,IAAM,CACzBxD,EAAgB,KAAK,EACrBG,EAAkB,KAAK,EACvBI,EAAkB,CAAA,CAAE,EACpBF,EAAe,EAAE,CACnB,EAEMoD,EAAmB1D,IAAiB,OAASG,IAAmB,OACpEI,EAAe,OAAS,GAAKF,EAAY,OAAS,EAEpD,cACG,MAAA,CAAI,UAAWzE,EAAG,YAAa6E,GAAmB,0BAA0B,EAE3E,SAAA,CAAA5E,EAAAA,KAAC,MAAA,CAAI,UAAU,qEACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAA5B,EAAAA,IAAC,KAAA,CAAG,UAAU,yCAA0C,SAAAa,EAAc,CAAE,GAAI,aAAA,CAAe,EAAE,EAC7Fb,MAAC,KAAE,UAAU,qCACV,WAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAC5C,CAAA,EACF,EACA4B,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAA5B,EAAAA,IAAC,SAAA,CACC,QAAS2G,EACT,UAAWhF,EACT,mCACA6E,EACI,6BACA,4DAAA,EAEN,MAAOA,EAAkB,kBAAoB,aAE5C,SAAAA,QAAmBkD,GAAA,CAAU,UAAU,UAAU,EAAK1J,EAAAA,IAAC2J,GAAA,CAAU,UAAU,SAAA,CAAU,CAAA,CAAA,EAExF/H,EAAAA,KAACM,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAAS,IAAMyF,EAAA,EACf,SAAUF,EAEV,SAAA,CAAAzH,MAAC4J,IAAU,UAAWjI,EAAG,eAAgB8F,GAAc,cAAc,EAAG,EACvE5G,EAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CAAA,CAAA,EAEjDe,OAACM,GAAO,KAAK,KAAK,QAAS,IAAM4E,EAAoB,EAAI,EACvD,SAAA,CAAA9G,EAAAA,IAAC6J,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BhJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CACF,CAAA,EACF,EAGC6G,GACC9F,EAAAA,KAAC,MAAA,CAAI,UAAU,yGACb,SAAA,CAAA5B,EAAAA,IAACC,GAAA,CAAY,UAAU,uBAAA,CAAwB,EAC/C2B,EAAAA,KAAC,MAAA,CAAI,UAAU,SACb,SAAA,CAAA5B,EAAAA,IAAC,IAAA,CAAE,UAAU,sBAAuB,SAAAa,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAE,EACtFb,EAAAA,IAAC,IAAA,CAAE,UAAU,iBAAkB,WAAM,OAAA,CAAQ,CAAA,EAC/C,EACAA,EAAAA,IAACkC,EAAA,CAAO,QAAQ,UAAU,KAAK,KAAK,QAAS,IAAMyF,EAAA,EAChD,SAAA9G,EAAc,CAAE,GAAI,mBAAA,CAAqB,CAAA,CAC5C,CAAA,EACF,EAIFb,EAAAA,IAAC8J,GAAA,CACC,MAAO5D,EACP,cAAgBZ,GAAMa,EAAkBb,CAAmB,EAC3D,KAAM,CACJ,CACE,MAAO,MACP,MAAOzE,EAAc,CAAE,GAAI,oBAAqB,EAChD,KAAMb,EAAAA,IAAC+J,GAAA,CAAM,UAAU,SAAA,CAAU,EACjC,YAAQjI,EAAA,CAAM,QAAQ,YAAY,UAAU,OAAQ,WAAM,MAAA,CAAO,EACjE,SAAUuG,CAAA,EAEZ,CACE,MAAO,UACP,MAAOxH,EAAc,CAAE,GAAI,yBAA0B,EACrD,KAAMb,EAAAA,IAACoB,EAAA,CAAO,UAAU,SAAA,CAAU,EAClC,MAAOpB,EAAAA,IAAC8B,EAAA,CAAM,QAAQ,YAAY,UAAU,OAAQ,SAAAgH,GAAkB,EACtE,SAAUT,CAAA,EAEZ,CACE,MAAO,OACP,MAAOxH,EAAc,CAAE,GAAI,sBAAuB,EAClD,KAAMb,EAAAA,IAACmB,GAAA,CAAK,UAAU,SAAA,CAAU,EAChC,MAAOnB,EAAAA,IAAC8B,EAAA,CAAM,QAAQ,YAAY,UAAU,OAAQ,SAAAiH,GAAe,EACnE,SAAUV,CAAA,CACZ,CACF,CAAA,EAIFzG,EAAAA,KAAC,MAAA,CAAI,UAAU,kDAEb,SAAA,CAAA5B,EAAAA,IAACgK,GAAA,CAAK,MAAOjE,EAAc,cAAgBT,GAAMU,EAAgBV,CAAiB,EAChF,SAAA1D,EAAAA,KAACqI,GAAA,CACC,SAAA,CAAAjK,EAAAA,IAACkK,EAAA,CAAY,MAAM,MAAO,SAAArJ,EAAc,CAAE,GAAI,mBAAA,CAAqB,EAAE,EACrEb,EAAAA,IAACkK,GAAY,MAAM,UAAW,WAAc,CAAE,GAAI,uBAAA,CAAyB,EAAE,EAC7ElK,MAACkK,GAAY,MAAM,WAAY,WAAc,CAAE,GAAI,wBAAA,CAA0B,CAAA,CAAE,CAAA,CAAA,CACjF,CAAA,CACF,EAGAtI,EAAAA,KAAC,MAAA,CAAI,UAAU,2BACb,SAAA,CAAA5B,EAAAA,IAACmK,GAAA,CAAO,UAAU,wEAAA,CAAyE,EAC3FnK,EAAAA,IAACoF,EAAA,CACC,YAAavE,EAAc,CAAE,GAAI,0BAA2B,EAC5D,MAAOuF,EACP,SAAW5E,GAAM6E,EAAe7E,EAAE,OAAO,KAAK,EAC9C,UAAU,WAAA,CAAA,EAEX4E,GACCpG,EAAAA,IAAC,SAAA,CACC,QAASoJ,EACT,UAAU,wFAEV,SAAApJ,EAAAA,IAACoK,EAAA,CAAE,UAAU,SAAA,CAAU,CAAA,CAAA,CACzB,EAEJ,EAGCxB,EAAW,OAAS,GACnBhH,EAAAA,KAACI,GAAA,CACC,SAAA,CAAAhC,EAAAA,IAACiC,GAAA,CAAoB,QAAO,GAC1B,SAAAL,EAAAA,KAACM,EAAA,CAAO,QAAQ,UAAU,KAAK,KAAK,UAAU,QAC5C,SAAA,CAAAlC,EAAAA,IAACqK,GAAA,CAAO,UAAU,SAAA,CAAU,EAC3BxJ,EAAc,CAAE,GAAI,yBAA0B,EAC9CyF,EAAe,OAAS,GACvBtG,EAAAA,IAAC8B,EAAA,CAAM,QAAQ,YAAY,UAAU,wBAClC,SAAAwE,EAAe,MAAA,CAClB,CAAA,CAAA,CAEJ,CAAA,CACF,EACA1E,EAAAA,KAACQ,GAAA,CAAoB,MAAM,MAAM,UAAU,OACzC,SAAA,CAAApC,MAACsK,IAAmB,SAAAzJ,EAAc,CAAE,GAAI,4BAAA,CAA8B,EAAE,QACvE0B,EAAA,EAAsB,EACtBqG,EAAW,IAAKlD,GACf9D,EAAAA,KAACS,EAAA,CAEC,QAAS,IAAMgH,EAAqB3D,CAAG,EACvC,UAAU,kBAEV,SAAA,CAAA1F,EAAAA,IAAC,OAAA,CAAM,SAAA0F,EAAI,OAAO,CAAC,EAAE,cAAgBA,EAAI,MAAM,CAAC,CAAA,CAAE,EACjDY,EAAe,SAASZ,CAAG,SACzB,OAAA,CAAK,UAAU,eAAe,SAAA,GAAA,CAAQ,CAAA,CAAA,EANpCA,CAAA,CASR,EACAY,EAAe,OAAS,GACvB1E,EAAAA,KAAA2I,EAAAA,SAAA,CACE,SAAA,CAAAvK,EAAAA,IAACuC,EAAA,EAAsB,EACvBvC,EAAAA,IAACqC,EAAA,CAAiB,QAAS,IAAMkE,EAAkB,CAAA,CAAE,EAAG,UAAU,mBAC/D,SAAA1F,EAAc,CAAE,GAAI,6BAAA,CAA+B,CAAA,CACtD,CAAA,CAAA,CACF,CAAA,CAAA,CAEJ,CAAA,CAAA,CACF,CAAA,EAEJ,EAGC4I,GACC7H,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,gCAAiC,SAAA,CAAAf,EAAc,CAAE,GAAI,yBAA0B,EAAE,GAAA,EAAC,EACjGkF,IAAiB,OAChBnE,EAAAA,KAACE,EAAA,CACC,QAAQ,YACR,UAAU,iBACV,QAAS,IAAMkE,EAAgB,KAAK,EAEnC,SAAA,CAAAnF,EAAc,CAAE,GAAI,iBAAiBkF,CAAY,GAAI,EACtD/F,EAAAA,IAACoK,EAAA,CAAE,UAAU,cAAA,CAAe,CAAA,CAAA,CAAA,EAG/BlE,IAAmB,OAClBtE,EAAAA,KAACE,EAAA,CACC,QAAQ,YACR,UAAU,iBACV,QAAS,IAAMqE,EAAkB,KAAK,EAErC,SAAA,CAAAtF,EAAc,CAAE,GAAI,kBAAkBqF,CAAc,GAAI,EACzDlG,EAAAA,IAACoK,EAAA,CAAE,UAAU,cAAA,CAAe,CAAA,CAAA,CAAA,EAG/B9D,EAAe,IAAKZ,GACnB9D,EAAAA,KAACE,EAAA,CAEC,QAAQ,YACR,UAAU,iBACV,QAAS,IAAMuH,EAAqB3D,CAAG,EAEtC,SAAA,CAAAA,EAAI,OAAO,CAAC,EAAE,cAAgBA,EAAI,MAAM,CAAC,EAC1C1F,EAAAA,IAACoK,EAAA,CAAE,UAAU,cAAA,CAAe,CAAA,CAAA,EANvB1E,CAAA,CAQR,EACAU,GACCxE,EAAAA,KAACE,EAAA,CACC,QAAQ,YACR,UAAU,iBACV,QAASsH,EAER,SAAA,CAAAvI,EAAc,CAAE,GAAI,wBAAyB,EAAE,KAAGuF,EACnDpG,EAAAA,IAACoK,EAAA,CAAE,UAAU,cAAA,CAAe,CAAA,CAAA,CAAA,EAGhCpK,EAAAA,IAACkC,EAAA,CAAO,QAAQ,QAAQ,KAAK,KAAK,QAASsH,EAAc,UAAU,cAChE,SAAA3I,EAAc,CAAE,GAAI,yBAAA,CAA2B,CAAA,CAClD,CAAA,EACF,EAID2G,GACCxH,EAAAA,IAAC,MAAA,CAAI,UAAU,uDACZ,SAAA,MAAM,KAAK,CAAE,OAAQ,CAAA,CAAG,EAAE,IAAI,CAACwK,EAAGC,IACjCzK,EAAAA,IAAC0C,GAAA,CAAA,EAAsB+H,CAAG,CAC3B,CAAA,CACH,EACEnC,EAAc,SAAW,EAC3B1G,EAAAA,KAAC,MAAA,CAAI,UAAU,qGACb,SAAA,CAAA5B,EAAAA,IAACyC,GAAA,CAAS,UAAU,sCAAA,CAAuC,QAC1D,KAAA,CAAG,UAAU,2CACX,SAAmB5B,EAAnB4I,EAAiC,CAAE,GAAI,wBAAA,EAA4C,CAAE,GAAI,wBAAA,CAAxB,EACpE,QACC,IAAA,CAAE,UAAU,0DACV,SACG5I,EADH4I,EACiB,CAAE,GAAI,0BAAA,EACN,CAAE,GAAI,8BAAA,CAD4B,EAEtD,EACCA,QACEvH,EAAA,CAAO,QAAQ,UAAU,QAASsH,EAChC,WAAc,CAAE,GAAI,8BAA+B,CAAA,CACtD,EAEA5H,EAAAA,KAACM,EAAA,CAAO,QAAS,IAAM4E,EAAoB,EAAI,EAC7C,SAAA,CAAA9G,EAAAA,IAAC6J,GAAA,CAAK,UAAU,cAAA,CAAe,EAC9BhJ,EAAc,CAAE,GAAI,oBAAA,CAAsB,CAAA,CAAA,CAC7C,CAAA,CAAA,CAEJ,QAEC,MAAA,CAAI,UAAU,uDACZ,SAAAyH,EAAc,IAAKhI,GAClBN,EAAAA,IAACK,GAAA,CAEC,KAAAC,EACA,OAAQ0I,GACR,SAAUC,GACV,SAAU5H,GACV,gBAAiBgH,CAAA,EALZ/H,EAAK,EAAA,CAOb,EACH,EAIFN,EAAAA,IAAC6C,GAAA,CACC,KAAK,MACL,KAAMgE,EACN,QAAS,IAAMC,EAAoB,EAAK,EACxC,OAAQ,IAAMA,EAAoB,EAAK,CAAA,CAAA,EAIzC9G,EAAAA,IAAC6C,GAAA,CACC,KAAK,OACL,KAAMsE,GAAgB,OACtB,KAAMJ,EACN,QAAS,IAAM,CACbC,EAAkB,EAAK,EACvBI,EAAgB,IAAI,CACtB,EACA,OAAQ,IAAM,CACZJ,EAAkB,EAAK,EACvBI,EAAgB,IAAI,CACtB,CAAA,CAAA,QAIDrC,GAAA,CAAO,KAAMkC,EAAkB,aAAcC,EAC5C,gBAAClC,GAAA,CACC,SAAA,CAAApD,OAACqD,GAAA,CACC,SAAA,CAAAjF,MAACkF,IAAa,SAAArE,EAAc,CAAE,GAAI,0BAAA,CAA4B,EAAE,QAC/DsE,GAAA,CACE,SAAAtE,EAAc,CAAE,GAAI,4BAAA,CAA8B,CAAA,CACrD,CAAA,EACF,SACCgF,GAAA,CACC,SAAA,CAAA7F,EAAAA,IAACkC,EAAA,CACC,QAAQ,UACR,QAAS,IAAM,CACbgF,EAAoB,EAAK,EACzBI,EAAgB,IAAI,CACtB,EAEC,SAAAzG,EAAc,CAAE,GAAI,uBAAA,CAAyB,CAAA,CAAA,EAEhDb,EAAAA,IAACkC,EAAA,CACC,QAAQ,cACR,QAASgH,GACT,SAAUlB,EAET,SAAanH,EAAbmH,EAA2B,CAAE,GAAI,uBAAA,EAA2C,CAAE,GAAI,uBAAA,CAAxB,CAAiD,CAAA,CAC9G,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EACF,CAEJ"}
|
|
1
|
+
{"version":3,"file":"RulesManagerPage-CdBjTmth.js","sources":["../../src/components/shared/RuleCard.tsx","../../src/components/shared/RuleDialog.tsx","../../src/pages/RulesManagerPage.tsx"],"sourcesContent":["// ========================================\r\n// RuleCard Component\r\n// ========================================\r\n// Rule card with status badge and action menu\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { cn } from '@/lib/utils';\r\nimport { Card, CardContent } from '@/components/ui/Card';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Switch } from '@/components/ui/Switch';\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuSeparator,\r\n} from '@/components/ui/Dropdown';\r\nimport {\r\n FileCode,\r\n MoreVertical,\r\n Edit,\r\n Trash2,\r\n Folder,\r\n User,\r\n AlertCircle,\r\n AlertTriangle,\r\n Info,\r\n} from 'lucide-react';\r\nimport type { Rule } from '@/types/store';\r\n\r\nexport interface RuleCardProps {\r\n /** Rule data */\r\n rule: Rule;\r\n /** Called when edit action is triggered */\r\n onEdit?: (rule: Rule) => void;\r\n /** Called when delete action is triggered */\r\n onDelete?: (ruleId: string) => void;\r\n /** Called when toggle enabled is triggered */\r\n onToggle?: (ruleId: string, enabled: boolean) => void;\r\n /** Optional className */\r\n className?: string;\r\n /** Show actions dropdown */\r\n showActions?: boolean;\r\n /** Disabled state for actions */\r\n actionsDisabled?: boolean;\r\n}\r\n\r\n// Severity variant configuration (without labels for i18n)\r\nconst severityVariantConfig: Record<\r\n string,\r\n { variant: 'default' | 'secondary' | 'destructive' | 'success' | 'warning' | 'info'; icon: React.ReactNode }\r\n> = {\r\n error: { variant: 'destructive' as const, icon: <AlertCircle className=\"h-3 w-3\" /> },\r\n warning: { variant: 'warning' as const, icon: <AlertTriangle className=\"h-3 w-3\" /> },\r\n info: { variant: 'info' as const, icon: <Info className=\"h-3 w-3\" /> },\r\n};\r\n\r\n// Severity label keys for i18n\r\nconst severityLabelKeys: Record<string, string> = {\r\n error: 'rules.severity.error',\r\n warning: 'rules.severity.warning',\r\n info: 'rules.severity.info',\r\n};\r\n\r\n/**\r\n * RuleCard component for displaying rule information\r\n */\r\nexport function RuleCard({\r\n rule,\r\n onEdit,\r\n onDelete,\r\n onToggle,\r\n className,\r\n showActions = true,\r\n actionsDisabled = false,\r\n}: RuleCardProps) {\r\n const { formatMessage } = useIntl();\r\n\r\n const { variant: severityVariant, icon: severityIcon } = severityVariantConfig[rule.severity || 'info'] || {\r\n variant: 'default' as const,\r\n icon: null,\r\n };\r\n const severityLabel = rule.severity\r\n ? formatMessage({ id: severityLabelKeys[rule.severity] })\r\n : null;\r\n\r\n const locationIcon = rule.location === 'user' ? <User className=\"h-3 w-3\" /> : <Folder className=\"h-3 w-3\" />;\r\n\r\n const handleToggle = (enabled: boolean) => {\r\n onToggle?.(rule.id, enabled);\r\n };\r\n\r\n const handleAction = (e: React.MouseEvent, action: 'edit' | 'delete') => {\r\n e.stopPropagation();\r\n switch (action) {\r\n case 'edit':\r\n onEdit?.(rule);\r\n break;\r\n case 'delete':\r\n onDelete?.(rule.id);\r\n break;\r\n }\r\n };\r\n\r\n return (\r\n <Card\r\n className={cn(\r\n 'group transition-all duration-200 hover:shadow-md hover:border-primary/30 hover-glow',\r\n !rule.enabled && 'opacity-60',\r\n className\r\n )}\r\n >\r\n <CardContent className=\"p-4\">\r\n {/* Header */}\r\n <div className=\"flex items-start justify-between gap-2\">\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <h3 className=\"font-medium text-card-foreground truncate\">\r\n {rule.name}\r\n </h3>\r\n <div className=\"flex items-center gap-1 text-muted-foreground\" title={formatMessage({ id: rule.location === 'user' ? 'rules.location.user' : 'rules.location.project' })}>\r\n {locationIcon}\r\n </div>\r\n </div>\r\n {rule.category && (\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">\r\n {rule.category}\r\n </p>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2 flex-shrink-0\">\r\n {rule.enabled && rule.severity && (\r\n <Badge variant={severityVariant} className=\"gap-1\">\r\n {severityIcon}\r\n {severityLabel}\r\n </Badge>\r\n )}\r\n <Switch\r\n checked={rule.enabled}\r\n onCheckedChange={handleToggle}\r\n disabled={actionsDisabled}\r\n className=\"data-[state=checked]:bg-primary\"\r\n />\r\n {showActions && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"h-8 w-8 opacity-0 group-hover:opacity-100 transition-opacity\"\r\n onClick={(e) => e.stopPropagation()}\r\n disabled={actionsDisabled}\r\n >\r\n <MoreVertical className=\"h-4 w-4\" />\r\n <span className=\"sr-only\">{formatMessage({ id: 'common.aria.actions' })}</span>\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\">\r\n <DropdownMenuItem onClick={(e) => handleAction(e, 'edit')}>\r\n <Edit className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'rules.actions.edit' })}\r\n </DropdownMenuItem>\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem\r\n onClick={(e) => handleAction(e, 'delete')}\r\n className=\"text-destructive focus:text-destructive\"\r\n >\r\n <Trash2 className=\"mr-2 h-4 w-4\" />\r\n {formatMessage({ id: 'rules.actions.delete' })}\r\n </DropdownMenuItem>\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Description */}\r\n {rule.description && (\r\n <p className=\"mt-3 text-sm text-muted-foreground line-clamp-2\">\r\n {rule.description}\r\n </p>\r\n )}\r\n\r\n {/* Meta info */}\r\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-muted-foreground\">\r\n {rule.pattern && (\r\n <span className=\"flex items-center gap-1 font-mono\">\r\n <FileCode className=\"h-3.5 w-3.5\" />\r\n {rule.pattern}\r\n </span>\r\n )}\r\n {rule.subdirectory && (\r\n <span className=\"flex items-center gap-1\">\r\n <Folder className=\"h-3.5 w-3.5\" />\r\n {rule.subdirectory}\r\n </span>\r\n )}\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n\r\n/**\r\n * Skeleton loader for RuleCard\r\n */\r\nexport function RuleCardSkeleton({ className }: { className?: string }) {\r\n return (\r\n <Card className={cn('animate-pulse', className)}>\r\n <CardContent className=\"p-4\">\r\n <div className=\"flex items-start justify-between\">\r\n <div className=\"flex-1\">\r\n <div className=\"h-5 w-32 rounded bg-muted\" />\r\n <div className=\"mt-1 h-3 w-24 rounded bg-muted\" />\r\n </div>\r\n <div className=\"h-5 w-8 rounded-full bg-muted\" />\r\n <div className=\"h-8 w-8 rounded bg-muted\" />\r\n </div>\r\n <div className=\"mt-3 h-4 w-full rounded bg-muted\" />\r\n <div className=\"mt-2 flex gap-4\">\r\n <div className=\"h-3 w-20 rounded bg-muted\" />\r\n <div className=\"h-3 w-16 rounded bg-muted\" />\r\n </div>\r\n </CardContent>\r\n </Card>\r\n );\r\n}\r\n","// ========================================\r\n// RuleDialog Component\r\n// ========================================\r\n// Add/Edit dialog for rule configuration\r\n\r\nimport { useState, useEffect } from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogDescription,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Button } from '@/components/ui/Button';\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@/components/ui/Select';\r\nimport {\r\n createRule,\r\n updateRule,\r\n type Rule,\r\n type RuleCreateInput,\r\n} from '@/lib/api';\r\nimport { rulesKeys } from '@/hooks';\r\nimport { cn } from '@/lib/utils';\r\n\r\n// ========== Types ==========\r\n\r\nexport interface RuleDialogProps {\r\n mode: 'add' | 'edit';\r\n rule?: Rule;\r\n open: boolean;\r\n onClose: () => void;\r\n onSave?: () => void;\r\n}\r\n\r\ninterface RuleFormData {\r\n name: string;\r\n description: string;\r\n enabled: boolean;\r\n category: string;\r\n severity: Rule['severity'];\r\n fileName: string;\r\n location: 'project' | 'user';\r\n subdirectory: string;\r\n content: string;\r\n pattern: string;\r\n}\r\n\r\ninterface FormErrors {\r\n name?: string;\r\n fileName?: string;\r\n content?: string;\r\n location?: string;\r\n}\r\n\r\n// ========== Categories ==========\r\n\r\nconst RULE_CATEGORIES = [\r\n 'coding',\r\n 'testing',\r\n 'security',\r\n 'architecture',\r\n 'documentation',\r\n 'performance',\r\n 'workflow',\r\n 'tooling',\r\n 'general',\r\n];\r\n\r\nconst SEVERITY_LEVELS: Exclude<Rule['severity'], undefined>[] = ['error', 'warning', 'info'];\r\n\r\n// ========== Component ==========\r\n\r\nexport function RuleDialog({\r\n mode,\r\n rule,\r\n open,\r\n onClose,\r\n onSave,\r\n}: RuleDialogProps) {\r\n const { formatMessage } = useIntl();\r\n const queryClient = useQueryClient();\r\n\r\n // Form state\r\n const [formData, setFormData] = useState<RuleFormData>({\r\n name: '',\r\n description: '',\r\n enabled: true,\r\n category: 'general',\r\n severity: 'info',\r\n fileName: '',\r\n location: 'project',\r\n subdirectory: '',\r\n content: '',\r\n pattern: '',\r\n });\r\n\r\n const [errors, setErrors] = useState<FormErrors>({});\r\n\r\n // Initialize form from rule prop (edit mode)\r\n useEffect(() => {\r\n if (rule && mode === 'edit') {\r\n setFormData({\r\n name: rule.name,\r\n description: rule.description || '',\r\n enabled: rule.enabled,\r\n category: rule.category || 'general',\r\n severity: rule.severity || 'info',\r\n fileName: rule.path?.split(/[/\\\\]/).pop() || `${rule.name.toLowerCase().replace(/\\s+/g, '-')}.md`,\r\n location: rule.location || 'project',\r\n subdirectory: rule.subdirectory || '',\r\n content: '',\r\n pattern: rule.pattern || '',\r\n });\r\n } else {\r\n // Reset form for add mode\r\n setFormData({\r\n name: '',\r\n description: '',\r\n enabled: true,\r\n category: 'general',\r\n severity: 'info',\r\n fileName: '',\r\n location: 'project',\r\n subdirectory: '',\r\n content: '',\r\n pattern: '',\r\n });\r\n }\r\n setErrors({});\r\n }, [rule, mode, open]);\r\n\r\n // Mutations\r\n const createMutation = useMutation({\r\n mutationFn: (data: RuleCreateInput) => createRule(data),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: rulesKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n const updateMutation = useMutation({\r\n mutationFn: ({ ruleId, config }: { ruleId: string; config: Partial<Rule> }) =>\r\n updateRule(ruleId, config),\r\n onSuccess: () => {\r\n queryClient.invalidateQueries({ queryKey: rulesKeys.all });\r\n handleClose();\r\n onSave?.();\r\n },\r\n });\r\n\r\n // Handlers\r\n const handleClose = () => {\r\n setErrors({});\r\n onClose();\r\n };\r\n\r\n const handleFieldChange = (\r\n field: keyof RuleFormData,\r\n value: string | boolean | Rule['severity']\r\n ) => {\r\n setFormData((prev) => ({ ...prev, [field]: value }));\r\n // Clear error for this field\r\n if (errors[field as keyof FormErrors]) {\r\n setErrors((prev) => ({ ...prev, [field]: undefined }));\r\n }\r\n };\r\n\r\n // Auto-generate fileName from name if not set\r\n useEffect(() => {\r\n if (formData.name && !formData.fileName) {\r\n const generatedFileName = `${formData.name.toLowerCase().replace(/\\s+/g, '-')}.md`;\r\n setFormData((prev) => ({ ...prev, fileName: generatedFileName }));\r\n }\r\n }, [formData.name, formData.fileName]);\r\n\r\n const validateForm = (): boolean => {\r\n const newErrors: FormErrors = {};\r\n\r\n // Name required\r\n if (!formData.name.trim()) {\r\n newErrors.name = formatMessage({ id: 'rules.dialog.validation.nameRequired' });\r\n }\r\n\r\n // File name required\r\n if (!formData.fileName.trim()) {\r\n newErrors.fileName = formatMessage({ id: 'rules.dialog.validation.fileNameRequired' });\r\n }\r\n\r\n // File name must end with .md\r\n if (formData.fileName && !formData.fileName.endsWith('.md')) {\r\n newErrors.fileName = formatMessage({ id: 'rules.dialog.validation.fileNameMd' });\r\n }\r\n\r\n // Location required\r\n if (!formData.location) {\r\n newErrors.location = formatMessage({ id: 'rules.dialog.validation.locationRequired' });\r\n }\r\n\r\n // Content required for new rules\r\n if (mode === 'add' && !formData.content.trim()) {\r\n newErrors.content = formatMessage({ id: 'rules.dialog.validation.contentRequired' });\r\n }\r\n\r\n setErrors(newErrors);\r\n return Object.keys(newErrors).length === 0;\r\n };\r\n\r\n const handleSubmit = async () => {\r\n if (!validateForm()) {\r\n return;\r\n }\r\n\r\n if (mode === 'add') {\r\n const input: RuleCreateInput = {\r\n name: formData.name.trim(),\r\n description: formData.description.trim() || undefined,\r\n enabled: formData.enabled,\r\n category: formData.category || undefined,\r\n severity: formData.severity,\r\n fileName: formData.fileName.trim(),\r\n location: formData.location,\r\n subdirectory: formData.subdirectory.trim() || undefined,\r\n content: formData.content.trim(),\r\n pattern: formData.pattern.trim() || undefined,\r\n };\r\n createMutation.mutate(input);\r\n } else {\r\n updateMutation.mutate({\r\n ruleId: rule!.id,\r\n config: {\r\n name: formData.name.trim(),\r\n description: formData.description.trim() || undefined,\r\n enabled: formData.enabled,\r\n category: formData.category || undefined,\r\n severity: formData.severity,\r\n pattern: formData.pattern.trim() || undefined,\r\n },\r\n });\r\n }\r\n };\r\n\r\n const isPending = createMutation.isPending || updateMutation.isPending;\r\n\r\n return (\r\n <Dialog open={open} onOpenChange={handleClose}>\r\n <DialogContent className=\"max-w-2xl max-h-[90vh] overflow-y-auto\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {mode === 'add'\r\n ? formatMessage({ id: 'rules.dialog.addTitle' })\r\n : formatMessage({ id: 'rules.dialog.editTitle' }, { name: rule?.name })}\r\n </DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'rules.dialog.description' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n\r\n <div className=\"space-y-4\">\r\n {/* Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.name' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.name}\r\n onChange={(e) => handleFieldChange('name', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.namePlaceholder' })}\r\n error={!!errors.name}\r\n />\r\n {errors.name && (\r\n <p className=\"text-sm text-destructive\">{errors.name}</p>\r\n )}\r\n </div>\r\n\r\n {/* Description */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.description' })}\r\n </label>\r\n <Input\r\n value={formData.description}\r\n onChange={(e) => handleFieldChange('description', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.descriptionPlaceholder' })}\r\n />\r\n </div>\r\n\r\n {/* Category */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.category' })}\r\n </label>\r\n <Select value={formData.category} onValueChange={(v) => handleFieldChange('category', v)}>\r\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {RULE_CATEGORIES.map((cat) => (\r\n <SelectItem key={cat} value={cat}>\r\n {cat.charAt(0).toUpperCase() + cat.slice(1)}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* Severity */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.severity' })}\r\n </label>\r\n <Select\r\n value={formData.severity}\r\n onValueChange={(v) => handleFieldChange('severity', v as Rule['severity'])}\r\n >\r\n <SelectTrigger>\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n {SEVERITY_LEVELS.map((sev) => (\r\n <SelectItem key={sev} value={sev}>\r\n {formatMessage({ id: `rules.severity.${sev}` })}\r\n </SelectItem>\r\n ))}\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {/* File Name */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.fileName' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <Input\r\n value={formData.fileName}\r\n onChange={(e) => handleFieldChange('fileName', e.target.value)}\r\n placeholder=\"rule-name.md\"\r\n error={!!errors.fileName}\r\n />\r\n {errors.fileName && (\r\n <p className=\"text-sm text-destructive\">{errors.fileName}</p>\r\n )}\r\n </div>\r\n\r\n {/* Location */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.location' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <div className=\"flex gap-4\">\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"location\"\r\n value=\"project\"\r\n checked={formData.location === 'project'}\r\n onChange={(e) => handleFieldChange('location', e.target.value as 'project' | 'user')}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'rules.location.project' })}\r\n </span>\r\n </label>\r\n <label className=\"flex items-center gap-2 cursor-pointer\">\r\n <input\r\n type=\"radio\"\r\n name=\"location\"\r\n value=\"user\"\r\n checked={formData.location === 'user'}\r\n onChange={(e) => handleFieldChange('location', e.target.value as 'project' | 'user')}\r\n className=\"w-4 h-4\"\r\n />\r\n <span className=\"text-sm\">\r\n {formatMessage({ id: 'rules.location.user' })}\r\n </span>\r\n </label>\r\n </div>\r\n {errors.location && (\r\n <p className=\"text-sm text-destructive\">{errors.location}</p>\r\n )}\r\n </div>\r\n\r\n {/* Subdirectory */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.subdirectory' })}\r\n </label>\r\n <Input\r\n value={formData.subdirectory}\r\n onChange={(e) => handleFieldChange('subdirectory', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.subdirectoryPlaceholder' })}\r\n />\r\n </div>\r\n\r\n {/* Pattern */}\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.pattern' })}\r\n </label>\r\n <Input\r\n value={formData.pattern}\r\n onChange={(e) => handleFieldChange('pattern', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.patternPlaceholder' })}\r\n />\r\n </div>\r\n\r\n {/* Content (only for new rules) */}\r\n {mode === 'add' && (\r\n <div className=\"space-y-2\">\r\n <label className=\"text-sm font-medium text-foreground\">\r\n {formatMessage({ id: 'rules.dialog.form.content' })}\r\n <span className=\"text-destructive ml-1\">*</span>\r\n </label>\r\n <textarea\r\n value={formData.content}\r\n onChange={(e) => handleFieldChange('content', e.target.value)}\r\n placeholder={formatMessage({ id: 'rules.dialog.form.contentPlaceholder' })}\r\n className={cn(\r\n 'flex min-h-[150px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\r\n errors.content && 'border-destructive focus-visible:ring-destructive'\r\n )}\r\n />\r\n {errors.content && (\r\n <p className=\"text-sm text-destructive\">{errors.content}</p>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Enabled */}\r\n <div className=\"flex items-center gap-2\">\r\n <input\r\n type=\"checkbox\"\r\n id=\"enabled\"\r\n checked={formData.enabled}\r\n onChange={(e) => handleFieldChange('enabled', e.target.checked)}\r\n className=\"w-4 h-4\"\r\n />\r\n <label htmlFor=\"enabled\" className=\"text-sm font-medium text-foreground cursor-pointer\">\r\n {formatMessage({ id: 'rules.dialog.form.enabled' })}\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={handleClose}\r\n disabled={isPending}\r\n >\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button\r\n onClick={handleSubmit}\r\n disabled={isPending}\r\n >\r\n {isPending\r\n ? formatMessage({ id: 'rules.dialog.actions.saving' })\r\n : formatMessage({ id: 'common.actions.save' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n );\r\n}\r\n\r\nexport default RuleDialog;\r\n","// ========================================\r\n// RulesManagerPage Component\r\n// ========================================\r\n// Rules list page with CRUD operations\r\n\r\nimport * as React from 'react';\r\nimport { useIntl } from 'react-intl';\r\nimport {\r\n Plus,\r\n RefreshCw,\r\n Search,\r\n Filter,\r\n AlertCircle,\r\n FileCode,\r\n X,\r\n Folder,\r\n User,\r\n Globe,\r\n Maximize2,\r\n Minimize2,\r\n} from 'lucide-react';\r\nimport { useAppStore, selectIsImmersiveMode } from '@/stores/appStore';\r\nimport {\r\n useRules,\r\n useCreateRule,\r\n useDeleteRule,\r\n useToggleRule,\r\n} from '@/hooks';\r\nimport { RuleCard, RuleCardSkeleton } from '@/components/shared/RuleCard';\r\nimport { RuleDialog } from '@/components/shared/RuleDialog';\r\nimport { Button } from '@/components/ui/Button';\r\nimport { Input } from '@/components/ui/Input';\r\nimport { Badge } from '@/components/ui/Badge';\r\nimport { TabsNavigation } from '@/components/ui/TabsNavigation';\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogDescription,\r\n DialogFooter,\r\n} from '@/components/ui/Dialog';\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuTrigger,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuSeparator,\r\n DropdownMenuLabel,\r\n} from '@/components/ui/Dropdown';\r\nimport { Tabs, TabsList, TabsTrigger } from '@/components/ui/Tabs';\r\nimport { cn } from '@/lib/utils';\r\nimport type { Rule } from '@/types/store';\r\n\r\ntype StatusFilter = 'all' | 'enabled' | 'disabled';\r\ntype LocationFilter = 'all' | 'project' | 'user';\r\n\r\n/**\r\n * RulesManagerPage component - Rules list with CRUD operations\r\n */\r\nexport function RulesManagerPage() {\r\n const { formatMessage } = useIntl();\r\n\r\n // Filter state\r\n const [statusFilter, setStatusFilter] = React.useState<StatusFilter>('all');\r\n const [locationFilter, setLocationFilter] = React.useState<LocationFilter>('all');\r\n const [searchQuery, setSearchQuery] = React.useState('');\r\n const [categoryFilter, setCategoryFilter] = React.useState<string[]>([]);\r\n\r\n // Immersive mode state\r\n const isImmersiveMode = useAppStore(selectIsImmersiveMode);\r\n const toggleImmersiveMode = useAppStore((s) => s.toggleImmersiveMode);\r\n\r\n // Dialog state\r\n const [createDialogOpen, setCreateDialogOpen] = React.useState(false);\r\n const [editDialogOpen, setEditDialogOpen] = React.useState(false);\r\n const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);\r\n const [selectedRule, setSelectedRule] = React.useState<Rule | null>(null);\r\n const [ruleToDelete, setRuleToDelete] = React.useState<string | null>(null);\r\n\r\n // Fetch rules\r\n const {\r\n rules,\r\n isLoading,\r\n isFetching,\r\n error,\r\n refetch,\r\n } = useRules();\r\n\r\n // Mutations\r\n const { isCreating } = useCreateRule();\r\n const { deleteRule, isDeleting } = useDeleteRule();\r\n const { toggleRule, isToggling } = useToggleRule();\r\n\r\n const isMutating = isCreating || isDeleting || isToggling;\r\n\r\n // Filter rules\r\n const filteredRules = React.useMemo(() => {\r\n let filtered = rules;\r\n\r\n // Status filter\r\n if (statusFilter === 'enabled') {\r\n filtered = filtered.filter((r) => r.enabled);\r\n } else if (statusFilter === 'disabled') {\r\n filtered = filtered.filter((r) => !r.enabled);\r\n }\r\n\r\n // Location filter\r\n if (locationFilter === 'project') {\r\n filtered = filtered.filter((r) => r.location === 'project');\r\n } else if (locationFilter === 'user') {\r\n filtered = filtered.filter((r) => r.location === 'user');\r\n }\r\n\r\n // Category filter\r\n if (categoryFilter.length > 0) {\r\n filtered = filtered.filter((r) =>\r\n r.category ? categoryFilter.includes(r.category) : false\r\n );\r\n }\r\n\r\n // Search filter\r\n if (searchQuery) {\r\n const query = searchQuery.toLowerCase();\r\n filtered = filtered.filter((r) =>\r\n r.name.toLowerCase().includes(query) ||\r\n r.description?.toLowerCase().includes(query) ||\r\n r.category?.toLowerCase().includes(query)\r\n );\r\n }\r\n\r\n return filtered;\r\n }, [rules, statusFilter, locationFilter, categoryFilter, searchQuery]);\r\n\r\n // Get all unique categories\r\n const categories = React.useMemo(() => {\r\n const cats = new Set<string>();\r\n rules.forEach((r) => {\r\n if (r.category) cats.add(r.category);\r\n });\r\n return Array.from(cats).sort();\r\n }, [rules]);\r\n\r\n // Count rules by location\r\n const projectRulesCount = React.useMemo(() =>\r\n rules.filter((r) => r.location === 'project').length, [rules]);\r\n const userRulesCount = React.useMemo(() =>\r\n rules.filter((r) => r.location === 'user').length, [rules]);\r\n\r\n // Handlers\r\n const handleEditClick = (rule: Rule) => {\r\n setSelectedRule(rule);\r\n setEditDialogOpen(true);\r\n };\r\n\r\n const handleDeleteClick = (ruleId: string) => {\r\n setRuleToDelete(ruleId);\r\n setDeleteDialogOpen(true);\r\n };\r\n\r\n const handleConfirmDelete = async () => {\r\n if (!ruleToDelete) return;\r\n\r\n try {\r\n const rule = rules.find((r) => r.id === ruleToDelete);\r\n await deleteRule(ruleToDelete, rule?.location);\r\n setDeleteDialogOpen(false);\r\n setRuleToDelete(null);\r\n } catch (err) {\r\n console.error('Failed to delete rule:', err);\r\n }\r\n };\r\n\r\n const handleToggle = async (ruleId: string, enabled: boolean) => {\r\n try {\r\n await toggleRule(ruleId, enabled);\r\n } catch (err) {\r\n console.error('Failed to toggle rule:', err);\r\n }\r\n };\r\n\r\n const handleClearSearch = () => {\r\n setSearchQuery('');\r\n };\r\n\r\n const toggleCategoryFilter = (category: string) => {\r\n setCategoryFilter((prev) =>\r\n prev.includes(category) ? prev.filter((c) => c !== category) : [...prev, category]\r\n );\r\n };\r\n\r\n const clearFilters = () => {\r\n setStatusFilter('all');\r\n setLocationFilter('all');\r\n setCategoryFilter([]);\r\n setSearchQuery('');\r\n };\r\n\r\n const hasActiveFilters = statusFilter !== 'all' || locationFilter !== 'all' ||\r\n categoryFilter.length > 0 || searchQuery.length > 0;\r\n\r\n return (\r\n <div className={cn(\"space-y-6\", isImmersiveMode && \"h-screen overflow-hidden\")}>\r\n {/* Header */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\r\n <div>\r\n <h1 className=\"text-2xl font-semibold text-foreground\">{formatMessage({ id: 'rules.title' })}</h1>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {formatMessage({ id: 'rules.description' })}\r\n </p>\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={toggleImmersiveMode}\r\n className={cn(\r\n 'p-2 rounded-md transition-colors',\r\n isImmersiveMode\r\n ? 'bg-primary/10 text-primary'\r\n : 'text-muted-foreground hover:text-foreground hover:bg-muted'\r\n )}\r\n title={isImmersiveMode ? 'Exit Fullscreen' : 'Fullscreen'}\r\n >\r\n {isImmersiveMode ? <Minimize2 className=\"w-4 h-4\" /> : <Maximize2 className=\"w-4 h-4\" />}\r\n </button>\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={() => refetch()}\r\n disabled={isFetching}\r\n >\r\n <RefreshCw className={cn('h-4 w-4 mr-2', isFetching && 'animate-spin')} />\r\n {formatMessage({ id: 'common.actions.refresh' })}\r\n </Button>\r\n <Button size=\"sm\" onClick={() => setCreateDialogOpen(true)}>\r\n <Plus className=\"h-4 w-4 mr-2\" />\r\n {formatMessage({ id: 'common.actions.new' })}\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Error alert */}\r\n {error && (\r\n <div className=\"flex items-center gap-2 p-4 rounded-lg bg-destructive/10 border border-destructive/30 text-destructive\">\r\n <AlertCircle className=\"h-5 w-5 flex-shrink-0\" />\r\n <div className=\"flex-1\">\r\n <p className=\"text-sm font-medium\">{formatMessage({ id: 'common.errors.loadFailed' })}</p>\r\n <p className=\"text-xs mt-0.5\">{error.message}</p>\r\n </div>\r\n <Button variant=\"outline\" size=\"sm\" onClick={() => refetch()}>\r\n {formatMessage({ id: 'home.errors.retry' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* Location Tabs - styled like LiteTasksPage */}\r\n <TabsNavigation\r\n value={locationFilter}\r\n onValueChange={(v) => setLocationFilter(v as LocationFilter)}\r\n tabs={[\r\n {\r\n value: 'all',\r\n label: formatMessage({ id: 'rules.filters.all' }),\r\n icon: <Globe className=\"h-4 w-4\" />,\r\n badge: <Badge variant=\"secondary\" className=\"ml-2\">{rules.length}</Badge>,\r\n disabled: isMutating,\r\n },\r\n {\r\n value: 'project',\r\n label: formatMessage({ id: 'rules.location.project' }),\r\n icon: <Folder className=\"h-4 w-4\" />,\r\n badge: <Badge variant=\"secondary\" className=\"ml-2\">{projectRulesCount}</Badge>,\r\n disabled: isMutating,\r\n },\r\n {\r\n value: 'user',\r\n label: formatMessage({ id: 'rules.location.user' }),\r\n icon: <User className=\"h-4 w-4\" />,\r\n badge: <Badge variant=\"secondary\" className=\"ml-2\">{userRulesCount}</Badge>,\r\n disabled: isMutating,\r\n },\r\n ]}\r\n />\r\n\r\n {/* Filters */}\r\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\r\n {/* Status tabs */}\r\n <Tabs value={statusFilter} onValueChange={(v) => setStatusFilter(v as StatusFilter)}>\r\n <TabsList>\r\n <TabsTrigger value=\"all\">{formatMessage({ id: 'rules.filters.all' })}</TabsTrigger>\r\n <TabsTrigger value=\"enabled\">{formatMessage({ id: 'rules.filters.enabled' })}</TabsTrigger>\r\n <TabsTrigger value=\"disabled\">{formatMessage({ id: 'rules.filters.disabled' })}</TabsTrigger>\r\n </TabsList>\r\n </Tabs>\r\n\r\n {/* Search input */}\r\n <div className=\"flex-1 max-w-sm relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\r\n <Input\r\n placeholder={formatMessage({ id: 'rules.searchPlaceholder' })}\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n className=\"pl-9 pr-9\"\r\n />\r\n {searchQuery && (\r\n <button\r\n onClick={handleClearSearch}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground\"\r\n >\r\n <X className=\"h-4 w-4\" />\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Category filter dropdown */}\r\n {categories.length > 0 && (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button variant=\"outline\" size=\"sm\" className=\"gap-2\">\r\n <Filter className=\"h-4 w-4\" />\r\n {formatMessage({ id: 'rules.filters.category' })}\r\n {categoryFilter.length > 0 && (\r\n <Badge variant=\"secondary\" className=\"ml-1 h-5 min-w-5 px-1\">\r\n {categoryFilter.length}\r\n </Badge>\r\n )}\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\" className=\"w-48\">\r\n <DropdownMenuLabel>{formatMessage({ id: 'rules.dialog.form.category' })}</DropdownMenuLabel>\r\n <DropdownMenuSeparator />\r\n {categories.map((cat) => (\r\n <DropdownMenuItem\r\n key={cat}\r\n onClick={() => toggleCategoryFilter(cat)}\r\n className=\"justify-between\"\r\n >\r\n <span>{cat.charAt(0).toUpperCase() + cat.slice(1)}</span>\r\n {categoryFilter.includes(cat) && (\r\n <span className=\"text-primary\">✓</span>\r\n )}\r\n </DropdownMenuItem>\r\n ))}\r\n {categoryFilter.length > 0 && (\r\n <>\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem onClick={() => setCategoryFilter([])} className=\"text-destructive\">\r\n {formatMessage({ id: 'common.actions.clearFilters' })}\r\n </DropdownMenuItem>\r\n </>\r\n )}\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n )}\r\n </div>\r\n\r\n {/* Active filters display */}\r\n {hasActiveFilters && (\r\n <div className=\"flex flex-wrap items-center gap-2\">\r\n <span className=\"text-sm text-muted-foreground\">{formatMessage({ id: 'common.actions.filters' })}:</span>\r\n {statusFilter !== 'all' && (\r\n <Badge\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={() => setStatusFilter('all')}\r\n >\r\n {formatMessage({ id: `rules.filters.${statusFilter}` })}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n )}\r\n {locationFilter !== 'all' && (\r\n <Badge\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={() => setLocationFilter('all')}\r\n >\r\n {formatMessage({ id: `rules.location.${locationFilter}` })}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n )}\r\n {categoryFilter.map((cat) => (\r\n <Badge\r\n key={cat}\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={() => toggleCategoryFilter(cat)}\r\n >\r\n {cat.charAt(0).toUpperCase() + cat.slice(1)}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n ))}\r\n {searchQuery && (\r\n <Badge\r\n variant=\"secondary\"\r\n className=\"cursor-pointer\"\r\n onClick={handleClearSearch}\r\n >\r\n {formatMessage({ id: 'common.actions.search' })}: {searchQuery}\r\n <X className=\"ml-1 h-3 w-3\" />\r\n </Badge>\r\n )}\r\n <Button variant=\"ghost\" size=\"sm\" onClick={clearFilters} className=\"h-6 text-xs\">\r\n {formatMessage({ id: 'common.actions.clearAll' })}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* Rules grid */}\r\n {isLoading ? (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {Array.from({ length: 9 }).map((_, i) => (\r\n <RuleCardSkeleton key={i} />\r\n ))}\r\n </div>\r\n ) : filteredRules.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center py-16 px-4 border border-dashed border-border rounded-lg\">\r\n <FileCode className=\"h-12 w-12 text-muted-foreground mb-4\" />\r\n <h3 className=\"text-lg font-medium text-foreground mb-1\">\r\n {hasActiveFilters ? formatMessage({ id: 'rules.emptyState.title' }) : formatMessage({ id: 'rules.emptyState.title' })}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground text-center max-w-sm mb-4\">\r\n {hasActiveFilters\r\n ? formatMessage({ id: 'rules.emptyState.message' })\r\n : formatMessage({ id: 'rules.emptyState.createFirst' })}\r\n </p>\r\n {hasActiveFilters ? (\r\n <Button variant=\"outline\" onClick={clearFilters}>\r\n {formatMessage({ id: 'common.actions.clearFilters' })}\r\n </Button>\r\n ) : (\r\n <Button onClick={() => setCreateDialogOpen(true)}>\r\n <Plus className=\"h-4 w-4 mr-2\" />\r\n {formatMessage({ id: 'common.actions.new' })}\r\n </Button>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3\">\r\n {filteredRules.map((rule) => (\r\n <RuleCard\r\n key={rule.id}\r\n rule={rule}\r\n onEdit={handleEditClick}\r\n onDelete={handleDeleteClick}\r\n onToggle={handleToggle}\r\n actionsDisabled={isMutating}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n\r\n {/* Create Rule Dialog */}\r\n <RuleDialog\r\n mode=\"add\"\r\n open={createDialogOpen}\r\n onClose={() => setCreateDialogOpen(false)}\r\n onSave={() => setCreateDialogOpen(false)}\r\n />\r\n\r\n {/* Edit Rule Dialog */}\r\n <RuleDialog\r\n mode=\"edit\"\r\n rule={selectedRule || undefined}\r\n open={editDialogOpen}\r\n onClose={() => {\r\n setEditDialogOpen(false);\r\n setSelectedRule(null);\r\n }}\r\n onSave={() => {\r\n setEditDialogOpen(false);\r\n setSelectedRule(null);\r\n }}\r\n />\r\n\r\n {/* Delete Confirmation Dialog */}\r\n <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>\r\n <DialogContent>\r\n <DialogHeader>\r\n <DialogTitle>{formatMessage({ id: 'rules.dialog.deleteTitle' })}</DialogTitle>\r\n <DialogDescription>\r\n {formatMessage({ id: 'rules.dialog.deleteConfirm' })}\r\n </DialogDescription>\r\n </DialogHeader>\r\n <DialogFooter>\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => {\r\n setDeleteDialogOpen(false);\r\n setRuleToDelete(null);\r\n }}\r\n >\r\n {formatMessage({ id: 'common.actions.cancel' })}\r\n </Button>\r\n <Button\r\n variant=\"destructive\"\r\n onClick={handleConfirmDelete}\r\n disabled={isDeleting}\r\n >\r\n {isDeleting ? formatMessage({ id: 'rules.status.deleting' }) : formatMessage({ id: 'common.actions.delete' })}\r\n </Button>\r\n </DialogFooter>\r\n </DialogContent>\r\n </Dialog>\r\n </div>\r\n );\r\n}\r\n\r\nexport default RulesManagerPage;\r\n"],"names":["severityVariantConfig","jsx","AlertCircle","AlertTriangle","Info","severityLabelKeys","RuleCard","rule","onEdit","onDelete","onToggle","className","showActions","actionsDisabled","formatMessage","useIntl","severityVariant","severityIcon","severityLabel","locationIcon","User","Folder","handleToggle","enabled","handleAction","e","action","Card","cn","jsxs","CardContent","Badge","Switch","DropdownMenu","DropdownMenuTrigger","Button","MoreVertical","DropdownMenuContent","DropdownMenuItem","Edit","DropdownMenuSeparator","Trash2","FileCode","RuleCardSkeleton","RULE_CATEGORIES","SEVERITY_LEVELS","RuleDialog","mode","open","onClose","onSave","queryClient","useQueryClient","formData","setFormData","useState","errors","setErrors","useEffect","_a","createMutation","useMutation","data","createRule","rulesKeys","handleClose","updateMutation","ruleId","config","updateRule","handleFieldChange","field","value","prev","generatedFileName","validateForm","newErrors","handleSubmit","input","isPending","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","Input","Select","v","SelectTrigger","SelectValue","SelectContent","cat","SelectItem","sev","DialogFooter","RulesManagerPage","statusFilter","setStatusFilter","React.useState","locationFilter","setLocationFilter","searchQuery","setSearchQuery","categoryFilter","setCategoryFilter","isImmersiveMode","useAppStore","selectIsImmersiveMode","toggleImmersiveMode","s","createDialogOpen","setCreateDialogOpen","editDialogOpen","setEditDialogOpen","deleteDialogOpen","setDeleteDialogOpen","selectedRule","setSelectedRule","ruleToDelete","setRuleToDelete","rules","isLoading","isFetching","error","refetch","useRules","isCreating","useCreateRule","deleteRule","isDeleting","useDeleteRule","toggleRule","isToggling","useToggleRule","isMutating","filteredRules","React.useMemo","filtered","r","query","_b","categories","cats","projectRulesCount","userRulesCount","handleEditClick","handleDeleteClick","handleConfirmDelete","err","handleClearSearch","toggleCategoryFilter","category","c","clearFilters","hasActiveFilters","Minimize2","Maximize2","RefreshCw","Plus","TabsNavigation","Globe","Tabs","TabsList","TabsTrigger","Search","X","Filter","DropdownMenuLabel","Fragment","_","i"],"mappings":"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"}
|
package/ccw/frontend/dist/assets/{SessionDetailPage-iMn0k84i.js → SessionDetailPage-B9ZK7LvX.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{O as se,a9 as ye,aa as ke,ab as De,ac as Ce,j as e,e as D,N as T,u as N,M as B,ad as H,c as ue,r as v,K as pe,D as _e,d as Te,B as p,f as Se,g as Me,L as J,C as w,a as y,ae as Le,af as fe,a1 as te,i as W,ag as U,ah as Fe,ai as R,aj as $,m as ge,ak as Pe,S as Ae,Y as Ie,al as Oe,x as qe,y as Ee,z as Be,A as Re,G as $e,am as ze,an as Ue,k as Ke,ao as je,ap as Ve,b as Z,aq as He,ar as Je,as as We,at as Ze,au as A,av as Ge,aw as Qe,H as Xe,n as Ye,J as K}from"./index-
|
|
1
|
+
import{O as se,a9 as ye,aa as ke,ab as De,ac as Ce,j as e,e as D,N as T,u as N,M as B,ad as H,c as ue,r as v,K as pe,D as _e,d as Te,B as p,f as Se,g as Me,L as J,C as w,a as y,ae as Le,af as fe,a1 as te,i as W,ag as U,ah as Fe,ai as R,aj as $,m as ge,ak as Pe,S as Ae,Y as Ie,al as Oe,x as qe,y as Ee,z as Be,A as Re,G as $e,am as ze,an as Ue,k as Ke,ao as je,ap as Ve,b as Z,aq as He,ar as Je,as as We,at as Ze,au as A,av as Ge,aw as Qe,H as Xe,n as Ye,J as K}from"./index-rLgoBCfV.js";import{C as G,a as Q,b as X}from"./Collapsible-DEm1rJ4h.js";import{F as xe,E as es,A as ss,C as ts,T as as}from"./TaskDrawer-BJkwfhIZ.js";import{P as I}from"./package-CH3smL37.js";import{T as ns}from"./test-tube-BHm7w3ON.js";import{S as is}from"./square-check-big-BbngGB2h.js";import{F as O}from"./file-text-DwuwPDPi.js";import{E as Ne}from"./eye-D3NY0bm6.js";import{T as ls}from"./TabsNavigation-DZAAspqR.js";import"./link-koEYiemK.js";import"./index-Bs80iCX0.js";/* empty css */import"./folder-CL6vb42J.js";/**
|
|
2
2
|
* @license lucide-react v0.460.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -20,4 +20,4 @@ import{O as se,a9 as ye,aa as ke,ab as De,ac as Ce,j as e,e as D,N as T,u as N,M
|
|
|
20
20
|
`),o=l.slice(0,5).join(`
|
|
21
21
|
`),i=l.length>5;return e.jsxs(e.Fragment,{children:[e.jsxs(w,{children:[e.jsx(R,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs($,{className:"flex items-center gap-2",children:[e.jsx(Y,{className:"w-5 h-5"}),t({id:"sessionDetail.implPlan.title"})]}),e.jsxs(D,{variant:"outline",size:"sm",onClick:()=>n(!0),children:[e.jsx(Ne,{className:"w-4 h-4 mr-1"}),t({id:"common.actions.view"})]})]})}),e.jsxs(y,{children:[e.jsxs("pre",{className:"text-sm text-muted-foreground whitespace-pre-wrap",children:[o,i&&`
|
|
22
22
|
...`]}),i&&e.jsx("div",{className:"mt-4",children:e.jsx(D,{variant:"outline",size:"sm",onClick:()=>n(!0),className:"w-full",children:t({id:"sessionDetail.implPlan.viewFull"},{count:l.length})})})]})]}),e.jsx(be,{isOpen:a,onClose:()=>n(!1),title:"IMPL_PLAN.md",content:s,contentType:"markdown",maxWidth:"3xl"})]})}function ws({conflicts:s}){const{formatMessage:t}=N();if(!s)return e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(ee,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium text-foreground mb-2",children:t({id:"sessionDetail.conflict.empty.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t({id:"sessionDetail.conflict.empty.message"})})]});const a=s.user_decisions&&Object.keys(s.user_decisions).length>0,n=s.resolved_conflicts&&s.resolved_conflicts.length>0;return!a&&!n?e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(ee,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium text-foreground mb-2",children:t({id:"sessionDetail.conflict.empty.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t({id:"sessionDetail.conflict.empty.message"})})]}):e.jsxs("div",{className:"space-y-6",children:[s.resolved_at&&e.jsxs("div",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[e.jsx(Ke,{className:"h-4 w-4 text-success"}),e.jsxs("span",{children:[t({id:"sessionDetail.conflict.resolvedAt"}),":"," ",new Date(s.resolved_at).toLocaleString()]})]}),a&&e.jsx(w,{children:e.jsxs(y,{className:"p-6",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground mb-4",children:t({id:"sessionDetail.conflict.userDecisions"})}),e.jsx("div",{className:"space-y-3",children:Object.entries(s.user_decisions).map(([l,o],i)=>e.jsxs(G,{defaultOpen:i<3,children:[e.jsxs(Q,{className:"flex items-center gap-2 w-full text-left p-3 rounded-lg hover:bg-accent/50 transition-colors",children:[e.jsx(je,{className:"h-4 w-4 transition-transform data-[state=open]:rotate-90"}),e.jsx("span",{className:"font-medium text-sm flex-1",children:l}),e.jsx(p,{variant:"success",className:"text-xs",children:o.choice})]}),e.jsxs(X,{className:"pl-6 pr-3 pb-3 space-y-2",children:[o.description&&e.jsxs("div",{className:"text-sm text-foreground",children:[e.jsxs("span",{className:"font-medium",children:[t({id:"sessionDetail.conflict.description"}),":"]})," ",o.description]}),o.implications&&e.jsxs("div",{className:"text-sm text-muted-foreground",children:[e.jsxs("span",{className:"font-medium",children:[t({id:"sessionDetail.conflict.implications"}),":"]})," ",o.implications]})]})]},l))})]})}),n&&e.jsx(w,{children:e.jsxs(y,{className:"p-6",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground mb-4",children:t({id:"sessionDetail.conflict.resolvedConflicts"})}),e.jsx("div",{className:"space-y-3",children:s.resolved_conflicts.map(l=>e.jsxs(G,{children:[e.jsxs(Q,{className:"flex items-center gap-2 w-full text-left p-3 rounded-lg hover:bg-accent/50 transition-colors",children:[e.jsx(Ve,{className:"h-4 w-4 transition-transform data-[state=closed]:rotate-[-90deg]"}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"font-medium text-sm",children:l.id}),l.category&&e.jsx(p,{variant:"outline",className:"text-xs",children:l.category})]}),l.brief&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1",children:l.brief})]})]}),e.jsx(X,{className:"pl-6 pr-3 pb-3",children:l.strategy&&e.jsxs("div",{className:"text-sm text-foreground",children:[e.jsxs("span",{className:"font-medium",children:[t({id:"sessionDetail.conflict.strategy"}),":"]})," ",l.strategy]})})]},l.id))})]})})]})}function ys(s){switch(s){case"critical":return"destructive";case"high":return"warning";case"medium":return"default";case"low":return"secondary";default:return"secondary"}}function ks(s){switch(s){case"critical":return"border-destructive";case"high":return"border-orange-500";case"medium":return"border-yellow-500";case"low":return"border-blue-500";default:return"border-border"}}function Ds(s){switch(s){case"critical":case"high":return e.jsx(ge,{className:"h-4 w-4"});case"medium":return e.jsx(Qe,{className:"h-4 w-4"});case"low":return e.jsx(Ge,{className:"h-4 w-4"});default:return null}}function Cs({review:s}){const{formatMessage:t}=N(),[a,n]=v.useState("all");if(!s||!s.dimensions||s.dimensions.length===0)return e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Z,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium text-foreground mb-2",children:t({id:"sessionDetail.review.empty.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t({id:"sessionDetail.review.empty.message"})})]});const l=s.dimensions.map(i=>{var c;return{...i,findings:(c=i.findings)==null?void 0:c.filter(x=>a==="all"||x.severity===a)}}).filter(i=>i.findings&&i.findings.length>0);return l.some(i=>i.findings&&i.findings.length>0)?e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsx("span",{className:"text-sm font-medium text-foreground",children:t({id:"sessionDetail.review.filterBySeverity"})}),e.jsxs(He,{value:a,onValueChange:i=>n(i),children:[e.jsx(Je,{className:"w-48",children:e.jsx(We,{})}),e.jsxs(Ze,{children:[e.jsx(A,{value:"all",children:t({id:"sessionDetail.review.severity.all"})}),e.jsx(A,{value:"critical",children:t({id:"sessionDetail.review.severity.critical"})}),e.jsx(A,{value:"high",children:t({id:"sessionDetail.review.severity.high"})}),e.jsx(A,{value:"medium",children:t({id:"sessionDetail.review.severity.medium"})}),e.jsx(A,{value:"low",children:t({id:"sessionDetail.review.severity.low"})})]})]})]}),l.map(i=>!i.findings||i.findings.length===0?null:e.jsx(w,{children:e.jsxs(y,{className:"p-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-4",children:[e.jsx("h3",{className:"text-lg font-semibold text-foreground",children:i.name}),e.jsx(p,{variant:"secondary",children:i.findings.length})]}),i.summary&&e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:i.summary}),e.jsx("div",{className:"space-y-3",children:i.findings.map((c,x)=>e.jsxs(G,{className:`border-l-4 ${ks(c.severity)} rounded-r-lg`,children:[e.jsxs(Q,{className:"flex items-center gap-2 w-full text-left p-3 hover:bg-accent/50 transition-colors",children:[e.jsx(je,{className:"h-4 w-4 transition-transform data-[state=open]:rotate-90"}),e.jsxs("div",{className:"flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[Ds(c.severity),e.jsx("span",{className:"font-medium text-sm",children:c.title}),e.jsx(p,{variant:ys(c.severity),className:"text-xs",children:t({id:`sessionDetail.review.severity.${c.severity}`})})]}),c.location&&e.jsx("p",{className:"text-xs text-muted-foreground mt-1 font-mono",children:c.location})]})]}),e.jsxs(X,{className:"px-6 pb-3 space-y-2",children:[c.description&&e.jsx("div",{className:"text-sm text-foreground",children:c.description}),c.code&&e.jsx("pre",{className:"text-xs bg-muted p-2 rounded overflow-x-auto",children:e.jsx("code",{children:c.code})})]})]},`${i.name}-${x}`))})]})},i.name))]}):e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Z,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium text-foreground mb-2",children:t({id:"sessionDetail.review.noFindings.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:t({id:"sessionDetail.review.noFindings.message"})})]})}const _s={planning:"sessions.status.planning",in_progress:"sessions.status.inProgress",completed:"sessions.status.completed",archived:"sessions.status.archived",paused:"sessions.status.paused"};function $s(){const{sessionId:s}=Xe(),t=Ye(),{formatMessage:a}=N(),{sessionDetail:n,isLoading:l,error:o,refetch:i}=os(s),[c,x]=v.useState("tasks"),[u,f]=v.useState(null),g=()=>{t("/sessions")};if(l)return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(D,{variant:"ghost",size:"sm",disabled:!0,children:[e.jsx(K,{className:"h-4 w-4 mr-2"}),a({id:"common.actions.back"})]}),e.jsx("div",{className:"h-8 w-64 rounded bg-muted animate-pulse"})]}),e.jsx("div",{className:"h-64 rounded-lg bg-muted animate-pulse"})]});if(o)return e.jsxs("div",{className:"flex items-center gap-2 p-4 rounded-lg bg-destructive/10 border border-destructive/30 text-destructive",children:[e.jsx(pe,{className:"h-5 w-5 flex-shrink-0"}),e.jsxs("div",{className:"flex-1",children:[e.jsx("p",{className:"text-sm font-medium",children:a({id:"common.errors.loadFailed"})}),e.jsx("p",{className:"text-xs mt-0.5",children:o.message})]}),e.jsx(D,{variant:"outline",size:"sm",onClick:()=>i(),children:a({id:"common.actions.retry"})})]});if(!n)return e.jsxs("div",{className:"flex flex-col items-center justify-center py-16 px-4",children:[e.jsx(I,{className:"h-12 w-12 text-muted-foreground mb-4"}),e.jsx("h3",{className:"text-lg font-medium text-foreground mb-2",children:a({id:"sessionDetail.notFound.title"})}),e.jsx("p",{className:"text-sm text-muted-foreground mb-4",children:a({id:"sessionDetail.notFound.message"})}),e.jsxs(D,{onClick:g,children:[e.jsx(K,{className:"h-4 w-4 mr-2"}),a({id:"common.actions.back"})]})]});const{session:h,context:C,summary:b,summaries:j,implPlan:S,conflicts:q,review:F}=n,M=h.tasks||[],P=M.filter(m=>m.status==="completed").length,r=h.has_review||h.review,d=[{value:"tasks",label:a({id:"sessionDetail.tabs.tasks"}),icon:e.jsx(J,{className:"h-4 w-4"}),badge:e.jsx(p,{variant:"secondary",className:"ml-2",children:M.length})},{value:"context",label:a({id:"sessionDetail.tabs.context"}),icon:e.jsx(I,{className:"h-4 w-4"})},{value:"summary",label:a({id:"sessionDetail.tabs.summary"}),icon:e.jsx(O,{className:"h-4 w-4"})},{value:"impl-plan",label:a({id:"sessionDetail.tabs.implPlan"}),icon:e.jsx(Y,{className:"h-4 w-4"})},{value:"conflict",label:a({id:"sessionDetail.tabs.conflict"}),icon:e.jsx(ee,{className:"h-4 w-4"})}];return r&&d.push({value:"review",label:a({id:"sessionDetail.tabs.review"}),icon:e.jsx(Z,{className:"h-4 w-4"})}),e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{className:"flex items-center gap-4",children:[e.jsxs(D,{variant:"ghost",size:"sm",onClick:g,children:[e.jsx(K,{className:"h-4 w-4 mr-2"}),a({id:"common.actions.back"})]}),e.jsxs("div",{children:[e.jsx("h1",{className:"text-2xl font-semibold text-foreground",children:h.title||h.session_id}),h.title&&h.title!==h.session_id&&e.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:h.session_id})]})]}),e.jsx(p,{variant:h.status==="completed"?"success":"secondary",children:a({id:_s[h.status]??"sessions.status.inProgress"})})]}),e.jsxs("div",{className:"flex flex-wrap gap-4 text-sm text-muted-foreground p-4 bg-background rounded-lg border",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(W,{className:"h-4 w-4"}),e.jsxs("span",{className:"font-medium",children:[a({id:"sessionDetail.info.created"}),":"]})," ",new Date(h.created_at).toLocaleString()]}),h.updated_at&&e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(W,{className:"h-4 w-4"}),e.jsxs("span",{className:"font-medium",children:[a({id:"sessionDetail.info.updated"}),":"]})," ",new Date(h.updated_at).toLocaleString()]}),e.jsxs("div",{className:"flex items-center gap-1",children:[e.jsx(J,{className:"h-4 w-4"}),e.jsxs("span",{className:"font-medium",children:[a({id:"sessionDetail.info.tasks"}),":"]})," ",P,"/",M.length]})]}),e.jsx(ls,{value:c,onValueChange:m=>x(m),tabs:d}),c==="tasks"&&e.jsx("div",{className:"mt-4",children:e.jsx(xs,{session:h,onTaskClick:f})}),c==="context"&&e.jsx("div",{className:"mt-4",children:e.jsx(js,{context:C})}),c==="summary"&&e.jsx("div",{className:"mt-4",children:e.jsx(Ns,{summary:b,summaries:j})}),c==="impl-plan"&&e.jsx("div",{className:"mt-4",children:e.jsx(bs,{implPlan:S})}),c==="conflict"&&e.jsx("div",{className:"mt-4",children:e.jsx(ws,{conflicts:q})}),r&&c==="review"&&e.jsx("div",{className:"mt-4",children:e.jsx(Cs,{review:F})}),h.description&&e.jsxs("div",{className:"p-4 bg-background rounded-lg border",children:[e.jsx("h3",{className:"text-sm font-semibold text-foreground mb-2",children:a({id:"sessionDetail.info.description"})}),e.jsx("p",{className:"text-sm text-muted-foreground",children:h.description})]}),e.jsx(as,{task:u,isOpen:!!u,onClose:()=>f(null)})]})}export{$s as SessionDetailPage,$s as default};
|
|
23
|
-
//# sourceMappingURL=SessionDetailPage-
|
|
23
|
+
//# sourceMappingURL=SessionDetailPage-B9ZK7LvX.js.map
|