From 3653b841c1fe7712f6b53e3a27b060c2f8070a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20G=C3=B6bel?= <dgoebel@techfak.uni-bielefeld.de> Date: Tue, 13 Feb 2024 11:36:48 +0100 Subject: [PATCH] Resolve "Add help for creating clomw_info.json" --- .gitlab-ci.yml | 1 + package-lock.json | 813 +++++++++--------- package.json | 2 + src/App.vue | 2 +- src/components/CopyToClipboardIcon.vue | 1 + src/components/DraggableLists.vue | 104 +++ src/components/NavbarTop.vue | 2 +- src/components/modals/BootstrapModal.vue | 2 +- .../modals/BucketDetailModal.vue | 1 + .../ParameterSchemaFormComponent.vue | 51 +- .../form-mode/ParameterBooleanInput.vue | 15 +- .../form-mode/ParameterEnumInput.vue | 26 +- .../form-mode/ParameterGroupForm.vue | 89 +- .../form-mode/ParameterNumberInput.vue | 20 +- .../workflows/WorkflowDocumentationTabs.vue | 2 +- .../workflows/WorkflowWithVersionsCard.vue | 73 +- .../workflows/modals/ParameterModal.vue | 9 +- .../modals/UpdateWorkflowCredentialsModal.vue | 3 +- .../workflows/modals/UpdateWorkflowModal.vue | 1 + src/router/workflowRoutes.ts | 12 + src/utils/DownloadJson.ts | 6 + src/views/admin/AdminResourcesView.vue | 2 +- src/views/admin/AdminUsersView.vue | 2 +- src/views/object-storage/BucketsView.vue | 5 +- src/views/object-storage/S3KeysView.vue | 4 +- src/views/resources/ListResourcesView.vue | 2 +- src/views/resources/MyResourcesView.vue | 2 +- src/views/resources/ReviewResourceView.vue | 2 +- src/views/workflows/ArbitraryWorkflowView.vue | 16 +- src/views/workflows/CreateClowmInfoView.vue | 565 ++++++++++++ .../workflows/ListWorkflowExecutionsView.vue | 2 +- src/views/workflows/ListWorkflowsView.vue | 14 +- src/views/workflows/MyWorkflowsView.vue | 2 +- src/views/workflows/ReviewWorkflowsView.vue | 2 +- src/views/workflows/StartWorkflowView.vue | 20 +- 35 files changed, 1279 insertions(+), 596 deletions(-) create mode 100644 src/components/DraggableLists.vue create mode 100644 src/utils/DownloadJson.ts create mode 100644 src/views/workflows/CreateClowmInfoView.vue diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dc9685d..7f2ea9f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,6 +13,7 @@ default: - docker before_script: - npm --version # For debugging + - node --version - npm install --no-fund lint: diff --git a/package-lock.json b/package-lock.json index fd24c5c..d350098 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "pinia": "~2.1.0", "semver": "~7.5.0", "showdown": "~2.1.0", + "sortablejs": "^1.15.2", "vue": "~3.4.0", "vue-router": "~4.2.0", "vue3-cookies": "~1.0.0" @@ -39,6 +40,7 @@ "@types/node": "^18.19.5", "@types/semver": "~7.5.1", "@types/showdown": "~2.0.1", + "@types/sortablejs": "^1.15.7", "@vitejs/plugin-vue": "~5.0.0", "@vue/eslint-config-prettier": "~8.0.0", "@vue/eslint-config-typescript": "~11.0.3", @@ -211,33 +213,33 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@aws-sdk/client-s3": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.507.0.tgz", - "integrity": "sha512-rRLiC5Ly3e7kZVNoRsG6JhZ8Yat5uEnDeShdWNdHchyTO88AaEnHaeyiVG9ecmKI8jYl6NbWSHB8xL0l9KIr/w==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.511.0.tgz", + "integrity": "sha512-IRUYev0KNKa5rQrpULE9IhJW6dhgGQWBmAJI+OyITHMu3uGvVHDqWKqnShV0IfMJWg1y37I3juFJ1KAti8jyHw==", "dependencies": { "@aws-crypto/sha1-browser": "3.0.0", "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.507.0", - "@aws-sdk/core": "3.496.0", - "@aws-sdk/credential-provider-node": "3.507.0", - "@aws-sdk/middleware-bucket-endpoint": "3.502.0", - "@aws-sdk/middleware-expect-continue": "3.502.0", - "@aws-sdk/middleware-flexible-checksums": "3.502.0", - "@aws-sdk/middleware-host-header": "3.502.0", - "@aws-sdk/middleware-location-constraint": "3.502.0", - "@aws-sdk/middleware-logger": "3.502.0", - "@aws-sdk/middleware-recursion-detection": "3.502.0", - "@aws-sdk/middleware-sdk-s3": "3.502.0", - "@aws-sdk/middleware-signing": "3.502.0", - "@aws-sdk/middleware-ssec": "3.502.0", - "@aws-sdk/middleware-user-agent": "3.502.0", - "@aws-sdk/region-config-resolver": "3.502.0", - "@aws-sdk/signature-v4-multi-region": "3.502.0", - "@aws-sdk/types": "3.502.0", - "@aws-sdk/util-endpoints": "3.502.0", - "@aws-sdk/util-user-agent-browser": "3.502.0", - "@aws-sdk/util-user-agent-node": "3.502.0", + "@aws-sdk/client-sts": "3.511.0", + "@aws-sdk/core": "3.511.0", + "@aws-sdk/credential-provider-node": "3.511.0", + "@aws-sdk/middleware-bucket-endpoint": "3.511.0", + "@aws-sdk/middleware-expect-continue": "3.511.0", + "@aws-sdk/middleware-flexible-checksums": "3.511.0", + "@aws-sdk/middleware-host-header": "3.511.0", + "@aws-sdk/middleware-location-constraint": "3.511.0", + "@aws-sdk/middleware-logger": "3.511.0", + "@aws-sdk/middleware-recursion-detection": "3.511.0", + "@aws-sdk/middleware-sdk-s3": "3.511.0", + "@aws-sdk/middleware-signing": "3.511.0", + "@aws-sdk/middleware-ssec": "3.511.0", + "@aws-sdk/middleware-user-agent": "3.511.0", + "@aws-sdk/region-config-resolver": "3.511.0", + "@aws-sdk/signature-v4-multi-region": "3.511.0", + "@aws-sdk/types": "3.511.0", + "@aws-sdk/util-endpoints": "3.511.0", + "@aws-sdk/util-user-agent-browser": "3.511.0", + "@aws-sdk/util-user-agent-node": "3.511.0", "@aws-sdk/xml-builder": "3.496.0", "@smithy/config-resolver": "^2.1.1", "@smithy/core": "^1.3.1", @@ -279,22 +281,22 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.507.0.tgz", - "integrity": "sha512-pFeaKwqv4tXD6QVxWC2V4N62DUoP3bPSm/mCe2SPhaNjNsmwwA53viUHz/nwxIbs8w4vV44UQsygb0AgKm+HoQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.511.0.tgz", + "integrity": "sha512-v1f5ZbuZWpad+fgTOpgFyIZT3A37wdqoSPh0hl+cKRu5kPsz96xCe9+UvLx+HdN2yJ/mV0UZcMq6ysj4xAGIEg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.496.0", - "@aws-sdk/middleware-host-header": "3.502.0", - "@aws-sdk/middleware-logger": "3.502.0", - "@aws-sdk/middleware-recursion-detection": "3.502.0", - "@aws-sdk/middleware-user-agent": "3.502.0", - "@aws-sdk/region-config-resolver": "3.502.0", - "@aws-sdk/types": "3.502.0", - "@aws-sdk/util-endpoints": "3.502.0", - "@aws-sdk/util-user-agent-browser": "3.502.0", - "@aws-sdk/util-user-agent-node": "3.502.0", + "@aws-sdk/core": "3.511.0", + "@aws-sdk/middleware-host-header": "3.511.0", + "@aws-sdk/middleware-logger": "3.511.0", + "@aws-sdk/middleware-recursion-detection": "3.511.0", + "@aws-sdk/middleware-user-agent": "3.511.0", + "@aws-sdk/region-config-resolver": "3.511.0", + "@aws-sdk/types": "3.511.0", + "@aws-sdk/util-endpoints": "3.511.0", + "@aws-sdk/util-user-agent-browser": "3.511.0", + "@aws-sdk/util-user-agent-node": "3.511.0", "@smithy/config-resolver": "^2.1.1", "@smithy/core": "^1.3.1", "@smithy/fetch-http-handler": "^2.4.1", @@ -326,24 +328,24 @@ } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.507.0.tgz", - "integrity": "sha512-ms5CH2ImhqqCIbo5irxayByuPOlVAmSiqDVfjZKwgIziqng2bVgNZMeKcT6t0bmrcgScEAVnZwY7j/iZTIw73g==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.511.0.tgz", + "integrity": "sha512-cITRRq54eTrq7ll9li+yYnLbNHKXG2P+ovdZSDiQ6LjCYBdcD4ela30qbs87Yye9YsopdslDzBhHHtrf5oiuMw==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.507.0", - "@aws-sdk/core": "3.496.0", - "@aws-sdk/middleware-host-header": "3.502.0", - "@aws-sdk/middleware-logger": "3.502.0", - "@aws-sdk/middleware-recursion-detection": "3.502.0", - "@aws-sdk/middleware-signing": "3.502.0", - "@aws-sdk/middleware-user-agent": "3.502.0", - "@aws-sdk/region-config-resolver": "3.502.0", - "@aws-sdk/types": "3.502.0", - "@aws-sdk/util-endpoints": "3.502.0", - "@aws-sdk/util-user-agent-browser": "3.502.0", - "@aws-sdk/util-user-agent-node": "3.502.0", + "@aws-sdk/client-sts": "3.511.0", + "@aws-sdk/core": "3.511.0", + "@aws-sdk/middleware-host-header": "3.511.0", + "@aws-sdk/middleware-logger": "3.511.0", + "@aws-sdk/middleware-recursion-detection": "3.511.0", + "@aws-sdk/middleware-signing": "3.511.0", + "@aws-sdk/middleware-user-agent": "3.511.0", + "@aws-sdk/region-config-resolver": "3.511.0", + "@aws-sdk/types": "3.511.0", + "@aws-sdk/util-endpoints": "3.511.0", + "@aws-sdk/util-user-agent-browser": "3.511.0", + "@aws-sdk/util-user-agent-node": "3.511.0", "@smithy/config-resolver": "^2.1.1", "@smithy/core": "^1.3.1", "@smithy/fetch-http-handler": "^2.4.1", @@ -374,26 +376,26 @@ "node": ">=14.0.0" }, "peerDependencies": { - "@aws-sdk/credential-provider-node": "^3.507.0" + "@aws-sdk/credential-provider-node": "^3.511.0" } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.507.0.tgz", - "integrity": "sha512-TOWBe0ApEh32QOib0R+irWGjd1F9wnhbGV5PcB9SakyRwvqwG5MKOfYxG7ocoDqLlaRwzZMidcy/PV8/OEVNKg==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.511.0.tgz", + "integrity": "sha512-lwVEEXK+1auEwmBuTv35m2GvbxPthi8SjNUpU4pRetZPVbGhnhCN6H7JqeMDP6GLf81Io2eySXRsmLMt7l/fjg==", "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/core": "3.496.0", - "@aws-sdk/middleware-host-header": "3.502.0", - "@aws-sdk/middleware-logger": "3.502.0", - "@aws-sdk/middleware-recursion-detection": "3.502.0", - "@aws-sdk/middleware-user-agent": "3.502.0", - "@aws-sdk/region-config-resolver": "3.502.0", - "@aws-sdk/types": "3.502.0", - "@aws-sdk/util-endpoints": "3.502.0", - "@aws-sdk/util-user-agent-browser": "3.502.0", - "@aws-sdk/util-user-agent-node": "3.502.0", + "@aws-sdk/core": "3.511.0", + "@aws-sdk/middleware-host-header": "3.511.0", + "@aws-sdk/middleware-logger": "3.511.0", + "@aws-sdk/middleware-recursion-detection": "3.511.0", + "@aws-sdk/middleware-user-agent": "3.511.0", + "@aws-sdk/region-config-resolver": "3.511.0", + "@aws-sdk/types": "3.511.0", + "@aws-sdk/util-endpoints": "3.511.0", + "@aws-sdk/util-user-agent-browser": "3.511.0", + "@aws-sdk/util-user-agent-node": "3.511.0", "@smithy/config-resolver": "^2.1.1", "@smithy/core": "^1.3.1", "@smithy/fetch-http-handler": "^2.4.1", @@ -426,13 +428,13 @@ "node": ">=14.0.0" }, "peerDependencies": { - "@aws-sdk/credential-provider-node": "^3.507.0" + "@aws-sdk/credential-provider-node": "^3.511.0" } }, "node_modules/@aws-sdk/core": { - "version": "3.496.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.496.0.tgz", - "integrity": "sha512-yT+ug7Cw/3eJi7x2es0+46x12+cIJm5Xv+GPWsrTFD1TKgqO/VPEgfDtHFagDNbFmjNQA65Ygc/kEdIX9ICX/A==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.511.0.tgz", + "integrity": "sha512-0gbDvQhToyLxPyr/7KP6uavrBYKh7exld2lju1Lp65U61XgEjTVP/thJmHTvH4BAKGSqeIz/rrwJ0KrC8nwBtw==", "dependencies": { "@smithy/core": "^1.3.1", "@smithy/protocol-http": "^3.1.1", @@ -446,11 +448,11 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.502.0.tgz", - "integrity": "sha512-KIB8Ae1Z7domMU/jU4KiIgK4tmYgvuXlhR54ehwlVHxnEoFPoPuGHFZU7oFn79jhhSLUFQ1lRYMxP0cEwb7XeQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.511.0.tgz", + "integrity": "sha512-4VUsnLRox8YzxnZwnFrfZM4bL5KKLhsjjjX7oiuLyzFkhauI4HFYt7rTB8YNGphpqAg/Wzw5DBZfO3Bw1iR1HA==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/property-provider": "^2.1.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -460,11 +462,11 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.503.1", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.503.1.tgz", - "integrity": "sha512-rTdlFFGoPPFMF2YjtlfRuSgKI+XsF49u7d98255hySwhsbwd3Xp+utTTPquxP+CwDxMHbDlI7NxDzFiFdsoZug==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.511.0.tgz", + "integrity": "sha512-y83Gt8GPpgMe/lMFxIq+0G2rbzLTC6lhrDocHUzqcApLD6wet8Esy2iYckSRlJgYY+qsVAzpLrSMtt85DwRPTw==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/fetch-http-handler": "^2.4.1", "@smithy/node-http-handler": "^2.3.1", "@smithy/property-provider": "^2.1.1", @@ -479,16 +481,16 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.507.0.tgz", - "integrity": "sha512-2CnyduoR9COgd7qH1LPYK8UggGqVs8R4ASDMB5bwGxbg9ZerlStDiHpqvJNNg1k+VlejBr++utxfmHd236XgmQ==", - "dependencies": { - "@aws-sdk/client-sts": "3.507.0", - "@aws-sdk/credential-provider-env": "3.502.0", - "@aws-sdk/credential-provider-process": "3.502.0", - "@aws-sdk/credential-provider-sso": "3.507.0", - "@aws-sdk/credential-provider-web-identity": "3.507.0", - "@aws-sdk/types": "3.502.0", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.511.0.tgz", + "integrity": "sha512-AgIOCtYzm61jbTQCY/2Vf/yu7DeLG0TLZa05a3VVRN9XE4ERtEnMn7TdbxM+hS24MTX8xI0HbMcWxCBkXRIg9w==", + "dependencies": { + "@aws-sdk/client-sts": "3.511.0", + "@aws-sdk/credential-provider-env": "3.511.0", + "@aws-sdk/credential-provider-process": "3.511.0", + "@aws-sdk/credential-provider-sso": "3.511.0", + "@aws-sdk/credential-provider-web-identity": "3.511.0", + "@aws-sdk/types": "3.511.0", "@smithy/credential-provider-imds": "^2.2.1", "@smithy/property-provider": "^2.1.1", "@smithy/shared-ini-file-loader": "^2.3.1", @@ -500,17 +502,17 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.507.0.tgz", - "integrity": "sha512-tkQnmOLkRBXfMLgDYHzogrqTNdtl0Im0ipzJb2IV5hfM5NoTfCf795e9A9isgwjSP/g/YEU0xQWxa4lq8LRtuA==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.502.0", - "@aws-sdk/credential-provider-http": "3.503.1", - "@aws-sdk/credential-provider-ini": "3.507.0", - "@aws-sdk/credential-provider-process": "3.502.0", - "@aws-sdk/credential-provider-sso": "3.507.0", - "@aws-sdk/credential-provider-web-identity": "3.507.0", - "@aws-sdk/types": "3.502.0", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.511.0.tgz", + "integrity": "sha512-5JDZXsSluliJmxOF+lYYFgJdSKQfVLQyic5NxScHULTERGoEwEHMgucFGwJ9MV9FoINjNTQLfAiWlJL/kGkCEQ==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.511.0", + "@aws-sdk/credential-provider-http": "3.511.0", + "@aws-sdk/credential-provider-ini": "3.511.0", + "@aws-sdk/credential-provider-process": "3.511.0", + "@aws-sdk/credential-provider-sso": "3.511.0", + "@aws-sdk/credential-provider-web-identity": "3.511.0", + "@aws-sdk/types": "3.511.0", "@smithy/credential-provider-imds": "^2.2.1", "@smithy/property-provider": "^2.1.1", "@smithy/shared-ini-file-loader": "^2.3.1", @@ -522,11 +524,11 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.502.0.tgz", - "integrity": "sha512-fJJowOjQ4infYQX0E1J3xFVlmuwEYJAFk0Mo1qwafWmEthsBJs+6BR2RiWDELHKrSK35u4Pf3fu3RkYuCtmQFw==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.511.0.tgz", + "integrity": "sha512-88hLUPqcTwjSubPS+34ZfmglnKeLny8GbmZsyllk96l26PmDTAqo5RScSA8BWxL0l5pRRWGtcrFyts+oibHIuQ==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/property-provider": "^2.1.1", "@smithy/shared-ini-file-loader": "^2.3.1", "@smithy/types": "^2.9.1", @@ -537,13 +539,13 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.507.0.tgz", - "integrity": "sha512-6WBjou52QukFpDi4ezb19bcAx/bM8ge8qnJnRT02WVRmU6zFQ5yLD2fW1MFsbX3cwbey+wSqKd5FGE1Hukd5wQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.511.0.tgz", + "integrity": "sha512-aEei9UdXYEE2e0Htf28/IcuHcWk3VkUkpcg3KDR/AyzXA3i/kxmixtAgRmHOForC5CMqoJjzVPFUITNkAscyag==", "dependencies": { - "@aws-sdk/client-sso": "3.507.0", - "@aws-sdk/token-providers": "3.507.0", - "@aws-sdk/types": "3.502.0", + "@aws-sdk/client-sso": "3.511.0", + "@aws-sdk/token-providers": "3.511.0", + "@aws-sdk/types": "3.511.0", "@smithy/property-provider": "^2.1.1", "@smithy/shared-ini-file-loader": "^2.3.1", "@smithy/types": "^2.9.1", @@ -554,12 +556,12 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.507.0.tgz", - "integrity": "sha512-f+aGMfazBimX7S06224JRYzGTaMh1uIhfj23tZylPJ05KxTVi5IO1RoqeI/uHLJ+bDOx+JHBC04g/oCdO4kHvw==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.511.0.tgz", + "integrity": "sha512-/3XMyN7YYefAsES/sMMY5zZGRmZ5QJisJw798DdMYmYMsb1dt0Qy8kZTu+59ZzOiVIcznsjSTCEB81QmGtDKcA==", "dependencies": { - "@aws-sdk/client-sts": "3.507.0", - "@aws-sdk/types": "3.502.0", + "@aws-sdk/client-sts": "3.511.0", + "@aws-sdk/types": "3.511.0", "@smithy/property-provider": "^2.1.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -569,9 +571,9 @@ } }, "node_modules/@aws-sdk/lib-storage": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.507.0.tgz", - "integrity": "sha512-cwCBGw6W71d0PrFSRizBd7WdyzsZnRWVftnOvNkyjIE5vFifdFbpdVaFidMVUZmvUQvS3Vgkx1LeXPT98EBWUQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.511.0.tgz", + "integrity": "sha512-inEbSyqzGxiQs8aEnkGdxw9ZDn370mRHOdE1TB/GvVe9buQVyZ2hQvOY5WBVOaIGDIxGpuUzVvr4o89XreU19w==", "dependencies": { "@smithy/abort-controller": "^2.1.1", "@smithy/middleware-endpoint": "^2.4.1", @@ -589,11 +591,11 @@ } }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.502.0.tgz", - "integrity": "sha512-mUSP2DUcjhO5zM2b21CvZ9AqwI8DaAeZA6NYHOxWGTV9BUxHcdGWXEjDkcVj9CQ0gvNwTtw6B5L/q52rVAnZbw==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.511.0.tgz", + "integrity": "sha512-G4dAAHPUZbpDCVBaCcAOlFoctO9lcecSs0EZYrvzQc/9d4XJvNWGd1C7GSdf204VPOCPZCjNpTkdWGm25r00wA==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@aws-sdk/util-arn-parser": "3.495.0", "@smithy/node-config-provider": "^2.2.1", "@smithy/protocol-http": "^3.1.1", @@ -606,11 +608,11 @@ } }, "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.502.0.tgz", - "integrity": "sha512-DxfAuBVuPSt8as9xP57o8ks6ySVSjwO2NNNAdpLwk4KhEAPYEpHlf2yWYorYLrS+dDmwfYgOhRNoguuBdCu6ow==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.511.0.tgz", + "integrity": "sha512-zjDzrJV9PFCkEqhNLKKK+9PB1vPveVZLJbcY71V3PZFvPII1bhlgwvI1e99MhEiaiH2a9I2PnS56bGwEKuNTrw==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/protocol-http": "^3.1.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -620,13 +622,13 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.502.0.tgz", - "integrity": "sha512-kCt2zQDFumz/LnJJJOSd2GW4dr8oT8YMJKgxC/pph3aRXoSHXRwhrMbFnQ8swEE9vjywxtcED8sym0b0tNhhoA==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.511.0.tgz", + "integrity": "sha512-oI8zULi6VXLXJ3zA6aCdbOoceSNOxGITosB7EKDsLllzAQFV1WlzmQCtjFY8DLLYZ521atgJNcVbzjxPQnrnJA==", "dependencies": { "@aws-crypto/crc32": "3.0.0", "@aws-crypto/crc32c": "3.0.0", - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/is-array-buffer": "^2.1.1", "@smithy/protocol-http": "^3.1.1", "@smithy/types": "^2.9.1", @@ -638,11 +640,11 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.502.0.tgz", - "integrity": "sha512-EjnG0GTYXT/wJBmm5/mTjDcAkzU8L7wQjOzd3FTXuTCNNyvAvwrszbOj5FlarEw5XJBbQiZtBs+I5u9+zy560w==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.511.0.tgz", + "integrity": "sha512-DbBzQP/6woSHR/+g9dHN3YiYaLIqFw9u8lQFMxi3rT3hqITFVYLzzXtEaHjDD6/is56pNT84CIKbyJ6/gY5d1Q==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/protocol-http": "^3.1.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -652,11 +654,11 @@ } }, "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.502.0.tgz", - "integrity": "sha512-fLRwPuTZvEWQkPjys03m3D6tYN4kf7zU6+c8mJxwvEg+yfBuv2RBsbd+Vn2bTisUjXvIg1kyBzONlpHoIyFneg==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.511.0.tgz", + "integrity": "sha512-PKHnOT3oBo41NELq3Esz3K9JuV1l9E+SrCcfr/07yU4EbqhS4UGPb22Yf5JakQu4fGbTFlAftcc8PXcE2zLr4g==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" }, @@ -665,11 +667,11 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.502.0.tgz", - "integrity": "sha512-FDyv6K4nCoHxbjLGS2H8ex8I0KDIiu4FJgVRPs140ZJy6gE5Pwxzv6YTzZGLMrnqcIs9gh065Lf6DjwMelZqaw==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.511.0.tgz", + "integrity": "sha512-EYU9dBlJXvQcCsM2Tfgi0NQoXrqovfDv/fDy8oGJgZFrgNuHDti8tdVVxeJTUJNEAF67xlDl5o+rWEkKthkYGQ==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" }, @@ -678,11 +680,11 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.502.0.tgz", - "integrity": "sha512-hvbyGJbxeuezxOu8VfFmcV4ql1hKXLxHTe5FNYfEBat2KaZXVhc1Hg+4TvB06/53p+E8J99Afmumkqbxs2esUA==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.511.0.tgz", + "integrity": "sha512-PlNPCV/6zpDVdNx1K69xDTh/wPNU4WyP4qa6hUo2/+4/PNG5HI9xbCWtpb4RjhdTRw6qDtkBNcPICHbtWx5aHg==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/protocol-http": "^3.1.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -692,11 +694,11 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.502.0.tgz", - "integrity": "sha512-GbGugrfyL5bNA/zw8iQll92yXBONfWSC8Ns00DtkOU1saPXp4/7WHtyyZGYdvPa73T1IsuZy9egpoYRBmRcd5Q==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.511.0.tgz", + "integrity": "sha512-SKJr8mKaqjcGpu0xxRPXZiKrJmyetDfgzvWuZ7QOgdnPa+6jk5fmEUTFoPb3VCarMkf8xo/l6cTZ5lei7Lbflw==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@aws-sdk/util-arn-parser": "3.495.0", "@smithy/node-config-provider": "^2.2.1", "@smithy/protocol-http": "^3.1.1", @@ -711,11 +713,11 @@ } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.502.0.tgz", - "integrity": "sha512-4hF08vSzJ7L6sB+393gOFj3s2N6nLusYS0XrMW6wYNFU10IDdbf8Z3TZ7gysDJJHEGQPmTAesPEDBsasGWcMxg==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.511.0.tgz", + "integrity": "sha512-IMijFLfm+QQHD6NNDX9k3op9dpBSlWKnqjcMU38Tytl2nbqV4gktkarOK1exHAmH7CdoYR5BufVtBzbASNSF/A==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/property-provider": "^2.1.1", "@smithy/protocol-http": "^3.1.1", "@smithy/signature-v4": "^2.1.1", @@ -728,11 +730,11 @@ } }, "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.502.0.tgz", - "integrity": "sha512-1nidVTIba6/aVjjzD/WNqWdzSyTrXOHO3Ddz2MGD8S1yGSrYz4iYaq4Bm/uosfdr8B1L0Ws0pjdRXrNfzSw/DQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.511.0.tgz", + "integrity": "sha512-8pfgBard9pj7oWJ79R6dbXHUGr7JPP/OmAsKBYZA0r/91a1XdFUDtRYZadstjcOv/X3QbeG3QqWOtNco+XgM7Q==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" }, @@ -741,12 +743,12 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.502.0.tgz", - "integrity": "sha512-TxbBZbRiXPH0AUxegqiNd9aM9zNSbfjtBs5MEfcBsweeT/B2O7K1EjP9+CkB8Xmk/5FLKhAKLr19b1TNoE27rw==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.511.0.tgz", + "integrity": "sha512-eLs+CxP2QCXh3tCGYCdAml3oyWj8MSIwKbH+8rKw0k/5vmY1YJDBy526whOxx61ivhz2e0muuijN4X5EZZ2Pnw==", "dependencies": { - "@aws-sdk/types": "3.502.0", - "@aws-sdk/util-endpoints": "3.502.0", + "@aws-sdk/types": "3.511.0", + "@aws-sdk/util-endpoints": "3.511.0", "@smithy/protocol-http": "^3.1.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -756,11 +758,11 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.502.0.tgz", - "integrity": "sha512-mxmsX2AGgnSM+Sah7mcQCIneOsJQNiLX0COwEttuf8eO+6cLMAZvVudH3BnWTfea4/A9nuri9DLCqBvEmPrilg==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.511.0.tgz", + "integrity": "sha512-RzBLSNaRd4iEkQyEGfiSNvSnWU/x23rsiFgA9tqYFA0Vqx7YmzSWC8QBUxpwybB8HkbbL9wNVKQqTbhI3mYneQ==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/node-config-provider": "^2.2.1", "@smithy/types": "^2.9.1", "@smithy/util-config-provider": "^2.2.1", @@ -772,13 +774,13 @@ } }, "node_modules/@aws-sdk/s3-request-presigner": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.507.0.tgz", - "integrity": "sha512-A3EGvXMeOvnG+qtAsmlcQyLP7+PlCePS+PsVqLm3Pz3C16avOTxTqOZIkYCqBBX2fnASr2qUr0d3cezBfsU7PQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.511.0.tgz", + "integrity": "sha512-CZRAA5Ru67DEStvz3i3yyS79oAPCXC5bqow5YWxAm6vkTydkA/Ybvim24T3EUDye6ParZvAtFhVV72odo5bitg==", "dependencies": { - "@aws-sdk/signature-v4-multi-region": "3.502.0", - "@aws-sdk/types": "3.502.0", - "@aws-sdk/util-format-url": "3.502.0", + "@aws-sdk/signature-v4-multi-region": "3.511.0", + "@aws-sdk/types": "3.511.0", + "@aws-sdk/util-format-url": "3.511.0", "@smithy/middleware-endpoint": "^2.4.1", "@smithy/protocol-http": "^3.1.1", "@smithy/smithy-client": "^2.3.1", @@ -790,12 +792,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.502.0.tgz", - "integrity": "sha512-NpOXtUXH0ZAgnyI3Y3s2fPrgwbsWoNMwdoXdFZvH0eDzzX80tim7Yuy6dzVA5zrxSzOYs1xjcOhM+4CmM0QZiw==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.511.0.tgz", + "integrity": "sha512-lwbU3LX5TpYu1DHBMH2Wz+2MWGccn5G3psu1Y9WTPc+1bubVQHWf8UD2lzON5L2QirT9tQheQjTke1u5JC7FTQ==", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.502.0", - "@aws-sdk/types": "3.502.0", + "@aws-sdk/middleware-sdk-s3": "3.511.0", + "@aws-sdk/types": "3.511.0", "@smithy/protocol-http": "^3.1.1", "@smithy/signature-v4": "^2.1.1", "@smithy/types": "^2.9.1", @@ -806,12 +808,12 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.507.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.507.0.tgz", - "integrity": "sha512-ehOINGjoGJc6Puzon7ev4bXckkaZx18WNgMTNttYJhj3vTpj5LPSQbI/5SS927bEbpGMFz1+hJ6Ra5WGfbTcEQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.511.0.tgz", + "integrity": "sha512-92dXjMHBJcRoUkJHc0Bvtsz7Sal8t6VASRJ5vfs5c2ZpTVgLpVnM4dBmwUgGUdnvHov0cZTXbbadTJ/qOWx5Zw==", "dependencies": { - "@aws-sdk/client-sso-oidc": "3.507.0", - "@aws-sdk/types": "3.502.0", + "@aws-sdk/client-sso-oidc": "3.511.0", + "@aws-sdk/types": "3.511.0", "@smithy/property-provider": "^2.1.1", "@smithy/shared-ini-file-loader": "^2.3.1", "@smithy/types": "^2.9.1", @@ -822,9 +824,9 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.502.0.tgz", - "integrity": "sha512-M0DSPYe/gXhwD2QHgoukaZv5oDxhW3FfvYIrJptyqUq3OnPJBcDbihHjrE0PBtfh/9kgMZT60/fQ2NVFANfa2g==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.511.0.tgz", + "integrity": "sha512-P03ufufxmkvd7nO46oOeEqYIMPJ8qMCKxAsfJk1JBVPQ1XctVntbail4/UFnrnzij8DTl4Mk/D62uGo7+RolXA==", "dependencies": { "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -845,11 +847,11 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.502.0.tgz", - "integrity": "sha512-6LKFlJPp2J24r1Kpfoz5ESQn+1v5fEjDB3mtUKRdpwarhm3syu7HbKlHCF3KbcCOyahobvLvhoedT78rJFEeeg==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.511.0.tgz", + "integrity": "sha512-J/5hsscJkg2pAOdLx1YKlyMCk5lFRxRxEtup9xipzOxVBlqOIE72Tuu31fbxSlF8XzO/AuCJcZL4m1v098K9oA==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/types": "^2.9.1", "@smithy/util-endpoints": "^1.1.1", "tslib": "^2.5.0" @@ -859,11 +861,11 @@ } }, "node_modules/@aws-sdk/util-format-url": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.502.0.tgz", - "integrity": "sha512-4+0zBD0ZIJqtTzSE6VRruRwUx3lG+is8Egv+LN99X5y7i6OdrS9ePYHbCJ9FxkzTThgbkUq6k2W7psEDYvn4VA==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.511.0.tgz", + "integrity": "sha512-2BycrBtplIGAtzjj5YYLGrDBQDHR0zTct9bWBVhSfI0w2YAWAvxfRmXG4Dd1FF5ZxTm2xB9lA2u8FKim7ZKD8Q==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/querystring-builder": "^2.1.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -884,22 +886,22 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.502.0.tgz", - "integrity": "sha512-v8gKyCs2obXoIkLETAeEQ3AM+QmhHhst9xbM1cJtKUGsRlVIak/XyyD+kVE6kmMm1cjfudHpHKABWk9apQcIZQ==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.511.0.tgz", + "integrity": "sha512-5LuESdwtIcA10aHcX7pde7aCIijcyTPBXFuXmFlDTgm/naAayQxelQDpvgbzuzGLgePf8eTyyhDKhzwPZ2EqiQ==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/types": "^2.9.1", "bowser": "^2.11.0", "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.502.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.502.0.tgz", - "integrity": "sha512-9RjxpkGZKbTdl96tIJvAo+vZoz4P/cQh36SBUt9xfRfW0BtsaLyvSrvlR5wyUYhvRcC12Axqh/8JtnAPq//+Vw==", + "version": "3.511.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.511.0.tgz", + "integrity": "sha512-UopdlRvYY5mxlS4wwFv+QAWL6/T302wmoQj7i+RY+c/D3Ej3PKBb/mW3r2wEOgZLJmPpeeM1SYMk+rVmsW1rqw==", "dependencies": { - "@aws-sdk/types": "3.502.0", + "@aws-sdk/types": "3.511.0", "@smithy/node-config-provider": "^2.2.1", "@smithy/types": "^2.9.1", "tslib": "^2.5.0" @@ -1553,9 +1555,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", - "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.10.0.tgz", + "integrity": "sha512-/MeDQmcD96nVoRumKUljsYOLqfv1YFJps+0pTrb2Z9Nl/w5qNUysMaWQsrd1mvAlNT4yza1iVyIu4Q4AgF6V3A==", "cpu": [ "arm" ], @@ -1566,9 +1568,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", - "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.10.0.tgz", + "integrity": "sha512-lvu0jK97mZDJdpZKDnZI93I0Om8lSDaiPx3OiCk0RXn3E8CMPJNS/wxjAvSJJzhhZpfjXsjLWL8LnS6qET4VNQ==", "cpu": [ "arm64" ], @@ -1579,9 +1581,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", - "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.10.0.tgz", + "integrity": "sha512-uFpayx8I8tyOvDkD7X6n0PriDRWxcqEjqgtlxnUA/G9oS93ur9aZ8c8BEpzFmsed1TH5WZNG5IONB8IiW90TQg==", "cpu": [ "arm64" ], @@ -1592,9 +1594,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", - "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.10.0.tgz", + "integrity": "sha512-nIdCX03qFKoR/MwQegQBK+qZoSpO3LESurVAC6s6jazLA1Mpmgzo3Nj3H1vydXp/JM29bkCiuF7tDuToj4+U9Q==", "cpu": [ "x64" ], @@ -1605,9 +1607,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", - "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.10.0.tgz", + "integrity": "sha512-Fz7a+y5sYhYZMQFRkOyCs4PLhICAnxRX/GnWYReaAoruUzuRtcf+Qnw+T0CoAWbHCuz2gBUwmWnUgQ67fb3FYw==", "cpu": [ "arm" ], @@ -1618,9 +1620,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", - "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.10.0.tgz", + "integrity": "sha512-yPtF9jIix88orwfTi0lJiqINnlWo6p93MtZEoaehZnmCzEmLL0eqjA3eGVeyQhMtxdV+Mlsgfwhh0+M/k1/V7Q==", "cpu": [ "arm64" ], @@ -1631,9 +1633,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", - "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.10.0.tgz", + "integrity": "sha512-9GW9yA30ib+vfFiwjX+N7PnjTnCMiUffhWj4vkG4ukYv1kJ4T9gHNg8zw+ChsOccM27G9yXrEtMScf1LaCuoWQ==", "cpu": [ "arm64" ], @@ -1644,9 +1646,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", - "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.10.0.tgz", + "integrity": "sha512-X1ES+V4bMq2ws5fF4zHornxebNxMXye0ZZjUrzOrf7UMx1d6wMQtfcchZ8SqUnQPPHdOyOLW6fTcUiFgHFadRA==", "cpu": [ "riscv64" ], @@ -1657,9 +1659,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", - "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.10.0.tgz", + "integrity": "sha512-w/5OpT2EnI/Xvypw4FIhV34jmNqU5PZjZue2l2Y3ty1Ootm3SqhI+AmfhlUYGBTd9JnpneZCDnt3uNOiOBkMyw==", "cpu": [ "x64" ], @@ -1670,9 +1672,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", - "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.10.0.tgz", + "integrity": "sha512-q/meftEe3QlwQiGYxD9rWwB21DoKQ9Q8wA40of/of6yGHhZuGfZO0c3WYkN9dNlopHlNT3mf5BPsUSxoPuVQaw==", "cpu": [ "x64" ], @@ -1683,9 +1685,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", - "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.10.0.tgz", + "integrity": "sha512-NrR6667wlUfP0BHaEIKgYM/2va+Oj+RjZSASbBMnszM9k+1AmliRjHc3lJIiOehtSSjqYiO7R6KLNrWOX+YNSQ==", "cpu": [ "arm64" ], @@ -1696,9 +1698,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", - "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.10.0.tgz", + "integrity": "sha512-FV0Tpt84LPYDduIDcXvEC7HKtyXxdvhdAOvOeWMWbQNulxViH2O07QXkT/FffX4FqEI02jEbCJbr+YcuKdyyMg==", "cpu": [ "ia32" ], @@ -1709,9 +1711,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", - "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.10.0.tgz", + "integrity": "sha512-OZoJd+o5TaTSQeFFQ6WjFCiltiYVjIdsXxwu/XZ8qRpsvMQr4UsVrE5UyT9RIvsnuF47DqkJKhhVZ2Q9YW9IpQ==", "cpu": [ "x64" ], @@ -1772,9 +1774,9 @@ } }, "node_modules/@smithy/core": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.3.1.tgz", - "integrity": "sha512-tf+NIu9FkOh312b6M9G4D68is4Xr7qptzaZGZUREELF8ysE1yLKphqt7nsomjKZVwW7WE5pDDex9idowNGRQ/Q==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.3.2.tgz", + "integrity": "sha512-tYDmTp0f2TZVE18jAOH1PnmkngLQ+dOGUlMd1u67s87ieueNeyqhja6z/Z4MxhybEiXKOWFOmGjfTZWFxljwJw==", "dependencies": { "@smithy/middleware-endpoint": "^2.4.1", "@smithy/middleware-retry": "^2.1.1", @@ -2245,9 +2247,9 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.1.1.tgz", - "integrity": "sha512-tYVrc+w+jSBfBd267KDnvSGOh4NMz+wVH7v4CClDbkdPfnjvImBZsOURncT5jsFwR9KCuDyPoSZq4Pa6+eCUrA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.2.0.tgz", + "integrity": "sha512-iFJp/N4EtkanFpBUtSrrIbtOIBf69KNuve03ic1afhJ9/korDxdM0c6cCH4Ehj/smI9pDCfVv+bqT3xZjF2WaA==", "dependencies": { "@smithy/config-resolver": "^2.1.1", "@smithy/credential-provider-imds": "^2.2.1", @@ -2416,18 +2418,18 @@ } }, "node_modules/@types/node": { - "version": "18.19.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.14.tgz", - "integrity": "sha512-EnQ4Us2rmOS64nHDWr0XqAD8DsO6f3XR6lf9UIIrZQpUzPVdN/oPuEzfDWNHSyXLvoGgjuEm/sPwFGSSs35Wtg==", + "version": "18.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.15.tgz", + "integrity": "sha512-AMZ2UWx+woHNfM11PyAEQmfSxi05jm9OlkxczuHeEqmvwPkYj6MWv44gbzDPefYOLysTOFyI3ziiy2ONmUZfpA==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", + "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", "dev": true }, "node_modules/@types/showdown": { @@ -2436,6 +2438,12 @@ "integrity": "sha512-pTvD/0CIeqe4x23+YJWlX2gArHa8G0J0Oh6GKaVXV7TAeickpkkZiNOgFcFcmLQ5lB/K0qBJL1FtRYltBfbGCQ==", "dev": true }, + "node_modules/@types/sortablejs": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.7.tgz", + "integrity": "sha512-PvgWCx1Lbgm88FdQ6S7OGvLIjWS66mudKPlfdrWil0TjsO5zmoZmzoKiiwRShs1dwPgrlkr0N4ewuy0/+QUXYQ==", + "dev": true + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -2631,9 +2639,9 @@ } }, "node_modules/@vitejs/plugin-vue": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.3.tgz", - "integrity": "sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz", + "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==", "dev": true, "engines": { "node": "^18.0.0 || >=20.0.0" @@ -2672,12 +2680,12 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz", - "integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", + "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/shared": "3.4.15", + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.19", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" @@ -2689,26 +2697,26 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, "node_modules/@vue/compiler-dom": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz", - "integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", + "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", "dependencies": { - "@vue/compiler-core": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-core": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz", - "integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==", - "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/compiler-core": "3.4.15", - "@vue/compiler-dom": "3.4.15", - "@vue/compiler-ssr": "3.4.15", - "@vue/shared": "3.4.15", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz", + "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==", + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.19", + "@vue/compiler-dom": "3.4.19", + "@vue/compiler-ssr": "3.4.19", + "@vue/shared": "3.4.19", "estree-walker": "^2.0.2", - "magic-string": "^0.30.5", + "magic-string": "^0.30.6", "postcss": "^8.4.33", "source-map-js": "^1.0.2" } @@ -2730,12 +2738,12 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz", - "integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", + "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", "dependencies": { - "@vue/compiler-dom": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-dom": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/devtools-api": { @@ -2831,48 +2839,48 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.15.tgz", - "integrity": "sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz", + "integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==", "dependencies": { - "@vue/shared": "3.4.15" + "@vue/shared": "3.4.19" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.15.tgz", - "integrity": "sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz", + "integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==", "dependencies": { - "@vue/reactivity": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/reactivity": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.15.tgz", - "integrity": "sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz", + "integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==", "dependencies": { - "@vue/runtime-core": "3.4.15", - "@vue/shared": "3.4.15", + "@vue/runtime-core": "3.4.19", + "@vue/shared": "3.4.19", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.15.tgz", - "integrity": "sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz", + "integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==", "dependencies": { - "@vue/compiler-ssr": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-ssr": "3.4.19", + "@vue/shared": "3.4.19" }, "peerDependencies": { - "vue": "3.4.15" + "vue": "3.4.19" } }, "node_modules/@vue/shared": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz", - "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", + "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/@vue/tsconfig": { "version": "0.5.1", @@ -3130,15 +3138,16 @@ } }, "node_modules/call-bind": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz", - "integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { + "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "set-function-length": "^1.2.0" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -3207,16 +3216,10 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -3229,6 +3232,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -3362,18 +3368,21 @@ "dev": true }, "node_modules/define-data-property": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz", - "integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.3.tgz", + "integrity": "sha512-h3GBouC+RPtNX2N0hHVLo2ZwPYurq8mLmXpOLTsw71gr7lHt5VaI4vVkDUNOfiWmm48JEXe3VM7PmLX45AMmmg==", "dev": true, "dependencies": { "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { @@ -3504,6 +3513,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-errors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", @@ -4157,13 +4178,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.1.tgz", - "integrity": "sha512-KmuibvwbWaM4BHcBRYwJfZ1JxyJeBwB8ct9YYu67SvYdbEIlcQ2e56dHxfbobqW38GXo8/zDFqJeGtHiVbWyQw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { "call-bind": "^1.0.5", - "es-errors": "^1.3.0" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -4326,12 +4348,12 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4377,9 +4399,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", "dev": true, "dependencies": { "function-bind": "^1.1.2" @@ -5507,9 +5529,9 @@ } }, "node_modules/postcss": { - "version": "8.4.34", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.34.tgz", - "integrity": "sha512-4eLTO36woPSocqZ1zIrFD2K1v6wH7pY1uBh0JIM2KKfrVtGvPFiAku6aNOP0W1Wr9qwnaCsF0Z+CrVnryB2A8Q==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "funding": [ { "type": "opencollective", @@ -5668,14 +5690,15 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -5744,9 +5767,9 @@ } }, "node_modules/rollup": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", - "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.10.0.tgz", + "integrity": "sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -5759,19 +5782,19 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.6", - "@rollup/rollup-android-arm64": "4.9.6", - "@rollup/rollup-darwin-arm64": "4.9.6", - "@rollup/rollup-darwin-x64": "4.9.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", - "@rollup/rollup-linux-arm64-gnu": "4.9.6", - "@rollup/rollup-linux-arm64-musl": "4.9.6", - "@rollup/rollup-linux-riscv64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-musl": "4.9.6", - "@rollup/rollup-win32-arm64-msvc": "4.9.6", - "@rollup/rollup-win32-ia32-msvc": "4.9.6", - "@rollup/rollup-win32-x64-msvc": "4.9.6", + "@rollup/rollup-android-arm-eabi": "4.10.0", + "@rollup/rollup-android-arm64": "4.10.0", + "@rollup/rollup-darwin-arm64": "4.10.0", + "@rollup/rollup-darwin-x64": "4.10.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.10.0", + "@rollup/rollup-linux-arm64-gnu": "4.10.0", + "@rollup/rollup-linux-arm64-musl": "4.10.0", + "@rollup/rollup-linux-riscv64-gnu": "4.10.0", + "@rollup/rollup-linux-x64-gnu": "4.10.0", + "@rollup/rollup-linux-x64-musl": "4.10.0", + "@rollup/rollup-win32-arm64-msvc": "4.10.0", + "@rollup/rollup-win32-ia32-msvc": "4.10.0", + "@rollup/rollup-win32-x64-msvc": "4.10.0", "fsevents": "~2.3.2" } }, @@ -5866,13 +5889,13 @@ ] }, "node_modules/safe-regex-test": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", - "integrity": "sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, "engines": { @@ -5914,14 +5937,15 @@ } }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.3", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.1" }, @@ -5997,14 +6021,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", + "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6019,6 +6047,11 @@ "node": ">=8" } }, + "node_modules/sortablejs": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz", + "integrity": "sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA==" + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6070,9 +6103,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", - "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, "node_modules/stream-browserify": { @@ -6301,14 +6334,14 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz", + "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -6914,15 +6947,15 @@ } }, "node_modules/vue": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.15.tgz", - "integrity": "sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==", - "dependencies": { - "@vue/compiler-dom": "3.4.15", - "@vue/compiler-sfc": "3.4.15", - "@vue/runtime-dom": "3.4.15", - "@vue/server-renderer": "3.4.15", - "@vue/shared": "3.4.15" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz", + "integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==", + "dependencies": { + "@vue/compiler-dom": "3.4.19", + "@vue/compiler-sfc": "3.4.19", + "@vue/runtime-dom": "3.4.19", + "@vue/server-renderer": "3.4.19", + "@vue/shared": "3.4.19" }, "peerDependencies": { "typescript": "*" diff --git a/package.json b/package.json index ef34c45..0d6de8d 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "pinia": "~2.1.0", "semver": "~7.5.0", "showdown": "~2.1.0", + "sortablejs": "^1.15.2", "vue": "~3.4.0", "vue-router": "~4.2.0", "vue3-cookies": "~1.0.0" @@ -46,6 +47,7 @@ "@types/node": "^18.19.5", "@types/semver": "~7.5.1", "@types/showdown": "~2.0.1", + "@types/sortablejs": "^1.15.7", "@vitejs/plugin-vue": "~5.0.0", "@vue/eslint-config-prettier": "~8.0.0", "@vue/eslint-config-typescript": "~11.0.3", diff --git a/src/App.vue b/src/App.vue index 1ae0d2e..4497959 100644 --- a/src/App.vue +++ b/src/App.vue @@ -87,7 +87,7 @@ onBeforeMount(() => { <template> <NavbarTop /> - <div class="container-xxl mt-4 flex-grow-1"> + <div class="container-xxl mt-4 flex-grow-1 py-2"> <div id="global-toast-container" class="toast-container position-fixed top-toast end-0 p-3" diff --git a/src/components/CopyToClipboardIcon.vue b/src/components/CopyToClipboardIcon.vue index b0d34b4..6e85078 100644 --- a/src/components/CopyToClipboardIcon.vue +++ b/src/components/CopyToClipboardIcon.vue @@ -47,6 +47,7 @@ onMounted(() => { </bootstrap-toast> <button v-if="props.button" @click="copyToClipboard" class="btn btn-primary"> Copy to Clipboard + <font-awesome-icon icon="fa-solid fa-clipboard" class="ms-1" /> </button> <span v-else diff --git a/src/components/DraggableLists.vue b/src/components/DraggableLists.vue new file mode 100644 index 0000000..bb72d1d --- /dev/null +++ b/src/components/DraggableLists.vue @@ -0,0 +1,104 @@ +<script setup lang="ts"> +import { onMounted, ref } from "vue"; +import Sortable from "sortablejs"; + +const leftList = defineModel<string[]>("leftList", { required: true }); +const rightList = defineModel<string[]>("rightList", { required: true }); + +const leftListElement = ref<HTMLUListElement | undefined>(undefined); +const rightListElement = ref<HTMLUListElement | undefined>(undefined); + +onMounted(() => { + if (leftListElement.value && rightListElement.value) { + new Sortable(leftListElement.value, { + group: "shared", + animation: 150, + sort: false, // To disable sorting: set sort to false + onRemove: (evt) => { + leftList.value.splice(evt.oldIndex ?? 0, 1); + }, + onAdd: (evt) => { + leftList.value.splice( + evt.newIndex ?? 0, + 0, + (evt.item as HTMLLIElement).innerText, + ); + }, + }); + + new Sortable(rightListElement.value, { + group: "shared", + animation: 150, + sort: false, // To disable sorting: set sort to false + onRemove: (evt) => { + rightList.value.splice(evt.oldIndex ?? 0, 1); + }, + onAdd: (evt) => { + rightList.value.splice( + evt.newIndex ?? 0, + 0, + (evt.item as HTMLLIElement).innerText, + ); + }, + }); + } +}); +</script> + +<template> + <div class="row"> + <div class="col-6 d-flex flex-column justify-content-start"> + <h5><slot name="leftHeader" /></h5> + <ul + id="items" + class="list-group flex-fill border border-dashed p-1 overflow-y-scroll" + ref="leftListElement" + style="max-height: 40vh" + > + <li + v-for="(left, index) in leftList" + class="list-group-item" + :key="left" + @click=" + rightList.push(left); + leftList.splice(index, 1); + " + > + {{ left }} + </li> + </ul> + </div> + <div class="col-6 d-flex flex-column justify-content-start"> + <h5><slot name="rightHeader" /></h5> + <ul + id="items" + class="list-group flex-fill border border-dashed p-1 overflow-y-scroll" + ref="rightListElement" + style="max-height: 40vh" + > + <li + v-for="(right, index) in rightList" + class="list-group-item" + :key="right" + @click=" + leftList.push(right); + rightList.splice(index, 1); + " + > + {{ right }} + </li> + </ul> + </div> + </div> +</template> + +<style scoped> +li:hover { + cursor: grab; + background: var(--bs-secondary-bg-subtle); +} + +.border-dashed { + border-style: dashed !important; +} +</style> diff --git a/src/components/NavbarTop.vue b/src/components/NavbarTop.vue index 0cb939d..4a85939 100644 --- a/src/components/NavbarTop.vue +++ b/src/components/NavbarTop.vue @@ -189,7 +189,7 @@ watch( <router-link class="dropdown-item" :to="{ name: 'resource-review' }" - >Review + >Reviews </router-link> </li> </ul> diff --git a/src/components/modals/BootstrapModal.vue b/src/components/modals/BootstrapModal.vue index 7f3a55e..cf6664b 100644 --- a/src/components/modals/BootstrapModal.vue +++ b/src/components/modals/BootstrapModal.vue @@ -36,7 +36,7 @@ const modalSizeClass = computed<string>(() => { <div class="modal-title fs-5" :id="modalLabel"> <slot name="header" /> </div> - <div> + <div class="d-flex align-items-center"> <slot name="extra-button" /> <button type="button" diff --git a/src/components/object-storage/modals/BucketDetailModal.vue b/src/components/object-storage/modals/BucketDetailModal.vue index 49eef59..3ceebc6 100644 --- a/src/components/object-storage/modals/BucketDetailModal.vue +++ b/src/components/object-storage/modals/BucketDetailModal.vue @@ -15,6 +15,7 @@ const props = defineProps<{ :modalId="modalID" :static-backdrop="false" modal-label="Bucket Detail Modal" + size-modifier="lg" > <template v-slot:header> <h4> diff --git a/src/components/parameter-schema/ParameterSchemaFormComponent.vue b/src/components/parameter-schema/ParameterSchemaFormComponent.vue index 4a93a52..4048dac 100644 --- a/src/components/parameter-schema/ParameterSchemaFormComponent.vue +++ b/src/components/parameter-schema/ParameterSchemaFormComponent.vue @@ -15,6 +15,7 @@ import type { ClowmInfo } from "@/types/ClowmInfo"; import UploadParameterFileModal from "@/components/parameter-schema/UploadParameterFileModal.vue"; import type { TemporaryParams, + WorkflowMetaParameters, WorkflowParameters, } from "@/types/WorkflowParameters"; import { useWorkflowExecutionStore } from "@/stores/workflowExecutions"; @@ -55,10 +56,7 @@ const emit = defineEmits<{ ( e: "start-workflow", parameters: WorkflowParameters, - notes?: string, - logs_s3_path?: string, - debug_s3_path?: string, - provenance_s3_path?: string, + metaParameters: WorkflowMetaParameters, ): void; }>(); @@ -90,18 +88,17 @@ const launchForm = ref<HTMLFormElement | null>(null); const formState = reactive<{ formInput: WorkflowParameters; validated: boolean; - pipelineNotes: string; - logs_s3_path?: string; - debug_s3_path?: string; - provenance_s3_path?: string; + metaParameters: WorkflowMetaParameters; errorType?: string; }>({ formInput: {}, validated: false, - pipelineNotes: "", - logs_s3_path: undefined, - debug_s3_path: undefined, - provenance_s3_path: undefined, + metaParameters: { + logs_s3_path: undefined, + debug_s3_path: undefined, + provenance_s3_path: undefined, + notes: undefined, + }, errorType: undefined, }); @@ -190,14 +187,7 @@ function startWorkflow() { console.error(validateSchema.errors); errorToast?.show(); } else { - emit( - "start-workflow", - formState.formInput, - formState.pipelineNotes, - formState.logs_s3_path, - formState.debug_s3_path, - formState.provenance_s3_path, - ); + emit("start-workflow", formState.formInput, formState.metaParameters); } } else { formState.errorType = "form"; @@ -212,10 +202,7 @@ function loadParameters(tempParams?: TemporaryParams) { formState.formInput[param] = tempParams.params[param]; } } - formState.pipelineNotes = tempParams.metaParams.notes ?? ""; - formState.logs_s3_path = tempParams.metaParams.logs_s3_path; - formState.provenance_s3_path = tempParams.metaParams.provenance_s3_path; - formState.debug_s3_path = tempParams.metaParams.debug_s3_path; + formState.metaParameters = tempParams.metaParams; if (Object.keys(tempParams?.params ?? {}).length > 0) { parameterLoadToast?.show(); } @@ -232,7 +219,8 @@ function scroll(selectedAnchor: string) { // ============================================================================= onMounted(() => { if (props.schema) updateSchema(props.schema); - if (props.clowmInfo?.exampleParameters) Tooltip.getOrCreateInstance("#exampleDataButton"); + if (props.clowmInfo?.exampleParameters) + Tooltip.getOrCreateInstance("#exampleDataButton"); bucketRepository.fetchBuckets(); bucketRepository.fetchOwnPermissions(); keyRepository.fetchS3Keys(); @@ -271,7 +259,7 @@ onMounted(() => { }) " /> - <div class="row mb-5 align-items-start"> + <div class="row align-items-start"> <form v-if="props.schema" class="col-9" @@ -283,8 +271,7 @@ onMounted(() => { > <template v-for="(group, groupName) in parameterGroups" :key="groupName"> <parameter-group-form - :modelValue="formState.formInput" - @update:model-value="(newValue) => (formState.formInput = newValue)" + v-model="formState.formInput" v-if="formState.formInput" :parameter-group-name="groupName" :parameter-group="group" @@ -317,7 +304,7 @@ onMounted(() => { <textarea class="form-control border border-secondary" rows="2" - v-model="formState.pipelineNotes" + v-model="formState.metaParameters.notes" /> </div> <label class="mb-3" for="pipelineNotes" @@ -335,7 +322,7 @@ onMounted(() => { </span> <parameter-string-input parameter-name="logs_s3_path" - v-model="formState.logs_s3_path" + v-model="formState.metaParameters.logs_s3_path" :parameter="{ format: 'directory-path', type: 'string', @@ -358,7 +345,7 @@ onMounted(() => { </span> <parameter-string-input parameter-name="provenance_s3_path" - v-model="formState.provenance_s3_path" + v-model="formState.metaParameters.provenance_s3_path" :parameter="{ format: 'directory-path', type: 'string', @@ -382,7 +369,7 @@ onMounted(() => { </span> <parameter-string-input parameter-name="debug_s3_path" - v-model="formState.debug_s3_path" + v-model="formState.metaParameters.debug_s3_path" :parameter="{ format: 'directory-path', type: 'string', diff --git a/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue b/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue index a30bd4e..54e519c 100644 --- a/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue +++ b/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue @@ -1,6 +1,8 @@ <script setup lang="ts"> import { computed } from "vue"; +const model = defineModel<boolean | undefined>({ required: true }); + const props = defineProps({ parameter: { type: Object, @@ -14,9 +16,6 @@ const props = defineProps({ type: String, required: true, }, - modelValue: { - type: Boolean, - }, helpId: { type: String, }, @@ -26,10 +25,6 @@ const randomIDSuffix = Math.random().toString(16).substring(2, 8); const helpTextPresent = computed<boolean>(() => props.parameter["help_text"]); const iconPresent = computed<boolean>(() => props.parameter["fa_icon"]); - -const emit = defineEmits<{ - (e: "update:modelValue", value: boolean): void; -}>(); </script> <template> @@ -47,8 +42,7 @@ const emit = defineEmits<{ :name="'inlineRadioOptions' + randomIDSuffix" :id="'trueOption' + randomIDSuffix" :value="true" - :checked="props.modelValue" - @input="emit('update:modelValue', true)" + v-model="model" /> </div> <div class="form-check form-check-inline"> @@ -58,8 +52,7 @@ const emit = defineEmits<{ :name="'inlineRadioOptions' + randomIDSuffix" :id="'falseOption' + randomIDSuffix" :value="false" - @input="emit('update:modelValue', false)" - :checked="!props.modelValue" + v-model="model" /> <label class="form-check-label" :for="'falseOption' + randomIDSuffix" >False</label diff --git a/src/components/parameter-schema/form-mode/ParameterEnumInput.vue b/src/components/parameter-schema/form-mode/ParameterEnumInput.vue index 03ec622..a92092c 100644 --- a/src/components/parameter-schema/form-mode/ParameterEnumInput.vue +++ b/src/components/parameter-schema/form-mode/ParameterEnumInput.vue @@ -1,5 +1,7 @@ <script setup lang="ts"> -import { computed, ref } from "vue"; +import { computed } from "vue"; + +const model = defineModel<string | undefined>({ required: true }); const props = defineProps({ parameter: { @@ -14,41 +16,23 @@ const props = defineProps({ type: String, required: true, }, - modelValue: { - type: String, - }, helpId: { type: String, }, }); const possibleValues = computed<string[]>(() => props.parameter["enum"]); - -const enumSelection = ref<HTMLSelectElement | undefined>(undefined); - -const emit = defineEmits<{ - (e: "update:modelValue", value: string | undefined): void; -}>(); - -function updateValue() { - emit("update:modelValue", enumSelection.value?.value); -} </script> <template> <select ref="enumSelection" - :value="props.modelValue" - @input="updateValue" + v-model="model" class="form-select border border-secondary" :required="required" :aria-describedby="props.helpId" > - <option - v-for="val in possibleValues" - :key="val" - :selected="props.modelValue === val" - > + <option v-for="val in possibleValues" :key="val"> {{ val }} </option> </select> diff --git a/src/components/parameter-schema/form-mode/ParameterGroupForm.vue b/src/components/parameter-schema/form-mode/ParameterGroupForm.vue index be65227..9d4b0f3 100644 --- a/src/components/parameter-schema/form-mode/ParameterGroupForm.vue +++ b/src/components/parameter-schema/form-mode/ParameterGroupForm.vue @@ -1,11 +1,14 @@ <script setup lang="ts"> import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; -import { computed, type PropType, watch } from "vue"; +import { computed, type PropType } from "vue"; import ParameterNumberInput from "@/components/parameter-schema/form-mode/ParameterNumberInput.vue"; import MarkdownRenderer from "@/components/MarkdownRenderer.vue"; import ParameterBooleanInput from "@/components/parameter-schema/form-mode/ParameterBooleanInput.vue"; import ParameterEnumInput from "@/components/parameter-schema/form-mode/ParameterEnumInput.vue"; import ParameterStringInput from "@/components/parameter-schema/form-mode/ParameterStringInput.vue"; +import type { WorkflowParameters } from "@/types/WorkflowParameters"; + +const model = defineModel<WorkflowParameters>({ required: true }); const props = defineProps({ parameterGroup: { @@ -19,10 +22,6 @@ const props = defineProps({ type: String, required: true, }, - modelValue: { - type: Object, - required: true, - }, showHidden: { type: Boolean, default: false, @@ -52,14 +51,6 @@ const parameters = computed<Record<string, never>>( () => props.parameterGroup["properties"], ); -const formInput = computed(() => props.modelValue); -const emit = defineEmits<{ - ( - e: "update:modelValue", - value: Record<string, number | string | boolean | undefined>, - ): void; -}>(); - function parameterRequired( // eslint-disable-next-line @typescript-eslint/no-explicit-any parameterGroup: Record<string, any>, @@ -68,20 +59,10 @@ function parameterRequired( return ( parameterGroup["required"]?.includes(parameterName) || // parameter is required parameterGroup["dependentRequired"]?.[parameterName] // parameter is required when another parameter is set - ?.map((param: string) => formInput.value[param]) + ?.map((param: string) => model.value[param]) ?.reduce((acc: boolean, val: string) => acc || val, false) ); } - -watch( - formInput, - (newVal) => { - emit("update:modelValue", newVal); - }, - { - deep: true, - }, -); </script> <template> @@ -120,50 +101,48 @@ watch( > <font-awesome-icon :icon="parameter['fa_icon']" /> </span> - <parameter-number-input + <template v-if=" parameter['type'] === 'number' || parameter['type'] === 'integer' " - :parameter-name="parameterName" - :parameter="parameter" - :help-id="parameterName + '-help'" - :required="parameterRequired(parameterGroup, parameterName)" - :model-value="formInput[parameterName]" - @update:model-value=" - (newValue) => (formInput[parameterName] = newValue) - " - /> - <parameter-boolean-input - v-else-if="parameter['type'] === 'boolean'" - :parameter-name="parameterName" - :parameter="parameter" - :help-id="parameterName + '-help'" - :model-value="formInput[parameterName]" - @update:model-value=" - (newValue) => (formInput[parameterName] = newValue) - " - /> - <template v-else-if="parameter['type'] === 'string'"> - <parameter-enum-input - v-if="parameter['enum']" + > + <!-- @vue-ignore --> + <parameter-number-input :parameter-name="parameterName" :parameter="parameter" - :model-value="formInput[parameterName]" + :help-id="parameterName + '-help'" :required="parameterRequired(parameterGroup, parameterName)" - @update:model-value=" - (newValue) => (formInput[parameterName] = newValue) - " + v-model="model[parameterName]" /> + </template> + <template v-else-if="parameter['type'] === 'boolean'"> + <!-- @vue-ignore --> + <parameter-boolean-input + :parameter-name="parameterName" + :parameter="parameter" + :help-id="parameterName + '-help'" + v-model="model[parameterName]" + /> + </template> + <template v-else-if="parameter['type'] === 'string'"> + <!-- @vue-ignore --> + <template v-if="parameter['enum']"> + <!-- @vue-ignore --> + <parameter-enum-input + :parameter-name="parameterName" + :parameter="parameter" + :required="parameterRequired(parameterGroup, parameterName)" + v-model="model[parameterName]" + /> + </template> + <!-- @vue-ignore --> <parameter-string-input v-else :parameter-name="parameterName" :parameter="parameter" - :model-value="formInput[parameterName]" :required="parameterRequired(parameterGroup, parameterName)" - @update:model-value=" - (newValue) => (formInput[parameterName] = newValue) - " + v-model="model[parameterName]" :remove-advanced="!showOptional" :clowm-resource="resourceParameters?.includes(parameterName)" /> diff --git a/src/components/parameter-schema/form-mode/ParameterNumberInput.vue b/src/components/parameter-schema/form-mode/ParameterNumberInput.vue index 55963a2..0cc7ca6 100644 --- a/src/components/parameter-schema/form-mode/ParameterNumberInput.vue +++ b/src/components/parameter-schema/form-mode/ParameterNumberInput.vue @@ -1,5 +1,6 @@ <script setup lang="ts"> -import { ref } from "vue"; +const model = defineModel<number | undefined>({ required: true }); + const props = defineProps({ parameter: { type: Object, @@ -13,37 +14,22 @@ const props = defineProps({ type: String, required: true, }, - modelValue: { - type: Number, - }, helpId: { type: String, }, }); - -const emit = defineEmits<{ - (e: "update:modelValue", value: number | undefined): void; -}>(); - -const numberInput = ref<HTMLInputElement | undefined>(undefined); - -function updateValue() { - emit("update:modelValue", Number(numberInput.value?.value)); -} </script> <template> <input class="form-control border border-secondary" type="number" - ref="numberInput" :max="props.parameter['maximum']" :min="props.parameter['minimum']" :step="props.parameter['type'] === 'integer' ? 1 : 0.0001" - :value="props.modelValue" + v-model="model" :required="props.required" :aria-describedby="props.helpId" - @input="updateValue" /> </template> diff --git a/src/components/workflows/WorkflowDocumentationTabs.vue b/src/components/workflows/WorkflowDocumentationTabs.vue index 7ce8afc..7ebecac 100644 --- a/src/components/workflows/WorkflowDocumentationTabs.vue +++ b/src/components/workflows/WorkflowDocumentationTabs.vue @@ -102,7 +102,7 @@ const activeTab = computed<string>( ></span> </p> </div> - <div v-else class="px-2 pt-3 border border-top-0 mb-2"> + <div v-else class="px-2 pt-3 border border-top-0"> <div v-if="activeTab === 'description'"> <markdown-renderer v-if="props.descriptionMarkdown" diff --git a/src/components/workflows/WorkflowWithVersionsCard.vue b/src/components/workflows/WorkflowWithVersionsCard.vue index defb55e..e0a960a 100644 --- a/src/components/workflows/WorkflowWithVersionsCard.vue +++ b/src/components/workflows/WorkflowWithVersionsCard.vue @@ -125,27 +125,7 @@ onMounted(() => { /> <span>{{ props.workflow.name }}</span> </div> - <div> - <button - type="button" - class="btn btn-outline-info me-2" - @click="emit('workflow-update-credentials-click', props.workflow)" - :class="{ disabled: props.loading }" - data-bs-toggle="modal" - data-bs-target="#updateWorkflowCredentialsModal" - > - <font-awesome-icon icon="fa-solid fa-key" /> - </button> - <button - type="button" - class="btn btn-outline-danger me-2" - @click="emit('workflow-delete-click', props.workflow)" - :class="{ disabled: props.loading }" - data-bs-toggle="modal" - data-bs-target="#deleteWorkflowModal" - > - <font-awesome-icon icon="fa-solid fa-trash" /> - </button> + <div class="btn-group"> <button type="button" class="btn btn-success" @@ -156,6 +136,56 @@ onMounted(() => { > Update </button> + <button + type="button" + class="btn btn-success dropdown-toggle dropdown-toggle-split" + data-bs-toggle="dropdown" + aria-expanded="false" + > + <span class="visually-hidden">Toggle Dropdown</span> + </button> + <ul class="dropdown-menu z-3"> + <li> + <a + class="dropdown-item" + href="#" + @click.prevent=" + emit('workflow-update-credentials-click', props.workflow) + " + :class="{ disabled: props.loading }" + data-bs-toggle="modal" + data-bs-target="#updateWorkflowCredentialsModal" + >Update Credentials</a + > + </li> + <li> + <router-link + :to="{ + name: 'workflows-clowminfo', + query: { + workflow_id: workflow.workflow_id, + workflow_version_id: sortedVersions( + props.workflow.versions, + )[0]?.workflow_version_id, + }, + }" + class="btn btn-primary dropdown-item" + >Add Metadata + </router-link> + </li> + <li> + <a + class="dropdown-item text-danger" + href="#" + @click.prevent="emit('workflow-delete-click', props.workflow)" + :class="{ disabled: props.loading }" + data-bs-toggle="modal" + data-bs-target="#deleteWorkflowModal" + >Delete + <font-awesome-icon icon="fa-solid fa-trash" class="ms-2" /> + </a> + </li> + </ul> </div> </div> <p class="card-text" :class="{ 'text-truncate': truncateDescription }"> @@ -331,7 +361,6 @@ onMounted(() => { } .card-hover:hover { - transform: translate(0, -5px); box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; } diff --git a/src/components/workflows/modals/ParameterModal.vue b/src/components/workflows/modals/ParameterModal.vue index 31c33ca..5ae588a 100644 --- a/src/components/workflows/modals/ParameterModal.vue +++ b/src/components/workflows/modals/ParameterModal.vue @@ -9,6 +9,7 @@ import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; import type { WorkflowExecutionOut, WorkflowVersion } from "@/client/workflow"; import { useNameStore } from "@/stores/names"; import { useWorkflowStore } from "@/stores/workflows"; +import { createDownloadUrl } from "@/utils/DownloadJson"; import type { WorkflowParameters } from "@/types/WorkflowParameters"; const nameRepository = useNameStore(); @@ -80,10 +81,10 @@ const parameterDownloadUrl = computed<string | undefined>(() => { if (parameters.value == undefined) { return undefined; } - const blob = new Blob([JSON.stringify(parameters.value, undefined, 2)], { - type: "application/json", - }); - return URL.createObjectURL(blob); + return createDownloadUrl( + JSON.stringify(parameters.value, null, 2), + "application/json", + ); }); const workflowName = computed<string>(() => { diff --git a/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue b/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue index 5da2ca9..43f6a61 100644 --- a/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue +++ b/src/components/workflows/modals/UpdateWorkflowCredentialsModal.vue @@ -139,6 +139,7 @@ onMounted(() => { :modalId="modalID" :static-backdrop="true" modal-label="Update Workflow Version Icon Modal" + size-modifier="lg" v-on="{ 'hidden.bs.modal': modalClosed }" > <template #header> @@ -147,7 +148,7 @@ onMounted(() => { </template> <template #extra-button v-if="props.workflow.private"> <button - class="btn delete-icon" + class="btn delete-icon px-1" data-bs-toggle="modal" :data-bs-target="'#delete-credentials-modal' + randomIDSuffix" > diff --git a/src/components/workflows/modals/UpdateWorkflowModal.vue b/src/components/workflows/modals/UpdateWorkflowModal.vue index f151066..e47ea0c 100644 --- a/src/components/workflows/modals/UpdateWorkflowModal.vue +++ b/src/components/workflows/modals/UpdateWorkflowModal.vue @@ -316,6 +316,7 @@ onMounted(() => { :static-backdrop="true" modal-label="Update Workflow Modal" v-on="{ 'hidden.bs.modal': modalClosed }" + size-modifier="lg" > <template #header> Update Workflow diff --git a/src/router/workflowRoutes.ts b/src/router/workflowRoutes.ts index f4d076c..4441fcb 100644 --- a/src/router/workflowRoutes.ts +++ b/src/router/workflowRoutes.ts @@ -20,6 +20,18 @@ export const workflowRoutes: RouteRecordRaw[] = [ requiresDeveloperRole: true, }, }, + { + path: "developer/workflows/clowminfo", + name: "workflows-clowminfo", + component: () => import("../views/workflows/CreateClowmInfoView.vue"), + props: (route) => ({ + workflow_version_id: route.query.workflow_version_id ?? undefined, + workflow_id: route.query.workflow_id ?? undefined, + }), + meta: { + requiresDeveloperRole: true, + }, + }, { path: "reviewer/workflows", name: "workflows-reviewer", diff --git a/src/utils/DownloadJson.ts b/src/utils/DownloadJson.ts new file mode 100644 index 0000000..9ad1f78 --- /dev/null +++ b/src/utils/DownloadJson.ts @@ -0,0 +1,6 @@ +export function createDownloadUrl(content: string, mimeType?: string): string { + const blob = new Blob([content], { + type: mimeType, + }); + return URL.createObjectURL(blob); +} diff --git a/src/views/admin/AdminResourcesView.vue b/src/views/admin/AdminResourcesView.vue index 095336b..9528652 100644 --- a/src/views/admin/AdminResourcesView.vue +++ b/src/views/admin/AdminResourcesView.vue @@ -147,7 +147,7 @@ function resetForm() { :resource="resourceState.inspectResource" /> <div - class="row m-2 border-bottom mb-4 justify-content-between align-items-center" + class="row border-bottom mb-4 justify-content-between align-items-center" > <h2>Manage Resources</h2> </div> diff --git a/src/views/admin/AdminUsersView.vue b/src/views/admin/AdminUsersView.vue index a1f3e14..58eeccc 100644 --- a/src/views/admin/AdminUsersView.vue +++ b/src/views/admin/AdminUsersView.vue @@ -43,7 +43,7 @@ function searchUsers() { <template> <div - class="row m-2 border-bottom mb-4 justify-content-between align-items-center" + class="row border-bottom mb-4 justify-content-between align-items-center" > <h2>Manage Users</h2> </div> diff --git a/src/views/object-storage/BucketsView.vue b/src/views/object-storage/BucketsView.vue index b19d7d8..1797014 100644 --- a/src/views/object-storage/BucketsView.vue +++ b/src/views/object-storage/BucketsView.vue @@ -92,11 +92,10 @@ onMounted(() => { modalID="create-bucket-modal" v-if="!authStore.foreignUser" /> - <div class="row m-2 border-bottom"> - <div class="col-12"></div> + <div class="row border-bottom"> <h2 class="mb-2">My Data Buckets</h2> </div> - <div class="row m-2 mt-4"> + <div class="row mt-4"> <div class="col-3"> <div class="d-flex justify-content-between"> <button diff --git a/src/views/object-storage/S3KeysView.vue b/src/views/object-storage/S3KeysView.vue index 8fce1fe..018415a 100644 --- a/src/views/object-storage/S3KeysView.vue +++ b/src/views/object-storage/S3KeysView.vue @@ -80,11 +80,11 @@ onMounted(() => { <bootstrap-toast toast-id="successKeyToast"> Successfully deleted S3 Key {{ keyState.deletedKey }} </bootstrap-toast> - <div class="row m-2 border-bottom mt-4"> + <div class="row border-bottom mt-4"> <div class="col-12"></div> <h2 class="mb-2">S3 Keys</h2> </div> - <div class="row m-2 mt-4"> + <div class="row mt-4"> <div class="col-4"> <div class="d-flex justify-content-between mb-4"> <button diff --git a/src/views/resources/ListResourcesView.vue b/src/views/resources/ListResourcesView.vue index b615344..5787adc 100644 --- a/src/views/resources/ListResourcesView.vue +++ b/src/views/resources/ListResourcesView.vue @@ -53,7 +53,7 @@ onMounted(() => { </script> <template> - <div class="row m-2 border-bottom mb-4"> + <div class="row border-bottom mb-4"> <h2 class="mb-2">Available Resources</h2> </div> <div class="d-flex m-2 mb-3 align-items-center justify-content-start"> diff --git a/src/views/resources/MyResourcesView.vue b/src/views/resources/MyResourcesView.vue index e9a3d23..5b2b365 100644 --- a/src/views/resources/MyResourcesView.vue +++ b/src/views/resources/MyResourcesView.vue @@ -62,7 +62,7 @@ onMounted(() => { modal-id="updateResourceModal" /> <div - class="row m-2 border-bottom mb-4 justify-content-between align-items-center pb-2" + class="row border-bottom mb-4 justify-content-between align-items-center pb-2" > <h2 class="w-fit">My Resources</h2> <div class="w-fit"> diff --git a/src/views/resources/ReviewResourceView.vue b/src/views/resources/ReviewResourceView.vue index 78f6785..e682c79 100644 --- a/src/views/resources/ReviewResourceView.vue +++ b/src/views/resources/ReviewResourceView.vue @@ -75,7 +75,7 @@ onMounted(() => { :resource="resourceState.inspectResource" /> <div - class="row m-2 border-bottom mb-4 justify-content-between align-items-center" + class="row border-bottom mb-4 justify-content-between align-items-center" > <h2 class="w-fit">Resource Requests</h2> <span diff --git a/src/views/workflows/ArbitraryWorkflowView.vue b/src/views/workflows/ArbitraryWorkflowView.vue index a32fd64..ff7589e 100644 --- a/src/views/workflows/ArbitraryWorkflowView.vue +++ b/src/views/workflows/ArbitraryWorkflowView.vue @@ -11,7 +11,10 @@ import type { WorkflowIn } from "@/client/workflow"; import { useWorkflowExecutionStore } from "@/stores/workflowExecutions"; import ParameterSchemaFormComponent from "@/components/parameter-schema/ParameterSchemaFormComponent.vue"; import BootstrapToast from "@/components/BootstrapToast.vue"; -import type { WorkflowParameters } from "@/types/WorkflowParameters"; +import type { + WorkflowMetaParameters, + WorkflowParameters, +} from "@/types/WorkflowParameters"; const props = defineProps<{ wid: string; @@ -94,10 +97,7 @@ watch( function startWorkflow( parameters: WorkflowParameters, - notes?: string, - logs_s3_path?: string, - debug_s3_path?: string, - provenance_s3_path?: string, + metaParameters: WorkflowMetaParameters, ) { if (workflowState.workflow) { errorToast?.hide(); @@ -106,9 +106,9 @@ function startWorkflow( .startDevExecution({ git_commit_hash: workflowState.workflow.git_commit_hash, parameters: parameters, - logs_s3_path: logs_s3_path ? logs_s3_path : undefined, - debug_s3_path: debug_s3_path ? debug_s3_path : undefined, - provenance_s3_path: provenance_s3_path ? provenance_s3_path : undefined, + logs_s3_path: metaParameters.logs_s3_path, + debug_s3_path: metaParameters.debug_s3_path, + provenance_s3_path: metaParameters.provenance_s3_path, repository_url: workflowState.workflow.repository_url, token: workflowState.workflow.token ?? undefined, mode: diff --git a/src/views/workflows/CreateClowmInfoView.vue b/src/views/workflows/CreateClowmInfoView.vue new file mode 100644 index 0000000..8137d54 --- /dev/null +++ b/src/views/workflows/CreateClowmInfoView.vue @@ -0,0 +1,565 @@ +<script setup lang="ts"> +import CopyToClipboardIcon from "@/components/CopyToClipboardIcon.vue"; +import { computed, onMounted, reactive, watch } from "vue"; +import { createDownloadUrl } from "@/utils/DownloadJson"; +import type { ClowmInfo } from "@/types/ClowmInfo"; +import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue"; +import { useWorkflowStore } from "@/stores/workflows"; +import { DocumentationEnum } from "@/client/workflow"; +import DraggableLists from "@/components/DraggableLists.vue"; + +const props = defineProps<{ + workflow_id?: string; + workflow_version_id?: string; +}>(); + +const workflowRepository = useWorkflowStore(); + +const infoState = reactive<ClowmInfo>({ + inputParameters: [], + outputParameters: [], + exampleParameters: undefined, + dois: undefined, + resourceParameters: undefined, +}); + +const parameterPools = reactive<{ + input: string[]; + output: string[]; + resources: string[]; + examples: string[]; +}>({ + examples: [], + input: [], + output: [], + resources: [], +}); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const parameterSchema = computed<Record<string, Record<string, any>>>(() => { + const schema = + workflowRepository.documentationFiles[props.workflow_version_id ?? ""] + ?.parameter_schema; + const a = schema?.["properties"] ?? {}; + for (const group in schema?.["definitions"] ?? {}) { + for (const param in schema?.["definitions"]?.[group]?.["properties"] ?? + {}) { + a[param] = schema["definitions"][group]["properties"][param]; + } + } + return a; +}); + +function getParameterType(param: string): string | undefined { + return parameterSchema.value[param]?.["type"]; +} + +const infoStateString = computed<string>(() => + JSON.stringify(infoState, null, 2), +); +const downloadUrl = computed<string>(() => + createDownloadUrl(infoStateString.value, "application/json"), +); + +watch( + () => workflowRepository.documentationFiles[props.workflow_version_id ?? ""], + (newVal, old) => { + if (newVal != old && newVal?.parameter_schema != undefined) { + updateParameterPools(newVal); + } + }, + { + deep: true, + }, +); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function updateParameterPools(newVal?: Record<DocumentationEnum, any>) { + if (newVal?.parameter_schema) { + const parameters = extractParameterList(newVal.parameter_schema); + parameterPools.input = parameters.slice(); + parameterPools.output = parameters.slice(); + parameterPools.resources = parameters.slice(); + parameterPools.examples = parameters.slice(); + infoState.inputParameters = []; + infoState.outputParameters = []; + infoState.exampleParameters = undefined; + infoState.resourceParameters = undefined; + } + if (newVal?.clowm_info && Object.keys(newVal.clowm_info).length > 0) { + Object.assign(infoState, JSON.parse(JSON.stringify(newVal.clowm_info))); + parameterPools.input = parameterPools.input.filter( + (param) => !infoState.inputParameters.includes(param), + ); + parameterPools.resources = parameterPools.resources?.filter( + (param) => !infoState.resourceParameters?.includes(param), + ); + parameterPools.output = parameterPools.output.filter( + (param) => !infoState.outputParameters.includes(param), + ); + parameterPools.examples = parameterPools.examples?.filter( + (param) => + !Object.keys(infoState.exampleParameters ?? {}).includes(param), + ); + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function extractParameterList(schema: Record<string, any>): string[] { + const groupedParameters = Object.keys(schema["definitions"] ?? {}).reduce( + (acc: string[], val) => [ + ...acc, + ...Object.keys(schema["definitions"][val]["properties"]), + ], + [], + ); + const singleParameters = Object.keys(schema["properties"] ?? {}); + return [...groupedParameters, ...singleParameters]; +} + +function addDoi() { + if (infoState.dois == undefined) { + infoState.dois = [""]; + } else { + infoState.dois.push(""); + } +} + +function removeDoi(index: number) { + if (infoState.dois?.length === 1) { + infoState.dois = undefined; + } + infoState.dois?.splice(index, 1); +} + +function addExampleParameter(param: string, index: number) { + if (infoState.exampleParameters == undefined) { + infoState.exampleParameters = {}; + } + parameterPools.examples.splice(index, 1); + switch (getParameterType(param)) { + case "integer": { + infoState.exampleParameters[param] = 0; + break; + } + case "number": { + infoState.exampleParameters[param] = 0; + break; + } + case "boolean": { + infoState.exampleParameters[param] = true; + break; + } + case "string": { + infoState.exampleParameters[param] = + parameterSchema.value[param]?.["enum"]?.[0] ?? ""; + break; + } + default: { + infoState.exampleParameters[param] = ""; + break; + } + } +} + +function deleteExampleParameter(param: string) { + delete infoState.exampleParameters?.[param]; + parameterPools.examples.push(param); + if (Object.keys(infoState.exampleParameters ?? {}).length === 0) { + infoState.exampleParameters = undefined; + } +} + +onMounted(() => { + if (props.workflow_id && props.workflow_version_id) { + Promise.all([ + workflowRepository.fetchWorkflowDocumentation( + props.workflow_id, + props.workflow_version_id, + DocumentationEnum.PARAMETER_SCHEMA, + ), + workflowRepository.fetchWorkflowDocumentation( + props.workflow_id, + props.workflow_version_id, + DocumentationEnum.CLOWM_INFO, + ), + ]).finally(() => { + updateParameterPools( + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + workflowRepository.documentationFiles[props.workflow_version_id!], + ); + }); + } +}); +</script> + +<template> + <div class="row border-bottom mb-4"> + <h2 class="mb-2">Enhance your Workflow</h2> + </div> + <div> + Enhance your Workflow with CloWM: + <ul> + <li> + Maximize the potential of your workflow within CloWM by incorporating a + <code>clowm_info.json</code> file directly into your repository's root + directory. This simple addition empowers you to provide comprehensive + details about your workflow's parameters and overall structure, + enhancing its usability and user experience. + </li> + <li> + Customize Parameters: Infuse semantic meaning into various parameters, + enriching the understanding and functionality of your workflow. + </li> + <li> + Publication Linking: Seamlessly integrate a DOI link to your + publication, facilitating easy access to additional resources and + information. + </li> + <li> + Experience Enhanced Workflow: Elevate your workflow's presentation on + the CloWM platform by ensuring essential information is readily + available to users. + </li> + </ul> + </div> + <p> + Unlock the full potential of your workflow in CloWM by exploring the tabs + below for guidance on creating and implementing the + <code>clowm_info.json</code> file. + </p> + <div class="accordion mb-4" id="clowmInfoAccordion"> + <div class="accordion-item"> + <h2 class="accordion-header"> + <button + class="accordion-button" + type="button" + data-bs-toggle="collapse" + data-bs-target="#clowmInfoAccordion-input" + aria-expanded="true" + aria-controls="clowmInfoAccordion-input" + > + Input Parameters + </button> + </h2> + <div + id="clowmInfoAccordion-input" + class="accordion-collapse collapse show" + data-bs-parent="#clowmInfoAccordion" + > + <div class="accordion-body"> + <p> + <b>Designate Parameters as Input Files</b>: Assign semantic meaning + to parameters by dragging them from the left side to the right side + to designate them as input files. + </p> + <draggable-lists + :left-list="parameterPools.input" + :right-list="infoState.inputParameters" + > + <template #leftHeader>Workflow Parameters</template> + <template #rightHeader>Input Parameters</template> + </draggable-lists> + </div> + </div> + </div> + <div class="accordion-item"> + <h2 class="accordion-header"> + <button + class="accordion-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#clowmInfoAccordion-output" + aria-expanded="false" + aria-controls="clowmInfoAccordion-output" + > + Output Parameters + </button> + </h2> + <div + id="clowmInfoAccordion-output" + class="accordion-collapse collapse" + data-bs-parent="#clowmInfoAccordion" + > + <div class="accordion-body"> + <p> + <b>Designate Parameters as Output</b>: Assign semantic meaning to + parameters by dragging them from the left side to the right side to + designate them as output files. + </p> + <draggable-lists + :left-list="parameterPools.output" + :right-list="infoState.outputParameters" + > + <template #leftHeader>Workflow Parameters</template> + <template #rightHeader>Output Parameters</template> + </draggable-lists> + </div> + </div> + </div> + <div class="accordion-item"> + <h2 class="accordion-header"> + <button + class="accordion-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#clowmInfoAccordion-resource" + aria-expanded="false" + aria-controls="clowmInfoAccordion-resource" + > + Resource Parameters + </button> + </h2> + <div + id="clowmInfoAccordion-resource" + class="accordion-collapse collapse" + data-bs-parent="#clowmInfoAccordion" + > + <div class="accordion-body"> + <p> + <b>Designate Parameters as Resources</b>: Drag parameters from the + left side to the right side to imbue them with semantic meaning as + resource parameters. CloWM automatically generates a specialized + form input for users to configure these parameters. + </p> + <button + v-if="infoState.resourceParameters == undefined" + type="button" + class="btn btn-primary" + @click="infoState.resourceParameters = []" + > + This workflow needs resources + </button> + <draggable-lists + :left-list="parameterPools.resources" + :right-list="infoState.resourceParameters" + v-else + > + <template #leftHeader>Workflow Parameters</template> + <template #rightHeader>Resources Parameters</template> + </draggable-lists> + </div> + </div> + </div> + <div class="accordion-item"> + <h2 class="accordion-header"> + <button + class="accordion-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#clowmInfoAccordion-example" + aria-expanded="false" + aria-controls="clowmInfoAccordion-example" + > + Example Parameters + </button> + </h2> + <div + id="clowmInfoAccordion-example" + class="accordion-collapse collapse" + data-bs-parent="#clowmInfoAccordion" + > + <div class="accordion-body"> + <p> + <b>Enhance Workflow Testing</b>: Incorporate example parameters + using publicly available test data. Easily achieve this by including + a sample dataset in your Git repository and linking its URL as the + input parameter. + </p> + <p> + <b>Guidance on Parameter Setting</b>: Avoid specifying parameters + that define output locations or resource paths, as these are heavily + dependent on the user or execution environment. + </p> + <div + class="d-flex flex-wrap overflow-y-scroll p-1 border rounded border-dashed mb-2" + style="max-height: 30vh" + > + <div + class="w-fit border px-2 rounded cursor-pointer m-1 parameter-container" + v-for="(param, index) in parameterPools.examples" + :key="param" + @click="addExampleParameter(param, index)" + > + {{ param }} + </div> + </div> + <table class="table table-bordered"> + <thead> + <tr> + <th scope="col"><b>Parameter</b></th> + <th scope="col"><b>Value</b></th> + </tr> + </thead> + <tbody v-if="infoState.exampleParameters"> + <tr + v-for="param in Object.keys(infoState.exampleParameters)" + :key="param" + > + <td style="width: 10%">{{ param }}</td> + <td class="d-flex justify-content-between align-items-center"> + <input + v-if=" + getParameterType(param) === 'number' || + getParameterType(param) === 'integer' + " + type="number" + class="form-control form-control-sm flex-grow" + v-model="infoState.exampleParameters[param]" + :step="getParameterType(param) === 'integer' ? 1 : 0.0001" + :min="parameterSchema[param]['minimum']" + :max="parameterSchema[param]['maximum']" + /> + <div + v-else-if="getParameterType(param) === 'boolean'" + class="flex-grow" + > + <div class="form-check form-check-inline"> + <label + class="form-check-label" + :for="'trueOption' + param.replace(/\./g, '')" + >True</label + > + <input + class="form-check-input" + type="radio" + :name="'inlineRadioOptions' + param.replace(/\./g, '')" + :id="'trueOption' + param.replace(/\./g, '')" + :value="true" + v-model="infoState.exampleParameters[param]" + /> + </div> + <div class="form-check form-check-inline"> + <input + class="form-check-input" + type="radio" + :name="'inlineRadioOptions' + param.replace(/\./g, '')" + :id="'falseOption' + param.replace(/\./g, '')" + :value="false" + v-model="infoState.exampleParameters[param]" + /> + <label + class="form-check-label" + :for="'falseOption' + param.replace(/\./g, '')" + >False</label + > + </div> + </div> + <select + v-else-if="parameterSchema[param]?.['enum']" + class="form-select form-select-sm flex-grow" + v-model="infoState.exampleParameters[param]" + > + <option + v-for="option in parameterSchema[param]?.['enum']" + :key="option" + :value="option" + > + {{ option }} + </option> + </select> + <input + v-else + type="text" + class="form-control form-control-sm flex-grow" + v-model="infoState.exampleParameters[param]" + :pattern="parameterSchema[param]?.['pattern']" + /> + <button + type="button" + class="btn btn-outline-danger btn-sm ms-2" + @click="deleteExampleParameter(param)" + > + Remove + </button> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + <div class="accordion-item"> + <h2 class="accordion-header"> + <button + class="accordion-button collapsed" + type="button" + data-bs-toggle="collapse" + data-bs-target="#clowmInfoAccordion-dois" + aria-expanded="false" + aria-controls="clowmInfoAccordion-dois" + > + DOIs + </button> + </h2> + <div + id="clowmInfoAccordion-dois" + class="accordion-collapse collapse" + data-bs-parent="#clowmInfoAccordion" + > + <div class="accordion-body"> + <p> + <b>Share Publications Easily</b>: Include the DOI for your + workflow's related publications and watch as the generated links + seamlessly appear on your workflow's dedicated page. + </p> + <button type="button" class="btn btn-primary" @click="addDoi"> + Add DOI + </button> + <div v-if="infoState.dois"> + <div + class="d-flex my-2" + v-for="(doi, index) in infoState.dois" + :key="index" + > + <button + type="button" + class="btn btn-outline-danger btn-sm" + @click="removeDoi(index)" + > + Remove + </button> + <input + type="text" + class="form-control mx-2" + v-model="infoState.dois[index]" + maxlength="48" + style="max-width: 400px" + /> + <div class="align-self-center"> + DOI Link: + <a + :href="'https://doi.org/' + doi" + target="_blank" + class="align-self-center" + >https://doi.org/{{ doi }} + <font-awesome-icon + icon="fa-solid fa-arrow-up-right-from-square" + class="ms-1" + /> + </a> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <h5>Generated <code>clowm_info.json</code></h5> + <pre class="rounded w-100"><code>{{ infoState }}</code></pre> + <p> + Add this file to your Git repository, commit and push your changes and + register the new workflow version in CloWM + </p> + <copy-to-clipboard-icon button :text="infoStateString" /> + <a class="btn btn-primary ms-2" :href="downloadUrl" download="clowm_info.json" + >Download to file + <font-awesome-icon icon="fa-solid fa-download" class="ms-1" /> + </a> +</template> + +<style scoped> +.parameter-container:hover { + background: var(--bs-secondary-bg-subtle); +} +</style> diff --git a/src/views/workflows/ListWorkflowExecutionsView.vue b/src/views/workflows/ListWorkflowExecutionsView.vue index c3d87aa..5b96f03 100644 --- a/src/views/workflows/ListWorkflowExecutionsView.vue +++ b/src/views/workflows/ListWorkflowExecutionsView.vue @@ -165,7 +165,7 @@ onUnmounted(() => { :execution-id="executionsState.executionParameters" /> <div - class="row m-2 border-bottom mb-4 justify-content-between align-items-center" + class="row border-bottom mb-4 justify-content-between align-items-center" > <h2 class="mb-2 w-fit">My Workflow Executions</h2> <div class="w-fit"> diff --git a/src/views/workflows/ListWorkflowsView.vue b/src/views/workflows/ListWorkflowsView.vue index 56ccb5a..4c54cf1 100644 --- a/src/views/workflows/ListWorkflowsView.vue +++ b/src/views/workflows/ListWorkflowsView.vue @@ -51,15 +51,15 @@ function filterWorkflowWithoutVersion(workflow: WorkflowOut): boolean { } const processedWorkflows = computed<WorkflowOut[]>(() => { - return [ - ...workflowRepository.workflows.filter( - (workflow) => - filterWorkflowByString(workflow) && - filterWorkflowWithoutVersion(workflow), - ), - ].sort((a, b) => + const temp = workflowRepository.workflows.filter( + (workflow) => + filterWorkflowByString(workflow) && + filterWorkflowWithoutVersion(workflow), + ); + temp.sort((a, b) => filterFunctionMapping[workflowsState.sortByAttribute](a, b) ? 1 : -1, ); + return temp; }); onMounted(() => { diff --git a/src/views/workflows/MyWorkflowsView.vue b/src/views/workflows/MyWorkflowsView.vue index 48d1c28..8b5b935 100644 --- a/src/views/workflows/MyWorkflowsView.vue +++ b/src/views/workflows/MyWorkflowsView.vue @@ -114,7 +114,7 @@ onMounted(() => { modal-i-d="updateWorkflowCredentialsModal" /> <div - class="row m-2 border-bottom mb-4 justify-content-between align-items-center pb-2" + class="row border-bottom mb-4 justify-content-between align-items-center pb-2" > <h2 class="w-fit">My Workflows</h2> <button diff --git a/src/views/workflows/ReviewWorkflowsView.vue b/src/views/workflows/ReviewWorkflowsView.vue index 8507574..ad15851 100644 --- a/src/views/workflows/ReviewWorkflowsView.vue +++ b/src/views/workflows/ReviewWorkflowsView.vue @@ -63,7 +63,7 @@ onMounted(() => { </script> <template> - <div class="row m-2 border-bottom mb-4"> + <div class="row border-bottom mb-4"> <h2 class="mb-2">Workflow Reviews</h2> </div> <div v-if="workflowsState.loading" class="text-center mt-5"> diff --git a/src/views/workflows/StartWorkflowView.vue b/src/views/workflows/StartWorkflowView.vue index df2f89e..e6fde26 100644 --- a/src/views/workflows/StartWorkflowView.vue +++ b/src/views/workflows/StartWorkflowView.vue @@ -8,7 +8,10 @@ import { Toast } from "bootstrap"; import { useWorkflowExecutionStore } from "@/stores/workflowExecutions"; import BootstrapToast from "@/components/BootstrapToast.vue"; import { useWorkflowStore } from "@/stores/workflows"; -import type { WorkflowParameters } from "@/types/WorkflowParameters"; +import type { + WorkflowMetaParameters, + WorkflowParameters, +} from "@/types/WorkflowParameters"; const executionRepository = useWorkflowExecutionStore(); const workflowRepository = useWorkflowStore(); @@ -69,10 +72,7 @@ function downloadParameterSchema() { function startWorkflow( parameters: WorkflowParameters, - notes?: string, - logs_s3_path?: string, - debug_s3_path?: string, - provenance_s3_path?: string, + metaParameters: WorkflowMetaParameters, ) { if (props.versionId) { versionState.workflowExecutionError = undefined; @@ -81,12 +81,10 @@ function startWorkflow( .startExecution({ workflow_version_id: props.versionId, parameters: parameters, - notes: notes, - logs_s3_path: logs_s3_path?.length ?? 0 > 0 ? logs_s3_path : undefined, - debug_s3_path: - debug_s3_path?.length ?? 0 > 0 ? debug_s3_path : undefined, - provenance_s3_path: - provenance_s3_path?.length ?? 0 > 0 ? provenance_s3_path : undefined, + notes: metaParameters.notes, + logs_s3_path: metaParameters.logs_s3_path, + debug_s3_path: metaParameters.debug_s3_path, + provenance_s3_path: metaParameters.provenance_s3_path, mode_id: props.workflowModeId, }) .then(() => { -- GitLab