create-windy 0.9.1 → 0.10.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/dist/cli.js +1769 -1277
- package/package.json +2 -2
- package/template/.agents/skills/windy-business-module/SKILL.md +33 -1
- package/template/.windy-template.json +6 -2
- package/template/AGENTS.md +4 -0
- package/template/README.md +2 -0
- package/template/apps/agent-server/Dockerfile +1 -1
- package/template/apps/agent-server/README.md +1 -1
- package/template/apps/agent-server/native/EXTENSIONS.md +2 -2
- package/template/apps/agent-server/native/parallel-harness.ts +2 -0
- package/template/apps/agent-server/native/storage-lifecycle.test.ts +2 -1
- package/template/apps/agent-server/package.json +42 -41
- package/template/apps/agent-server/plugins/downloads/README.md +1 -1
- package/template/apps/agent-server/plugins/drop-overlay/README.md +1 -1
- package/template/apps/agent-server/plugins/settings/README.md +1 -1
- package/template/apps/agent-server/plugins/skill-library/client-chunks.test.ts +4 -1
- package/template/apps/agent-server/plugins/theme/README.md +5 -1
- package/template/apps/agent-server/plugins/theme/source-tokens.ts +0 -1
- package/template/apps/agent-server/plugins/theme/tokens.json +0 -4
- package/template/apps/agent-server/plugins/tool-catalog/README.md +6 -3
- package/template/apps/agent-server/plugins/tool-catalog/discovery.mjs +13 -10
- package/template/apps/agent-server/plugins/tool-catalog/discovery.test.ts +68 -6
- package/template/apps/agent-server/runtime/compatibility.ts +7 -1
- package/template/apps/agent-server/runtime/dsh-engine.ts +2 -0
- package/template/apps/agent-server/runtime/questions-workflow.nodecheck.ts +2 -0
- package/template/apps/server/Dockerfile +2 -1
- package/template/apps/server/package.json +11 -11
- package/template/apps/server/scripts/validate-module-composition-once.ts +2 -0
- package/template/apps/server/scripts/validate-module-composition.ts +8 -4
- package/template/apps/server/src/admin/routes.test.ts +29 -1
- package/template/apps/server/src/admin/routes.ts +20 -2
- package/template/apps/server/src/agent/client-session/completion.ts +1 -1
- package/template/apps/server/src/agent/client-session/manifest-admission.ts +1 -1
- package/template/apps/server/src/agent/client-session/request.ts +1 -1
- package/template/apps/server/src/agent/context-version-routes.ts +37 -13
- package/template/apps/server/src/agent/run-facade.ts +1 -1
- package/template/apps/server/src/agent/run-input-verification.ts +1 -1
- package/template/apps/server/src/agent/run-routes.ts +1 -14
- package/template/apps/server/src/agent/run-start-preparation.ts +1 -1
- package/template/apps/server/src/agent/runtime-bootstrap-input.ts +2 -0
- package/template/apps/server/src/agent/runtime-bootstrap.ts +49 -157
- package/template/apps/server/src/agent/runtime-disabled-composition.ts +2 -1
- package/template/apps/server/src/agent/session-invalidation/authorization-revocation.ts +54 -0
- package/template/apps/server/src/agent/session-runtime-composition.ts +1 -51
- package/template/apps/server/src/agent/unavailable-routes.ts +13 -2
- package/template/apps/server/src/agent-workflow/runtime-composition.ts +3 -0
- package/template/apps/server/src/agent-workflow/service.ts +17 -1
- package/template/apps/server/src/ai-artifact/media-resource-route.test.ts +134 -0
- package/template/apps/server/src/ai-artifact/routes.ts +1 -1
- package/template/apps/server/src/ai-artifact/runtime.ts +12 -0
- package/template/apps/server/src/ai-runtime-readiness/operation-port.test-support.ts +1 -1
- package/template/apps/server/src/ai-runtime-readiness/operation-port.ts +8 -0
- package/template/apps/server/src/ai-runtime-security/internal-token.ts +14 -0
- package/template/apps/server/src/app/antivirus-composition.test.ts +63 -0
- package/template/apps/server/src/app/antivirus-composition.ts +29 -0
- package/template/apps/server/src/app/dsh-workbench-socket-audit.test.ts +2 -1
- package/template/apps/server/src/configuration/definition.ts +15 -11
- package/template/apps/server/src/document/facade-support.ts +2 -2
- package/template/apps/server/src/document/facade.ts +2 -2
- package/template/apps/server/src/document/output-artifact-composition.ts +9 -5
- package/template/apps/server/src/document/output-artifact.test-support.ts +1 -1
- package/template/apps/server/src/embedding/facade.ts +1 -1
- package/template/apps/server/src/embedding/input.ts +1 -1
- package/template/apps/server/src/embedding/routes.ts +1 -1
- package/template/apps/server/src/index.ts +60 -60
- package/template/apps/server/src/license/routes.ts +4 -1
- package/template/apps/server/src/license/runtime-business-access.test.ts +261 -0
- package/template/apps/server/src/media-runtime/composition.ts +157 -0
- package/template/apps/server/src/media-runtime/media-only-composition.ts +44 -0
- package/template/apps/server/src/media-runtime/module-ai-port-factory.test.ts +69 -0
- package/template/apps/server/src/media-runtime/module-ai-port-factory.ts +72 -0
- package/template/apps/server/src/{agent → media-runtime}/runtime-readiness-sources.ts +14 -6
- package/template/apps/server/src/media-runtime/shared-composition.ts +104 -0
- package/template/apps/server/src/module-composition.test.ts +22 -0
- package/template/apps/server/src/module-composition.ts +48 -0
- package/template/apps/server/src/module-host/ai-operation-port.ts +97 -30
- package/template/apps/server/src/module-host/ai-operation-speech-normalize.test.ts +1 -1
- package/template/apps/server/src/module-host/http-runtime.ts +9 -3
- package/template/apps/server/src/module-host/static-route-authorization.test.ts +6 -3
- package/template/apps/server/src/module-host/storage-authorization-binding.test.ts +4 -0
- package/template/apps/server/src/module-runtime-validation.ts +2 -0
- package/template/apps/server/src/observability/diagnostic-index.ts +26 -1
- package/template/apps/server/src/observability/diagnostic-repository.ts +40 -11
- package/template/apps/server/src/platform-http-runtime.ts +1 -1
- package/template/apps/server/src/runtime-feature.ts +5 -1
- package/template/apps/server/src/runtime.ts +3 -0
- package/template/apps/server/src/settings/drizzle-watermark-repository.ts +35 -4
- package/template/apps/server/src/settings/watermark-repository.ts +14 -0
- package/template/apps/server/src/settings/watermark-routes.test.ts +84 -2
- package/template/apps/server/src/settings/watermark-routes.ts +109 -0
- package/template/apps/server/src/settings/watermark-transfer.ts +79 -0
- package/template/apps/server/src/speech/facade-validation.ts +1 -1
- package/template/apps/server/src/speech/facade.ts +2 -2
- package/template/apps/server/src/startup-composition-validation.test.ts +32 -0
- package/template/apps/server/src/startup-finalization.ts +2 -0
- package/template/apps/server/src/startup-runtime.ts +77 -0
- package/template/apps/server/src/system/ai-runtime-build.ts +3 -0
- package/template/apps/server/src/system/ai-runtime-configuration.test.ts +36 -0
- package/template/apps/server/src/system/ai-runtime-configuration.ts +58 -0
- package/template/apps/server/src/system/diagnostic-routes.test.ts +45 -0
- package/template/apps/server/src/system/diagnostic-routes.ts +35 -0
- package/template/apps/server/src/system/environment-policy-reader.test.ts +74 -0
- package/template/apps/server/src/system/environment-policy-reader.ts +62 -0
- package/template/apps/server/src/system/feature-environment-assessment.test.ts +148 -0
- package/template/apps/server/src/system/feature-environment-assessment.ts +179 -0
- package/template/apps/server/src/system/host-diagnostics.test.ts +155 -0
- package/template/apps/server/src/system/host-diagnostics.ts +225 -0
- package/template/apps/server/src/system/menu-registry.test.ts +26 -0
- package/template/apps/server/src/system/menu-registry.ts +9 -7
- package/template/apps/server/src/system/operations.test.ts +5 -0
- package/template/apps/server/src/system/operations.ts +36 -12
- package/template/apps/server/src/system/role-authorization-postgres.integration.test.ts +181 -0
- package/template/apps/web/Dockerfile +7 -3
- package/template/apps/web/dev/dev-port.test.ts +6 -6
- package/template/apps/web/dev/dev-port.ts +1 -1
- package/template/apps/web/dev/start.ts +6 -1
- package/template/apps/web/index.html +1 -0
- package/template/apps/web/package.json +16 -16
- package/template/apps/web/runtime-server.test.ts +22 -1
- package/template/apps/web/runtime-server.ts +6 -0
- package/template/apps/web/src/App.vue +6 -3
- package/template/apps/web/src/assets/windy.svg +4 -0
- package/template/apps/web/src/components/auth/LoginForm.vue +2 -2
- package/template/apps/web/src/components/auth/PasswordChangeForm.vue +14 -3
- package/template/apps/web/src/components/common/FormDialog.vue +1 -1
- package/template/apps/web/src/components/license/LicenseFlow.webtest.ts +3 -0
- package/template/apps/web/src/components/license/LicenseMachineCodeQr.vue +99 -0
- package/template/apps/web/src/components/license/LicenseMachineCodeQr.webtest.ts +83 -0
- package/template/apps/web/src/components/license/LicensePairingCard.vue +1 -1
- package/template/apps/web/src/components/license/LicenseStatusCard.vue +14 -2
- package/template/apps/web/src/composables/useLoginFlow.ts +2 -2
- package/template/apps/web/src/composables/usePlatformSettings.ts +1 -1
- package/template/apps/web/src/composables/useWatermarkSettings.ts +1 -0
- package/template/apps/web/src/layout/AppSidebar.vue +5 -9
- package/template/apps/web/src/layout/AppSidebar.webtest.ts +4 -1
- package/template/apps/web/src/pages/auth/ChangePasswordPage.vue +67 -6
- package/template/apps/web/src/pages/auth/LoginPage.vue +3 -12
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationEditor.vue +30 -0
- package/template/apps/web/src/pages/configuration/components/ModuleConfigurationWorkbench.vue +25 -14
- package/template/apps/web/src/pages/configuration/components/TimeZoneSelect.vue +55 -0
- package/template/apps/web/src/pages/profile/PersonalSettingsPage.vue +64 -11
- package/template/apps/web/src/pages/profile/PersonalSettingsPage.webtest.ts +21 -1
- package/template/apps/web/src/pages/settings/BrandingSettingsSection.vue +7 -18
- package/template/apps/web/src/pages/settings/BrandingSettingsSection.webtest.ts +9 -4
- package/template/apps/web/src/pages/settings/GlobalSettingsPage.vue +51 -6
- package/template/apps/web/src/pages/settings/GlobalSettingsPage.webtest.ts +19 -3
- package/template/apps/web/src/pages/settings/WatermarkSettingsSection.vue +1 -0
- package/template/apps/web/src/pages/settings/WatermarkYamlTransfer.vue +211 -0
- package/template/apps/web/src/pages/system/DiagnosticLookupPage.vue +18 -3
- package/template/apps/web/src/pages/system/DiagnosticLookupPage.webtest.ts +4 -1
- package/template/apps/web/src/pages/system/SystemOperationsPage.vue +23 -0
- package/template/apps/web/src/pages/system/components/DiagnosticLogList.vue +120 -0
- package/template/apps/web/src/pages/system/components/OperationEnvironmentPanel.vue +237 -0
- package/template/apps/web/src/pages/system/components/OperationFeatureAssessmentPanel.vue +131 -0
- package/template/apps/web/src/pages/system/components/PagedSelectionList.vue +31 -24
- package/template/apps/web/src/pages/system/components/SystemResourceActions.vue +2 -1
- package/template/apps/web/src/pages/system/components/SystemResourceEditor.vue +11 -2
- package/template/apps/web/src/pages/system/components/SystemResourcePage.vue +1 -0
- package/template/apps/web/src/pages/system/components/SystemResourcePage.webtest.ts +6 -2
- package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.vue +18 -9
- package/template/apps/web/src/pages/system/components/agent-workbench/SessionReplayTimeline.vue +18 -9
- package/template/apps/web/src/pages/system/components/agent-workbench/TestRunComposer.vue +66 -34
- package/template/apps/web/src/pages/system/components/agent-workbench/ToolCatalogPanel.vue +48 -33
- package/template/apps/web/src/pages/system/components/agent-workbench/ToolCatalogPanel.webtest.ts +9 -2
- package/template/apps/web/src/pages/system/components/agent-workbench/ToolRuleDetail.vue +23 -16
- package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkJobDetail.vue +10 -7
- package/template/apps/web/src/pages/system/components/user-account/RolePermissionSummary.vue +81 -57
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.vue +6 -4
- package/template/apps/web/src/pages/system/components/user-account/UserRoleSelector.webtest.ts +20 -4
- package/template/apps/web/src/pages/system/resource-config.ts +9 -0
- package/template/apps/web/src/pages/work-orders/WorkOrderListPage.vue +1 -1
- package/template/apps/web/src/router/disabled-feature-loading.webtest.ts +78 -0
- package/template/apps/web/src/router/index.ts +3 -6
- package/template/apps/web/src/router/manifest-routes.ts +2 -3
- package/template/apps/web/src/router/platform-admin-pages.ts +21 -62
- package/template/apps/web/src/router/platform-admin-route-bindings.ts +4 -4
- package/template/apps/web/src/services/diagnostics-api.ts +13 -1
- package/template/apps/web/src/services/operations-api.ts +4 -0
- package/template/apps/web/src/services/platform-settings-api.ts +35 -1
- package/template/apps/web/vite.config.ts +9 -3
- package/template/deploy/environment/windy.environment.example.yaml +53 -0
- package/template/docker-compose.yml +4 -2
- package/template/docs/architecture/agent-admin-workbench-implementation.md +1 -1
- package/template/docs/architecture/agent-admin-workbench-plan.md +1 -1
- package/template/docs/architecture/agent-workflow.md +8 -0
- package/template/docs/architecture/durable-jobs.md +17 -0
- package/template/docs/architecture/embedded-dsh-integration.md +1 -1
- package/template/docs/development/dsh-plugins.md +1 -1
- package/template/docs/development/performance-engineering.md +24 -0
- package/template/docs/operations/admin-settings-yaml.md +29 -0
- package/template/docs/operations/dsh-agent-migration.md +2 -2
- package/template/docs/operations/environment-capabilities.md +185 -0
- package/template/docs/platform/module-configuration.md +18 -3
- package/template/docs/platform/platform-authentication.md +1 -1
- package/template/package.json +10 -8
- package/template/packages/config/package.json +2 -2
- package/template/packages/config/src/definition.ts +14 -4
- package/template/packages/config/src/environment-loader.ts +27 -3
- package/template/packages/config/src/platform-ai-runtime.test.ts +94 -0
- package/template/packages/config/src/platform.ts +5 -2
- package/template/packages/database/drizzle/0065_durable_job_lease_snapshot_lookup.sql +1 -0
- package/template/packages/database/drizzle/0066_agent_source_sequence_bigint.sql +3 -0
- package/template/packages/database/drizzle/0067_media_runtime_access.sql +46 -0
- package/template/packages/database/drizzle/meta/0065_snapshot.json +15370 -0
- package/template/packages/database/drizzle/meta/0066_snapshot.json +15370 -0
- package/template/packages/database/drizzle/meta/0067_snapshot.json +15370 -0
- package/template/packages/database/drizzle/meta/_journal.json +21 -0
- package/template/packages/database/package.json +3 -3
- package/template/packages/database/src/schema/agent-session.ts +4 -3
- package/template/packages/database/src/schema/durable-jobs.ts +4 -0
- package/template/packages/database/src/schema/index.ts +3 -1
- package/template/packages/database/src/schema-durable-recovery.test.ts +21 -1
- package/template/packages/database/src/schema-source-sequence.test.ts +24 -0
- package/template/packages/example-work-order/package.json +2 -2
- package/template/packages/modules/package.json +1 -1
- package/template/packages/modules/src/admin-ui-boundary.test.ts +33 -0
- package/template/packages/modules/src/composition.ts +11 -28
- package/template/packages/modules/src/manifest.ts +2 -0
- package/template/packages/modules/src/menu-composition.ts +24 -0
- package/template/packages/modules/src/system-admin-routes.ts +2 -2
- package/template/packages/modules/src/system-admin-ui-catalog.ts +6 -1
- package/template/packages/modules/src/system-ai-api-bindings.ts +0 -16
- package/template/packages/modules/src/system-api-control-plane.ts +9 -1
- package/template/packages/modules/src/system-api-permissions.ts +7 -0
- package/template/packages/modules/src/system-api-watermark.ts +21 -0
- package/template/packages/modules/src/system-audit-actions.ts +3 -1
- package/template/packages/modules/src/system-features.ts +21 -3
- package/template/packages/modules/src/system-media-api-bindings.ts +97 -0
- package/template/packages/modules/src/system-module-audit-selection.ts +2 -0
- package/template/packages/modules/src/system-module-catalog.test.ts +13 -6
- package/template/packages/modules/src/system-module-catalog.ts +6 -241
- package/template/packages/modules/src/system-module-definitions.ts +260 -0
- package/template/packages/modules/src/system-modules-access.test.ts +2 -0
- package/template/packages/modules/src/system-modules.test.ts +7 -1
- package/template/packages/modules/src/system-modules.ts +25 -13
- package/template/packages/modules/src/system-permissions.ts +12 -0
- package/template/packages/server-sdk/package.json +1 -1
- package/template/packages/shared/index.ts +3 -0
- package/template/packages/shared/package.json +1 -1
- package/template/packages/shared/src/environment-assessment.ts +68 -0
- package/template/packages/shared/src/environment-policy.ts +205 -0
- package/template/packages/shared/src/license-console-capabilities.ts +7 -0
- package/template/packages/shared/src/license.ts +1 -0
- package/template/packages/shared/src/module-configuration.ts +2 -1
- package/template/scripts/operations/collect-device-info.py +230 -0
- package/template/apps/server/src/agent/module-ai-port-factory.ts +0 -41
- /package/template/apps/server/src/{agent → ai-runtime-security}/execution-grants.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/idempotency-key.test.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/idempotency-key.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/provider-input-governance.test.ts +0 -0
- /package/template/apps/server/src/{agent → ai-runtime-security}/provider-input-governance.ts +0 -0
- /package/template/apps/server/src/{agent → media-runtime}/required-environment.ts +0 -0
- /package/template/apps/server/src/{agent → media-runtime}/runtime-readiness-sources.test.ts +0 -0
|
@@ -91,7 +91,16 @@ onMounted(() => window.addEventListener("beforeunload", preventDirtyUnload));
|
|
|
91
91
|
onBeforeUnmount(() =>
|
|
92
92
|
window.removeEventListener("beforeunload", preventDirtyUnload),
|
|
93
93
|
);
|
|
94
|
-
const title = computed(
|
|
94
|
+
const title = computed(
|
|
95
|
+
() =>
|
|
96
|
+
`${props.item ? "编辑" : "新增"}${props.config.entityLabel ?? props.config.title}`,
|
|
97
|
+
);
|
|
98
|
+
const contentClass = computed(() => {
|
|
99
|
+
if (["users", "departments"].includes(props.config.key)) {
|
|
100
|
+
return "sm:max-w-[calc(100%-2rem)]";
|
|
101
|
+
}
|
|
102
|
+
return props.config.key === "roles" ? "sm:max-w-4xl" : undefined;
|
|
103
|
+
});
|
|
95
104
|
</script>
|
|
96
105
|
|
|
97
106
|
<template>
|
|
@@ -101,7 +110,7 @@ const title = computed(() => (props.item ? "编辑记录" : "新增记录"));
|
|
|
101
110
|
:description="config.description"
|
|
102
111
|
:loading="loading || saving"
|
|
103
112
|
:before-close="beforeClose"
|
|
104
|
-
:content-class="
|
|
113
|
+
:content-class="contentClass"
|
|
105
114
|
@submit="saveForm"
|
|
106
115
|
>
|
|
107
116
|
<p v-if="error" class="text-sm text-destructive" role="alert">
|
|
@@ -200,6 +200,7 @@ async function importData(file: File) {
|
|
|
200
200
|
<CardTitle class="text-base">数据列表</CardTitle>
|
|
201
201
|
<SystemResourceActions
|
|
202
202
|
:can-create="resource.canCreate.value"
|
|
203
|
+
:create-label="config.key === 'users' ? '新增人员' : undefined"
|
|
203
204
|
:can-import="resource.canImport.value"
|
|
204
205
|
:replaces-native-transfer="config.replacesNativeTransfer"
|
|
205
206
|
@refresh="resource.reload"
|
|
@@ -280,10 +280,14 @@ describe("SystemResourcePage", () => {
|
|
|
280
280
|
|
|
281
281
|
const add = wrapper
|
|
282
282
|
.findAll("button")
|
|
283
|
-
.find((button) => button.text() === "
|
|
284
|
-
|
|
283
|
+
.find((button) => button.text() === "新增人员");
|
|
284
|
+
expect(add).toBeDefined();
|
|
285
|
+
await add!.trigger("click");
|
|
285
286
|
await flushPromises();
|
|
286
287
|
|
|
288
|
+
expect(
|
|
289
|
+
document.body.querySelector('[role="dialog"]')?.textContent,
|
|
290
|
+
).toContain("新增人员");
|
|
287
291
|
expect(document.body.textContent).toContain("所属部门");
|
|
288
292
|
expect(document.body.textContent).toContain("新建部门");
|
|
289
293
|
expect(document.body.textContent).toContain("每页 10 条");
|
package/template/apps/web/src/pages/system/components/agent-skills/AgentSkillImportDialog.vue
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Select,
|
|
4
|
+
SelectContent,
|
|
5
|
+
SelectItem,
|
|
6
|
+
SelectTrigger,
|
|
7
|
+
SelectValue,
|
|
8
|
+
} from "@/components/ui/select";
|
|
9
|
+
|
|
2
10
|
import { computed, onBeforeUnmount, shallowRef, watch } from "vue";
|
|
3
11
|
import { onBeforeRouteLeave } from "vue-router";
|
|
4
12
|
import type {
|
|
@@ -229,15 +237,16 @@ onBeforeUnmount(() => {
|
|
|
229
237
|
<div class="grid gap-4 sm:grid-cols-2">
|
|
230
238
|
<label class="space-y-2 text-sm"
|
|
231
239
|
><span>共享范围</span
|
|
232
|
-
><
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
><Select v-model="scope" :disabled="saving">
|
|
241
|
+
<SelectTrigger aria-label="共享范围" class="w-full"
|
|
242
|
+
><SelectValue
|
|
243
|
+
/></SelectTrigger>
|
|
244
|
+
<SelectContent>
|
|
245
|
+
<SelectItem value="tenant">全租户</SelectItem>
|
|
246
|
+
<SelectItem value="department">当前部门</SelectItem>
|
|
247
|
+
<SelectItem value="personal">仅本人</SelectItem>
|
|
248
|
+
</SelectContent>
|
|
249
|
+
</Select></label
|
|
241
250
|
><label class="space-y-2 text-sm"
|
|
242
251
|
><span>当前版本(新技能填 0)</span
|
|
243
252
|
><Input
|
package/template/apps/web/src/pages/system/components/agent-workbench/SessionReplayTimeline.vue
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Select,
|
|
4
|
+
SelectContent,
|
|
5
|
+
SelectItem,
|
|
6
|
+
SelectTrigger,
|
|
7
|
+
SelectValue,
|
|
8
|
+
} from "@/components/ui/select";
|
|
9
|
+
|
|
2
10
|
import { computed } from "vue";
|
|
3
11
|
import type { AgentWorkbenchRecordingV1 } from "@southwind-ai/shared";
|
|
4
12
|
import { Button } from "@/components/ui/button";
|
|
@@ -68,15 +76,16 @@ const replay = useSessionReplay(events);
|
|
|
68
76
|
:disabled="replay.cursor.value >= entries.length - 1"
|
|
69
77
|
@click="replay.seek(replay.cursor.value + 1)"
|
|
70
78
|
>下一事件</Button
|
|
71
|
-
><
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
><Select v-model="replay.speed.value">
|
|
80
|
+
<SelectTrigger aria-label="回放速度"><SelectValue /></SelectTrigger>
|
|
81
|
+
<SelectContent>
|
|
82
|
+
<SelectItem
|
|
83
|
+
v-for="speed in [0.5, 1, 2, 4]"
|
|
84
|
+
:key="speed"
|
|
85
|
+
:value="speed"
|
|
86
|
+
>{{ speed }} 倍速</SelectItem
|
|
87
|
+
>
|
|
88
|
+
</SelectContent> </Select
|
|
80
89
|
><span class="text-xs text-muted-foreground"
|
|
81
90
|
>{{ replay.cursor.value + 1 }} / {{ entries.length }}</span
|
|
82
91
|
>
|
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
Select,
|
|
4
|
+
SelectContent,
|
|
5
|
+
SelectItem,
|
|
6
|
+
SelectTrigger,
|
|
7
|
+
SelectValue,
|
|
8
|
+
} from "@/components/ui/select";
|
|
9
|
+
|
|
2
10
|
import { computed } from "vue";
|
|
3
11
|
import type { AgentAdminOperationCatalogItem } from "@southwind-ai/shared";
|
|
4
12
|
import { Button } from "@/components/ui/button";
|
|
13
|
+
import {
|
|
14
|
+
Sheet,
|
|
15
|
+
SheetContent,
|
|
16
|
+
SheetDescription,
|
|
17
|
+
SheetHeader,
|
|
18
|
+
SheetTitle,
|
|
19
|
+
SheetTrigger,
|
|
20
|
+
} from "@/components/ui/sheet";
|
|
5
21
|
import { availabilityLabel, formatJson } from "./catalog-presenter";
|
|
6
22
|
const props = defineProps<{
|
|
7
23
|
operations: readonly AgentAdminOperationCatalogItem[];
|
|
@@ -31,44 +47,60 @@ const operation = computed(() =>
|
|
|
31
47
|
</p>
|
|
32
48
|
<label class="grid gap-2 text-sm"
|
|
33
49
|
><span>Operation</span
|
|
34
|
-
><
|
|
50
|
+
><Select
|
|
35
51
|
required
|
|
36
|
-
|
|
52
|
+
name="operationKey"
|
|
53
|
+
:model-value="operationKey || null"
|
|
37
54
|
:disabled="starting || running || !canManage"
|
|
38
|
-
|
|
39
|
-
@change="$emit('operation', ($event.target as HTMLSelectElement).value)"
|
|
55
|
+
@update:model-value="$emit('operation', String($event ?? ''))"
|
|
40
56
|
>
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
<SelectTrigger aria-label="Operation" class="w-full"
|
|
58
|
+
><SelectValue placeholder="请选择已注册操作"
|
|
59
|
+
/></SelectTrigger>
|
|
60
|
+
<SelectContent>
|
|
61
|
+
<SelectItem
|
|
62
|
+
v-for="item in operations"
|
|
63
|
+
:key="item.key"
|
|
64
|
+
:value="item.key"
|
|
65
|
+
:disabled="!item.selectable"
|
|
66
|
+
>
|
|
67
|
+
{{ item.key }} · {{ item.moduleLabel
|
|
68
|
+
}}{{
|
|
69
|
+
item.selectable
|
|
70
|
+
? ""
|
|
71
|
+
: `(${availabilityLabel(item.availabilityReason)})`
|
|
72
|
+
}}
|
|
73
|
+
</SelectItem>
|
|
74
|
+
</SelectContent>
|
|
75
|
+
</Select></label
|
|
56
76
|
>
|
|
57
|
-
<
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
77
|
+
<Sheet v-if="operation" :key="operation.key">
|
|
78
|
+
<SheetTrigger as-child>
|
|
79
|
+
<Button type="button" variant="outline" size="sm">
|
|
80
|
+
查看输入 Schema 与运行规则
|
|
81
|
+
</Button>
|
|
82
|
+
</SheetTrigger>
|
|
83
|
+
<SheetContent class="w-full overflow-y-auto sm:max-w-xl">
|
|
84
|
+
<SheetHeader>
|
|
85
|
+
<SheetTitle>输入 Schema 与运行规则</SheetTitle>
|
|
86
|
+
<SheetDescription class="break-all">{{
|
|
87
|
+
operation.key
|
|
88
|
+
}}</SheetDescription>
|
|
89
|
+
</SheetHeader>
|
|
90
|
+
<div class="space-y-4 px-4 pb-4">
|
|
91
|
+
<p class="text-sm text-muted-foreground">
|
|
92
|
+
{{ availabilityLabel(operation.availabilityReason) }};最长
|
|
93
|
+
{{ operation.limits.maxDurationSeconds }} 秒;输入
|
|
94
|
+
{{ operation.limits.maxInputBytes }} 字节。允许工具:{{
|
|
95
|
+
operation.allowedToolKeys.join("、") || "无"
|
|
96
|
+
}}
|
|
97
|
+
</p>
|
|
98
|
+
<pre class="overflow-auto rounded-md bg-muted p-3 text-xs">{{
|
|
99
|
+
formatJson(operation.inputSchema)
|
|
100
|
+
}}</pre>
|
|
101
|
+
</div>
|
|
102
|
+
</SheetContent>
|
|
103
|
+
</Sheet>
|
|
72
104
|
<label class="grid gap-2 text-sm"
|
|
73
105
|
><span>测试输入(JSON)</span
|
|
74
106
|
><textarea
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { AgentAdminToolCatalogItem } from "@southwind-ai/shared";
|
|
3
3
|
import { computed, shallowRef } from "vue";
|
|
4
|
+
import {
|
|
5
|
+
Select,
|
|
6
|
+
SelectContent,
|
|
7
|
+
SelectItem,
|
|
8
|
+
SelectTrigger,
|
|
9
|
+
SelectValue,
|
|
10
|
+
} from "@/components/ui/select";
|
|
4
11
|
import { Input } from "@/components/ui/input";
|
|
5
12
|
import { availabilityLabel } from "./catalog-presenter";
|
|
6
13
|
const props = defineProps<{
|
|
@@ -9,9 +16,9 @@ const props = defineProps<{
|
|
|
9
16
|
}>();
|
|
10
17
|
defineEmits<{ select: [key: string] }>();
|
|
11
18
|
const query = shallowRef("");
|
|
12
|
-
const moduleKey = shallowRef("");
|
|
13
|
-
const operationKey = shallowRef("");
|
|
14
|
-
const availability = shallowRef("");
|
|
19
|
+
const moduleKey = shallowRef("*");
|
|
20
|
+
const operationKey = shallowRef("*");
|
|
21
|
+
const availability = shallowRef("*");
|
|
15
22
|
const modules = computed(() =>
|
|
16
23
|
[...new Set(props.tools.map((tool) => tool.module))].sort(),
|
|
17
24
|
);
|
|
@@ -21,10 +28,10 @@ const operations = computed(() =>
|
|
|
21
28
|
const filtered = computed(() =>
|
|
22
29
|
props.tools.filter(
|
|
23
30
|
(tool) =>
|
|
24
|
-
(
|
|
25
|
-
(
|
|
31
|
+
(moduleKey.value === "*" || tool.module === moduleKey.value) &&
|
|
32
|
+
(operationKey.value === "*" ||
|
|
26
33
|
tool.allowedOperationKeys.includes(operationKey.value)) &&
|
|
27
|
-
(
|
|
34
|
+
(availability.value === "*" ||
|
|
28
35
|
tool.allowed === (availability.value === "allowed")) &&
|
|
29
36
|
`${tool.key} ${tool.label} ${tool.description}`
|
|
30
37
|
.toLocaleLowerCase()
|
|
@@ -43,33 +50,41 @@ const filtered = computed(() =>
|
|
|
43
50
|
placeholder="搜索名称、说明或 Key"
|
|
44
51
|
/>
|
|
45
52
|
<div class="grid gap-2 sm:grid-cols-3 lg:grid-cols-1">
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
53
|
+
<Select v-model="moduleKey">
|
|
54
|
+
<SelectTrigger aria-label="所属模块筛选" class="w-full"
|
|
55
|
+
><SelectValue
|
|
56
|
+
/></SelectTrigger>
|
|
57
|
+
<SelectContent>
|
|
58
|
+
<SelectItem value="*">所有模块</SelectItem>
|
|
59
|
+
<SelectItem v-for="module in modules" :key="module" :value="module">{{
|
|
60
|
+
module
|
|
61
|
+
}}</SelectItem>
|
|
62
|
+
</SelectContent>
|
|
63
|
+
</Select>
|
|
64
|
+
<Select v-model="operationKey">
|
|
65
|
+
<SelectTrigger aria-label="Operation 筛选" class="w-full"
|
|
66
|
+
><SelectValue
|
|
67
|
+
/></SelectTrigger>
|
|
68
|
+
<SelectContent>
|
|
69
|
+
<SelectItem value="*">所有 Operations</SelectItem>
|
|
70
|
+
<SelectItem
|
|
71
|
+
v-for="operation in operations"
|
|
72
|
+
:key="operation"
|
|
73
|
+
:value="operation"
|
|
74
|
+
>{{ operation }}</SelectItem
|
|
75
|
+
>
|
|
76
|
+
</SelectContent>
|
|
77
|
+
</Select>
|
|
78
|
+
<Select v-model="availability">
|
|
79
|
+
<SelectTrigger aria-label="调用条件筛选" class="w-full"
|
|
80
|
+
><SelectValue
|
|
81
|
+
/></SelectTrigger>
|
|
82
|
+
<SelectContent>
|
|
83
|
+
<SelectItem value="*">所有调用状态</SelectItem>
|
|
84
|
+
<SelectItem value="allowed">具备调用条件</SelectItem>
|
|
85
|
+
<SelectItem value="denied">当前不可调用</SelectItem>
|
|
86
|
+
</SelectContent>
|
|
87
|
+
</Select>
|
|
73
88
|
</div>
|
|
74
89
|
<p class="text-xs text-muted-foreground">
|
|
75
90
|
{{ filtered.length }} /
|
package/template/apps/web/src/pages/system/components/agent-workbench/ToolCatalogPanel.webtest.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mount } from "@vue/test-utils";
|
|
2
2
|
import { describe, expect, test } from "vitest";
|
|
3
3
|
import type { AgentAdminToolCatalogItem } from "@southwind-ai/shared";
|
|
4
|
+
import { Select } from "@/components/ui/select";
|
|
4
5
|
import ToolCatalogPanel from "./ToolCatalogPanel.vue";
|
|
5
6
|
import ToolRuleDetail from "./ToolRuleDetail.vue";
|
|
6
7
|
const tool: AgentAdminToolCatalogItem = {
|
|
@@ -39,10 +40,16 @@ describe("动态工具目录", () => {
|
|
|
39
40
|
await wrapper.get("input").setValue("copilot");
|
|
40
41
|
expect(wrapper.text()).toContain("没有匹配");
|
|
41
42
|
await wrapper.get("input").setValue("位置");
|
|
42
|
-
await wrapper.get("button").trigger("click");
|
|
43
|
+
await wrapper.get("button[aria-pressed]").trigger("click");
|
|
43
44
|
expect(wrapper.emitted("select")).toEqual([[tool.key]]);
|
|
44
|
-
await wrapper
|
|
45
|
+
await wrapper
|
|
46
|
+
.findAllComponents(Select)[2]!
|
|
47
|
+
.vm.$emit("update:modelValue", "allowed");
|
|
45
48
|
expect(wrapper.text()).toContain("没有匹配");
|
|
49
|
+
await wrapper
|
|
50
|
+
.findAllComponents(Select)[2]!
|
|
51
|
+
.vm.$emit("update:modelValue", "*");
|
|
52
|
+
expect(wrapper.text()).toContain("位置查询");
|
|
46
53
|
});
|
|
47
54
|
test("Schema 和审批/范围/限制展示使用实际注册投影", () => {
|
|
48
55
|
const wrapper = mount(ToolRuleDetail, { props: { tool } });
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
2
3
|
import type { AgentAdminToolCatalogItem } from "@southwind-ai/shared";
|
|
3
4
|
import { availabilityLabel, formatJson } from "./catalog-presenter";
|
|
4
5
|
defineProps<{ tool?: AgentAdminToolCatalogItem }>();
|
|
@@ -60,22 +61,28 @@ defineProps<{ tool?: AgentAdminToolCatalogItem }>();
|
|
|
60
61
|
{{ tool.allowedOperationKeys.join("、") || "没有已注册操作允许调用" }}
|
|
61
62
|
</dd>
|
|
62
63
|
</dl>
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
<Tabs :key="tool.key" default-value="input">
|
|
65
|
+
<TabsList aria-label="工具 Schema">
|
|
66
|
+
<TabsTrigger value="input">输入 Schema</TabsTrigger>
|
|
67
|
+
<TabsTrigger value="output">输出 Schema</TabsTrigger>
|
|
68
|
+
</TabsList>
|
|
69
|
+
<TabsContent value="input">
|
|
70
|
+
<p class="break-all font-mono text-xs text-muted-foreground">
|
|
71
|
+
{{ tool.inputSchemaKey }}
|
|
72
|
+
</p>
|
|
73
|
+
<pre
|
|
74
|
+
class="mt-2 max-h-80 overflow-auto rounded-md bg-muted p-3 text-xs"
|
|
75
|
+
>{{ formatJson(tool.inputSchema) }}</pre>
|
|
76
|
+
</TabsContent>
|
|
77
|
+
<TabsContent value="output">
|
|
78
|
+
<p class="break-all font-mono text-xs text-muted-foreground">
|
|
79
|
+
{{ tool.outputSchemaKey }}
|
|
80
|
+
</p>
|
|
81
|
+
<pre
|
|
82
|
+
class="mt-2 max-h-80 overflow-auto rounded-md bg-muted p-3 text-xs"
|
|
83
|
+
>{{ formatJson(tool.outputSchema) }}</pre>
|
|
84
|
+
</TabsContent>
|
|
85
|
+
</Tabs>
|
|
79
86
|
</template>
|
|
80
87
|
</section>
|
|
81
88
|
</template>
|
package/template/apps/web/src/pages/system/components/dictionary-bulk/DictionaryBulkJobDetail.vue
CHANGED
|
@@ -71,13 +71,6 @@ const detail = computed(() => {
|
|
|
71
71
|
<dd class="mt-1">{{ detail.retryAt }}</dd>
|
|
72
72
|
</div>
|
|
73
73
|
</dl>
|
|
74
|
-
<details class="rounded-md bg-muted/50 p-3 text-xs">
|
|
75
|
-
<summary class="cursor-pointer font-medium">技术信息</summary>
|
|
76
|
-
<p class="mt-2 text-muted-foreground">
|
|
77
|
-
防重复令牌由浏览器自动生成,同一次网络重试会复用,避免重复创建任务。
|
|
78
|
-
</p>
|
|
79
|
-
<p class="mt-2 break-all font-mono">{{ job.idempotencyKey }}</p>
|
|
80
|
-
</details>
|
|
81
74
|
<p v-if="job.error" class="rounded-md bg-muted p-3 text-sm">
|
|
82
75
|
最近一次系统错误:{{ job.error }}
|
|
83
76
|
</p>
|
|
@@ -104,6 +97,16 @@ const detail = computed(() => {
|
|
|
104
97
|
<p v-if="detail.failuresAvailable" class="text-xs text-muted-foreground">
|
|
105
98
|
失败明细仅含行号、错误分类、安全消息和输入摘要,不回显原始输入行。
|
|
106
99
|
</p>
|
|
100
|
+
<section class="grid gap-2 border-t pt-3 text-xs">
|
|
101
|
+
<h4 class="font-medium">技术信息</h4>
|
|
102
|
+
<dl class="grid gap-1">
|
|
103
|
+
<dt class="text-muted-foreground">防重复令牌</dt>
|
|
104
|
+
<dd class="break-all font-mono">{{ job.idempotencyKey }}</dd>
|
|
105
|
+
</dl>
|
|
106
|
+
<p class="text-muted-foreground">
|
|
107
|
+
同一次网络重试会复用此令牌,避免重复创建任务。
|
|
108
|
+
</p>
|
|
109
|
+
</section>
|
|
107
110
|
</template>
|
|
108
111
|
</aside>
|
|
109
112
|
</template>
|
package/template/apps/web/src/pages/system/components/user-account/RolePermissionSummary.vue
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
import { computed, shallowRef, watch } from "vue";
|
|
3
3
|
import { Input } from "@/components/ui/input";
|
|
4
4
|
import { Button } from "@/components/ui/button";
|
|
5
|
+
import {
|
|
6
|
+
Sheet,
|
|
7
|
+
SheetContent,
|
|
8
|
+
SheetDescription,
|
|
9
|
+
SheetHeader,
|
|
10
|
+
SheetTitle,
|
|
11
|
+
SheetTrigger,
|
|
12
|
+
} from "@/components/ui/sheet";
|
|
5
13
|
import type { PermissionDefinition } from "@southwind-ai/shared";
|
|
6
14
|
import {
|
|
7
15
|
groupPermissions,
|
|
@@ -9,6 +17,7 @@ import {
|
|
|
9
17
|
} from "../role-policy/permission-tree";
|
|
10
18
|
|
|
11
19
|
const props = defineProps<{
|
|
20
|
+
roleName: string;
|
|
12
21
|
permissionKeys: string[];
|
|
13
22
|
permissions: PermissionDefinition[];
|
|
14
23
|
}>();
|
|
@@ -54,64 +63,79 @@ const unknownKeys = computed(() =>
|
|
|
54
63
|
>
|
|
55
64
|
未分配功能权限
|
|
56
65
|
</p>
|
|
57
|
-
<
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
v-model="keyword"
|
|
66
|
-
@keydown.enter.prevent
|
|
67
|
-
aria-label="搜索角色权限摘要"
|
|
68
|
-
placeholder="搜索功能权限"
|
|
69
|
-
/>
|
|
70
|
-
<section v-for="group in groups" :key="group.key" class="grid gap-2">
|
|
71
|
-
<p class="font-medium text-foreground">{{ group.label }}</p>
|
|
72
|
-
<div
|
|
73
|
-
v-for="resource in group.resources"
|
|
74
|
-
:key="resource.key"
|
|
75
|
-
class="grid gap-1 sm:grid-cols-[8rem_1fr]"
|
|
76
|
-
>
|
|
77
|
-
<span class="text-muted-foreground">{{ resource.label }}</span>
|
|
78
|
-
<span class="leading-5">
|
|
79
|
-
{{ resource.permissions.map(({ label }) => label).join("、") }}
|
|
80
|
-
</span>
|
|
81
|
-
</div>
|
|
82
|
-
</section>
|
|
83
|
-
<section v-if="unknownKeys.length" class="grid gap-1">
|
|
84
|
-
<p class="font-medium text-amber-700 dark:text-amber-400">
|
|
85
|
-
未注册的历史权限
|
|
86
|
-
</p>
|
|
87
|
-
<code class="break-all leading-5">{{ unknownKeys.join("、") }}</code>
|
|
88
|
-
</section>
|
|
89
|
-
<div
|
|
90
|
-
class="flex flex-wrap items-center justify-between gap-2 text-muted-foreground"
|
|
91
|
-
>
|
|
92
|
-
<span
|
|
93
|
-
>共 {{ filteredKeys.length }} 条,每页 10 条,第 {{ page }} /
|
|
94
|
-
{{ pageCount }} 页</span
|
|
66
|
+
<div v-else class="mt-3 border-t pt-3">
|
|
67
|
+
<Sheet>
|
|
68
|
+
<SheetTrigger as-child>
|
|
69
|
+
<Button
|
|
70
|
+
type="button"
|
|
71
|
+
variant="outline"
|
|
72
|
+
size="sm"
|
|
73
|
+
data-testid="role-permissions-trigger"
|
|
95
74
|
>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
75
|
+
查看 {{ permissionKeys.length }} 项功能权限
|
|
76
|
+
</Button>
|
|
77
|
+
</SheetTrigger>
|
|
78
|
+
<SheetContent class="w-full overflow-y-auto sm:max-w-lg">
|
|
79
|
+
<SheetHeader>
|
|
80
|
+
<SheetTitle>角色功能权限</SheetTitle>
|
|
81
|
+
<SheetDescription class="break-all">{{ roleName }}</SheetDescription>
|
|
82
|
+
</SheetHeader>
|
|
83
|
+
<div class="grid gap-3 px-4 pb-4">
|
|
84
|
+
<Input
|
|
85
|
+
v-model="keyword"
|
|
86
|
+
@keydown.enter.prevent
|
|
87
|
+
aria-label="搜索角色权限摘要"
|
|
88
|
+
placeholder="搜索功能权限"
|
|
89
|
+
/>
|
|
90
|
+
<section v-for="group in groups" :key="group.key" class="grid gap-2">
|
|
91
|
+
<p class="font-medium text-foreground">{{ group.label }}</p>
|
|
92
|
+
<div
|
|
93
|
+
v-for="resource in group.resources"
|
|
94
|
+
:key="resource.key"
|
|
95
|
+
class="grid gap-1 sm:grid-cols-[8rem_1fr]"
|
|
96
|
+
>
|
|
97
|
+
<span class="text-muted-foreground">{{ resource.label }}</span>
|
|
98
|
+
<span class="leading-5">
|
|
99
|
+
{{ resource.permissions.map(({ label }) => label).join("、") }}
|
|
100
|
+
</span>
|
|
101
|
+
</div>
|
|
102
|
+
</section>
|
|
103
|
+
<section v-if="unknownKeys.length" class="grid gap-1">
|
|
104
|
+
<p class="font-medium text-amber-700 dark:text-amber-400">
|
|
105
|
+
未注册的历史权限
|
|
106
|
+
</p>
|
|
107
|
+
<code class="break-all leading-5">{{
|
|
108
|
+
unknownKeys.join("、")
|
|
109
|
+
}}</code>
|
|
110
|
+
</section>
|
|
111
|
+
<div
|
|
112
|
+
class="flex flex-wrap items-center justify-between gap-2 text-muted-foreground"
|
|
112
113
|
>
|
|
114
|
+
<span
|
|
115
|
+
>共 {{ filteredKeys.length }} 条,每页 10 条,第 {{ page }} /
|
|
116
|
+
{{ pageCount }} 页</span
|
|
117
|
+
>
|
|
118
|
+
<div class="flex gap-2">
|
|
119
|
+
<Button
|
|
120
|
+
type="button"
|
|
121
|
+
size="sm"
|
|
122
|
+
variant="outline"
|
|
123
|
+
:disabled="page <= 1"
|
|
124
|
+
@click="page--"
|
|
125
|
+
>上一页</Button
|
|
126
|
+
>
|
|
127
|
+
<Button
|
|
128
|
+
type="button"
|
|
129
|
+
size="sm"
|
|
130
|
+
variant="outline"
|
|
131
|
+
:disabled="page >= pageCount"
|
|
132
|
+
@click="page++"
|
|
133
|
+
>下一页</Button
|
|
134
|
+
>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
113
137
|
</div>
|
|
114
|
-
</
|
|
115
|
-
</
|
|
116
|
-
</
|
|
138
|
+
</SheetContent>
|
|
139
|
+
</Sheet>
|
|
140
|
+
</div>
|
|
117
141
|
</template>
|