@givolt/i3-composer-agent 2.3.7 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +1 -1
- package/.claude/commands/i3-sop.md +19 -0
- package/.claude/commands/i3-ui-demo.md +21 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.gemini/commands/i3-sop.toml +19 -0
- package/.gemini/commands/i3-ui-demo.toml +21 -0
- package/README.md +42 -6
- package/bin/i3-composer-agent.cjs +38 -44
- package/bin/install.cjs +15 -3
- package/bin/native-layout.cjs +2 -1
- package/bin/native-migration.cjs +19 -2
- package/bin/retired-sop-fingerprints.json +213 -0
- package/bin/wizard.cjs +7 -18
- package/commands/i3-sop.toml +19 -0
- package/commands/i3-ui-demo.toml +21 -0
- package/docs/codebuddy-setup.md +20 -23
- package/docs/codex-setup.md +2 -2
- package/docs/comparison.md +131 -0
- package/docs/developer-onboarding.md +143 -0
- package/docs/opencode-setup.md +1 -1
- package/docs/other-hosts.md +2 -2
- package/docs/skill-anatomy.md +211 -0
- package/docs/upstream-repository/AGENTS.md +92 -0
- package/docs/upstream-repository/CLAUDE.md +60 -0
- package/docs/upstream-repository/CONTRIBUTING.md +137 -0
- package/docs/upstream-repository/README.md +8 -0
- package/docs/upstream-repository/gitattributes.txt +1 -0
- package/docs/upstream-repository/gitignore.txt +10 -0
- package/docs/upstream-repository/manifest.json +71 -0
- package/docs/upstream-repository/opencode-skills.link +1 -0
- package/docs/upstream-repository/skill-gap.yml +80 -0
- package/docs/upstream-repository/skills-contributing.md +15 -0
- package/docs/upstream-repository/test-plugin-install.yml +167 -0
- package/docs/workbuddy-setup.md +7 -10
- package/evals/cases/i3-enterprise-sop.json +64 -0
- package/evals/cases/i3-ui-demo.json +98 -0
- package/evals/fixtures/i3-enterprise-sop/brief.md +11 -0
- package/evals/fixtures/i3-ui-demo/asset-management.md +25 -0
- package/evals/zh-CN/cases/i3-enterprise-sop.json +61 -0
- package/evals/zh-CN/cases/i3-ui-demo.json +103 -0
- package/hooks/PROTOTYPE.md +16 -8
- package/hooks/i3-prototype.cjs +4 -10
- package/hooks/manage.cjs +30 -31
- package/package.json +48 -5
- package/plugin.json +1 -1
- package/scripts/ui-demo-dependencies-test.js +228 -0
- package/scripts/ui-demo-mcp-test.js +95 -0
- package/scripts/ui-demo-test.js +170 -0
- package/scripts/ui-prototype-execution-runtime-test.js +1 -1
- package/scripts/ui-prototype-native-test.js +25 -3
- package/skills/i3-enterprise-sop/SKILL.md +173 -0
- package/skills/i3-enterprise-sop/agents/openai.yaml +2 -0
- package/skills/i3-enterprise-sop/references/ad/assets-manifest.json +86 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/01-generate.md +58 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/02-review.md +54 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/03-revise.md +54 -0
- package/skills/i3-enterprise-sop/references/ad/prompts/04-recheck.md +54 -0
- package/skills/i3-enterprise-sop/references/ad/readme.md +70 -0
- package/skills/i3-enterprise-sop/references/ad/templates/ad.md +337 -0
- package/skills/i3-enterprise-sop/references/assets-manifest.json +230 -0
- package/skills/i3-enterprise-sop/references/brd/assets-manifest.json +83 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/01-generate.md +51 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/02-review.md +47 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/03-revise.md +47 -0
- package/skills/i3-enterprise-sop/references/brd/prompts/04-recheck.md +47 -0
- package/skills/i3-enterprise-sop/references/brd/readme.md +50 -0
- package/skills/i3-enterprise-sop/references/brd/templates/brd.md +169 -0
- package/skills/i3-enterprise-sop/references/codebuddy-project-guide.md +34 -0
- package/skills/i3-enterprise-sop/references/controlled-handoff.md +41 -0
- package/skills/i3-enterprise-sop/references/controlled_handoff.py +379 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/adoption.md +200 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/catalog.json +17 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/directory-standard.md +119 -0
- package/skills/i3-enterprise-sop/references/engineering-skeleton/readme.md +52 -0
- package/skills/i3-enterprise-sop/references/handoff-contract.md +196 -0
- package/skills/i3-enterprise-sop/references/handoff.py +277 -0
- package/skills/i3-enterprise-sop/references/lifecycle-contract.md +91 -0
- package/skills/i3-enterprise-sop/references/plan-handoff.md +73 -0
- package/skills/i3-enterprise-sop/references/prd/assets-manifest.json +109 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/01-generate.md +64 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/02-review.md +49 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/03-revise.md +48 -0
- package/skills/i3-enterprise-sop/references/prd/prompts/04-recheck.md +47 -0
- package/skills/i3-enterprise-sop/references/prd/readme.md +137 -0
- package/skills/i3-enterprise-sop/references/prd/template-contracts.md +39 -0
- package/skills/i3-enterprise-sop/references/prd/templates/ad.md +17 -0
- package/skills/i3-enterprise-sop/references/prd/templates/prd.md +257 -0
- package/skills/i3-enterprise-sop/references/readme.md +167 -0
- package/skills/i3-enterprise-sop/references/recovery-contract.md +65 -0
- package/skills/i3-enterprise-sop/references/review-handoff.md +105 -0
- package/skills/i3-enterprise-sop/references/selection-handoff.md +55 -0
- package/skills/i3-enterprise-sop/references/selection_handoff.py +225 -0
- package/skills/i3-enterprise-sop/references/stages.json +271 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/assets-manifest.json +84 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/baselines/enterprise-application-technical-baseline-v0-0-4.md +380 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/readme.md +132 -0
- package/skills/i3-enterprise-sop/references/technical-baseline/templates/technical-baseline.md +133 -0
- package/skills/i3-enterprise-sop/references/template-contracts.md +142 -0
- package/skills/i3-enterprise-sop/references/testcase/assets-manifest.json +91 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/01-generate.md +53 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/02-review.md +51 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/03-revise.md +49 -0
- package/skills/i3-enterprise-sop/references/testcase/prompts/04-recheck.md +51 -0
- package/skills/i3-enterprise-sop/references/testcase/readme.md +61 -0
- package/skills/i3-enterprise-sop/references/testcase/templates/testcase.md +269 -0
- package/skills/i3-enterprise-sop/references/verification/check_execution.py +185 -0
- package/skills/i3-enterprise-sop/references/verification/check_native_execution.py +282 -0
- package/skills/i3-enterprise-sop/references/verification/check_reads.py +348 -0
- package/skills/i3-enterprise-sop/references/verification/readme.md +149 -0
- package/skills/i3-enterprise-sop/references/verification/review-output.schema.json +155 -0
- package/skills/i3-enterprise-sop/references/verification/review_handoff.py +329 -0
- package/skills/i3-ui-demo/SKILL.md +234 -0
- package/skills/i3-ui-demo/assets/antdv-build/package-lock.json +3363 -0
- package/skills/i3-ui-demo/assets/antdv-build/package.json +28 -0
- package/skills/i3-ui-demo/assets/design-source.json +11 -0
- package/skills/i3-ui-demo/assets/host-targets.json +739 -0
- package/skills/i3-ui-demo/assets/official-files.json +76 -0
- package/skills/i3-ui-demo/assets/starter/index.html +11 -0
- package/skills/i3-ui-demo/assets/starter/package-lock.json +2299 -0
- package/skills/i3-ui-demo/assets/starter/package.json +28 -0
- package/skills/i3-ui-demo/assets/starter/provenance.json +14 -0
- package/skills/i3-ui-demo/assets/starter/public/prototype-config.json +22 -0
- package/skills/i3-ui-demo/assets/starter/src/App.vue +64 -0
- package/skills/i3-ui-demo/assets/starter/src/PrototypeShell.vue +59 -0
- package/skills/i3-ui-demo/assets/starter/src/config.ts +23 -0
- package/skills/i3-ui-demo/assets/starter/src/domain/presentation.ts +30 -0
- package/skills/i3-ui-demo/assets/starter/src/domain/theme.ts +25 -0
- package/skills/i3-ui-demo/assets/starter/src/main.ts +18 -0
- package/skills/i3-ui-demo/assets/starter/src/style.css +26 -0
- package/skills/i3-ui-demo/assets/starter/tests/presentation.test.ts +23 -0
- package/skills/i3-ui-demo/assets/starter/tests/theme.test.ts +26 -0
- package/skills/i3-ui-demo/assets/starter/tsconfig.json +15 -0
- package/skills/i3-ui-demo/assets/starter/vite.config.ts +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/capability-definition.json +1395 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/component-inventory.json +707 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/design-system.md +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/generation.json +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/index.html +534 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/manifest.json +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline-build.json +265 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline.js +8888 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/origin.json +344 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/preset.json +928 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/app.js +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/baseline.json +173 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/conversion.md +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/credits.md +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/index.html +28 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/package.json +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/readme.md +73 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/reference.md +59 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/routes.json +178 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/serve.cjs +16 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/template-inventory.json +28791 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/template.json +9 -0
- package/skills/i3-ui-demo/assets/templates/enterprise-admin/usability.css +44 -0
- package/skills/i3-ui-demo/assets/templates.json +10 -0
- package/skills/i3-ui-demo/assets/versions.json +20 -0
- package/skills/i3-ui-demo/readme.md +350 -0
- package/skills/i3-ui-demo/references/browser.md +71 -0
- package/skills/i3-ui-demo/references/dependencies.md +67 -0
- package/skills/i3-ui-demo/references/resources.md +142 -0
- package/skills/i3-ui-demo/scripts/dependencies.cjs +364 -0
- package/skills/i3-ui-demo/scripts/design-install.cjs +105 -0
- package/skills/i3-ui-demo/scripts/design-provider.cjs +57 -0
- package/skills/i3-ui-demo/scripts/locations.cjs +52 -0
- package/skills/i3-ui-demo/scripts/mcp.cjs +112 -0
- package/skills/i3-ui-demo/scripts/provider-discovery.cjs +131 -0
- package/skills/i3-ui-demo/scripts/resources.cjs +283 -0
- package/skills/i3-ui-prototype/SKILL.md +1 -1
- package/skills/i3-ui-prototype/references/execution-evidence.md +12 -56
- package/skills/i3-ui-prototype/scripts/codebuddy-registration.cjs +1 -1
- package/skills/i3-ui-prototype/scripts/execution-runtime.cjs +5 -2
- package/skills/i3-ui-prototype/scripts/hosts/codebuddy.cjs +3 -2
- package/skills/i3-ui-prototype/scripts/native-delivery.cjs +2 -2
- package/skills/i3-ui-prototype/scripts/prototype-hooks.cjs +23 -20
- package/docs/ui-prototype-native/MAIN-SESSION-REPORT.md +0 -66
- package/docs/ui-prototype-native/USAGE.md +0 -93
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useDeliveryView } from "../shared/deliveryView.js";
|
|
2
|
+
import { computed } from '../../runtime/state.js';
|
|
3
|
+
import { defineStore } from "../../runtime/state.js";
|
|
4
|
+
import { usePbcs } from "./store.js";
|
|
5
|
+
import { useSession } from "../shared/session.js";
|
|
6
|
+
import { useSpecs } from "../specs/store.js";
|
|
7
|
+
import { useIntents } from "../intents/store.js";
|
|
8
|
+
import { taskRecords } from "../tasks/registry.js";
|
|
9
|
+
import { agentRecords } from "../agents/registry.js";
|
|
10
|
+
import { flowRecords, flowUses } from "../workflows/registry.js";
|
|
11
|
+
import { assertBatch } from "../shared/listBatch.js";
|
|
12
|
+
import { stateOf, assertPbcRemovable, assertServiceRemovable, revisePbc, reviseService, requireReason } from "./management.js";
|
|
13
|
+
export const usePbcManagement = defineStore('pbc-management', () => {
|
|
14
|
+
const pbcs = usePbcs(), session = useSession(), specs = useSpecs(), intents = useIntents();
|
|
15
|
+
const records = computed(() => pbcs.items), item = (id) => records.value.find(p => p.id === id);
|
|
16
|
+
const { candidates } = useDeliveryView();
|
|
17
|
+
const newSources = computed(() => candidates.value.filter(s => s.guide.create));
|
|
18
|
+
function references(p) {
|
|
19
|
+
return [
|
|
20
|
+
...pbcs.jobs.filter(j => j.pbc.id === p.id).map(() => '需求归属'),
|
|
21
|
+
...taskRecords.value.filter(t => !t.isDeleted && t.binding.pbcId === p.id).map(() => '交付任务'),
|
|
22
|
+
...agentRecords.value.filter(a => !a.isDeleted && a.pbcId === p.id).map(() => 'Agent'),
|
|
23
|
+
...flowRecords.value.filter(f => !f.isDeleted && f.pbcId === p.id).map(() => '流程模板'),
|
|
24
|
+
...flowUses.value.filter(f => f.pbcId === p.id).map(() => '模板交接记录'),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
function current(id, action, version, fresh = false) { if (fresh)
|
|
28
|
+
pbcs.refreshLatest(); const p = item(id); if (!p)
|
|
29
|
+
throw Error('PBC 不存在或无权访问。'); session.require('pbc:view', p.tenantId, p.id); session.require(action, p.tenantId, p.id); if (version !== undefined && version !== p.recordVersion)
|
|
30
|
+
throw Error('PBC 记录已更新,请重新打开核对。'); return p; }
|
|
31
|
+
function event(p, action, reason, before, after) { return { id: crypto.randomUUID(), pbcId: p.id, tenantId: p.tenantId, actor: session.actor.name, at: new Date().toISOString(), action, reason, before: JSON.stringify(before, null, 2), after: JSON.stringify(after, null, 2) }; }
|
|
32
|
+
function persist(next, e) { session.writeCheck(); pbcs.saveManagement(pbcs.catalog.map(p => p.id === next.id ? next : p), [e]); return next; }
|
|
33
|
+
function save(id, version, input, reason) { requireReason(reason); const p = current(id, 'pbc:edit', version, true); if (pbcs.catalog.some(q => !q.isDeleted && q.id !== id && q.tenantId === p.tenantId && q.name === input.name.trim()))
|
|
34
|
+
throw Error('同一租户下 PBC 名称不能重复。'); const n = revisePbc(p, input, session.actor, new Date().toISOString()); const fields = (x) => ({ name: x.name, ebc: x.ebc, owner: x.owner, description: x.description || '', recordVersion: x.recordVersion }); return persist(n, event(p, '修改基础资料', reason, fields(p), fields(n))); }
|
|
35
|
+
function archive(id, version, reason) { requireReason(reason); const p = current(id, 'pbc:archive', version, true), active = stateOf(p) === 'active'; if (active && (taskRecords.value.some(t => !t.isDeleted && t.binding.pbcId === id) || pbcs.jobs.some(j => j.pbc.id === id && j.status !== 'done') || agentRecords.value.some(a => !a.isDeleted && a.pbcId === id && a.enabled) || flowRecords.value.some(f => !f.isDeleted && f.pbcId === id && f.enabled)))
|
|
36
|
+
throw Error('仍有交付任务、在途创建或启用资源,请处理后再归档。'); const n = { ...p, state: active ? 'archived' : 'active', recordVersion: p.recordVersion + 1, updatedAt: new Date().toISOString(), updatedBy: session.actor.name }; return persist(n, event(p, active ? '归档 PBC' : '恢复 PBC', reason, { state: stateOf(p), version: p.recordVersion }, { state: n.state, version: n.recordVersion })); }
|
|
37
|
+
function checkRemove(t) { const p = current(t.id, 'pbc:delete', t.recordVersion); assertPbcRemovable(p, references(p)); }
|
|
38
|
+
function removeMany(targets) { pbcs.refreshLatest(); const selected = assertBatch(pbcs.catalog, targets, p => { session.require('pbc:view', p.tenantId, p.id); session.require('pbc:delete', p.tenantId, p.id); assertPbcRemovable(p, references(p)); }), ids = new Set(selected.map(p => p.id)), at = new Date().toISOString(); session.writeCheck(); pbcs.saveManagement(pbcs.catalog.map(p => ids.has(p.id) ? { ...p, isDeleted: true, recordVersion: p.recordVersion + 1, updatedBy: session.actor.name, updatedAt: at } : p), selected.map(p => event(p, '删除 PBC', '已核对归档状态及无工程/引用;批量 ' + ids.size + ' 项', { deleted: false }, { deleted: true }))); }
|
|
39
|
+
function serviceSave(id, version, serviceId, input, reason) { requireReason(reason); const p = current(id, 'pbc:service', version, true), old = serviceId ? p.services.find(s => s.id === serviceId && !s.isDeleted) : undefined; if (serviceId && !old)
|
|
40
|
+
throw Error('服务记录已不存在。'); if (input.sourceIntentId && !pbcs.jobs.some(j => j.intentId === input.sourceIntentId && j.pbc.id === id && j.status === 'done' && session.can('spec:view', j.tenantId)))
|
|
41
|
+
throw Error('需求依据不可访问或不属于当前 PBC。'); const s = reviseService(p, old, input, session.actor, new Date().toISOString()), n = { ...p, services: old ? p.services.map(x => x.id === s.id ? s : x) : [s, ...p.services], recordVersion: p.recordVersion + 1, updatedBy: session.actor.name, updatedAt: new Date().toISOString() }; return persist(n, event(p, old ? '修改服务资料' : '新增服务方案', reason, old || {}, s)); }
|
|
42
|
+
function serviceCheck(id, t) { const p = current(id, 'pbc:service'), s = p.services.find(s => !s.isDeleted && s.id === t.id); if (!s)
|
|
43
|
+
throw Error('服务已不存在。'); if (s.recordVersion !== t.recordVersion)
|
|
44
|
+
throw Error('服务已更新,请重新核对。'); assertServiceRemovable(p, s); }
|
|
45
|
+
function serviceRemove(id, version, targets) { const p = current(id, 'pbc:service', version, true); const selected = assertBatch(p.services, targets, s => assertServiceRemovable(p, s)); const ids = new Set(selected.map(s => s.id)), at = new Date().toISOString(), n = { ...p, services: p.services.map(s => ids.has(s.id) ? { ...s, isDeleted: true, recordVersion: s.recordVersion + 1, updatedAt: at, updatedBy: session.actor.name } : s), recordVersion: p.recordVersion + 1, updatedAt: at, updatedBy: session.actor.name }; session.writeCheck(); pbcs.saveManagement(pbcs.catalog.map(x => x.id === id ? n : x), selected.map(s => event(p, '删除服务方案', '已核对未登记工程;批量 ' + ids.size + ' 项', s, { id: s.id, isDeleted: true }))); }
|
|
46
|
+
const jobsFor = (id) => pbcs.jobs.filter(j => j.pbc.id === id && item(id) && session.can('intent:view', j.tenantId) && session.can('spec:view', j.tenantId));
|
|
47
|
+
const eventsFor = (id) => { const p = item(id); return p && session.can('pbc:audit', p.tenantId, id) ? pbcs.managementAudit.filter(e => e.pbcId === id && e.tenantId === p.tenantId) : []; };
|
|
48
|
+
return { records, item, newSources, save, archive, checkRemove, removeMany, serviceSave, serviceCheck, serviceRemove, jobsFor, eventsFor };
|
|
49
|
+
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { computed, ref } from '../../runtime/state.js';
|
|
2
|
+
import { seedTaskJobs } from "../tasks/exampleSource.js";
|
|
3
|
+
import { defineStore } from "../../runtime/state.js";
|
|
4
|
+
import { useSession } from "../shared/session.js";
|
|
5
|
+
import { useIntents } from "../intents/store.js";
|
|
6
|
+
import { useSpecs } from "../specs/store.js";
|
|
7
|
+
import { clone } from "../specs/domain.js";
|
|
8
|
+
import { seedPbcs } from "./data.js";
|
|
9
|
+
import { activeStep, makeJob, newDraft, queryReceipt, validateDraft, assertBinding } from "./domain.js";
|
|
10
|
+
import { assertActive } from "./management.js";
|
|
11
|
+
const key = 'i3-prototype-antdv-pbc-v010', now = () => new Date().toISOString();
|
|
12
|
+
export const usePbcs = defineStore('pbcs', () => {
|
|
13
|
+
const session = useSession(), intents = useIntents(), specs = useSpecs(), catalog = ref(seedPbcs()), drafts = ref([]), jobs = ref(seedTaskJobs()), notice = ref(''), mode = ref('success'), scene = ref('normal');
|
|
14
|
+
const managementAudit = ref([]);
|
|
15
|
+
let epoch = 0;
|
|
16
|
+
try {
|
|
17
|
+
const saved = JSON.parse(localStorage.getItem(key) || 'null');
|
|
18
|
+
if (saved) {
|
|
19
|
+
catalog.value = saved.catalog;
|
|
20
|
+
drafts.value = saved.drafts;
|
|
21
|
+
managementAudit.value = saved.audit || [];
|
|
22
|
+
jobs.value = saved.jobs.map((j) => ({ ...j, status: j.status === 'running' ? 'unknown' : j.status, steps: j.steps.map(s => ({ ...s, state: s.state === 'running' ? 'unknown' : s.state })) }));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
notice.value = '本地归属数据无法读取,已加载初始目录。';
|
|
27
|
+
}
|
|
28
|
+
const items = computed(() => catalog.value.filter(p => !p.isDeleted && session.readable('pbc:view', p.tenantId, p.id)));
|
|
29
|
+
const job = (id) => jobs.value.find(j => j.intentId === id && session.readable('pbc:view', j.tenantId, j.pbc.id));
|
|
30
|
+
function persist(nextCatalog = catalog.value, nextDrafts = drafts.value, nextJobs = jobs.value, nextAudit = managementAudit.value) { try {
|
|
31
|
+
localStorage.setItem(key, JSON.stringify({ catalog: nextCatalog, drafts: nextDrafts, jobs: nextJobs, audit: nextAudit }));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
throw Error('浏览器保存失败,操作未提交,请重试。');
|
|
35
|
+
} catalog.value = nextCatalog; drafts.value = nextDrafts; jobs.value = nextJobs; managementAudit.value = nextAudit; }
|
|
36
|
+
function update(j, text) { const next = { ...clone(j), recordVersion: j.recordVersion + 1, updatedAt: now(), updatedBy: session.actor.name, events: [...j.events, { at: now(), actor: session.actor.name, text }] }; persist(catalog.value, drafts.value, jobs.value.map(old => old.id === j.id ? next : old)); return next; }
|
|
37
|
+
function draft(id) { const i = intents.get(id); if (!i)
|
|
38
|
+
throw Error('没有来源意图权限。'); session.require('pbc:create', i.tenantId); return clone(drafts.value.find(d => d.intentId === id) || newDraft(i, session.actor, now())); }
|
|
39
|
+
function saveDraft(d) { session.require('pbc:create', d.tenantId); if (jobs.value.some(j => j.intentId === d.intentId))
|
|
40
|
+
throw Error('该意图已提交归属;已提交内容只读。'); session.writeCheck(); const old = drafts.value.find(v => v.id === d.id); if (old && old.recordVersion !== d.recordVersion)
|
|
41
|
+
throw Error('草稿已更新,请重新打开核对。'); const next = { ...clone(d), recordVersion: d.recordVersion + 1, updatedAt: now(), updatedBy: session.actor.name }; persist(catalog.value, [next, ...drafts.value.filter(v => v.id !== d.id)]); return clone(next); }
|
|
42
|
+
function sources(id, binding) { const i = intents.get(id), s = specs.get(id); if (!i || !s)
|
|
43
|
+
throw Error('意图或规格不可访问。'); if (jobs.value.some(j => j.intentId === id))
|
|
44
|
+
throw Error('此意图已有归属请求,请查看原请求结果,避免重复创建。'); assertBinding(i, s, binding); return { i, s }; }
|
|
45
|
+
async function start(id, target, d, binding) { const { i, s } = sources(id, binding); session.require(d ? 'pbc:create' : 'pbc:link', i.tenantId, d ? undefined : target.id); if (d)
|
|
46
|
+
validateDraft(d, catalog.value); session.writeCheck(); const j = makeJob(i, s, session.actor, target, d); persist(catalog.value, drafts.value, [j, ...jobs.value]); await run(j.id); }
|
|
47
|
+
async function link(id, pbcId, binding) { const p = items.value.find(p => p.id === pbcId); if (!p)
|
|
48
|
+
throw Error('PBC 不可访问。'); assertActive(p); await start(id, p, undefined, binding); }
|
|
49
|
+
async function create(id, d, binding) { const p = { ...clone(d), id: 'pbc-' + d.slug, state: 'active', provisioned: true, resourceKey: d.name, services: d.services.filter(s => !s.isDeleted).map(s => ({ ...clone(s), id: d.prefix + '-' + s.name, registered: true })) }; await start(id, p, d, binding); }
|
|
50
|
+
const current = (id) => jobs.value.find(j => j.id === id);
|
|
51
|
+
function complete(j) { const list = j.kind === 'create' && !catalog.value.some(p => p.id === j.pbc.id) ? [j.pbc, ...catalog.value] : catalog.value; persist(list, drafts.value, jobs.value.map(x => x.id === j.id ? { ...j, status: 'done' } : x)); }
|
|
52
|
+
async function run(id) {
|
|
53
|
+
let j = current(id);
|
|
54
|
+
if (j.status === 'done' || j.status === 'unknown')
|
|
55
|
+
return;
|
|
56
|
+
const permission = j.kind === 'create' ? 'pbc:create' : 'pbc:link';
|
|
57
|
+
session.require(permission, j.tenantId, j.kind === 'link' ? j.pbc.id : undefined);
|
|
58
|
+
if (j.steps.some(s => s.state === 'running'))
|
|
59
|
+
throw Error('该请求正在执行。');
|
|
60
|
+
const runEpoch = epoch, result = mode.value, actorId = session.actor.id;
|
|
61
|
+
mode.value = 'success';
|
|
62
|
+
for (let index = activeStep(j); index < j.steps.length && index >= 0; index++) {
|
|
63
|
+
j = current(id);
|
|
64
|
+
const next = clone(j);
|
|
65
|
+
next.status = 'running';
|
|
66
|
+
next.steps[index].state = 'running';
|
|
67
|
+
next.steps[index].detail = '正在处理(模拟)';
|
|
68
|
+
update(next, '开始:' + next.steps[index].name);
|
|
69
|
+
await new Promise(resolve => setTimeout(resolve, 450));
|
|
70
|
+
if (runEpoch !== epoch)
|
|
71
|
+
return;
|
|
72
|
+
j = clone(current(id));
|
|
73
|
+
let allowed = session.actor.id === actorId && session.can(permission, j.tenantId, j.kind === 'link' ? j.pbc.id : undefined);
|
|
74
|
+
const step = j.steps[index];
|
|
75
|
+
if (!allowed) {
|
|
76
|
+
step.state = 'failed';
|
|
77
|
+
step.detail = '身份、权限或登录状态变化;本步尚未执行。';
|
|
78
|
+
j.status = 'paused';
|
|
79
|
+
update(j, '暂停执行:' + step.detail);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (result === 'failure' && index === (j.kind === 'create' ? 2 : 0)) {
|
|
83
|
+
step.state = 'failed';
|
|
84
|
+
step.detail = '模拟服务不可用,已完成步骤保留。';
|
|
85
|
+
j.status = 'failed';
|
|
86
|
+
update(j, '步骤失败:' + step.name);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
step.receipt = j.id + ':' + index;
|
|
90
|
+
if (result === 'unknown' && index === 0) {
|
|
91
|
+
step.state = 'unknown';
|
|
92
|
+
step.detail = '响应未收到,先核实原操作。';
|
|
93
|
+
j.status = 'unknown';
|
|
94
|
+
update(j, '步骤结果待核实:' + step.name);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
step.state = 'done';
|
|
98
|
+
step.detail = '已完成(模拟);操作回执 ' + step.receipt;
|
|
99
|
+
j = update(j, '完成:' + step.name);
|
|
100
|
+
}
|
|
101
|
+
complete(current(id));
|
|
102
|
+
}
|
|
103
|
+
async function resume(id) { const j = job(id); if (!j)
|
|
104
|
+
throw Error('没有可访问的归属请求。'); await run(j.id); }
|
|
105
|
+
function reconcile(id) { const j = job(id); if (!j)
|
|
106
|
+
throw Error('没有可访问的归属请求。'); session.require('pbc:view', j.tenantId, j.pbc.id); const next = update(queryReceipt(j), '查询原操作结果'); if (next.status === 'done')
|
|
107
|
+
complete(next); }
|
|
108
|
+
function reset() { epoch++; localStorage.removeItem(key); catalog.value = seedPbcs(); drafts.value = []; jobs.value = seedTaskJobs(); notice.value = ''; mode.value = 'success'; scene.value = 'normal'; managementAudit.value = []; }
|
|
109
|
+
function refreshLatest() { try {
|
|
110
|
+
const raw = JSON.parse(localStorage.getItem(key) || 'null');
|
|
111
|
+
if (raw) {
|
|
112
|
+
catalog.value = raw.catalog;
|
|
113
|
+
drafts.value = raw.drafts;
|
|
114
|
+
jobs.value = raw.jobs;
|
|
115
|
+
managementAudit.value = raw.audit || [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
throw Error('本地数据无法读取,请保留输入并重新加载。');
|
|
120
|
+
} }
|
|
121
|
+
function saveManagement(next, events) { persist(next, drafts.value, jobs.value, [...events, ...managementAudit.value]); }
|
|
122
|
+
if (typeof window !== 'undefined')
|
|
123
|
+
window.addEventListener('storage', e => { if (e.key === key && e.newValue) {
|
|
124
|
+
try {
|
|
125
|
+
refreshLatest();
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
notice.value = '本地数据刷新失败,请重新加载。';
|
|
129
|
+
}
|
|
130
|
+
} });
|
|
131
|
+
return { catalog, jobs, managementAudit, refreshLatest, saveManagement, items, notice, mode, scene, job, draft, saveDraft, link, create, resume, reconcile, reset };
|
|
132
|
+
});
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/AdminList.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<div class="page-heading"><div><h1>{{ (title) }}</h1><p>{{ (description) }}</p></div><template data-component="Button" data-if="(!readonly)" type="primary" data-bind-disabled="(!session.can(createAction))" data-on-click="(emit('create'))">{{ (kind === 'roles' ? '新增角色' : '添加成员') }}</template></div><section class="auth-list"><div class="auth-filters"><template data-component="Input" data-model-value="(query)" aria-label="查找权限记录" placeholder="搜索名称、编码或说明" allow-clear=""></template><template data-component="Select" data-model-value="(scope)" aria-label="所属范围筛选" data-bind-options="(scopeOptions)"></template><template data-component="Select" data-if="(kind === 'roles')" data-model-value="(status)" aria-label="角色状态筛选" data-bind-options="([{ label: '全部状态', value: 'all' }, { label: '启用', value: '启用' }, { label: '停用', value: '停用' }])"></template><template data-component="Button" data-on-click="(reset)">重置</template></div><div class="auth-tools"><template data-component="ListBatchBar" data-if="(!readonly)" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(canDelete)" data-on-remove="(emit('remove', selection.selected.value))" data-on-clear="(selection.clear)"></template><p data-else="" class="muted">授权记录只读,保留变更前后内容;删除不适用。</p><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(desc = !desc)">时间{{ (desc ? '倒序' : '正序') }}</template><template data-component="Button" data-bind-loading="(refreshing)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(kind === 'members')" class="page-alert" type="info" show-icon="" title="此处管理业务关联与角色授权" description="账号、姓名和部门来自 MaxKey 身份目录;移除业务关联会撤去该范围的角色授权,账号保留。"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" title="权限数据加载失败" description="请刷新重试;现有授权未改变。" show-icon=""><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-component="ProTable" data-else="" data-bind-table="(table)" data-bind-search="(async () => { })" data-bind-control="(false)" data-bind-table-container="(false)" row-key="id" data-bind-loading="(refreshing)" data-bind-row-selection="(readonly ? undefined : selection.rowSelection.value)" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) => '共 ' + n + ' 项', showSizeChanger: true, pageSizeOptions: [5, 10, 20] })"></template></section>
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { computed, ref, watch } from '../../runtime/state.js';
|
|
2
|
+
import { h } from '../../runtime/dom.js';
|
|
3
|
+
import { Alert, Button, Input, Select, Space, Tag } from "../../runtime/widgets.js";
|
|
4
|
+
import { ProTable, useTable } from "../../runtime/widgets.js";
|
|
5
|
+
import { useSession } from "../shared/session.js";
|
|
6
|
+
import { tenantLabel, tenants, formatDate } from "../shared/policy.js";
|
|
7
|
+
import { useColumns } from "../shared/columns.js";
|
|
8
|
+
import { useListSelection } from "../shared/listSelection.js";
|
|
9
|
+
import ColumnSettings from "../shared/ColumnSettings.js";
|
|
10
|
+
import ListMore from "../shared/ListMore.js";
|
|
11
|
+
import ListBatchBar from "../shared/ListBatchBar.js";
|
|
12
|
+
import { useAuthority } from "./store.js";
|
|
13
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
14
|
+
export default createComponent({ name: 'AdminList', propKeys: ["rows", "kind", "title", "description", "initialQuery"], template: new URL('./AdminList.html', import.meta.url).href, setup(__props, __emit) {
|
|
15
|
+
const props = __props;
|
|
16
|
+
const emit = __emit;
|
|
17
|
+
const session = useSession(), store = useAuthority(), query = ref(props.initialQuery || ''), scope = ref('all'), status = ref('all'), desc = ref(true), refreshing = ref(false);
|
|
18
|
+
const readonly = computed(() => props.kind === 'records'), createAction = computed(() => props.kind === 'roles' ? 'permission:roles' : 'permission:members');
|
|
19
|
+
const canDelete = computed(() => !readonly.value && session.can('permission:delete') && (props.kind !== 'members' || session.can('permission:members')));
|
|
20
|
+
const scopeOptions = computed(() => [{ value: 'all', label: '全部可见范围' }, ...[{ value: 'platform', label: '平台统一管理' }, ...tenants].filter(t => session.can(readonly.value ? 'permission:audit' : 'permission:view', t.value))]);
|
|
21
|
+
const prefs = useColumns('permission-' + props.kind, [{ key: 'name', label: props.kind === 'roles' ? '角色名称' : props.kind === 'members' ? '成员' : '操作对象', locked: true }, { key: 'code', label: props.kind === 'roles' ? '角色编码' : props.kind === 'members' ? '已关联角色' : '操作类型', defaultVisible: true }, { key: 'tenantId', label: '所属范围', defaultVisible: true }, { key: 'status', label: '状态', defaultVisible: true }, { key: 'extra', label: readonly.value ? '变更原因' : '用途 / 说明', defaultVisible: false }, { key: 'createdBy', label: readonly.value ? '操作者' : '创建人', defaultVisible: true }, { key: 'createdAt', label: readonly.value ? '操作时间' : '创建时间', defaultVisible: true }, { key: 'createdDept', label: '创建部门' }, { key: 'updatedBy', label: '修改人' }, { key: 'updatedAt', label: '修改时间' }, { key: 'actions', label: '操作', locked: true }]);
|
|
22
|
+
function actionButtons(r) {
|
|
23
|
+
const disabled = r.protected || !session.can(createAction.value, r.tenantId);
|
|
24
|
+
const items = [{ key: 'detail', label: readonly.value ? '查看变更详情' : '查看详情' }, ...(!readonly.value ? [{ key: 'edit', label: props.kind === 'roles' ? '编辑角色' : '修改成员授权', disabled }, ...(props.kind === 'roles' ? [{ key: 'toggle', label: r.status === '启用' ? '停用角色' : '启用角色', disabled }] : []), { key: 'history', label: '授权记录', disabled: !session.can('permission:audit', r.tenantId) }, { key: 'delete', label: props.kind === 'members' ? '移除业务关联' : '删除角色', danger: true, disabled: !canDelete.value || !session.can('permission:delete', r.tenantId) }] : [])];
|
|
25
|
+
return h('div', { class: 'row-actions' }, [h(Button, { type: 'link', disabled: readonly.value ? false : props.kind === 'roles' ? (!!r.protected || !session.can('permission:grant', r.tenantId)) : disabled, onClick: () => emit('action', readonly.value ? 'detail' : props.kind === 'roles' ? 'grant' : 'edit', r) }, () => readonly.value ? '详情' : props.kind === 'roles' ? '配置权限' : '配置角色'), h(ListMore, { name: r.name, items, onAction: (key) => emit('action', key, r) })]);
|
|
26
|
+
}
|
|
27
|
+
const table = useTable({ pageParam: { current: 1, pageSize: 5, total: 0 }, columns: prefs.choices.map(c => ({ key: c.key, title: c.label, dataIndex: c.key, fixed: c.key === 'actions' ? 'right' : undefined, width: c.key === 'name' ? 180 : c.key === 'code' ? 240 : c.key === 'actions' ? 190 : 160, ...(c.key === 'actions' ? { render: (_, r) => actionButtons(r) } : c.key === 'tenantId' ? { render: (v) => tenantLabel(String(v)) } : c.key.endsWith('At') ? { render: (v) => formatDate(String(v)) } : c.key === 'status' ? { render: (v) => h(Tag, { color: v === '停用' ? 'default' : 'green' }, () => String(v)) } : {}) })) });
|
|
28
|
+
const columns = new Map(table.columns.value.map(c => [c.key, c]));
|
|
29
|
+
watch(prefs.keys, keys => table.columns.value = keys.map(k => columns.get(k)).filter(Boolean), { immediate: true });
|
|
30
|
+
const filtered = computed(() => store.scene === 'empty' ? [] : props.rows.filter(r => (r.name + r.code + r.extra).toLowerCase().includes(query.value.trim().toLowerCase()) && (scope.value === 'all' || r.tenantId === scope.value) && (status.value === 'all' || r.status === status.value)).sort((a, b) => desc.value ? b.createdAt.localeCompare(a.createdAt) : a.createdAt.localeCompare(b.createdAt)));
|
|
31
|
+
watch([filtered, () => table.pageParam.current, () => table.pageParam.pageSize], () => { const size = table.pageParam.pageSize || 5, max = Math.max(1, Math.ceil(filtered.value.length / size)); if ((table.pageParam.current || 1) > max)
|
|
32
|
+
table.setPageParam({ current: max }); const start = ((table.pageParam.current || 1) - 1) * size; table.dataSource.value = filtered.value.slice(start, start + size); table.setPageParam({ total: filtered.value.length }); }, { immediate: true });
|
|
33
|
+
const selection = useListSelection(table.dataSource, computed(() => JSON.stringify([session.key, query.value, scope.value, status.value, desc.value, table.pageParam.current, table.pageParam.pageSize])), canDelete, r => r.name);
|
|
34
|
+
watch([query, scope, status], () => table.setPageParam({ current: 1 }));
|
|
35
|
+
async function refresh() { selection.clear(); refreshing.value = true; await new Promise(r => setTimeout(r, 250)); store.scene = 'normal'; refreshing.value = false; }
|
|
36
|
+
function reset() { query.value = ''; scope.value = 'all'; status.value = 'all'; }
|
|
37
|
+
return { computed, ref, watch, h, Alert, Button, Input, Select, Space, Tag, ProTable, useTable, useSession, tenantLabel, tenants, formatDate, useColumns, useListSelection, ColumnSettings, ListMore, ListBatchBar, useAuthority, props, emit, session, store, query, scope, status, desc, refreshing, readonly, createAction, canDelete, scopeOptions, prefs, actionButtons, table, columns, filtered, selection, refresh, reset };
|
|
38
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/EffectiveGrants.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Empty" data-if="(!grants.length)" description="当前没有生效的业务权限"></template><section data-each="grant in (grants)" data-bind-key="(grant.id)" class="auth-grant"><h3>{{ (grant.name) }}</h3><p><strong>范围:</strong>{{ (grant.tenantIds.map(t => t === '*' ? '全部范围' : tenantLabel(t)).join('、')) }}</p><p><strong>PBC:</strong>{{ ((grant.pbcIds || ['*']).map(pbc).join('、')) }}</p><div class="auth-tags"><template data-component="Tag" data-each="code in (grant.actions)" data-bind-key="(code)">{{ (label(code)) }}</template></div></section>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Empty, Tag } from "../../runtime/widgets.js";
|
|
2
|
+
import { usePbcs } from "../pbc/store.js";
|
|
3
|
+
import { actionGroups, tenantLabel } from "../shared/policy.js";
|
|
4
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
5
|
+
export default createComponent({ name: 'EffectiveGrants', propKeys: ["grants"], template: new URL('./EffectiveGrants.html', import.meta.url).href, setup(__props, __emit) {
|
|
6
|
+
__props;
|
|
7
|
+
const label = (code) => actionGroups.flatMap(g => g.items).find(i => i.value === code)?.label || code;
|
|
8
|
+
const directory = usePbcs();
|
|
9
|
+
const pbc = (id) => id === '*' ? '全部 PBC(含新建)' : directory.items.find(p => p.id === id)?.name || id;
|
|
10
|
+
return { Empty, Tag, usePbcs, actionGroups, tenantLabel, label, directory, pbc };
|
|
11
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/GrantEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" data-bind-title="('配置权限 · ' + role.name)" data-bind-size="(780)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" type="info" show-icon="" data-bind-title="('本次变更影响 ' + affected.length + ' 条成员关联')" data-bind-description="(affected.join('、') || '当前尚无成员使用此角色。')" class="page-alert"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" class="page-alert"></template><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'features', label: '功能与数据范围' }, { key: 'explain', label: '授权规则' }])"></template><div data-if="(tab === 'features')"><section data-each="(grant,index) in (value.grants)" data-bind-key="(grant.id)" class="auth-grant"><div class="section-heading"><h2>授权组 {{ (index + 1) }}</h2><template data-component="Button" danger="" type="text" data-bind-disabled="(!allowed)" data-on-click="(value.grants.splice(index, 1))">移除此组</template></div><label data-bind-for="('auth-group-' + index)">授权组名称</label><template data-component="Input" data-bind-id="('auth-group-' + index)" data-model-value="(grant.name)" data-bind-disabled="(!allowed)"></template><div class="auth-grant-columns"><div><h3>菜单与功能</h3><template data-component="Tree" checkable="" default-expand-all="" data-bind-tree-data="(tree)" data-bind-checked-keys="(grant.actions)" data-bind-disabled="(!allowed)" data-on-check="((keys) => update(index, keys))"></template></div><div><h3>数据与资源范围</h3><label data-bind-for="('auth-tenants-' + index)">租户 / 平台范围</label><template data-component="Select" data-bind-id="('auth-tenants-' + index)" data-model-value="(grant.tenantIds)" mode="multiple" data-bind-options="(scopeOptions)" data-bind-disabled="(!allowed)"></template><label data-bind-for="('auth-pbc-' + index)">PBC 范围</label><template data-component="Select" data-bind-id="('auth-pbc-' + index)" data-model-value="(grant.pbcIds)" mode="multiple" data-bind-options="(pbcOptions)" data-bind-disabled="(!allowed)"></template><template data-if="(grant.actions.some(a => a.startsWith('release:')))"><label data-bind-for="('auth-env-' + index)">发布目标环境</label><template data-component="Select" data-bind-id="('auth-env-' + index)" data-model-value="(grant.environmentIds)" mode="multiple" data-bind-options="([{ value: '*', label: '全部环境' }, { value: 'staging', label: '预发布环境' }, { value: 'production', label: '生产环境' }])" data-bind-disabled="(!allowed)" placeholder="未限定时适用全部环境"></template></template><p class="muted">此范围只约束本组所选功能。意图与规格在立项前按租户控制;PBC 查看、关联和结果还核对具体资源。</p></div></div></section><template data-component="Button" block="" data-bind-disabled="(!allowed)" data-on-click="(add)">新增授权组</template><p data-if="(!value.grants.length)" class="muted">角色将没有功能权限;保存后关联成员失去此角色提供的授权。</p></div><div data-else="" class="auth-explanation"><h2>统一配置,业务页面按权限开放</h2><p>同一人可以关联多个角色;角色名称仅用于识别,实际按每组功能和资源范围判定。</p><h3>菜单、按钮与接口</h3><p>查看权限控制页面入口,操作权限控制按钮与业务动作。正式后端必须独立校验对应接口,不能仅依赖按钮隐藏。</p><p class="muted">本原型沿用现有业务动作标识。正式领域权限码及 OpenAPI 映射尚待 spec/design,本页不虚构已接通的接口清单。</p><h3>授权范围与变更生效</h3><p>管理员只能授出受管范围内的权限;转授管理能力还需专门授权。生产人工确认、独立评审和版本检查继续有效。</p></div><template data-component="ProForm" name="role-grant-reason" data-bind-form="(form)" layout="vertical" data-bind-disabled="(!allowed || busy)" class="auth-reason"></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存权限</template></template></template></template>
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { computed, ref } from '../../runtime/state.js';
|
|
2
|
+
import { Alert, Button, Drawer, Input, Select, Space, Tabs, Tree, message } from "../../runtime/widgets.js";
|
|
3
|
+
import { ProForm, useForm } from "../../runtime/widgets.js";
|
|
4
|
+
import { actionGroups, allActions, tenants } from "../shared/policy.js";
|
|
5
|
+
import { useSession } from "../shared/session.js";
|
|
6
|
+
import { clone } from "./domain.js";
|
|
7
|
+
import { usePbcs } from "../pbc/store.js";
|
|
8
|
+
import { useAuthority } from "./store.js";
|
|
9
|
+
import { confirmAction } from "../shell/confirmation.js";
|
|
10
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
11
|
+
export default createComponent({ name: 'GrantEditor', propKeys: ["role"], template: new URL('./GrantEditor.html', import.meta.url).href, setup(__props, __emit) {
|
|
12
|
+
const props = __props, emit = __emit, session = useSession(), store = useAuthority(), value = ref(clone(props.role)), tab = ref('features'), error = ref(''), busy = ref(false);
|
|
13
|
+
const form = useForm({ reason: '' }, [{ path: 'reason', label: '变更原因', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写变更原因' }] }]);
|
|
14
|
+
const allowed = computed(() => !props.role.protected && session.can('permission:grant', props.role.tenantId));
|
|
15
|
+
const affected = computed(() => store.members.filter(m => m.roleIds.includes(props.role.id)).map(m => store.actorName(m.actorId)));
|
|
16
|
+
const scopeOptions = computed(() => props.role.tenantId === 'platform' ? [{ value: '*', label: '全部范围(含后续新增)' }, { value: 'platform', label: '平台统一管理' }, ...tenants] : tenants.filter(t => t.value === props.role.tenantId));
|
|
17
|
+
const pbcDirectory = usePbcs();
|
|
18
|
+
const pbcOptions = computed(() => [{ value: '*', label: '授权租户内全部 PBC(含新建)' }, ...pbcDirectory.items.filter(p => props.role.tenantId === 'platform' || p.tenantId === props.role.tenantId).map(p => ({ value: p.id, label: p.name })), ...[...new Set(value.value.grants.flatMap(g => g.pbcIds || []))].filter(id => id !== '*' && !pbcDirectory.items.some(p => p.id === id)).map(id => ({ value: id, label: id + '(保留的范围引用)' }))]);
|
|
19
|
+
const tree = computed(() => actionGroups.map((g, i) => ({ key: 'group-' + i, title: g.name, children: g.items.map(a => ({ key: a.value, title: a.label, disabled: !allowed.value || (a.value.startsWith('permission:') && !session.can('permission:delegate', props.role.tenantId)) })) })));
|
|
20
|
+
function update(index, keys) { const list = Array.isArray(keys) ? keys : keys.checked; value.value.grants[index].actions = list.filter((v) => allActions.includes(v)); if (value.value.grants[index].actions.some(a => a.startsWith('release:')) && !value.value.grants[index].environmentIds)
|
|
21
|
+
value.value.grants[index].environmentIds = ['*']; }
|
|
22
|
+
function add() { value.value.grants.push({ id: crypto.randomUUID(), name: '授权组 ' + (value.value.grants.length + 1), actions: [], tenantIds: [props.role.tenantId], pbcIds: ['*'], environmentIds: ['*'] }); }
|
|
23
|
+
function close() { if (busy.value)
|
|
24
|
+
return; if (JSON.stringify(value.value) !== JSON.stringify(props.role) || form.formData.reason)
|
|
25
|
+
confirmAction({ title: '放弃未保存的授权?', content: '当前角色权限不会改变。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
|
|
26
|
+
else
|
|
27
|
+
emit('close'); }
|
|
28
|
+
async function save() { try {
|
|
29
|
+
await form.formRef.value?.validate();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return;
|
|
33
|
+
} busy.value = true; error.value = ''; try {
|
|
34
|
+
store.saveGrants(value.value, form.formData.reason);
|
|
35
|
+
message.success('角色权限已更新,关联成员同步生效');
|
|
36
|
+
emit('saved');
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
error.value = e.message;
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
busy.value = false;
|
|
43
|
+
} }
|
|
44
|
+
return { computed, ref, Alert, Button, Drawer, Input, Select, Space, Tabs, Tree, message, ProForm, useForm, actionGroups, allActions, tenants, useSession, clone, usePbcs, useAuthority, confirmAction, props, emit, session, store, value, tab, error, busy, form, allowed, affected, scopeOptions, pbcDirectory, pbcOptions, tree, update, add, close, save };
|
|
45
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/MemberEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" data-bind-title="(member ? '修改成员授权' : '添加成员')" data-bind-size="(640)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" type="info" show-icon="" title="关联已有身份,不创建新账号" description="姓名、部门、账号状态由 MaxKey 管理;本页仅维护 EASEL 业务角色关联。" class="page-alert"></template><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)" show-icon="" class="page-alert"></template><template data-component="ProForm" name="business-member" data-bind-form="(form)" layout="vertical" data-bind-disabled="(!allowed || busy)"></template><template data-component="RecordMetadata" data-if="(member)" data-bind-record="(member)"></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存成员授权</template></template></template></template>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { computed, ref, watch } from '../../runtime/state.js';
|
|
2
|
+
import { Alert, Button, Drawer, Space, message } from "../../runtime/widgets.js";
|
|
3
|
+
import { ProForm, useForm } from "../../runtime/widgets.js";
|
|
4
|
+
import { actors, metadata, tenants } from "../shared/policy.js";
|
|
5
|
+
import { useSession } from "../shared/session.js";
|
|
6
|
+
import { clone, checkDelegation } from "./domain.js";
|
|
7
|
+
import { useAuthority } from "./store.js";
|
|
8
|
+
import { confirmAction } from "../shell/confirmation.js";
|
|
9
|
+
import RecordMetadata from "../shared/RecordMetadata.js";
|
|
10
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
11
|
+
export default createComponent({ name: 'MemberEditor', propKeys: ["member"], template: new URL('./MemberEditor.html', import.meta.url).href, setup(__props, __emit) {
|
|
12
|
+
const props = __props, emit = __emit, session = useSession(), store = useAuthority(), busy = ref(false), error = ref('');
|
|
13
|
+
const scopes = [{ value: 'platform', label: '平台统一管理' }, ...tenants].filter(t => session.can('permission:members', t.value));
|
|
14
|
+
const initial = props.member ? clone(props.member) : { ...metadata(session.actor, '', scopes[0]?.value || session.actor.tenantId), id: crypto.randomUUID(), actorId: '', roleIds: [] };
|
|
15
|
+
const form = useForm({ ...initial, reason: '' });
|
|
16
|
+
const people = computed(() => actors.filter(a => session.can('permission:members', 'platform') || a.tenantId === form.formData.tenantId).map(a => ({ value: a.id, label: a.name + ' · ' + a.department + (a.id === 'complete' ? '(全程演示身份)' : '') })));
|
|
17
|
+
const roles = computed(() => store.roles.filter(r => r.tenantId === form.formData.tenantId).map(r => { let disabled = !r.enabled; try {
|
|
18
|
+
checkDelegation(session.actor, r);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
disabled = true;
|
|
22
|
+
} return { value: r.id, label: r.name + (r.enabled ? '' : '(已停用)'), disabled }; }));
|
|
23
|
+
form.fields.value = [
|
|
24
|
+
{ path: 'tenantId', label: '所属范围', component: 'select', span: 24, disabled: !!props.member, options: scopes, rules: [{ required: true, message: '请选择所属范围' }] },
|
|
25
|
+
{ path: 'actorId', label: '身份目录成员', component: 'select', span: 24, disabled: !!props.member, options: people, showSearch: true, optionFilterProp: 'label', rules: [{ required: true, message: '请选择已有成员' }] },
|
|
26
|
+
{ path: 'roleIds', label: '关联业务角色', component: 'select', span: 24, mode: 'multiple', options: roles, extra: '同一范围内可关联多个角色;停用或不可转授的角色不可新分配。', rules: [{ required: true, type: 'array', min: 1, message: '请选择至少一个角色' }] },
|
|
27
|
+
{ path: 'reason', label: '变更原因', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写变更原因' }] },
|
|
28
|
+
];
|
|
29
|
+
watch(() => form.formData.tenantId, () => { form.formData.roleIds = []; if (!props.member)
|
|
30
|
+
form.formData.actorId = ''; });
|
|
31
|
+
const allowed = computed(() => session.can('permission:members', form.formData.tenantId));
|
|
32
|
+
function close() { if (busy.value)
|
|
33
|
+
return; if (JSON.stringify(form.formData) !== JSON.stringify({ ...initial, reason: '' }))
|
|
34
|
+
confirmAction({ title: '放弃未保存的成员授权?', content: '现有成员关联和权限保持不变。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
|
|
35
|
+
else
|
|
36
|
+
emit('close'); }
|
|
37
|
+
async function save() { try {
|
|
38
|
+
await form.formRef.value?.validate();
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return;
|
|
42
|
+
} busy.value = true; error.value = ''; try {
|
|
43
|
+
store.saveMember(form.formData, form.formData.reason);
|
|
44
|
+
message.success('成员授权已保存');
|
|
45
|
+
emit('saved');
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
error.value = e.message;
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
busy.value = false;
|
|
52
|
+
} }
|
|
53
|
+
return { computed, ref, watch, Alert, Button, Drawer, Space, message, ProForm, useForm, actors, metadata, tenants, useSession, clone, checkDelegation, useAuthority, confirmAction, RecordMetadata, props, emit, session, store, busy, error, scopes, initial, form, people, roles, allowed, close, save };
|
|
54
|
+
} });
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/MembersPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="AdminList" kind="members" title="成员授权" description="关联已有成员,按角色统一分配功能和资源权限。" data-bind-rows="(rows)" data-on-create="selected = undefined;
|
|
3
|
+
overlay = 'edit';" data-on-action="(action)" data-on-remove="(remove)"></template><template data-component="MemberEditor" data-if="(overlay === 'edit')" data-bind-member="(selected)" data-on-close="(close)" data-on-saved="(close)"></template><template data-component="Drawer" data-bind-open="(overlay === 'detail')" title="成员有效权限" data-bind-size="(720)" data-on-close="(close)"><template data-if="(current)"><h2>{{ (store.actorName(current.actorId)) }}</h2><p>关联角色:{{ (current.roleIds.map(store.roleName).join('、')) }}</p><p class="muted">以下显示本条业务关联范围内各角色的生效权限;停用角色不参与授权。账号由 MaxKey 管理。</p><template data-component="EffectiveGrants" data-bind-grants="(store.effective(current.actorId, current.tenantId).grants)"></template><template data-component="RecordMetadata" data-bind-record="(current)"></template></template></template><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="业务关联(账号保留)" data-bind-check="(store.checkDeleteMember)" data-bind-submit="(store.deleteMembers)" data-on-close="(targets = [])" data-on-deleted="(targets = [])"></template>
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { computed, ref } from '../../runtime/state.js';
|
|
2
|
+
import { useRouter } from "../../runtime/router.js";
|
|
3
|
+
import { Drawer } from "../../runtime/widgets.js";
|
|
4
|
+
import { useAuthority } from "./store.js";
|
|
5
|
+
import { clone } from "./domain.js";
|
|
6
|
+
import AdminList from "./AdminList.js";
|
|
7
|
+
import MemberEditor from "./MemberEditor.js";
|
|
8
|
+
import EffectiveGrants from "./EffectiveGrants.js";
|
|
9
|
+
import RecordMetadata from "../shared/RecordMetadata.js";
|
|
10
|
+
import ListDeleteDialog from "../shared/ListDeleteDialog.js";
|
|
11
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
12
|
+
export default createComponent({ name: 'MembersPage', propKeys: [], template: new URL('./MembersPage.html', import.meta.url).href, setup(__props, __emit) {
|
|
13
|
+
const store = useAuthority(), router = useRouter(), overlay = ref(''), selected = ref(), targets = ref([]);
|
|
14
|
+
const rows = computed(() => store.members.map(m => ({ ...m, name: store.actorName(m.actorId), code: m.roleIds.map(store.roleName).join('、'), status: store.effective(m.actorId, m.tenantId).grants.length ? '有生效权限' : '无生效权限', extra: '仅业务角色关联;身份账号归 MaxKey。' })));
|
|
15
|
+
const current = computed(() => store.members.find(m => m.id === selected.value?.id));
|
|
16
|
+
function close() { overlay.value = ''; selected.value = undefined; }
|
|
17
|
+
function remove(rows) { targets.value = rows.map(r => ({ id: r.id, name: r.name, recordVersion: r.recordVersion })); }
|
|
18
|
+
function action(key, row) { const m = store.members.find(m => m.id === row.id); if (!m)
|
|
19
|
+
return; if (key === 'history') {
|
|
20
|
+
router.push({ path: '/permissions/records', query: { target: row.name } });
|
|
21
|
+
return;
|
|
22
|
+
} if (key === 'delete') {
|
|
23
|
+
remove([row]);
|
|
24
|
+
return;
|
|
25
|
+
} selected.value = clone(m); overlay.value = key; }
|
|
26
|
+
return { computed, ref, useRouter, Drawer, useAuthority, clone, AdminList, MemberEditor, EffectiveGrants, RecordMetadata, ListDeleteDialog, store, router, overlay, selected, targets, rows, current, close, remove, action };
|
|
27
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/RecordsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="AdminList" data-bind-key="(route.fullPath)" kind="records" title="授权记录" description="按对象和时间追溯角色及成员授权变更。" data-bind-initial-query="(String(route.query.target || ''))" data-bind-rows="(rows)" data-on-action="((_key, row) => selected = row.id)"></template><template data-component="Drawer" data-bind-open="(!!record)" title="授权变更详情" data-bind-size="(780)" data-on-close="(selected = '')"><template data-if="(record)"><h2>{{ (record.operation) }} · {{ (record.target) }}</h2><p>{{ (record.actorName) }} · {{ (new Date(record.at).toLocaleString('zh-CN')) }}</p><p><strong>变更原因:</strong>{{ (record.reason) }}</p><div class="auth-diff"><section><h3>变更前</h3><pre>{{ (record.before) }}</pre></section><section><h3>变更后</h3><pre>{{ (record.after) }}</pre></section></div><p class="muted">本地原型记录;真实后端审计和不可篡改存储尚未接入。</p></template></template>
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { computed, ref } from '../../runtime/state.js';
|
|
2
|
+
import { useRoute } from "../../runtime/router.js";
|
|
3
|
+
import { Drawer } from "../../runtime/widgets.js";
|
|
4
|
+
import { useAuthority } from "./store.js";
|
|
5
|
+
import AdminList from "./AdminList.js";
|
|
6
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
7
|
+
export default createComponent({ name: 'RecordsPage', propKeys: [], template: new URL('./RecordsPage.html', import.meta.url).href, setup(__props, __emit) {
|
|
8
|
+
const store = useAuthority(), route = useRoute(), selected = ref('');
|
|
9
|
+
const rows = computed(() => store.records.map(r => ({ id: r.id, name: r.target, code: r.operation, status: '已生效', extra: r.reason, createdById: r.actorId, createdBy: r.actorName, createdDept: '—', createdAt: r.at, updatedBy: r.actorName, updatedAt: r.at, tenantId: r.tenantId, recordVersion: 1, isDeleted: false })));
|
|
10
|
+
const record = computed(() => store.records.find(r => r.id === selected.value));
|
|
11
|
+
return { computed, ref, useRoute, Drawer, useAuthority, AdminList, store, route, selected, rows, record };
|
|
12
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/RoleEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" data-bind-title="(role ? '编辑角色' : '新增角色')" data-bind-size="(600)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" data-if="(error)" class="page-alert" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="ProForm" name="business-role" data-bind-form="(form)" layout="vertical" data-bind-disabled="(busy || !allowed)"></template><p class="muted">新增角色初始没有功能权限,保存后通过「配置权限」授予。</p><template data-component="RecordMetadata" data-if="(role)" data-bind-record="(role)"></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存角色</template></template></template></template>
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { computed, ref } from '../../runtime/state.js';
|
|
2
|
+
import { Alert, Button, Drawer, Space, message } from "../../runtime/widgets.js";
|
|
3
|
+
import { ProForm, useForm } from "../../runtime/widgets.js";
|
|
4
|
+
import { useSession } from "../shared/session.js";
|
|
5
|
+
import { metadata, tenants } from "../shared/policy.js";
|
|
6
|
+
import { clone } from "./domain.js";
|
|
7
|
+
import { useAuthority } from "./store.js";
|
|
8
|
+
import { confirmAction } from "../shell/confirmation.js";
|
|
9
|
+
import RecordMetadata from "../shared/RecordMetadata.js";
|
|
10
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
11
|
+
export default createComponent({ name: 'RoleEditor', propKeys: ["role"], template: new URL('./RoleEditor.html', import.meta.url).href, setup(__props, __emit) {
|
|
12
|
+
const props = __props, emit = __emit, session = useSession(), store = useAuthority(), busy = ref(false), error = ref('');
|
|
13
|
+
const scopes = [{ value: 'platform', label: '平台统一管理' }, ...tenants].filter(t => session.can('permission:roles', t.value));
|
|
14
|
+
const initial = props.role ? clone(props.role) : { ...metadata(session.actor, '', scopes[0]?.value || session.actor.tenantId), id: crypto.randomUUID(), name: '', code: '', description: '', enabled: true, protected: false, grants: [] };
|
|
15
|
+
const form = useForm({ ...initial, reason: '' }, [
|
|
16
|
+
{ path: 'name', label: '角色名称', component: 'input', span: 24, rules: [{ required: true, whitespace: true, message: '请输入角色名称' }] },
|
|
17
|
+
{ path: 'code', label: '角色编码', component: 'input', span: 24, disabled: !!props.role, extra: '创建后编码不可修改;角色名称可以调整。', rules: [{ required: true, message: '请输入角色编码' }] },
|
|
18
|
+
{ path: 'tenantId', label: '所属范围', component: 'select', span: 24, disabled: !!props.role, options: scopes, rules: [{ required: true, message: '请选择所属范围' }] },
|
|
19
|
+
{ path: 'description', label: '用途说明', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写用途说明' }] },
|
|
20
|
+
{ path: 'reason', label: '变更原因', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写变更原因' }] },
|
|
21
|
+
]);
|
|
22
|
+
const allowed = computed(() => session.can('permission:roles', form.formData.tenantId));
|
|
23
|
+
function close() { if (busy.value)
|
|
24
|
+
return; if (JSON.stringify(form.formData) !== JSON.stringify({ ...initial, reason: '' }))
|
|
25
|
+
confirmAction({ title: '放弃未保存的修改?', content: '本次输入将不保存,现有角色保持不变。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
|
|
26
|
+
else
|
|
27
|
+
emit('close'); }
|
|
28
|
+
async function save() { try {
|
|
29
|
+
await form.formRef.value?.validate();
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return;
|
|
33
|
+
} busy.value = true; error.value = ''; try {
|
|
34
|
+
store.saveRole(form.formData, form.formData.reason);
|
|
35
|
+
message.success('角色已保存');
|
|
36
|
+
emit('saved');
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
error.value = e.message;
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
busy.value = false;
|
|
43
|
+
} }
|
|
44
|
+
return { computed, ref, Alert, Button, Drawer, Space, message, ProForm, useForm, useSession, metadata, tenants, clone, useAuthority, confirmAction, RecordMetadata, props, emit, session, store, busy, error, scopes, initial, form, allowed, close, save };
|
|
45
|
+
} });
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<!-- 来源:src/permissions/RolesPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="AdminList" kind="roles" title="角色管理" description="配置角色的功能与资源范围,按需关联成员。" data-bind-rows="(rows)" data-on-create="selected = undefined;
|
|
3
|
+
overlay = 'edit';" data-on-action="(action)" data-on-remove="(remove)"></template><template data-component="RoleEditor" data-if="(overlay === 'edit')" data-bind-role="(selected)" data-on-close="(close)" data-on-saved="(close)"></template><template data-component="GrantEditor" data-if="(overlay === 'grant' && selected)" data-bind-role="(selected)" data-on-close="(close)" data-on-saved="(close)"></template><template data-component="Drawer" data-bind-open="(overlay === 'detail')" title="角色详情" data-bind-size="(720)" data-on-close="(close)"><template data-if="(current)"><h2>{{ (current.name) }} <template data-component="Tag">{{ (current.enabled ? '启用' : '停用') }}</template></h2><p>{{ (current.code) }} · {{ (current.description) }}</p><p>关联成员 {{ (affected.length) }} 条:{{ (affected.join('、') || '暂无') }}</p><template data-component="Alert" data-if="(!current.enabled)" type="warning" title="角色已停用,以下配置暂不生效。"></template><template data-component="EffectiveGrants" data-bind-grants="(current.grants)"></template><template data-component="RecordMetadata" data-bind-record="(current)"></template></template></template><template data-component="Drawer" data-bind-open="(overlay === 'toggle')" data-bind-title="(selected?.enabled ? '停用角色' : '启用角色')" data-bind-size="(560)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-if="(selected)"><template data-component="Alert" show-icon="" data-bind-type="(selected.enabled ? 'warning' : 'info')" data-bind-title="(selected.name)" data-bind-description="('影响 ' + affected.length + ' 条成员关联:' + (affected.join('、') || '暂无'))"></template><p>保存后按新状态计算业务权限;其他角色提供的权限仍保留。</p><label for="role-status-reason">变更原因</label><template data-component="Input.TextArea" id="role-status-reason" data-model-value="(reason)"></template><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)"></template><template data-if="(selected.protected)"><p>系统引导角色受保护。</p></template></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-danger="(selected?.enabled)" data-bind-disabled="(!selected || selected.protected || !session.can('permission:roles', selected.tenantId))" data-on-click="(toggle)">{{ (selected?.enabled ? '确认停用' : '确认启用') }}</template></template></template></template><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="角色" data-bind-check="(store.checkDeleteRole)" data-bind-submit="(store.deleteRoles)" data-on-close="(targets = [])" data-on-deleted="(targets = [])"></template>
|
package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { computed, ref } from '../../runtime/state.js';
|
|
2
|
+
import { useRouter } from "../../runtime/router.js";
|
|
3
|
+
import { Alert, Button, Drawer, Space, Tag, Input, message } from "../../runtime/widgets.js";
|
|
4
|
+
import { useAuthority } from "./store.js";
|
|
5
|
+
import { useSession } from "../shared/session.js";
|
|
6
|
+
import { clone } from "./domain.js";
|
|
7
|
+
import AdminList from "./AdminList.js";
|
|
8
|
+
import RoleEditor from "./RoleEditor.js";
|
|
9
|
+
import GrantEditor from "./GrantEditor.js";
|
|
10
|
+
import EffectiveGrants from "./EffectiveGrants.js";
|
|
11
|
+
import RecordMetadata from "../shared/RecordMetadata.js";
|
|
12
|
+
import ListDeleteDialog from "../shared/ListDeleteDialog.js";
|
|
13
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
14
|
+
export default createComponent({ name: 'RolesPage', propKeys: [], template: new URL('./RolesPage.html', import.meta.url).href, setup(__props, __emit) {
|
|
15
|
+
const store = useAuthority(), session = useSession(), router = useRouter(), overlay = ref(''), selected = ref(), targets = ref([]), reason = ref(''), error = ref('');
|
|
16
|
+
const rows = computed(() => store.roles.map(r => ({ ...r, status: r.enabled ? '启用' : '停用', extra: r.description })));
|
|
17
|
+
const current = computed(() => store.roles.find(r => r.id === selected.value?.id));
|
|
18
|
+
const affected = computed(() => store.members.filter(m => m.roleIds.includes(selected.value?.id || '')).map(m => store.actorName(m.actorId)));
|
|
19
|
+
function close() { overlay.value = ''; selected.value = undefined; reason.value = ''; error.value = ''; }
|
|
20
|
+
function action(key, row) { const r = store.roles.find(r => r.id === row.id); if (!r)
|
|
21
|
+
return; if (key === 'history') {
|
|
22
|
+
router.push({ path: '/permissions/records', query: { target: r.name } });
|
|
23
|
+
return;
|
|
24
|
+
} if (key === 'delete') {
|
|
25
|
+
remove([row]);
|
|
26
|
+
return;
|
|
27
|
+
} selected.value = clone(r); overlay.value = key; reason.value = ''; error.value = ''; }
|
|
28
|
+
function remove(rs) { targets.value = rs.map(r => ({ id: r.id, name: r.name, recordVersion: r.recordVersion })); }
|
|
29
|
+
function toggle() { try {
|
|
30
|
+
store.toggleRole(selected.value, reason.value);
|
|
31
|
+
message.success('角色状态已更新');
|
|
32
|
+
close();
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
error.value = e.message;
|
|
36
|
+
} }
|
|
37
|
+
return { computed, ref, useRouter, Alert, Button, Drawer, Space, Tag, Input, message, useAuthority, useSession, clone, AdminList, RoleEditor, GrantEditor, EffectiveGrants, RecordMetadata, ListDeleteDialog, store, session, router, overlay, selected, targets, reason, error, rows, current, affected, close, action, remove, toggle };
|
|
38
|
+
} });
|