@synopackageland/cli 0.4.1 → 0.5.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/README.md +7 -3
- package/dist/build-spk/delete-app-data.d.ts +27 -7
- package/dist/build-spk/delete-app-data.js +35 -34
- package/dist/build-spk/dsm-arch.d.ts +6 -1
- package/dist/build-spk/dsm-arch.js +25 -1
- package/dist/build-spk/dsm-version.d.ts +14 -0
- package/dist/build-spk/dsm-version.js +47 -0
- package/dist/build-spk/gateway.d.ts +31 -0
- package/dist/build-spk/gateway.js +55 -0
- package/dist/build-spk/generator.d.ts +5 -0
- package/dist/build-spk/generator.js +103 -107
- package/dist/build-spk/install-wizard.d.ts +20 -0
- package/dist/build-spk/install-wizard.js +76 -0
- package/dist/build-spk/native-lifecycle.d.ts +5 -0
- package/dist/build-spk/native-lifecycle.js +12 -2
- package/dist/build-spk/resource-worker.d.ts +9 -4
- package/dist/build-spk/resource-worker.js +15 -6
- package/dist/build-spk/share-combobox.d.ts +3 -0
- package/dist/build-spk/share-combobox.js +27 -0
- package/dist/build-spk/uninstall-wizard.d.ts +14 -0
- package/dist/build-spk/uninstall-wizard.js +33 -0
- package/dist/build-spk/wizard-i18n.d.ts +18 -0
- package/dist/build-spk/wizard-i18n.js +38 -0
- package/dist/build-spk/wizard-messages.d.ts +388 -0
- package/dist/build-spk/wizard-messages.js +387 -0
- package/dist/cli.js +130 -30
- package/dist/compose/analyze.d.ts +20 -0
- package/dist/compose/analyze.js +75 -11
- package/dist/contract/validate.js +33 -1
- package/dist/contract/web-launch.d.ts +22 -0
- package/dist/contract/web-launch.js +37 -0
- package/dist/deploy/deploy.d.ts +3 -0
- package/dist/deploy/deploy.js +11 -2
- package/dist/error-registry.js +60 -1
- package/dist/host/open-url.d.ts +2 -0
- package/dist/host/open-url.js +4 -1
- package/dist/images/pin.d.ts +52 -0
- package/dist/images/pin.js +249 -0
- package/dist/init.d.ts +27 -3
- package/dist/init.js +104 -15
- package/dist/inspect.d.ts +3 -0
- package/dist/inspect.js +15 -3
- package/dist/standalone/background.d.ts +21 -0
- package/dist/standalone/background.js +52 -0
- package/dist/standalone/binary.d.ts +1 -0
- package/dist/standalone/binary.js +1 -1
- package/dist/standalone/build.d.ts +2 -0
- package/dist/standalone/build.js +38 -6
- package/dist/standalone/dsm-window.js +2 -2
- package/dist/standalone/helper-inventory.d.ts +15 -0
- package/dist/standalone/helper-inventory.js +9 -0
- package/dist/standalone/helper.d.ts +1 -0
- package/dist/standalone/helper.js +28 -10
- package/dist/standalone/host-adapter.d.ts +1 -1
- package/dist/standalone/host-adapter.js +33 -15
- package/dist/standalone/host-file-navigation.d.ts +7 -0
- package/dist/standalone/host-file-navigation.js +172 -0
- package/dist/standalone/inspect-helper.js +9 -4
- package/dist/standalone/inspect-spk.d.ts +1 -1
- package/dist/standalone/inspect-spk.js +200 -7
- package/dist/standalone/job-diagnostics.d.ts +1 -0
- package/dist/standalone/job-diagnostics.js +49 -0
- package/dist/standalone/lifecycle.js +12 -2
- package/dist/standalone/manifest.d.ts +15 -2
- package/dist/standalone/manifest.js +37 -6
- package/dist/standalone/native-layout.d.ts +74 -0
- package/dist/standalone/native-layout.js +318 -0
- package/dist/standalone/resource.d.ts +11 -0
- package/dist/standalone/resource.js +13 -0
- package/dist/standalone/root-window.d.ts +3 -1
- package/dist/standalone/root-window.js +156 -38
- package/dist/standalone/shared-folder.d.ts +39 -0
- package/dist/standalone/shared-folder.js +141 -0
- package/dist/standalone/spk.d.ts +2 -0
- package/dist/standalone/spk.js +33 -3
- package/dist/standalone/worker-contract-json.d.ts +8 -0
- package/dist/standalone/worker-contract-json.js +141 -0
- package/dist/standalone/worker-contract.d.ts +189 -0
- package/dist/standalone/worker-contract.js +175 -0
- package/dist/standalone/worker-registry.d.ts +40 -0
- package/dist/standalone/worker-registry.js +167 -0
- package/dist/templates/_daemon/go.mod +2 -0
- package/dist/templates/_gateway/auth.go +101 -0
- package/dist/templates/_gateway/auth_test.go +216 -0
- package/dist/templates/_gateway/cgi.go +133 -0
- package/dist/templates/_gateway/cgi_test.go +156 -0
- package/dist/templates/_gateway/csrf.go +73 -0
- package/dist/templates/_gateway/csrf_test.go +155 -0
- package/dist/templates/_gateway/directory.go +108 -0
- package/dist/templates/_gateway/directory_test.go +202 -0
- package/dist/templates/_gateway/gateway.go +412 -0
- package/dist/templates/_gateway/gateway_test.go +676 -0
- package/dist/templates/_gateway/go.mod +3 -0
- package/dist/templates/_gateway/groups.go +66 -0
- package/dist/templates/_gateway/main.go +45 -0
- package/dist/templates/binary/synology-app.yaml +1 -1
- package/dist/templates/compose-import/compose.yaml +1 -1
- package/dist/templates/compose-import/synology-app.yaml +1 -1
- package/dist/templates/hello-files/compose.yaml +1 -1
- package/dist/templates/hello-files/synology-app.yaml +1 -1
- package/dist/templates/hello-web/compose.yaml +5 -2
- package/dist/templates/hello-web/synology-app.yaml +4 -1
- package/dist/templates/hello-web-page/compose.yaml +5 -2
- package/dist/templates/hello-web-page/synology-app.yaml +4 -1
- package/dist/templates/native-go/README.md +93 -4
- package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +3 -1
- package/dist/templates/native-go/backend/cmd/app/main.go +17 -0
- package/dist/templates/native-go/backend/cmd/app/sdk_main.go +60 -0
- package/dist/templates/native-go/backend/cmd/background-worker/main.go +38 -0
- package/dist/templates/native-go/backend/cmd/helper/main.go +10 -1
- package/dist/templates/native-go/backend/cmd/helper/sdk_registry.go +19 -0
- package/dist/templates/native-go/backend/go.mod +5 -3
- package/dist/templates/native-go/backend/go.sum +4 -4
- package/dist/templates/native-go/backend/internal/api/registry.go +17 -6
- package/dist/templates/native-go/backend/internal/api/server.go +7 -1
- package/dist/templates/native-go/backend/internal/app/background.go +270 -0
- package/dist/templates/native-go/backend/internal/app/background_none.go +8 -0
- package/dist/templates/native-go/backend/internal/app/background_owner.go +59 -0
- package/dist/templates/native-go/backend/internal/app/background_owner_test.go +145 -0
- package/dist/templates/native-go/backend/internal/app/background_schedule.go +74 -0
- package/dist/templates/native-go/backend/internal/app/background_schedule_test.go +62 -0
- package/dist/templates/native-go/backend/internal/app/background_test.go +346 -0
- package/dist/templates/native-go/backend/internal/app/integration_state.go +16 -0
- package/dist/templates/native-go/backend/internal/app/migrations.go +41 -0
- package/dist/templates/native-go/backend/internal/app/migrations_test.go +41 -0
- package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +8 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +17 -3
- package/dist/templates/native-go/backend/internal/app/routes_test.go +20 -3
- package/dist/templates/native-go/backend/internal/app/sdk_jobs.go +70 -0
- package/dist/templates/native-go/backend/internal/app/sdk_jobs_test.go +116 -0
- package/dist/templates/native-go/backend/internal/app/sdk_routes.go +174 -0
- package/dist/templates/native-go/backend/internal/app/session_files.go +15 -0
- package/dist/templates/native-go/backend/internal/app/session_files_test.go +26 -0
- package/dist/templates/native-go/backend/internal/app/shared_folder.go +144 -0
- package/dist/templates/native-go/backend/internal/app/shared_folder_test.go +158 -0
- package/dist/templates/native-go/backend/internal/background/access.go +57 -0
- package/dist/templates/native-go/backend/internal/background/owner_test.go +126 -0
- package/dist/templates/native-go/backend/internal/background/runner.go +185 -0
- package/dist/templates/native-go/backend/internal/background/runner_test.go +209 -0
- package/dist/templates/native-go/backend/internal/background/schedule.go +300 -0
- package/dist/templates/native-go/backend/internal/background/schedule_test.go +335 -0
- package/dist/templates/native-go/backend/internal/background/store.go +807 -0
- package/dist/templates/native-go/backend/internal/background/store_test.go +407 -0
- package/dist/templates/native-go/backend/internal/datamigrate/migrate.go +191 -0
- package/dist/templates/native-go/backend/internal/datamigrate/migrate_test.go +177 -0
- package/dist/templates/native-go/backend/internal/filestation/browse_test.go +67 -0
- package/dist/templates/native-go/backend/internal/filestation/client.go +251 -0
- package/dist/templates/native-go/backend/internal/filestation/client_test.go +155 -0
- package/dist/templates/native-go/backend/internal/filestation/doc.go +4 -0
- package/dist/templates/native-go/backend/internal/filestation/read_file_test.go +90 -0
- package/dist/templates/native-go/backend/internal/filestation/repository.go +207 -0
- package/dist/templates/native-go/backend/internal/filestation/repository_test.go +104 -0
- package/dist/templates/native-go/backend/internal/filestation/sdk_session.go +241 -0
- package/dist/templates/native-go/backend/internal/filestation/sdk_session_test.go +183 -0
- package/dist/templates/native-go/backend/internal/filestation/service.go +254 -0
- package/dist/templates/native-go/backend/internal/filestation/service_test.go +94 -0
- package/dist/templates/native-go/backend/internal/filestation/session_semantics_test.go +383 -0
- package/dist/templates/native-go/backend/internal/filestation/write.go +72 -0
- package/dist/templates/native-go/backend/internal/filestation/write_test.go +123 -0
- package/dist/templates/native-go/backend/internal/helper/background_proof.go +163 -0
- package/dist/templates/native-go/backend/internal/helper/background_proof_contract.go +46 -0
- package/dist/templates/native-go/backend/internal/helper/background_proof_test.go +161 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +1 -1
- package/dist/templates/native-go/backend/internal/helper/grant_authority.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +1 -1
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +2 -1
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +4 -3
- package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/bindings.go +48 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/contract_test.go +436 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/decode.go +185 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/digest.go +55 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/registry.go +85 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/registry_test.go +73 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/result.go +53 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/stub.go +8 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/testdata/input-digests.json +127 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/types.go +234 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/types_test.go +29 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/validate.go +462 -0
- package/dist/templates/native-go/backend/internal/helper/legacy_authority_schema_linux_test.go +34 -0
- package/dist/templates/native-go/backend/internal/helper/legacy_authority_schema_test.go +6 -0
- package/dist/templates/native-go/backend/internal/helper/management.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/observation.go +42 -2
- package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +13 -1
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +56 -10
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +6 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_writer.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/process_linux.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/query_deadline_linux_test.go +115 -0
- package/dist/templates/native-go/backend/internal/helper/query_pending_diagnostic_test.go +254 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +23 -4
- package/dist/templates/native-go/backend/internal/helper/sdk_assembly_linux.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_attach.go +83 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_attach_contract.go +32 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_attach_test.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_authority_schema_test.go +6 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_authority.go +832 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_authority_test.go +714 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_invalidation.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_lease.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_snapshot.go +110 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_store_linux_test.go +261 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_store_test.go +58 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_bindings.go +60 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_data_contract.go +251 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_data_protocol.go +424 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_dispatch_absence_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_display.go +488 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_display_contract.go +121 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_display_test.go +459 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_grant_authority.go +559 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_grant_repository_linux.go +417 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_grant_snapshot.go +94 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_history.go +80 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_history_test.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job.go +697 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_child_linux.go +309 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_contract.go +122 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_linux_test.go +159 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_process_linux.go +327 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_test.go +501 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_vm_linux_test.go +343 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal.go +77 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal_linux.go +244 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal_linux_test.go +295 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal_test.go +71 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_picker_test.go +50 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_process_linux.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_public_vm_linux_test.go +129 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_relaxed_invalidation.go +242 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_rpc.go +299 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_rpc_contract.go +70 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_rpc_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_server_linux.go +152 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session.go +677 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session_contract.go +72 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session_fence_test.go +215 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session_test.go +475 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_supervisor_frame.go +78 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_supervisor_linux.go +414 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_transport.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_transport_linux.go +82 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_transport_test.go +64 -0
- package/dist/templates/native-go/backend/internal/helper/server_linux.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/stale_management_linux_test.go +126 -0
- package/dist/templates/native-go/backend/internal/helper/stale_management_test.go +122 -0
- package/dist/templates/native-go/backend/internal/helper/startup_diagnostic.go +68 -0
- package/dist/templates/native-go/backend/internal/helper/startup_diagnostic_linux_test.go +126 -0
- package/dist/templates/native-go/backend/internal/helper/startup_diagnostic_test.go +117 -0
- package/dist/templates/native-go/backend/internal/helper/status.go +22 -13
- package/dist/templates/native-go/backend/internal/helper/status_test.go +45 -0
- package/dist/templates/native-go/backend/internal/helper/supervision.go +1 -1
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +6 -2
- package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +22 -4
- package/dist/templates/native-go/backend/internal/helper/unit_linux.go +7 -3
- package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +5 -1
- package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +7 -4
- package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +26 -0
- package/dist/templates/native-go/dsm-package.yaml +1 -1
- package/dist/templates/native-go-background/BACKGROUND.md +111 -0
- package/dist/templates/native-go-background/backend/internal/app/background_on.go +7 -0
- package/dist/templates/native-go-background/backend/internal/app/background_routes_test.go +32 -0
- package/dist/templates/native-go-background/frontend/src/background/BackgroundPanel.vue +178 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/de.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/en.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/es.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/fr.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/it.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/ja.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/ko.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/zh-CN.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/zh-TW.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n.ts +19 -0
- package/dist/templates/native-go-background/frontend/src/background/picker-provider.ts +13 -0
- package/dist/templates/native-go-background/frontend/test/background.test.ts +179 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal.go +2 -2
- package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +37 -0
- package/dist/templates/native-go-vue/README.md +38 -7
- package/dist/templates/native-go-vue/frontend/DESIGN.md +15 -3
- package/dist/templates/native-go-vue/frontend/README-JOBS.md +75 -0
- package/dist/templates/native-go-vue/frontend/README-M2.md +64 -0
- package/dist/templates/native-go-vue/frontend/package-lock.json +5 -4
- package/dist/templates/native-go-vue/frontend/package.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/App.vue +39 -11
- package/dist/templates/native-go-vue/frontend/src/M2App.vue +57 -0
- package/dist/templates/native-go-vue/frontend/src/SDKApp.vue +203 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/InteractiveJobForm.vue +70 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/JobsAdminPanel.vue +33 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/JobsPanel.vue +135 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/connected-provider.ts +179 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/de.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/en.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/es.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/fr.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/it.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/ja.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/ko.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/zh-CN.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/zh-TW.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n.ts +15 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/mock-provider.ts +67 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/provider.ts +60 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/validate.ts +44 -0
- package/dist/templates/native-go-vue/frontend/src/m2-main.ts +21 -0
- package/dist/templates/native-go-vue/frontend/src/m2-style.css +7 -0
- package/dist/templates/native-go-vue/frontend/src/nas/M2Files.vue +94 -0
- package/dist/templates/native-go-vue/frontend/src/nas/M2PathPicker.vue +70 -0
- package/dist/templates/native-go-vue/frontend/src/nas/M2Settings.vue +69 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/de.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/en.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/es.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/fr.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/it.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/ja.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/ko.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-CN.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-TW.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/m2-contract.ts +33 -0
- package/dist/templates/native-go-vue/frontend/src/nas/m2-i18n.ts +24 -0
- package/dist/templates/native-go-vue/frontend/src/nas/m2-provider.ts +104 -0
- package/dist/templates/native-go-vue/frontend/src/nas/use-m2-request.ts +18 -0
- package/dist/templates/native-go-vue/frontend/src/sdk-main.ts +39 -0
- package/dist/templates/native-go-vue/frontend/src/shell/AppShell.vue +48 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/de.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/en.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/es.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/fr.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/it.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/ja.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/ko.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/zh-CN.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/zh-TW.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n.ts +17 -0
- package/dist/templates/native-go-vue/frontend/src/shell/pages.ts +34 -0
- package/dist/templates/native-go-vue/frontend/src/style.css +2 -6
- package/dist/templates/native-go-vue/frontend/test/apps.test.ts +21 -0
- package/dist/templates/native-go-vue/frontend/test/jobs-connected.test.ts +163 -0
- package/dist/templates/native-go-vue/frontend/test/jobs-preview.html +22 -0
- package/dist/templates/native-go-vue/frontend/test/jobs.test.ts +176 -0
- package/dist/templates/native-go-vue/frontend/test/m2-preview.html +27 -0
- package/dist/templates/native-go-vue/frontend/test/m2-provider.test.ts +87 -0
- package/dist/templates/native-go-vue/frontend/test/m2-ui.test.ts +209 -0
- package/dist/templates/native-go-vue/frontend/test/native-controls.test.ts +27 -0
- package/dist/templates/native-go-vue/frontend/test/picker-wire.test.ts +110 -0
- package/dist/templates/native-go-vue/frontend/test/shell-preview.html +19 -0
- package/dist/templates/native-go-vue/frontend/test/shell-sdk.test.ts +73 -0
- package/dist/templates/native-go-vue/frontend/test/shell-ui.test.ts +114 -0
- package/dist/templates/native-go-vue/frontend/test/shell.test.ts +45 -0
- package/dist/templates/native-go-vue/frontend/vite.config.ts +2 -2
- package/dist/validate.js +6 -3
- package/package.json +1 -1
- package/schema/synology-app.schema.json +19 -0
- package/skills/reference/create.md +4 -0
- package/templates/_daemon/go.mod +2 -0
- package/templates/_gateway/auth.go +101 -0
- package/templates/_gateway/auth_test.go +216 -0
- package/templates/_gateway/cgi.go +133 -0
- package/templates/_gateway/cgi_test.go +156 -0
- package/templates/_gateway/csrf.go +73 -0
- package/templates/_gateway/csrf_test.go +155 -0
- package/templates/_gateway/directory.go +108 -0
- package/templates/_gateway/directory_test.go +202 -0
- package/templates/_gateway/gateway.go +412 -0
- package/templates/_gateway/gateway_test.go +676 -0
- package/templates/_gateway/go.mod +3 -0
- package/templates/_gateway/groups.go +66 -0
- package/templates/_gateway/main.go +45 -0
- package/templates/binary/synology-app.yaml +1 -1
- package/templates/compose-import/compose.yaml +1 -1
- package/templates/compose-import/synology-app.yaml +1 -1
- package/templates/hello-files/compose.yaml +1 -1
- package/templates/hello-files/synology-app.yaml +1 -1
- package/templates/hello-web/compose.yaml +5 -2
- package/templates/hello-web/synology-app.yaml +4 -1
- package/templates/hello-web-page/compose.yaml +5 -2
- package/templates/hello-web-page/synology-app.yaml +4 -1
- package/templates/native-go/README.md +93 -4
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +3 -1
- package/templates/native-go/backend/cmd/app/main.go +17 -0
- package/templates/native-go/backend/cmd/app/sdk_main.go +60 -0
- package/templates/native-go/backend/cmd/background-worker/main.go +38 -0
- package/templates/native-go/backend/cmd/helper/main.go +10 -1
- package/templates/native-go/backend/cmd/helper/sdk_registry.go +19 -0
- package/templates/native-go/backend/go.mod +5 -3
- package/templates/native-go/backend/go.sum +4 -4
- package/templates/native-go/backend/internal/api/registry.go +17 -6
- package/templates/native-go/backend/internal/api/server.go +7 -1
- package/templates/native-go/backend/internal/app/background.go +270 -0
- package/templates/native-go/backend/internal/app/background_none.go +8 -0
- package/templates/native-go/backend/internal/app/background_owner.go +59 -0
- package/templates/native-go/backend/internal/app/background_owner_test.go +145 -0
- package/templates/native-go/backend/internal/app/background_schedule.go +74 -0
- package/templates/native-go/backend/internal/app/background_schedule_test.go +62 -0
- package/templates/native-go/backend/internal/app/background_test.go +346 -0
- package/templates/native-go/backend/internal/app/integration_state.go +16 -0
- package/templates/native-go/backend/internal/app/migrations.go +41 -0
- package/templates/native-go/backend/internal/app/migrations_test.go +41 -0
- package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +8 -0
- package/templates/native-go/backend/internal/app/routes.go +17 -3
- package/templates/native-go/backend/internal/app/routes_test.go +20 -3
- package/templates/native-go/backend/internal/app/sdk_jobs.go +70 -0
- package/templates/native-go/backend/internal/app/sdk_jobs_test.go +116 -0
- package/templates/native-go/backend/internal/app/sdk_routes.go +174 -0
- package/templates/native-go/backend/internal/app/session_files.go +15 -0
- package/templates/native-go/backend/internal/app/session_files_test.go +26 -0
- package/templates/native-go/backend/internal/app/shared_folder.go +144 -0
- package/templates/native-go/backend/internal/app/shared_folder_test.go +158 -0
- package/templates/native-go/backend/internal/background/access.go +57 -0
- package/templates/native-go/backend/internal/background/owner_test.go +126 -0
- package/templates/native-go/backend/internal/background/runner.go +185 -0
- package/templates/native-go/backend/internal/background/runner_test.go +209 -0
- package/templates/native-go/backend/internal/background/schedule.go +300 -0
- package/templates/native-go/backend/internal/background/schedule_test.go +335 -0
- package/templates/native-go/backend/internal/background/store.go +807 -0
- package/templates/native-go/backend/internal/background/store_test.go +407 -0
- package/templates/native-go/backend/internal/datamigrate/migrate.go +191 -0
- package/templates/native-go/backend/internal/datamigrate/migrate_test.go +177 -0
- package/templates/native-go/backend/internal/filestation/browse_test.go +67 -0
- package/templates/native-go/backend/internal/filestation/client.go +251 -0
- package/templates/native-go/backend/internal/filestation/client_test.go +155 -0
- package/templates/native-go/backend/internal/filestation/doc.go +4 -0
- package/templates/native-go/backend/internal/filestation/read_file_test.go +90 -0
- package/templates/native-go/backend/internal/filestation/repository.go +207 -0
- package/templates/native-go/backend/internal/filestation/repository_test.go +104 -0
- package/templates/native-go/backend/internal/filestation/sdk_session.go +241 -0
- package/templates/native-go/backend/internal/filestation/sdk_session_test.go +183 -0
- package/templates/native-go/backend/internal/filestation/service.go +254 -0
- package/templates/native-go/backend/internal/filestation/service_test.go +94 -0
- package/templates/native-go/backend/internal/filestation/session_semantics_test.go +383 -0
- package/templates/native-go/backend/internal/filestation/write.go +72 -0
- package/templates/native-go/backend/internal/filestation/write_test.go +123 -0
- package/templates/native-go/backend/internal/helper/background_proof.go +163 -0
- package/templates/native-go/backend/internal/helper/background_proof_contract.go +46 -0
- package/templates/native-go/backend/internal/helper/background_proof_test.go +161 -0
- package/templates/native-go/backend/internal/helper/data_contract.go +3 -0
- package/templates/native-go/backend/internal/helper/data_protocol.go +3 -0
- package/templates/native-go/backend/internal/helper/data_protocol_test.go +1 -1
- package/templates/native-go/backend/internal/helper/grant_authority.go +3 -0
- package/templates/native-go/backend/internal/helper/grant_authority_test.go +1 -1
- package/templates/native-go/backend/internal/helper/grant_repository_linux.go +2 -1
- package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +4 -3
- package/templates/native-go/backend/internal/helper/grant_snapshot.go +3 -0
- package/templates/native-go/backend/internal/helper/jobcontract/bindings.go +48 -0
- package/templates/native-go/backend/internal/helper/jobcontract/contract_test.go +436 -0
- package/templates/native-go/backend/internal/helper/jobcontract/decode.go +185 -0
- package/templates/native-go/backend/internal/helper/jobcontract/digest.go +55 -0
- package/templates/native-go/backend/internal/helper/jobcontract/registry.go +85 -0
- package/templates/native-go/backend/internal/helper/jobcontract/registry_test.go +73 -0
- package/templates/native-go/backend/internal/helper/jobcontract/result.go +53 -0
- package/templates/native-go/backend/internal/helper/jobcontract/stub.go +8 -0
- package/templates/native-go/backend/internal/helper/jobcontract/testdata/input-digests.json +127 -0
- package/templates/native-go/backend/internal/helper/jobcontract/types.go +234 -0
- package/templates/native-go/backend/internal/helper/jobcontract/types_test.go +29 -0
- package/templates/native-go/backend/internal/helper/jobcontract/validate.go +462 -0
- package/templates/native-go/backend/internal/helper/legacy_authority_schema_linux_test.go +34 -0
- package/templates/native-go/backend/internal/helper/legacy_authority_schema_test.go +6 -0
- package/templates/native-go/backend/internal/helper/management.go +79 -0
- package/templates/native-go/backend/internal/helper/observation.go +42 -2
- package/templates/native-go/backend/internal/helper/observation_health_test.go +13 -1
- package/templates/native-go/backend/internal/helper/observer_diagnostic.go +56 -10
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +6 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_writer.go +40 -0
- package/templates/native-go/backend/internal/helper/process_linux.go +3 -0
- package/templates/native-go/backend/internal/helper/query_deadline_linux_test.go +115 -0
- package/templates/native-go/backend/internal/helper/query_pending_diagnostic_test.go +254 -0
- package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +3 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +23 -4
- package/templates/native-go/backend/internal/helper/sdk_assembly_linux.go +51 -0
- package/templates/native-go/backend/internal/helper/sdk_attach.go +83 -0
- package/templates/native-go/backend/internal/helper/sdk_attach_contract.go +32 -0
- package/templates/native-go/backend/internal/helper/sdk_attach_test.go +184 -0
- package/templates/native-go/backend/internal/helper/sdk_authority_schema_test.go +6 -0
- package/templates/native-go/backend/internal/helper/sdk_background_authority.go +832 -0
- package/templates/native-go/backend/internal/helper/sdk_background_authority_test.go +714 -0
- package/templates/native-go/backend/internal/helper/sdk_background_invalidation.go +218 -0
- package/templates/native-go/backend/internal/helper/sdk_background_lease.go +218 -0
- package/templates/native-go/backend/internal/helper/sdk_background_snapshot.go +110 -0
- package/templates/native-go/backend/internal/helper/sdk_background_store_linux_test.go +261 -0
- package/templates/native-go/backend/internal/helper/sdk_background_store_test.go +58 -0
- package/templates/native-go/backend/internal/helper/sdk_bindings.go +60 -0
- package/templates/native-go/backend/internal/helper/sdk_data_contract.go +251 -0
- package/templates/native-go/backend/internal/helper/sdk_data_protocol.go +424 -0
- package/templates/native-go/backend/internal/helper/sdk_dispatch_absence_test.go +51 -0
- package/templates/native-go/backend/internal/helper/sdk_display.go +488 -0
- package/templates/native-go/backend/internal/helper/sdk_display_contract.go +121 -0
- package/templates/native-go/backend/internal/helper/sdk_display_test.go +459 -0
- package/templates/native-go/backend/internal/helper/sdk_grant_authority.go +559 -0
- package/templates/native-go/backend/internal/helper/sdk_grant_repository_linux.go +417 -0
- package/templates/native-go/backend/internal/helper/sdk_grant_snapshot.go +94 -0
- package/templates/native-go/backend/internal/helper/sdk_history.go +80 -0
- package/templates/native-go/backend/internal/helper/sdk_history_test.go +76 -0
- package/templates/native-go/backend/internal/helper/sdk_job.go +697 -0
- package/templates/native-go/backend/internal/helper/sdk_job_child_linux.go +309 -0
- package/templates/native-go/backend/internal/helper/sdk_job_contract.go +122 -0
- package/templates/native-go/backend/internal/helper/sdk_job_linux_test.go +159 -0
- package/templates/native-go/backend/internal/helper/sdk_job_process_linux.go +327 -0
- package/templates/native-go/backend/internal/helper/sdk_job_test.go +501 -0
- package/templates/native-go/backend/internal/helper/sdk_job_vm_linux_test.go +343 -0
- package/templates/native-go/backend/internal/helper/sdk_journal.go +77 -0
- package/templates/native-go/backend/internal/helper/sdk_journal_linux.go +244 -0
- package/templates/native-go/backend/internal/helper/sdk_journal_linux_test.go +295 -0
- package/templates/native-go/backend/internal/helper/sdk_journal_test.go +71 -0
- package/templates/native-go/backend/internal/helper/sdk_picker_test.go +50 -0
- package/templates/native-go/backend/internal/helper/sdk_process_linux.go +184 -0
- package/templates/native-go/backend/internal/helper/sdk_public_vm_linux_test.go +129 -0
- package/templates/native-go/backend/internal/helper/sdk_relaxed_invalidation.go +242 -0
- package/templates/native-go/backend/internal/helper/sdk_rpc.go +299 -0
- package/templates/native-go/backend/internal/helper/sdk_rpc_contract.go +70 -0
- package/templates/native-go/backend/internal/helper/sdk_rpc_test.go +135 -0
- package/templates/native-go/backend/internal/helper/sdk_server_linux.go +152 -0
- package/templates/native-go/backend/internal/helper/sdk_session.go +677 -0
- package/templates/native-go/backend/internal/helper/sdk_session_contract.go +72 -0
- package/templates/native-go/backend/internal/helper/sdk_session_fence_test.go +215 -0
- package/templates/native-go/backend/internal/helper/sdk_session_test.go +475 -0
- package/templates/native-go/backend/internal/helper/sdk_supervisor_frame.go +78 -0
- package/templates/native-go/backend/internal/helper/sdk_supervisor_linux.go +414 -0
- package/templates/native-go/backend/internal/helper/sdk_transport.go +79 -0
- package/templates/native-go/backend/internal/helper/sdk_transport_linux.go +82 -0
- package/templates/native-go/backend/internal/helper/sdk_transport_test.go +64 -0
- package/templates/native-go/backend/internal/helper/server_linux.go +3 -0
- package/templates/native-go/backend/internal/helper/stale_management_linux_test.go +126 -0
- package/templates/native-go/backend/internal/helper/stale_management_test.go +122 -0
- package/templates/native-go/backend/internal/helper/startup_diagnostic.go +68 -0
- package/templates/native-go/backend/internal/helper/startup_diagnostic_linux_test.go +126 -0
- package/templates/native-go/backend/internal/helper/startup_diagnostic_test.go +117 -0
- package/templates/native-go/backend/internal/helper/status.go +22 -13
- package/templates/native-go/backend/internal/helper/status_test.go +45 -0
- package/templates/native-go/backend/internal/helper/supervision.go +1 -1
- package/templates/native-go/backend/internal/helper/supervisor_frame.go +3 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux.go +6 -2
- package/templates/native-go/backend/internal/helper/unit_connection_test.go +22 -4
- package/templates/native-go/backend/internal/helper/unit_linux.go +7 -3
- package/templates/native-go/backend/internal/helper/unit_query_linux.go +5 -1
- package/templates/native-go/backend/internal/helper/write_files_linux.go +7 -4
- package/templates/native-go/backend/internal/helper/write_files_linux_test.go +26 -0
- package/templates/native-go/dsm-package.yaml +1 -1
- package/templates/native-go-background/BACKGROUND.md +111 -0
- package/templates/native-go-background/backend/internal/app/background_on.go +7 -0
- package/templates/native-go-background/backend/internal/app/background_routes_test.go +32 -0
- package/templates/native-go-background/frontend/src/background/BackgroundPanel.vue +178 -0
- package/templates/native-go-background/frontend/src/background/i18n/de.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/en.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/es.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/fr.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/it.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/ja.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/ko.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/zh-CN.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/zh-TW.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n.ts +19 -0
- package/templates/native-go-background/frontend/src/background/picker-provider.ts +13 -0
- package/templates/native-go-background/frontend/test/background.test.ts +179 -0
- package/templates/native-go-integration/backend/internal/app/personal.go +2 -2
- package/templates/native-go-integration/backend/internal/app/personal_test.go +37 -0
- package/templates/native-go-vue/README.md +38 -7
- package/templates/native-go-vue/frontend/DESIGN.md +15 -3
- package/templates/native-go-vue/frontend/README-JOBS.md +75 -0
- package/templates/native-go-vue/frontend/README-M2.md +64 -0
- package/templates/native-go-vue/frontend/package-lock.json +5 -4
- package/templates/native-go-vue/frontend/package.json +1 -1
- package/templates/native-go-vue/frontend/src/App.vue +39 -11
- package/templates/native-go-vue/frontend/src/M2App.vue +57 -0
- package/templates/native-go-vue/frontend/src/SDKApp.vue +203 -0
- package/templates/native-go-vue/frontend/src/jobs/InteractiveJobForm.vue +70 -0
- package/templates/native-go-vue/frontend/src/jobs/JobsAdminPanel.vue +33 -0
- package/templates/native-go-vue/frontend/src/jobs/JobsPanel.vue +135 -0
- package/templates/native-go-vue/frontend/src/jobs/connected-provider.ts +179 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/de.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/en.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/es.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/fr.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/it.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/ja.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/ko.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/zh-CN.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/zh-TW.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n.ts +15 -0
- package/templates/native-go-vue/frontend/src/jobs/mock-provider.ts +67 -0
- package/templates/native-go-vue/frontend/src/jobs/provider.ts +60 -0
- package/templates/native-go-vue/frontend/src/jobs/validate.ts +44 -0
- package/templates/native-go-vue/frontend/src/m2-main.ts +21 -0
- package/templates/native-go-vue/frontend/src/m2-style.css +7 -0
- package/templates/native-go-vue/frontend/src/nas/M2Files.vue +94 -0
- package/templates/native-go-vue/frontend/src/nas/M2PathPicker.vue +70 -0
- package/templates/native-go-vue/frontend/src/nas/M2Settings.vue +69 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/de.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/en.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/es.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/fr.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/it.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/ja.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/ko.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-CN.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-TW.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/m2-contract.ts +33 -0
- package/templates/native-go-vue/frontend/src/nas/m2-i18n.ts +24 -0
- package/templates/native-go-vue/frontend/src/nas/m2-provider.ts +104 -0
- package/templates/native-go-vue/frontend/src/nas/use-m2-request.ts +18 -0
- package/templates/native-go-vue/frontend/src/sdk-main.ts +39 -0
- package/templates/native-go-vue/frontend/src/shell/AppShell.vue +48 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/de.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/en.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/es.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/fr.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/it.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/ja.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/ko.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/zh-CN.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/zh-TW.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n.ts +17 -0
- package/templates/native-go-vue/frontend/src/shell/pages.ts +34 -0
- package/templates/native-go-vue/frontend/src/style.css +2 -6
- package/templates/native-go-vue/frontend/test/apps.test.ts +21 -0
- package/templates/native-go-vue/frontend/test/jobs-connected.test.ts +163 -0
- package/templates/native-go-vue/frontend/test/jobs-preview.html +22 -0
- package/templates/native-go-vue/frontend/test/jobs.test.ts +176 -0
- package/templates/native-go-vue/frontend/test/m2-preview.html +27 -0
- package/templates/native-go-vue/frontend/test/m2-provider.test.ts +87 -0
- package/templates/native-go-vue/frontend/test/m2-ui.test.ts +209 -0
- package/templates/native-go-vue/frontend/test/native-controls.test.ts +27 -0
- package/templates/native-go-vue/frontend/test/picker-wire.test.ts +110 -0
- package/templates/native-go-vue/frontend/test/shell-preview.html +19 -0
- package/templates/native-go-vue/frontend/test/shell-sdk.test.ts +73 -0
- package/templates/native-go-vue/frontend/test/shell-ui.test.ts +114 -0
- package/templates/native-go-vue/frontend/test/shell.test.ts +45 -0
- package/templates/native-go-vue/frontend/vite.config.ts +2 -2
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Interactive File Station UI (experimental)
|
|
2
|
+
|
|
3
|
+
This optional entry uses the package CGI's `ctx.call` transport and the current
|
|
4
|
+
user's DSM session. It does not borrow an administrator session, request root
|
|
5
|
+
helper approval, cache DSM credentials or install a mock provider.
|
|
6
|
+
|
|
7
|
+
The existing `main.ts` and SDK worker entry remain the default. To select this
|
|
8
|
+
session-only UI in a generated `native-go --ui vue` project:
|
|
9
|
+
|
|
10
|
+
1. Enable `integration: {protocol: 2, workers: {}}` in `dsm-package.yaml`.
|
|
11
|
+
2. Set `SYNOPKGLAND_M2_SIMPLE=1` in `frontend/.env.production.local`.
|
|
12
|
+
3. Run the existing `synopkgland build-spk` workflow and inspect the final SPK.
|
|
13
|
+
|
|
14
|
+
You can also build the frontend with `SYNOPKGLAND_M2_SIMPLE=1 npm run build`.
|
|
15
|
+
The flag selects `src/m2-main.ts` before the existing SDK-workers entry; it
|
|
16
|
+
selects a session-only surface, without background job or root-maintenance UI.
|
|
17
|
+
It does not change backend permissions. Protocol 1 / no integration lacks the
|
|
18
|
+
required routes and the UI shows that the adapter is unavailable. Without this
|
|
19
|
+
flag, generated artifacts retain their previous bytes.
|
|
20
|
+
|
|
21
|
+
## SDK display contract
|
|
22
|
+
|
|
23
|
+
`src/nas/m2-contract.ts` exports `M2Provider`, `M2Selection`, `M2Entry`,
|
|
24
|
+
`M2Page`, `M2Session`, safe codes and the 512 KiB / 100-entry bounds.
|
|
25
|
+
`createM2Provider(ctx)` implements status, discovery, confirmation, saved
|
|
26
|
+
selection listing/revocation, relative list/stat/read, mkdir and upload.
|
|
27
|
+
Pass an AbortSignal per operation and call `dispose()` on unmount. Each mount
|
|
28
|
+
owns its provider and clears its UI after account/package change or pagehide.
|
|
29
|
+
|
|
30
|
+
`M2Selection.writable` records consent to attempt writes; it is not a File
|
|
31
|
+
Station permission probe. The backend validates the actual session and current
|
|
32
|
+
File Station permissions on every operation. A selection is an opaque handle
|
|
33
|
+
with a display path, not the native helper's prepare/digest/revision grant.
|
|
34
|
+
User/UID fields in backend records are stripped from the frontend projection.
|
|
35
|
+
Selections use relaxed username/UID identity: recreating both may preserve a
|
|
36
|
+
selection. Paths do not pin inodes or provide symlink/rename confinement.
|
|
37
|
+
|
|
38
|
+
Discovery supports files in returned pages but shows only folders in the
|
|
39
|
+
picker. Pagination advances by the full server page, not the filtered count;
|
|
40
|
+
rendering is bounded to the latest 200 entries. Writes require explicit
|
|
41
|
+
writable consent. Upload creates a new file and does not overwrite. Read and
|
|
42
|
+
upload are limited to 512 KiB; read bytes become a local binary download, never
|
|
43
|
+
HTML or an inline preview.
|
|
44
|
+
|
|
45
|
+
Requests are observed for at most 22 seconds (backend handler: 20 seconds).
|
|
46
|
+
The existing `ctx.call` does not expose transport abort: closing or canceling
|
|
47
|
+
suppresses late display updates but does not establish server rollback or Q.
|
|
48
|
+
No operation is retried automatically. A lost mutation response reports
|
|
49
|
+
`commit-uncertain`; inspect saved selections or the destination before
|
|
50
|
+
resubmitting. Session expiry requires signing into DSM again and refreshing.
|
|
51
|
+
Background/offline work, streaming and atomic publish remain unsupported.
|
|
52
|
+
|
|
53
|
+
## Local checks
|
|
54
|
+
|
|
55
|
+
Copy `../../_shared/third-party-notices.mjs` into this folder before `npm ci`,
|
|
56
|
+
`npm test`, `npx vue-tsc --noEmit` and `npm run build`. Also build with the M2
|
|
57
|
+
flag. Remove the copied notice tool, `node_modules` and `dist` before root
|
|
58
|
+
repository tests or generating fixtures: the generator copies template files.
|
|
59
|
+
|
|
60
|
+
`test/m2-preview.html` serves synthetic `ctx.call` responses for local browser
|
|
61
|
+
QA. It does not access a NAS and is not the production provider's backend.
|
|
62
|
+
Local unit/jsdom/Chromium tests do not establish DSM compatibility. Actual DSM
|
|
63
|
+
session, File Station ACL, multipart upload and download validation belongs to
|
|
64
|
+
the backend/device-validation thread. No public support claim is made here.
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
"": {
|
|
7
7
|
"name": "native-dsm-vue-app",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@
|
|
9
|
+
"@lucide/vue": "1.48.0",
|
|
10
|
+
"@synopackageland/ui": "0.5.7",
|
|
10
11
|
"vue": "3.5.43"
|
|
11
12
|
},
|
|
12
13
|
"devDependencies": {
|
|
@@ -1050,9 +1051,9 @@
|
|
|
1050
1051
|
}
|
|
1051
1052
|
},
|
|
1052
1053
|
"node_modules/@synopackageland/ui": {
|
|
1053
|
-
"version": "0.
|
|
1054
|
-
"resolved": "https://registry.npmjs.org/@synopackageland/ui/-/ui-0.
|
|
1055
|
-
"integrity": "sha512-
|
|
1054
|
+
"version": "0.5.7",
|
|
1055
|
+
"resolved": "https://registry.npmjs.org/@synopackageland/ui/-/ui-0.5.7.tgz",
|
|
1056
|
+
"integrity": "sha512-egHKoU4Jk33MhZULykelsq5+JB+l8DuRTCD/hOo3ZZa+p2aXoZSl6M0Gwpd+FGLvvARTsrtT8A5lk/PXTMqUmA==",
|
|
1056
1057
|
"license": "MIT",
|
|
1057
1058
|
"dependencies": {
|
|
1058
1059
|
"@internationalized/date": "3.12.4",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "native-dsm-vue-app", "private": true, "type": "module",
|
|
3
3
|
"scripts": {"build": "vue-tsc --noEmit && vite build", "test": "vitest run"},
|
|
4
|
-
"dependencies": {"@synopackageland/ui": "0.
|
|
4
|
+
"dependencies": {"@lucide/vue": "1.48.0", "@synopackageland/ui": "0.5.7", "vue": "3.5.43"},
|
|
5
5
|
"devDependencies": {"@vitejs/plugin-vue": "6.0.9", "vite": "7.3.6", "typescript": "5.9.3", "vue-tsc": "3.3.11", "vitest": "4.1.11", "jsdom": "26.1.0"}
|
|
6
6
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {computed, inject, onMounted, onUnmounted, ref} from 'vue'
|
|
3
|
-
import {AppRoot, Button, Callout, Dialog, SettingsSection, Textarea} from '@synopackageland/ui'
|
|
2
|
+
import {computed, inject, onMounted, onUnmounted, ref, watch} from 'vue'
|
|
3
|
+
import {AppRoot, ConfigProvider, Button, Callout, Dialog, Form, FormActions, FormItem, SettingsSection, Textarea} from '@synopackageland/ui'
|
|
4
|
+
import {uiLocale} from './nas/m2-i18n'
|
|
4
5
|
import {stateCopy, type AppStatus, type Context, type Status} from './context'
|
|
5
6
|
import {NasProviderKey} from './nas/provider'
|
|
6
7
|
import {errorCopy, nasCopy} from './nas/i18n'
|
|
7
8
|
import NasGrantSettings from './nas/NasGrantSettings.vue'
|
|
8
9
|
import NasUnavailable from './nas/NasUnavailable.vue'
|
|
10
|
+
import AppShell from './shell/AppShell.vue'
|
|
11
|
+
import {activePage, shellPages, type ShellPage} from './shell/pages'
|
|
9
12
|
const nasProvider = inject(NasProviderKey, null)
|
|
10
13
|
// A mount owns one provider binding. A native subject/package switch must
|
|
11
14
|
// discard its UI and pending work; the host supplies a new provider on remount.
|
|
@@ -22,9 +25,20 @@ const text = ref('')
|
|
|
22
25
|
const identity = ref('')
|
|
23
26
|
let disposed = false
|
|
24
27
|
const refreshing = ref(false)
|
|
28
|
+
const hasIdentity = ref(false)
|
|
25
29
|
let appCookie = ''
|
|
30
|
+
// The CLI rewrites this to "true" only for a project whose manifest declares
|
|
31
|
+
// the sha256-v1 background worker (--background).
|
|
32
|
+
const backgroundEnabled = (('__BACKGROUND_ENABLED__') as string) === 'true'
|
|
33
|
+
const page = ref<ShellPage>('status')
|
|
34
|
+
const pages = computed(() => shellPages({sample:status.value?.state === 'ready',nas:true,background:backgroundEnabled,identity:hasIdentity.value}))
|
|
35
|
+
watch(pages,list => {page.value = activePage(page.value,list)})
|
|
36
|
+
const subtitle = computed(() => app.value ? `${app.value.package} · ${app.value.user} · ${app.value.version}` : undefined)
|
|
26
37
|
const configured = computed(() => status.value?.reason !== "not-requested")
|
|
38
|
+
// An integration built without a privileged helper has nothing to approve.
|
|
39
|
+
const packageOnly = computed(() => status.value?.reason === 'package-only')
|
|
27
40
|
const details = computed(() => {
|
|
41
|
+
if(packageOnly.value) return {label:'Ready',description:'This package runs as its own DSM package account. No privileged helper is installed.'}
|
|
28
42
|
if(status.value?.state === 'pending') {
|
|
29
43
|
const copy = nasCopy(props.ctx.locale)
|
|
30
44
|
return {label:copy.healthPending,description:copy.healthPendingHelp}
|
|
@@ -97,7 +111,6 @@ async function checkIdentity() {
|
|
|
97
111
|
try {const result=await props.ctx.call<{user:string}>('identity.current',{cookie:appCookie});if(!disposed) identity.value=`App session for ${result.user}`}
|
|
98
112
|
catch(e) {if(!disposed) {appCookie='';identity.value='';error.value=message(e)}} finally {if(!disposed) busy.value=false}
|
|
99
113
|
}
|
|
100
|
-
const hasIdentity = ref(false)
|
|
101
114
|
onMounted(async()=>{
|
|
102
115
|
props.ctx.reopen(()=>{if(!disposed) void refresh()})
|
|
103
116
|
await refresh()
|
|
@@ -109,20 +122,22 @@ onUnmounted(()=>{disposed=true;appCookie='';text.value='';id.value=''})
|
|
|
109
122
|
|
|
110
123
|
<template>
|
|
111
124
|
<AppRoot modal-scope="app" style="height: 100%">
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
<ConfigProvider :locale="uiLocale(ctx.locale)">
|
|
126
|
+
<AppShell v-model="page" :locale="ctx.locale" :pages="pages" :description="subtitle">
|
|
127
|
+
<template #actions>
|
|
115
128
|
<Button variant="secondary" :disabled="busy || refreshing" @click="error=''; refresh()">Refresh</Button>
|
|
116
|
-
</
|
|
129
|
+
</template>
|
|
130
|
+
<div class="integration-app" :aria-busy="busy || refreshing" aria-label="Package settings">
|
|
117
131
|
<p v-if="refreshing" role="status">Refreshing status…</p>
|
|
118
132
|
<p v-else-if="busy" role="status">Completing operation…</p>
|
|
119
133
|
<Callout v-if="error" tone="danger" title="Action required"><span role="alert">{{ error }}</span></Callout>
|
|
120
134
|
<p v-if="notice" class="integration-notice" role="status">{{ notice }}</p>
|
|
135
|
+
<div data-page="status" v-show="page==='status'">
|
|
121
136
|
<SettingsSection title="DSM integration" :collapsible="false">
|
|
122
137
|
<div v-if="status && details" :data-integration-state="status.state" class="integration-status" role="status">
|
|
123
138
|
<h2>{{ details.label }}</h2><p>{{ details.description }}</p>
|
|
124
139
|
<p v-if="status.cleanup === 'required'">Cleanup is required. Ask an administrator to run teardown or disable. If the helper supervisor was lost, use Repair cleanup and follow the package recovery instructions.</p>
|
|
125
|
-
<dl><dt>Package running</dt><dd>{{ status.packageRunning }}</dd><dt>Scheduler</dt><dd>{{ status.scheduler }}</dd></dl>
|
|
140
|
+
<dl><dt>Package running</dt><dd>{{ status.packageRunning }}</dd><template v-if="!packageOnly"><dt>Scheduler</dt><dd>{{ status.scheduler }}</dd></template></dl>
|
|
126
141
|
</div>
|
|
127
142
|
<p v-else-if="error" role="status">Status could not be loaded. Refresh to try again.</p>
|
|
128
143
|
<p v-else role="status">Loading integration status…</p>
|
|
@@ -136,24 +151,37 @@ onUnmounted(()=>{disposed=true;appCookie='';text.value='';id.value=''})
|
|
|
136
151
|
<p v-if="app?.admin && ctx.root && configured" class="integration-help">Repair cleanup clears verified leftover helper state. It does not restart integration.</p>
|
|
137
152
|
<Callout v-if="app && !app.admin && status?.state !== 'ready' && status?.state !== 'pending'" title="Administrator action needed">Ask a DSM administrator to open this package's settings. Your login cannot approve root operations.</Callout>
|
|
138
153
|
</SettingsSection>
|
|
154
|
+
</div>
|
|
155
|
+
<div data-page="sample" v-show="page==='sample'">
|
|
139
156
|
<SettingsSection v-if="status?.state === 'ready'" title="My sample data" :collapsible="false">
|
|
140
157
|
<p class="integration-help">This synthetic note belongs to your DSM account and is stored in package data.</p>
|
|
141
158
|
<p v-if="refreshing" role="status">Loading your sample data…</p>
|
|
142
159
|
<Callout v-else-if="!id" title="No sample data">Refresh to request your sample data again.</Callout>
|
|
143
|
-
<
|
|
144
|
-
|
|
160
|
+
<Form v-if="id" @submit.prevent><FormItem label="My sample note"><Textarea v-model="text" :disabled="busy || refreshing" /></FormItem>
|
|
161
|
+
<FormActions><Button variant="primary" :disabled="busy || refreshing" @click="save">Save my note</Button></FormActions>
|
|
162
|
+
</Form>
|
|
145
163
|
</SettingsSection>
|
|
164
|
+
</div>
|
|
165
|
+
<div data-page="nas" v-show="page==='nas'">
|
|
146
166
|
<NasGrantSettings v-if="nasProvider && app && status && !nasInvalidated" :locale="ctx.locale" />
|
|
147
167
|
<NasUnavailable v-else :locale="ctx.locale" />
|
|
168
|
+
</div>
|
|
169
|
+
<div data-page="background" v-show="page==='background'">
|
|
170
|
+
<!-- BACKGROUND_PANEL -->
|
|
171
|
+
</div>
|
|
172
|
+
<div data-page="identity" v-show="page==='identity'">
|
|
148
173
|
<SettingsSection v-if="hasIdentity" title="Optional app identity" :collapsible="false">
|
|
149
174
|
<p class="integration-help">Your DSM login is checked again for every app session request.</p>
|
|
150
175
|
<div class="integration-actions"><Button variant="primary" :disabled="busy || refreshing" @click="login">Create app session</Button><Button variant="secondary" :disabled="busy || refreshing || !identity" @click="checkIdentity">Check app session</Button></div>
|
|
151
176
|
<p v-if="identity" role="status">{{ identity }}</p>
|
|
152
177
|
</SettingsSection>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
153
180
|
<Dialog v-model:open="disableOpen" title="Disable integration?" description="New integration requests will be refused before helper cleanup begins.">
|
|
154
181
|
<p>Your sample data and historical root output are retained. A failed cleanup remains visible.</p>
|
|
155
182
|
<template #footer><Button variant="secondary" @click="disableOpen=false">Cancel</Button><Button variant="danger" :disabled="busy || refreshing" @click="disableOpen=false; action('helper_disable')">Confirm disable</Button></template>
|
|
156
183
|
</Dialog>
|
|
157
|
-
</
|
|
184
|
+
</AppShell>
|
|
185
|
+
</ConfigProvider>
|
|
158
186
|
</AppRoot>
|
|
159
187
|
</template>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {computed,inject,onMounted,onUnmounted,ref} from 'vue'
|
|
3
|
+
import {AppRoot,ConfigProvider,Button,Callout,SettingsSection} from '@synopackageland/ui'
|
|
4
|
+
import type {AppStatus,Context} from './context'
|
|
5
|
+
import {M2ProviderKey} from './nas/m2-contract'
|
|
6
|
+
import {m2Copy,m2ErrorCopy,uiLocale} from './nas/m2-i18n'
|
|
7
|
+
import {useM2Request} from './nas/use-m2-request'
|
|
8
|
+
import M2Settings from './nas/M2Settings.vue'
|
|
9
|
+
import AppShell from './shell/AppShell.vue'
|
|
10
|
+
import {shellPages,type ShellPage} from './shell/pages'
|
|
11
|
+
const props=defineProps<{ctx:Context}>(),copy=computed(()=>m2Copy(props.ctx.locale)),provider=inject(M2ProviderKey)!
|
|
12
|
+
const request=useM2Request(),{busy,error}=request
|
|
13
|
+
const app=ref<AppStatus>(),invalid=ref(false),view=ref(0),nestedBusy=ref(false)
|
|
14
|
+
const page=ref<ShellPage>('status')
|
|
15
|
+
// The simple session build only has the File Station folder screen.
|
|
16
|
+
const pages=computed(()=>shellPages({folders:true}))
|
|
17
|
+
const subtitle=computed(()=>app.value?`${app.value.package} · ${app.value.version} · ${app.value.user}`:undefined)
|
|
18
|
+
let bound:{user:string;package:string}|undefined
|
|
19
|
+
let removeReopen:()=>void=()=>{}
|
|
20
|
+
async function refresh(){
|
|
21
|
+
if(invalid.value)return
|
|
22
|
+
const value=await request.run(()=>props.ctx.call<AppStatus>('app.status'))
|
|
23
|
+
if(value){
|
|
24
|
+
if(typeof value.user!=='string'||!value.user||typeof value.package!=='string'||!value.package){error.value={code:'unavailable'};return}
|
|
25
|
+
if(bound&&(bound.user!==value.user||bound.package!==value.package)){invalidate();return}
|
|
26
|
+
bound??={user:value.user,package:value.package};app.value=value;view.value++
|
|
27
|
+
}else{app.value=undefined}
|
|
28
|
+
}
|
|
29
|
+
function invalidate(){invalid.value=true;app.value=undefined;request.cancel();provider.dispose()}
|
|
30
|
+
onMounted(()=>{removeReopen=props.ctx.reopen(()=>void refresh());window.addEventListener('pagehide',invalidate);void refresh()})
|
|
31
|
+
onUnmounted(()=>{removeReopen?.();window.removeEventListener('pagehide',invalidate);app.value=undefined})
|
|
32
|
+
</script>
|
|
33
|
+
<template>
|
|
34
|
+
<AppRoot theme="dsm7" modal-scope="app" style="height: 100%">
|
|
35
|
+
<ConfigProvider :locale="uiLocale(ctx.locale)">
|
|
36
|
+
<AppShell v-model="page" :locale="ctx.locale" :pages="pages" :description="subtitle">
|
|
37
|
+
<template #actions>
|
|
38
|
+
<Button v-if="!invalid" variant="secondary" :disabled="busy||nestedBusy" @click="refresh">{{ copy.refresh }}</Button>
|
|
39
|
+
</template>
|
|
40
|
+
<div class="integration-app m2-app" :aria-busy="busy||nestedBusy">
|
|
41
|
+
<Callout v-if="invalid" tone="warning" role="alert">{{ copy.accountChanged }}</Callout>
|
|
42
|
+
<Callout v-else-if="error" tone="danger" role="alert">{{ m2ErrorCopy(error,copy) }}</Callout>
|
|
43
|
+
<p v-if="busy" role="status">{{ copy.loading }}</p>
|
|
44
|
+
<div data-page="status" v-show="page==='status'">
|
|
45
|
+
<SettingsSection title="Package" :collapsible="false">
|
|
46
|
+
<p v-if="app" role="status">{{ app.package }} · {{ app.version }} · {{ app.user }}</p>
|
|
47
|
+
<p v-else role="status">{{ copy.loading }}</p>
|
|
48
|
+
</SettingsSection>
|
|
49
|
+
</div>
|
|
50
|
+
<div data-page="folders" v-show="page==='folders'">
|
|
51
|
+
<M2Settings v-if="app&&!invalid" :key="view" :locale="ctx.locale" @busy="value=>nestedBusy=value" />
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</AppShell>
|
|
55
|
+
</ConfigProvider>
|
|
56
|
+
</AppRoot>
|
|
57
|
+
</template>
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {computed, inject, onMounted, onUnmounted, ref, watch} from 'vue'
|
|
3
|
+
import {AppRoot, ConfigProvider, Button, Callout, Dialog, Form, FormActions, FormItem, SettingsSection, Textarea} from '@synopackageland/ui'
|
|
4
|
+
import {uiLocale} from './nas/m2-i18n'
|
|
5
|
+
import {stateCopy, type AppStatus, type Context, type Status} from './context'
|
|
6
|
+
import {NasProviderKey} from './nas/provider'
|
|
7
|
+
import {errorCopy, nasCopy} from './nas/i18n'
|
|
8
|
+
import NasGrantSettings from './nas/NasGrantSettings.vue'
|
|
9
|
+
import NasUnavailable from './nas/NasUnavailable.vue'
|
|
10
|
+
import JobsPanel from './jobs/JobsPanel.vue'
|
|
11
|
+
import {JobsProviderKey} from './jobs/provider'
|
|
12
|
+
const jobsProvider=inject(JobsProviderKey,null)
|
|
13
|
+
import JobsAdminPanel from './jobs/JobsAdminPanel.vue'
|
|
14
|
+
import AppShell from './shell/AppShell.vue'
|
|
15
|
+
import {activePage,shellPages,type ShellPage} from './shell/pages'
|
|
16
|
+
const nasProvider = inject(NasProviderKey, null)
|
|
17
|
+
// A mount owns one provider binding. A native subject/package switch must
|
|
18
|
+
// discard its UI and pending work; the host supplies a new provider on remount.
|
|
19
|
+
const nasInvalidated = ref(false)
|
|
20
|
+
const props = defineProps<{ctx: Context}>()
|
|
21
|
+
const app = ref<AppStatus>()
|
|
22
|
+
const status = ref<Status>()
|
|
23
|
+
const busy = ref(false)
|
|
24
|
+
const error = ref('')
|
|
25
|
+
const notice = ref('')
|
|
26
|
+
const disableOpen = ref(false)
|
|
27
|
+
const id = ref('')
|
|
28
|
+
const text = ref('')
|
|
29
|
+
const identity = ref('')
|
|
30
|
+
let disposed = false
|
|
31
|
+
const refreshing = ref(false)
|
|
32
|
+
const hasIdentity = ref(false)
|
|
33
|
+
let appCookie = ''
|
|
34
|
+
const page = ref<ShellPage>('status')
|
|
35
|
+
const pages = computed(() => shellPages({
|
|
36
|
+
// The session-SDK build submits interactive work instead of sample notes.
|
|
37
|
+
sample: status.value?.state === 'ready' && !jobsProvider?.interactive,
|
|
38
|
+
// Connected workers carry their own consent per job; the grant screen only
|
|
39
|
+
// exists while no interactive worker is advertised.
|
|
40
|
+
nas: !!nasProvider || !jobsProvider?.interactive?.workers.length,
|
|
41
|
+
interactive: !!jobsProvider?.interactive,
|
|
42
|
+
background: jobsProvider?.readiness?.background !== 'unavailable',
|
|
43
|
+
admin: !!app.value?.admin,
|
|
44
|
+
identity: hasIdentity.value,
|
|
45
|
+
}))
|
|
46
|
+
watch(pages,list => {page.value = activePage(page.value,list)})
|
|
47
|
+
const subtitle = computed(() => app.value ? `${app.value.package} · ${app.value.user} · ${app.value.version}` : undefined)
|
|
48
|
+
const configured = computed(() => status.value?.reason !== "not-requested")
|
|
49
|
+
const details = computed(() => {
|
|
50
|
+
if(status.value?.state === 'pending') {
|
|
51
|
+
const copy = nasCopy(props.ctx.locale)
|
|
52
|
+
return {label:copy.healthPending,description:copy.healthPendingHelp}
|
|
53
|
+
}
|
|
54
|
+
return status.value ? stateCopy[status.value.state] : undefined
|
|
55
|
+
})
|
|
56
|
+
function message(e: unknown) {
|
|
57
|
+
const code = (e as {code?: string})?.code || 'request_failed'
|
|
58
|
+
if(['denied','unknown_method','unavailable','unsupported','session_required','auth_unavailable'].includes(code)) return errorCopy(e,nasCopy(props.ctx.locale))
|
|
59
|
+
return ({session_required:'Your DSM session expired. Sign in again.',access_denied:'This sample belongs to another account.',integration_unavailable:'Integration is unavailable. Ask an administrator to activate or recover it.',personal_unavailable:'Sample storage is unavailable. Ask an administrator to check package data.',root_conflict:'A conflicting scheduler task exists. Ask an administrator to review it.',root_verify_failed:'Scheduler verification failed. Refresh and review the task.',root_run_failed:'The approved operation failed. Review integration status and cleanup.'} as Record<string,string>)[code] || `Request failed (${code}). Refresh and try again.`
|
|
60
|
+
}
|
|
61
|
+
async function refresh() {
|
|
62
|
+
if(disposed || refreshing.value) return
|
|
63
|
+
refreshing.value = true; error.value = ''
|
|
64
|
+
try {
|
|
65
|
+
const [a,s] = await Promise.all([props.ctx.call<AppStatus>('app.status'),props.ctx.call<Status>('integration.status')])
|
|
66
|
+
if(disposed) return
|
|
67
|
+
if(app.value && (app.value.user!==a.user || app.value.package!==a.package)) nasInvalidated.value=true
|
|
68
|
+
app.value = a; status.value = s
|
|
69
|
+
if(s.state !== 'ready') {id.value='';text.value='';return}
|
|
70
|
+
// The session SDK build exposes File Station jobs, not native sample notes.
|
|
71
|
+
if(jobsProvider?.interactive) {id.value='';text.value='';return}
|
|
72
|
+
// Plain --ui vue has no personal routes; not-enabled status hides this.
|
|
73
|
+
const list = await props.ctx.call<{items:Array<{id:string;name:string}>}>('personal.list')
|
|
74
|
+
if(disposed) return
|
|
75
|
+
id.value = list.items[0]?.id || ''
|
|
76
|
+
if(id.value) {
|
|
77
|
+
const note = await props.ctx.call<{text:string}>('personal.read',{id:id.value})
|
|
78
|
+
if(!disposed) text.value = note.text
|
|
79
|
+
}
|
|
80
|
+
} catch(e) {if(!disposed) {error.value = message(e);status.value=undefined;id.value='';text.value=''}} finally {refreshing.value=false}
|
|
81
|
+
}
|
|
82
|
+
async function action(op: string) {
|
|
83
|
+
if(busy.value || refreshing.value || disposed) return
|
|
84
|
+
busy.value=true;error.value='';notice.value=''
|
|
85
|
+
try {
|
|
86
|
+
if(!props.ctx.root) throw {code:'unsupported'}
|
|
87
|
+
const approved = await props.ctx.root.authorize(op)
|
|
88
|
+
if(disposed) return
|
|
89
|
+
if(approved !== 'ready') {notice.value='Approval cancelled. No operation was run.';return}
|
|
90
|
+
await props.ctx.root.run(op)
|
|
91
|
+
if(disposed) return
|
|
92
|
+
notice.value=op==='helper_repair' ? 'Cleanup repaired. Use Recover or Approve and activate when ready.' : 'Operation completed. Integration status was checked again.'
|
|
93
|
+
await refresh()
|
|
94
|
+
} catch(e) {if(!disposed) {
|
|
95
|
+
await refresh()
|
|
96
|
+
if(!disposed) {
|
|
97
|
+
const code=(e as {code?:string})?.code
|
|
98
|
+
if(code==='root_cancelled') notice.value='Repair confirmation cancelled. No operation was run.'
|
|
99
|
+
else error.value=op==='helper_repair' && (code==='root_run_failed' || code==='root_task_failed') ? 'Repair could not verify safe cleanup. Review the package recovery instructions before trying again.' : message(e)
|
|
100
|
+
}
|
|
101
|
+
}}
|
|
102
|
+
finally {if(!disposed) busy.value=false}
|
|
103
|
+
}
|
|
104
|
+
async function save() {
|
|
105
|
+
if(busy.value || refreshing.value || !id.value || disposed) return
|
|
106
|
+
busy.value=true;error.value='';notice.value=''
|
|
107
|
+
try {await props.ctx.call('personal.write',{id:id.value,text:text.value});if(!disposed) notice.value='Your sample note was saved.'}
|
|
108
|
+
catch(e) {if(!disposed) error.value=message(e)} finally {if(!disposed) busy.value=false}
|
|
109
|
+
}
|
|
110
|
+
async function login() {
|
|
111
|
+
if(busy.value || refreshing.value || disposed) return
|
|
112
|
+
busy.value=true;error.value=''
|
|
113
|
+
try {
|
|
114
|
+
const result=await props.ctx.call<{cookie:string;user:string}>('identity.login')
|
|
115
|
+
if(!disposed){appCookie=result.cookie;identity.value=`App session for ${result.user}`}
|
|
116
|
+
} catch(e) {if(!disposed) error.value=message(e)} finally {if(!disposed) busy.value=false}
|
|
117
|
+
}
|
|
118
|
+
async function checkIdentity() {
|
|
119
|
+
if(busy.value || refreshing.value || disposed) return
|
|
120
|
+
busy.value=true;error.value=''
|
|
121
|
+
try {const result=await props.ctx.call<{user:string}>('identity.current',{cookie:appCookie});if(!disposed) identity.value=`App session for ${result.user}`}
|
|
122
|
+
catch(e) {if(!disposed) {appCookie='';identity.value='';error.value=message(e)}} finally {if(!disposed) busy.value=false}
|
|
123
|
+
}
|
|
124
|
+
onMounted(async()=>{
|
|
125
|
+
props.ctx.reopen(()=>{if(!disposed) void refresh()})
|
|
126
|
+
await refresh()
|
|
127
|
+
if(disposed || !app.value) return
|
|
128
|
+
try {const result = await props.ctx.call<{mode:string}>('identity.status');if(!disposed) hasIdentity.value = result.mode==='better-auth'} catch { /* Optional route absent in Go-only. */ }
|
|
129
|
+
})
|
|
130
|
+
onUnmounted(()=>{disposed=true;appCookie='';text.value='';id.value=''})
|
|
131
|
+
</script>
|
|
132
|
+
|
|
133
|
+
<template>
|
|
134
|
+
<AppRoot modal-scope="app" style="height: 100%">
|
|
135
|
+
<ConfigProvider :locale="uiLocale(ctx.locale)">
|
|
136
|
+
<AppShell v-model="page" :locale="ctx.locale" :pages="pages" :description="subtitle">
|
|
137
|
+
<template #actions>
|
|
138
|
+
<Button variant="secondary" :disabled="busy || refreshing" @click="error=''; refresh()">Refresh</Button>
|
|
139
|
+
</template>
|
|
140
|
+
<div class="integration-app" :aria-busy="busy || refreshing" aria-label="Package settings">
|
|
141
|
+
<p v-if="refreshing" role="status">Refreshing status…</p>
|
|
142
|
+
<p v-else-if="busy" role="status">Completing operation…</p>
|
|
143
|
+
<Callout v-if="error" tone="danger" title="Action required"><span role="alert">{{ error }}</span></Callout>
|
|
144
|
+
<p v-if="notice" class="integration-notice" role="status">{{ notice }}</p>
|
|
145
|
+
<div data-page="status" v-show="page==='status'">
|
|
146
|
+
<SettingsSection title="DSM integration" :collapsible="false">
|
|
147
|
+
<div v-if="status && details" :data-integration-state="status.state" class="integration-status" role="status">
|
|
148
|
+
<h2>{{ details.label }}</h2><p>{{ details.description }}</p>
|
|
149
|
+
<p v-if="status.cleanup === 'required'">Cleanup is required. Ask an administrator to run teardown or disable. If the helper supervisor was lost, use Repair cleanup and follow the package recovery instructions.</p>
|
|
150
|
+
<dl><dt>Package running</dt><dd>{{ status.packageRunning }}</dd><dt>Scheduler</dt><dd>{{ status.scheduler }}</dd></dl>
|
|
151
|
+
</div>
|
|
152
|
+
<p v-else-if="error" role="status">Status could not be loaded. Refresh to try again.</p>
|
|
153
|
+
<p v-else role="status">Loading integration status…</p>
|
|
154
|
+
<div v-if="app?.admin && ctx.root && configured" class="integration-actions">
|
|
155
|
+
<Button variant="primary" :disabled="busy || refreshing" @click="action('helper_enable')">Approve and activate</Button>
|
|
156
|
+
<Button variant="secondary" :disabled="busy || refreshing" @click="action('helper_recover')">Recover</Button>
|
|
157
|
+
<Button variant="secondary" :disabled="busy || refreshing" @click="action('helper_teardown')">Teardown</Button>
|
|
158
|
+
<Button variant="secondary" :disabled="busy || refreshing" @click="disableOpen=true">Disable</Button>
|
|
159
|
+
<Button variant="secondary" :disabled="busy || refreshing" @click="action('helper_repair')">Repair cleanup</Button>
|
|
160
|
+
</div>
|
|
161
|
+
<p v-if="app?.admin && ctx.root && configured" class="integration-help">Repair cleanup clears verified leftover helper state. It does not restart integration.</p>
|
|
162
|
+
<Callout v-if="app && !app.admin && status?.state !== 'ready' && status?.state !== 'pending'" title="Administrator action needed">Ask a DSM administrator to open this package's settings. Your login cannot approve root operations.</Callout>
|
|
163
|
+
</SettingsSection>
|
|
164
|
+
</div>
|
|
165
|
+
<div data-page="sample" v-show="page==='sample'">
|
|
166
|
+
<SettingsSection v-if="status?.state === 'ready' && !jobsProvider?.interactive" title="My sample data" :collapsible="false">
|
|
167
|
+
<p class="integration-help">This synthetic note belongs to your DSM account and is stored in package data.</p>
|
|
168
|
+
<p v-if="refreshing" role="status">Loading your sample data…</p>
|
|
169
|
+
<Callout v-else-if="!id" title="No sample data">Refresh to request your sample data again.</Callout>
|
|
170
|
+
<Form v-if="id" @submit.prevent><FormItem label="My sample note"><Textarea v-model="text" :disabled="busy || refreshing" /></FormItem>
|
|
171
|
+
<FormActions><Button variant="primary" :disabled="busy || refreshing" @click="save">Save my note</Button></FormActions>
|
|
172
|
+
</Form>
|
|
173
|
+
</SettingsSection>
|
|
174
|
+
</div>
|
|
175
|
+
<div data-page="nas" v-show="page==='nas'">
|
|
176
|
+
<NasGrantSettings v-if="nasProvider && app && status && !nasInvalidated" :locale="ctx.locale" />
|
|
177
|
+
<NasUnavailable v-else-if="!jobsProvider?.interactive?.workers.length" :locale="ctx.locale" />
|
|
178
|
+
</div>
|
|
179
|
+
<div data-page="interactive" v-show="page==='interactive'">
|
|
180
|
+
<JobsPanel v-if="app && !nasInvalidated" section="interactive" :locale="ctx.locale" />
|
|
181
|
+
</div>
|
|
182
|
+
<div data-page="background" v-show="page==='background'">
|
|
183
|
+
<JobsPanel v-if="app && !nasInvalidated" section="background" :locale="ctx.locale" />
|
|
184
|
+
</div>
|
|
185
|
+
<div data-page="admin" v-show="page==='admin'">
|
|
186
|
+
<JobsAdminPanel v-if="app?.admin && !nasInvalidated" :locale="ctx.locale" />
|
|
187
|
+
</div>
|
|
188
|
+
<div data-page="identity" v-show="page==='identity'">
|
|
189
|
+
<SettingsSection v-if="hasIdentity" title="Optional app identity" :collapsible="false">
|
|
190
|
+
<p class="integration-help">Your DSM login is checked again for every app session request.</p>
|
|
191
|
+
<div class="integration-actions"><Button variant="primary" :disabled="busy || refreshing" @click="login">Create app session</Button><Button variant="secondary" :disabled="busy || refreshing || !identity" @click="checkIdentity">Check app session</Button></div>
|
|
192
|
+
<p v-if="identity" role="status">{{ identity }}</p>
|
|
193
|
+
</SettingsSection>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
<Dialog v-model:open="disableOpen" title="Disable integration?" description="New integration requests will be refused before helper cleanup begins.">
|
|
197
|
+
<p>Your sample data and historical root output are retained. A failed cleanup remains visible.</p>
|
|
198
|
+
<template #footer><Button variant="secondary" @click="disableOpen=false">Cancel</Button><Button variant="danger" :disabled="busy || refreshing" @click="disableOpen=false; action('helper_disable')">Confirm disable</Button></template>
|
|
199
|
+
</Dialog>
|
|
200
|
+
</AppShell>
|
|
201
|
+
</ConfigProvider>
|
|
202
|
+
</AppRoot>
|
|
203
|
+
</template>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {computed,ref,watch} from 'vue'
|
|
3
|
+
import {Button,Callout,Form,FormActions,FormItem,Input,Select} from '@synopackageland/ui'
|
|
4
|
+
import type {JobsProvider,PreparedInteractive} from './provider'
|
|
5
|
+
import type {M2JobSource} from '../nas/m2-contract'
|
|
6
|
+
import M2PathPicker from '../nas/M2PathPicker.vue'
|
|
7
|
+
import {m2Copy,m2ErrorCopy} from '../nas/m2-i18n'
|
|
8
|
+
import {jobCopy} from './i18n'
|
|
9
|
+
import {useNasRequest} from '../nas/use-request'
|
|
10
|
+
const props=defineProps<{locale:string;provider:JobsProvider}>(),emit=defineEmits<{submitted:[]}>()
|
|
11
|
+
const copy=computed(()=>jobCopy(props.locale)),request=useNasRequest(),{busy,error}=request
|
|
12
|
+
const open=ref(false),pickerBusy=ref(false),source=ref<M2JobSource>(),workerId=ref(''),action=ref('nas.files.stat'),bound=ref(100),uncertain=ref<PreparedInteractive>(),notice=ref(false),invalid=ref(false)
|
|
13
|
+
const worker=computed(()=>props.provider.interactive?.workers.find(w=>w.id===workerId.value))
|
|
14
|
+
const actions=computed(()=>worker.value?.actions.filter(a=>source.value?.entry.isDir?a!=='nas.files.read':a!=='nas.files.list')??[])
|
|
15
|
+
const workerOptions=computed(()=>props.provider.interactive?.workers.map(w=>({value:w.id,label:`${w.id} · ${w.revision}`}))??[])
|
|
16
|
+
const operationLabel=(a:string)=>a==='nas.files.list'?copy.value.listOperation:a==='nas.files.read'?copy.value.readOperation:copy.value.statOperation
|
|
17
|
+
const actionOptions=computed(()=>actions.value.map(a=>({value:a,label:operationLabel(a)})))
|
|
18
|
+
const ready=computed(()=>props.provider.readiness?.interactive==='ready'&&!invalid.value)
|
|
19
|
+
const locked=computed(()=>busy.value||pickerBusy.value||!!uncertain.value||!ready.value)
|
|
20
|
+
watch(()=>props.provider.interactive?.workers,workers=>{if(!workers?.some(w=>w.id===workerId.value))workerId.value=workers?.[0]?.id??''},{immediate:true})
|
|
21
|
+
watch(actions,values=>{if(!values.includes(action.value as never))action.value=values[0]??''})
|
|
22
|
+
watch(action,value=>{bound.value=value==='nas.files.read'?worker.value?.maxBytes??1:100})
|
|
23
|
+
watch(error,e=>{if(['session_required','auth_unavailable','denied'].includes((e as {code?:string})?.code??'')){invalid.value=true;source.value=undefined;open.value=false}})
|
|
24
|
+
function select(value:M2JobSource){source.value=value;notice.value=false}
|
|
25
|
+
async function submit(){
|
|
26
|
+
if(locked.value||!source.value||!worker.value)return
|
|
27
|
+
const chosen=source.value,w=worker.value,a=action.value
|
|
28
|
+
if(!actions.value.includes(a as never)||((a==='nas.files.list'||a==='nas.files.read')&&(!Number.isSafeInteger(bound.value)||bound.value<1||bound.value>(a==='nas.files.list'?100:w.maxBytes)))){error.value={code:'invalid-request'};return}
|
|
29
|
+
await request.run(async signal=>{
|
|
30
|
+
const prepared=await props.provider.interactive!.prepareInteractive(signal,{id:w.id,revision:w.revision},{id:chosen.selection.grantId,revision:1},{steps:[{action:a,segments:[...chosen.segments],...(a==='nas.files.list'?{limit:bound.value}:a==='nas.files.read'?{maxBytes:bound.value}:{})}]})
|
|
31
|
+
if(Date.now()>=prepared.expiresAt)throw {code:'expired'}
|
|
32
|
+
// Preserve the original intent before the single submit attempt. A missing
|
|
33
|
+
// reply cannot establish rollback; lookup never creates or attaches a job.
|
|
34
|
+
uncertain.value=prepared
|
|
35
|
+
await props.provider.interactive!.submitInteractive(prepared,signal)
|
|
36
|
+
uncertain.value=undefined;source.value=undefined;notice.value=true;emit('submitted')
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
async function lookup(){
|
|
40
|
+
const original=uncertain.value;if(!original||busy.value)return
|
|
41
|
+
const found=await request.run(signal=>props.provider.lookup(original.intentId,signal))
|
|
42
|
+
if(found?.jobId===original.jobId){uncertain.value=undefined;source.value=undefined;notice.value=true;emit('submitted')}
|
|
43
|
+
}
|
|
44
|
+
const errorText=computed(()=>{
|
|
45
|
+
const code=(error.value as {code?:string})?.code
|
|
46
|
+
if(code==='revalidating')return copy.value.revalidating
|
|
47
|
+
if(code==='session_required'||code==='auth_unavailable')return copy.value.accessLost
|
|
48
|
+
if(['denied','invalid-request','limit-exceeded'].includes(code??''))return m2ErrorCopy(error.value,m2Copy(props.locale))
|
|
49
|
+
return copy.value.error
|
|
50
|
+
})
|
|
51
|
+
</script>
|
|
52
|
+
<template>
|
|
53
|
+
<Form class="jobs-input" :aria-label="copy.newInteractive" :aria-busy="busy||pickerBusy" @submit.prevent="submit">
|
|
54
|
+
<h3>{{ copy.newInteractive }}</h3>
|
|
55
|
+
<p>{{ copy.sourceHelp }}</p>
|
|
56
|
+
<Callout v-if="error" tone="danger" role="alert">{{ errorText }}</Callout>
|
|
57
|
+
<p v-if="notice" role="status">{{ copy.interactiveSubmitted }}</p>
|
|
58
|
+
<Button variant="secondary" :disabled="locked" @click="open=true">{{ copy.chooseSource }}</Button>
|
|
59
|
+
<p v-if="source" role="status">{{ source.entry.path }}</p>
|
|
60
|
+
<FormItem :label="copy.worker"><Select v-model="workerId" :options="workerOptions" :disabled="locked" /></FormItem>
|
|
61
|
+
<FormItem :label="copy.operation"><Select v-model="action" data-job-action :options="actionOptions" :disabled="locked||!source" /></FormItem>
|
|
62
|
+
<FormItem v-if="action==='nas.files.list'||action==='nas.files.read'" :label="action==='nas.files.list'?copy.entryLimit:copy.byteLimit"><Input v-model.number="bound" data-job-bound type="number" min="1" :max="action==='nas.files.list'?100:worker?.maxBytes" step="1" :disabled="locked" /></FormItem>
|
|
63
|
+
<FormActions><Button type="submit" variant="primary" :disabled="locked||!source||!worker||!actions.length">{{ copy.submitInteractive }}</Button></FormActions>
|
|
64
|
+
<template v-if="uncertain"><p role="status">{{ copy.uncertain }}</p><Button variant="secondary" :disabled="busy||invalid" @click="lookup">{{ copy.lookup }}</Button></template>
|
|
65
|
+
<M2PathPicker v-model:open="open" :locale="locale" :title="copy.chooseSource" select-files read-only @source="select" @busy="value=>pickerBusy=value" />
|
|
66
|
+
</Form>
|
|
67
|
+
</template>
|
|
68
|
+
<style scoped>
|
|
69
|
+
.jobs-input { margin-block: var(--ui-space-4, 16px); }
|
|
70
|
+
</style>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {computed,inject,onMounted,ref,watch} from 'vue'
|
|
3
|
+
import {Button,Callout,SettingsSection} from '@synopackageland/ui'
|
|
4
|
+
import {JobsAdminProviderKey,type AdminJobView} from './provider'
|
|
5
|
+
import {jobCopy} from './i18n'
|
|
6
|
+
import {adminPage} from './validate'
|
|
7
|
+
import {useNasRequest} from '../nas/use-request'
|
|
8
|
+
const props=defineProps<{locale:string}>(),copy=computed(()=>jobCopy(props.locale))
|
|
9
|
+
const provider=inject(JobsAdminProviderKey,null),request=useNasRequest(),{busy,error}=request,items=ref<readonly AdminJobView[]>([]),nextCursor=ref<string>()
|
|
10
|
+
const invalidated=ref(false),loaded=ref(false)
|
|
11
|
+
watch(error,e=>{if(['denied','session_required','auth_unavailable'].includes((e as {code?:string})?.code??'')){invalidated.value=true;items.value=[]}})
|
|
12
|
+
async function load(cursor?:string){if(!provider||invalidated.value)return;const result=await request.run(async signal=>adminPage(await provider.list(signal,cursor)));if(result){loaded.value=true;items.value=result.items;nextCursor.value=result.nextCursor}else if(error.value){items.value=[];nextCursor.value=undefined}}
|
|
13
|
+
async function refresh(){await load()}
|
|
14
|
+
async function cancel(item:AdminJobView){if(!provider)return;await request.run(signal=>provider.cancel(item.jobId,item.revision,signal));await refresh()}
|
|
15
|
+
function state(item:AdminJobView){return ({pending:copy.value.pending,running:copy.value.running,'cancel-requested':copy.value.stopping,draining:copy.value.stopping,succeeded:copy.value.succeeded,failed:copy.value.failed,canceled:copy.value.canceled,interrupted:copy.value.interrupted,'cleanup-required':copy.value.cleanup})[item.state]}
|
|
16
|
+
onMounted(()=>{if(provider?.mode==='mock')void refresh()})
|
|
17
|
+
</script>
|
|
18
|
+
<template>
|
|
19
|
+
<SettingsSection :title="copy.adminTitle" :collapsible="false" :aria-busy="busy">
|
|
20
|
+
<Callout v-if="!provider||provider.mode==='unavailable'" tone="info" :title="copy.unavailable" />
|
|
21
|
+
<Callout v-else-if="invalidated" tone="danger" :title="copy.accessLost" role="alert" />
|
|
22
|
+
<template v-else>
|
|
23
|
+
<p v-if="provider.mode==='mock'">{{ copy.mock }}</p><p v-else-if="!loaded&&!error">{{ copy.loadManagement }}</p><Callout v-if="error" tone="danger" :title="copy.error" role="alert" />
|
|
24
|
+
<Button :disabled="busy" variant="secondary" @click="refresh">{{ copy.refresh }}</Button>
|
|
25
|
+
<p v-if="loaded&&!items.length&&!error">{{ copy.empty }}</p>
|
|
26
|
+
<ul class="nas-grants"><li v-for="item in items" :key="item.jobId">
|
|
27
|
+
<p role="status">{{ state(item) }}</p><p v-if="item.drained">{{ copy.drained }}</p><p v-if="item.effectsUnknown">{{ copy.effects }}</p>
|
|
28
|
+
<Button v-if="['pending','running','cancel-requested','draining'].includes(item.state)" :disabled="busy" variant="secondary" @click="cancel(item)">{{ copy.cancel }}</Button>
|
|
29
|
+
</li></ul>
|
|
30
|
+
<Button v-if="nextCursor" :disabled="busy" variant="secondary" @click="load(nextCursor)">{{ copy.next }}</Button>
|
|
31
|
+
</template>
|
|
32
|
+
</SettingsSection>
|
|
33
|
+
</template>
|