diff --git a/src/Umbraco.Web.UI.Client/.github/localization_overview.md b/src/Umbraco.Web.UI.Client/.github/localization_overview.md index 3277e268fa..f69d559fcd 100644 --- a/src/Umbraco.Web.UI.Client/.github/localization_overview.md +++ b/src/Umbraco.Web.UI.Client/.github/localization_overview.md @@ -75,7 +75,7 @@ Before you start: - [ ] Section: Info - [ ] Relation Types - [ ] Log Viewer -- [ ] Document Blueprints +- [x] Document Blueprints - [ ] Languages - [ ] Extensions - [ ] Templates diff --git a/src/Umbraco.Web.UI.Client/eslint.config.js b/src/Umbraco.Web.UI.Client/eslint.config.js index 6206318d6e..498884d147 100644 --- a/src/Umbraco.Web.UI.Client/eslint.config.js +++ b/src/Umbraco.Web.UI.Client/eslint.config.js @@ -55,6 +55,8 @@ export default [ 'import/order': ['warn', { groups: ['builtin', 'parent', 'sibling', 'index', 'external'] }], 'import/no-self-import': 'error', 'import/no-cycle': ['error', { maxDepth: 6, allowUnsafeDynamicCyclicDependency: true }], + 'import/no-named-as-default': 'off', // Does not work with eslint 9 + 'import/no-named-as-default-member': 'off', // Does not work with eslint 9 'local-rules/prefer-static-styles-last': 'warn', 'local-rules/enforce-umbraco-external-imports': [ 'error', diff --git a/src/Umbraco.Web.UI.Client/index.html b/src/Umbraco.Web.UI.Client/index.html index 94d6a2ed4d..b92c54f0d6 100644 --- a/src/Umbraco.Web.UI.Client/index.html +++ b/src/Umbraco.Web.UI.Client/index.html @@ -7,7 +7,6 @@ Umbraco - diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 277cef9094..5a1f3cde7f 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -11,6 +11,7 @@ "license": "MIT", "workspaces": [ "./src/packages/block", + "./src/packages/code-editor", "./src/packages/core", "./src/packages/data-type", "./src/packages/dictionary", @@ -29,32 +30,32 @@ "dependencies": { "@types/diff": "^5.2.1", "@types/dompurify": "^3.0.5", - "@types/uuid": "^9.0.8", - "@umbraco-ui/uui": "1.8.2", - "@umbraco-ui/uui-css": "1.8.0", + "@types/uuid": "^10.0.0", + "@umbraco-ui/uui": "1.9.0-rc.2", + "@umbraco-ui/uui-css": "1.9.0-rc.0", "base64-js": "^1.5.1", "diff": "^5.2.0", - "dompurify": "^3.1.4", + "dompurify": "^3.1.6", "element-internals-polyfill": "^1.3.11", - "lit": "^3.1.3", - "marked": "^12.0.2", - "monaco-editor": "^0.48.0", + "lit": "^3.1.4", + "marked": "^13.0.2", + "monaco-editor": "^0.50.0", "rxjs": "^7.8.1", "tinymce": "^6.8.3", - "tinymce-i18n": "^24.5.8", - "uuid": "^9.0.1" + "tinymce-i18n": "^24.7.15", + "uuid": "^10.0.0" }, "devDependencies": { - "@babel/core": "^7.24.3", - "@eslint/js": "^9.6.0", - "@hey-api/openapi-ts": "^0.48.1", - "@mdx-js/react": "^3.0.0", + "@babel/core": "^7.24.9", + "@eslint/js": "^9.7.0", + "@hey-api/openapi-ts": "^0.48.3", + "@mdx-js/react": "^3.0.1", "@open-wc/testing": "^4.0.0", - "@playwright/test": "^1.45.1", - "@rollup/plugin-commonjs": "^25.0.7", + "@playwright/test": "^1.45.2", + "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-replace": "^5.0.7", "@storybook/addon-a11y": "^7.6.17", "@storybook/addon-actions": "^7.6.17", "@storybook/addon-essentials": "^7.6.17", @@ -62,45 +63,45 @@ "@storybook/mdx2-csf": "^1.1.0", "@storybook/web-components": "^7.6.17", "@storybook/web-components-vite": "^7.6.17", - "@types/chai": "^4.3.5", + "@types/chai": "^4.3.16", "@types/eslint__js": "^8.42.3", - "@types/mocha": "^10.0.1", + "@types/mocha": "^10.0.7", "@web/dev-server-esbuild": "^1.0.2", - "@web/dev-server-import-maps": "^0.2.0", - "@web/dev-server-rollup": "^0.6.3", - "@web/test-runner": "^0.18.1", + "@web/dev-server-import-maps": "^0.2.1", + "@web/dev-server-rollup": "^0.6.4", + "@web/test-runner": "^0.18.2", "@web/test-runner-playwright": "^0.11.0", "babel-loader": "^9.1.3", - "eslint": "^9.6.0", + "eslint": "^9.7.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-lit": "^1.14.0", "eslint-plugin-local-rules": "^3.0.2", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-wc": "^2.1.0", - "glob": "^10.3.10", - "globals": "^15.7.0", - "lucide-static": "^0.407.0", + "glob": "^11.0.0", + "globals": "^15.8.0", + "lucide-static": "^0.408.0", "msw": "^1.3.2", "playwright-msw": "^3.0.1", - "prettier": "3.3.2", + "prettier": "3.3.3", "react": "^18.2.0", "react-dom": "^18.2.0", "remark-gfm": "^3.0.1", - "rollup": "^4.14.1", + "rollup": "^4.18.1", "rollup-plugin-esbuild": "^6.1.1", "rollup-plugin-import-css": "^3.5.0", "rollup-plugin-web-worker-loader": "^1.6.1", "simple-icons": "^13.1.0", "storybook": "^7.6.17", "tiny-glob": "^0.2.9", - "tsc-alias": "^1.8.8", - "typedoc": "^0.26.3", + "tsc-alias": "^1.8.10", + "typedoc": "^0.26.4", "typescript": "^5.5.3", - "typescript-eslint": "^7.15.0", - "typescript-json-schema": "^0.63.0", - "vite": "^5.2.9", - "vite-plugin-static-copy": "^1.0.5", + "typescript-eslint": "^7.16.1", + "typescript-json-schema": "^0.64.0", + "vite": "^5.3.4", + "vite-plugin-static-copy": "^1.0.6", "vite-tsconfig-paths": "^4.3.2", "web-component-analyzer": "^2.0.0" }, @@ -187,30 +188,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", + "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", + "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", + "@babel/generator": "^7.24.9", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-module-transforms": "^7.24.9", + "@babel/helpers": "^7.24.8", + "@babel/parser": "^7.24.8", "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.9", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -226,12 +227,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.24.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz", + "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==", "dev": true, "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.24.9", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -266,14 +267,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", + "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -401,9 +402,9 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", + "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.24.7", @@ -513,9 +514,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -531,9 +532,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "engines": { "node": ">=6.9.0" @@ -555,13 +556,13 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", + "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", "dev": true, "dependencies": { "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/types": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -583,9 +584,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -2070,19 +2071,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", + "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", + "@babel/generator": "^7.24.8", "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-function-name": "^7.24.7", "@babel/helper-hoist-variables": "^7.24.7", "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/parser": "^7.24.8", + "@babel/types": "^7.24.8", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2100,12 +2101,12 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.24.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", + "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -2617,9 +2618,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.6.0.tgz", - "integrity": "sha512-D9B0/3vNg44ZeWbYMpBoXqNP4j6eQD5vNwIlGAuFRRzK/WtT/jvDQW3Bi9kkf3PMDMlM7Yi+73VLUsn5bJcl8A==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", + "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2694,9 +2695,9 @@ "dev": true }, "node_modules/@hey-api/openapi-ts": { - "version": "0.48.2", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.48.2.tgz", - "integrity": "sha512-pjJb0kzjTyKAdKGfi3GkOqD4AklImS5xz7xx1grZQMlNv87iV12g2pccEsml6WYDxQ1qJ7DFWa8FexAPDbzvZg==", + "version": "0.48.3", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.48.3.tgz", + "integrity": "sha512-R53Nr4Gicz77icS+RiH0fwHa9A0uFPtzsjC8SBaGwtOel5ZyxeBbayWE6HhE789hp3dok9pegwWncwwOrr4WFA==", "dev": true, "dependencies": { "@apidevtools/json-schema-ref-parser": "11.6.4", @@ -3384,12 +3385,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.1.tgz", - "integrity": "sha512-Wo1bWTzQvGA7LyKGIZc8nFSTFf2TkthGIFBR+QVNilvwouGzFd4PYukZe3rvf5PSqjHi1+1NyKSDZKcQWETzaA==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz", + "integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==", "dev": true, "dependencies": { - "playwright": "1.45.1" + "playwright": "1.45.2" }, "bin": { "playwright": "cli.js" @@ -4681,20 +4682,20 @@ } }, "node_modules/@rollup/plugin-commonjs": { - "version": "25.0.8", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.8.tgz", - "integrity": "sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-26.0.1.tgz", + "integrity": "sha512-UnsKoZK6/aGIH6AdkptXhNvhaqftcjq3zZdT+LY5Ftms6JR06nADcDsYp5hTU9E2lbJUEOhdlY5J4DNTneM+jQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", - "glob": "^8.0.3", + "glob": "^10.4.1", "is-reference": "1.2.1", "magic-string": "^0.30.3" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.0.0 || 14 >= 14.17" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" @@ -4715,35 +4716,75 @@ } }, "node_modules/@rollup/plugin-commonjs/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">=12" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@rollup/plugin-commonjs/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@rollup/plugin-commonjs/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@rollup/plugin-json": { @@ -5089,6 +5130,25 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@storybook/addon-actions/node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true + }, + "node_modules/@storybook/addon-actions/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@storybook/addon-backgrounds": { "version": "7.6.20", "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.6.20.tgz", @@ -5837,6 +5897,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@storybook/core-common/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/@storybook/core-common/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -5853,6 +5922,26 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@storybook/core-common/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@storybook/core-common/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5862,6 +5951,58 @@ "node": ">=8" } }, + "node_modules/@storybook/core-common/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@storybook/core-common/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, + "node_modules/@storybook/core-common/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@storybook/core-common/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@storybook/core-common/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6943,9 +7084,9 @@ "dev": true }, "node_modules/@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==" + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==" }, "node_modules/@types/ws": { "version": "7.4.7", @@ -6982,16 +7123,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.0.tgz", - "integrity": "sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/type-utils": "7.16.0", - "@typescript-eslint/utils": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -7014,161 +7155,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", - "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.0.tgz", - "integrity": "sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -7187,14 +7183,14 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -7204,120 +7200,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.0.tgz", - "integrity": "sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.0", - "@typescript-eslint/utils": "7.16.0", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -7337,27 +7227,10 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", + "node_modules/@typescript-eslint/types": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -7367,14 +7240,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7395,46 +7268,7 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", - "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", @@ -7443,19 +7277,7 @@ "balanced-match": "^1.0.0" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", @@ -7470,10 +7292,10 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -7482,10 +7304,65 @@ "node": ">=10" } }, + "node_modules/@typescript-eslint/utils": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.16.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@umbraco-backoffice/block": { "resolved": "src/packages/block", "link": true }, + "node_modules/@umbraco-backoffice/code-editor": { + "resolved": "src/packages/code-editor", + "link": true + }, "node_modules/@umbraco-backoffice/core": { "resolved": "src/packages/core", "link": true @@ -7543,814 +7420,814 @@ "link": true }, "node_modules/@umbraco-ui/uui": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.8.2.tgz", - "integrity": "sha512-uJvF+YcqwivhoUJnVpT7Na3/8toyfsnBj34/DVh97BIMv7gsWL+ijQ/6gS5VlDMZKEMeK74DtnwzdDY3ahL67Q==", + "version": "1.9.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.9.0-rc.2.tgz", + "integrity": "sha512-S3kVHhpPLb4M/XFMAB46s4cWSoBivZaVdY0omKHkHwtndi1GfYtCmUov+KJ7H9K9Pbz6lRN+FAm1aOUvSwH40g==", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.8.0", - "@umbraco-ui/uui-avatar": "1.8.0", - "@umbraco-ui/uui-avatar-group": "1.8.0", - "@umbraco-ui/uui-badge": "1.8.0", - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-boolean-input": "1.8.2", - "@umbraco-ui/uui-box": "1.8.0", - "@umbraco-ui/uui-breadcrumbs": "1.8.0", - "@umbraco-ui/uui-button": "1.8.0", - "@umbraco-ui/uui-button-group": "1.8.0", - "@umbraco-ui/uui-button-inline-create": "1.8.0", - "@umbraco-ui/uui-card": "1.8.0", - "@umbraco-ui/uui-card-block-type": "1.8.0", - "@umbraco-ui/uui-card-content-node": "1.8.0", - "@umbraco-ui/uui-card-media": "1.8.2", - "@umbraco-ui/uui-card-user": "1.8.0", - "@umbraco-ui/uui-caret": "1.8.0", - "@umbraco-ui/uui-checkbox": "1.8.2", - "@umbraco-ui/uui-color-area": "1.8.0", - "@umbraco-ui/uui-color-picker": "1.8.0", - "@umbraco-ui/uui-color-slider": "1.8.0", - "@umbraco-ui/uui-color-swatch": "1.8.0", - "@umbraco-ui/uui-color-swatches": "1.8.0", - "@umbraco-ui/uui-combobox": "1.8.0", - "@umbraco-ui/uui-combobox-list": "1.8.0", - "@umbraco-ui/uui-css": "1.8.0", - "@umbraco-ui/uui-dialog": "1.8.0", - "@umbraco-ui/uui-dialog-layout": "1.8.0", - "@umbraco-ui/uui-file-dropzone": "1.8.0", - "@umbraco-ui/uui-file-preview": "1.8.0", - "@umbraco-ui/uui-form": "1.8.0", - "@umbraco-ui/uui-form-layout-item": "1.8.1", - "@umbraco-ui/uui-form-validation-message": "1.8.1", - "@umbraco-ui/uui-icon": "1.8.0", - "@umbraco-ui/uui-icon-registry": "1.8.0", - "@umbraco-ui/uui-icon-registry-essential": "1.8.0", - "@umbraco-ui/uui-input": "1.8.0", - "@umbraco-ui/uui-input-file": "1.8.0", - "@umbraco-ui/uui-input-lock": "1.8.2", - "@umbraco-ui/uui-input-password": "1.8.0", - "@umbraco-ui/uui-keyboard-shortcut": "1.8.0", - "@umbraco-ui/uui-label": "1.8.0", - "@umbraco-ui/uui-loader": "1.8.0", - "@umbraco-ui/uui-loader-bar": "1.8.0", - "@umbraco-ui/uui-loader-circle": "1.8.0", - "@umbraco-ui/uui-menu-item": "1.8.2", - "@umbraco-ui/uui-modal": "1.8.0", - "@umbraco-ui/uui-pagination": "1.8.0", - "@umbraco-ui/uui-popover": "1.8.0", - "@umbraco-ui/uui-popover-container": "1.8.0", - "@umbraco-ui/uui-progress-bar": "1.8.0", - "@umbraco-ui/uui-radio": "1.8.0", - "@umbraco-ui/uui-range-slider": "1.8.0", - "@umbraco-ui/uui-ref": "1.8.0", - "@umbraco-ui/uui-ref-list": "1.8.0", - "@umbraco-ui/uui-ref-node": "1.8.0", - "@umbraco-ui/uui-ref-node-data-type": "1.8.0", - "@umbraco-ui/uui-ref-node-document-type": "1.8.0", - "@umbraco-ui/uui-ref-node-form": "1.8.0", - "@umbraco-ui/uui-ref-node-member": "1.8.0", - "@umbraco-ui/uui-ref-node-package": "1.8.0", - "@umbraco-ui/uui-ref-node-user": "1.8.0", - "@umbraco-ui/uui-scroll-container": "1.8.0", - "@umbraco-ui/uui-select": "1.8.0", - "@umbraco-ui/uui-slider": "1.8.2", - "@umbraco-ui/uui-symbol-expand": "1.8.0", - "@umbraco-ui/uui-symbol-file": "1.8.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.8.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.8.0", - "@umbraco-ui/uui-symbol-folder": "1.8.0", - "@umbraco-ui/uui-symbol-lock": "1.8.0", - "@umbraco-ui/uui-symbol-more": "1.8.0", - "@umbraco-ui/uui-symbol-sort": "1.8.0", - "@umbraco-ui/uui-table": "1.8.0", - "@umbraco-ui/uui-tabs": "1.8.0", - "@umbraco-ui/uui-tag": "1.8.0", - "@umbraco-ui/uui-textarea": "1.8.0", - "@umbraco-ui/uui-toast-notification": "1.8.0", - "@umbraco-ui/uui-toast-notification-container": "1.8.0", - "@umbraco-ui/uui-toast-notification-layout": "1.8.0", - "@umbraco-ui/uui-toggle": "1.8.2", - "@umbraco-ui/uui-visually-hidden": "1.8.0" + "@umbraco-ui/uui-action-bar": "1.9.0-rc.1", + "@umbraco-ui/uui-avatar": "1.9.0-rc.1", + "@umbraco-ui/uui-avatar-group": "1.9.0-rc.1", + "@umbraco-ui/uui-badge": "1.9.0-rc.1", + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-boolean-input": "1.9.0-rc.1", + "@umbraco-ui/uui-box": "1.9.0-rc.1", + "@umbraco-ui/uui-breadcrumbs": "1.9.0-rc.1", + "@umbraco-ui/uui-button": "1.9.0-rc.1", + "@umbraco-ui/uui-button-group": "1.9.0-rc.1", + "@umbraco-ui/uui-button-inline-create": "1.9.0-rc.1", + "@umbraco-ui/uui-card": "1.9.0-rc.1", + "@umbraco-ui/uui-card-block-type": "1.9.0-rc.1", + "@umbraco-ui/uui-card-content-node": "1.9.0-rc.1", + "@umbraco-ui/uui-card-media": "1.9.0-rc.1", + "@umbraco-ui/uui-card-user": "1.9.0-rc.1", + "@umbraco-ui/uui-caret": "1.9.0-rc.1", + "@umbraco-ui/uui-checkbox": "1.9.0-rc.1", + "@umbraco-ui/uui-color-area": "1.9.0-rc.1", + "@umbraco-ui/uui-color-picker": "1.9.0-rc.1", + "@umbraco-ui/uui-color-slider": "1.9.0-rc.1", + "@umbraco-ui/uui-color-swatch": "1.9.0-rc.1", + "@umbraco-ui/uui-color-swatches": "1.9.0-rc.1", + "@umbraco-ui/uui-combobox": "1.9.0-rc.1", + "@umbraco-ui/uui-combobox-list": "1.9.0-rc.1", + "@umbraco-ui/uui-css": "1.9.0-rc.0", + "@umbraco-ui/uui-dialog": "1.9.0-rc.1", + "@umbraco-ui/uui-dialog-layout": "1.9.0-rc.1", + "@umbraco-ui/uui-file-dropzone": "1.9.0-rc.2", + "@umbraco-ui/uui-file-preview": "1.9.0-rc.1", + "@umbraco-ui/uui-form": "1.9.0-rc.1", + "@umbraco-ui/uui-form-layout-item": "1.9.0-rc.1", + "@umbraco-ui/uui-form-validation-message": "1.9.0-rc.1", + "@umbraco-ui/uui-icon": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry-essential": "1.9.0-rc.1", + "@umbraco-ui/uui-input": "1.9.0-rc.1", + "@umbraco-ui/uui-input-file": "1.9.0-rc.2", + "@umbraco-ui/uui-input-lock": "1.9.0-rc.1", + "@umbraco-ui/uui-input-password": "1.9.0-rc.1", + "@umbraco-ui/uui-keyboard-shortcut": "1.9.0-rc.1", + "@umbraco-ui/uui-label": "1.9.0-rc.1", + "@umbraco-ui/uui-loader": "1.9.0-rc.1", + "@umbraco-ui/uui-loader-bar": "1.9.0-rc.1", + "@umbraco-ui/uui-loader-circle": "1.9.0-rc.1", + "@umbraco-ui/uui-menu-item": "1.9.0-rc.1", + "@umbraco-ui/uui-modal": "1.9.0-rc.1", + "@umbraco-ui/uui-pagination": "1.9.0-rc.1", + "@umbraco-ui/uui-popover": "1.9.0-rc.1", + "@umbraco-ui/uui-popover-container": "1.9.0-rc.1", + "@umbraco-ui/uui-progress-bar": "1.9.0-rc.1", + "@umbraco-ui/uui-radio": "1.9.0-rc.1", + "@umbraco-ui/uui-range-slider": "1.9.0-rc.1", + "@umbraco-ui/uui-ref": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-list": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node-data-type": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node-document-type": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node-form": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node-member": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node-package": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node-user": "1.9.0-rc.1", + "@umbraco-ui/uui-scroll-container": "1.9.0-rc.1", + "@umbraco-ui/uui-select": "1.9.0-rc.1", + "@umbraco-ui/uui-slider": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-expand": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-file": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-file-dropzone": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-folder": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-lock": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-more": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-sort": "1.9.0-rc.1", + "@umbraco-ui/uui-table": "1.9.0-rc.1", + "@umbraco-ui/uui-tabs": "1.9.0-rc.1", + "@umbraco-ui/uui-tag": "1.9.0-rc.1", + "@umbraco-ui/uui-textarea": "1.9.0-rc.1", + "@umbraco-ui/uui-toast-notification": "1.9.0-rc.1", + "@umbraco-ui/uui-toast-notification-container": "1.9.0-rc.1", + "@umbraco-ui/uui-toast-notification-layout": "1.9.0-rc.1", + "@umbraco-ui/uui-toggle": "1.9.0-rc.1", + "@umbraco-ui/uui-visually-hidden": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.8.0.tgz", - "integrity": "sha512-IRs42chstgXFo5b3i0j80Emt+uZSt/WmDDv7gTtB768FL1C+k0BR5sYVleEmUdkfCOv+WIVo1FAqd+9CPFkDDw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.9.0-rc.1.tgz", + "integrity": "sha512-HZCJS5z2nY6aKAwQSbN1QGMAYyFXEqWLTZ2zojxVRVI+nUF/IbElpMIFLrB2YQhhooE/ER8+5O99FrO/5jMwZw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-button-group": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-button-group": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.8.0.tgz", - "integrity": "sha512-ek6SFYEvEbu1Jf1FVrqBDHuWqCnekkU1hm4XDHEpEyhPE5OOC70SyYLB6brT0kvgBE0QKB2txYu7u8ZbWzy+OQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.9.0-rc.1.tgz", + "integrity": "sha512-CEZR1Vo3+raILWBxRq9zVcLTr2MosPtJZruRGUjWjEN5lxZm4kqzTYRWvyYG1oQgh9ePiQIqngX/MWHC51U6yQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.8.0.tgz", - "integrity": "sha512-AS6+GzeoAOS6vuZ6okP30iik8cvYPjBvoWtSYcnV0gScw52FIg9ak+j5L+rQHzE8LCqT8c6RE63HsAsJe7f6oA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.9.0-rc.1.tgz", + "integrity": "sha512-ftPQnWV5HKM030SrtyoB+t/KLgdX4TNLg7yZHwvD0TMAaWy6do8+jJtlIzdgKv8DhbkgOD8OUQxBVP4FbW1K4w==", "dependencies": { - "@umbraco-ui/uui-avatar": "1.8.0", - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-avatar": "1.9.0-rc.1", + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.8.0.tgz", - "integrity": "sha512-mKHkkXIwN7oUybeQo5J5TOgqghinJH5gE9lJwOemNCy/oiV/TeYHOr7MqHxIJ+13Nwl9O6JbSRWbPbOD9TSkVw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.9.0-rc.1.tgz", + "integrity": "sha512-CZyWjaOnj7O6lnmqky3+5K6Ia0wcHa0h3u9dcAG7l/EE/0Dq7HxE0XXJvSIldZ2xUD8tE8twTy7otvCkxwkPCQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.8.0.tgz", - "integrity": "sha512-LIPS3sfgOr/cgpDueTqpX+t6Bw0BpNISQSrAeyC+c6X0WiahKLuwob6UXSnefh9j5xIYa5+GY1gEUDgI4wlRhg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.9.0-rc.1.tgz", + "integrity": "sha512-S+PnRuSjK9tFYPltLOnifjhJPemhynRy2ZsVawvRiETCUjbgaPyDHJby+5CDH1H6VDo5iNQ/G3W7lK248+L1cA==", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.8.2.tgz", - "integrity": "sha512-qXHoMJKuszaAK5EYSDk1ZoA64NpIejOLwXJXDML0m4ci9G2AGUslAJn1mn4Kni0xeGoSkHuvSxB1WL2AI69Zdw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.9.0-rc.1.tgz", + "integrity": "sha512-Y/mVBUe8mnRatlsz6McBZoFaL5vpeE9PA0NWlmK6E/ub9MPZcqZQbgud2gj/9D80Q2EwFVvpTiLySyt0eXZCaA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.8.0.tgz", - "integrity": "sha512-/j/69od/uWd1Utb2IzU5pq5cvKpsq0cV4F+pS9e6HejzpcVUCz1AtdKNQvgpyOzd/oS9r8Z6pYL/V/gEydyqwg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.9.0-rc.1.tgz", + "integrity": "sha512-efxo/xmj31+p0LXXa2pJLYPfcAbMz5yi9+tYJYkj5G1Fz40JJnx3mqmiH8HI820Hg8lqjSf8JhkVSsqWjFdlaw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-css": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-css": "1.9.0-rc.0" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.8.0.tgz", - "integrity": "sha512-Hv5NAfRzfaXcDYcuribjpaooZk1LVcHNTaLwoxVAUN64sufYS8kfw0sN8+jsacumUP3rpy0XgR9Ic37JUoIkBw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.9.0-rc.1.tgz", + "integrity": "sha512-MYbDe9Av5vupu4A35sQe2etwH5xoUtFM1+hHMpzB2GGw9n4Ye6noZkC4+gTnzroHqNH/0GsHflc+6HNUqjG+8w==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.8.0.tgz", - "integrity": "sha512-M0pLzpGt2CuzQAHqiHQwVdzFOyb9EznCT7b+YMQOlJCMfeVmN2KBF2xUlfb/3M2LVDukTHyGHzqaWj8Lj6YUbA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.9.0-rc.1.tgz", + "integrity": "sha512-PCoPRm1sxBcaa+l/EsKHNrrY2r7amNqoSF+sho/BdkRwaq7ssPxM67y5+qp+YSpAyNa57/rGZZ4fhJETO+26ow==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-icon-registry-essential": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry-essential": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.8.0.tgz", - "integrity": "sha512-5K/cvrOWvRmoXByuI1illF2e9sCzzegmlEpS4XbVk1XW/6quzRJpXSCrY+awj01kFrxB+UC8mB1DIECHKNyeVg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.9.0-rc.1.tgz", + "integrity": "sha512-lx6t53OOWW7qFfx8vgee4dNfo29z6I3tadtJzxwKRbMjihA9JJJxpTvJemRwMRFscaHQjrVxXtL3gN5/Y6Tc9Q==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.8.0.tgz", - "integrity": "sha512-smSZKMG0cAp+BTZe0wRaYotcQElja8gqznGaIyuGuWvvpvWEiuWMC9xjMytFNvaawCN1+uLc5fdcCArPmFjH+w==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.9.0-rc.1.tgz", + "integrity": "sha512-RfrJ/1YyOubGzWut4ZiBNO/Uo4u0gDvD5vKxXUJXo92N5WIFlRPoIpah0CHtE6Z37OWed0jsnIN/7JW/rVLjjw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.8.0.tgz", - "integrity": "sha512-wwHaDbwDmragvIhhAtv/D2Ys47kXFPBKvE+/ahofXUygjTGbmjbKJ57Qfo6x8sD1BM3bSTDU6gUWaf4s0/D3WQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.9.0-rc.1.tgz", + "integrity": "sha512-gWOJY48ifsuZh208Md7hdJ/wEe3g9KNhxvq0S05TnTw+fqRwK7hfnxBh0sHj+OazA4esaVBkYzqPeRF5qx5y4A==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-card-block-type": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.8.0.tgz", - "integrity": "sha512-8Ydat2K4LipsQaCEhDTN4DeVHiqOCdEOY4Z43XCf6bTU91lNPGdagtC0ZE9b4M28E03ou4E19Ms7o2m59g0OWw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.9.0-rc.1.tgz", + "integrity": "sha512-uxqM7s89IohqjJv+1+OSMKuopIyTlwTnLCBjc0R1aYCo+7oIbUT9f7yXw87+RenHCoIWD/XCS6aUa3TYW3iqHA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-card": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-card": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.8.0.tgz", - "integrity": "sha512-R0SYtKk5Z+on0xQ0cD1z2z43mSTgYi7sKtQDrhwoP/sWbp9xIS2wPOO+PoMiUonwXPo4JuSZ9ghgT4HzsQce1A==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.9.0-rc.1.tgz", + "integrity": "sha512-WNFwENIMuGobHmb2I6k8PZL0ByipiAdQ6W34ZLpAgOGRcBQne01MSmOKgs188AGSMDRs+/CH50bEkuRGPXOfXA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-card": "1.8.0", - "@umbraco-ui/uui-icon": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-card": "1.9.0-rc.1", + "@umbraco-ui/uui-icon": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.8.2.tgz", - "integrity": "sha512-rzuBoGXb8uoEE76vD+EHJkiMeTsPFGhf+bmE5Vw6oMfSJuQXyaFdQWFPu7MwKntRq63WUE47tqME9wqDl8VTaw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.9.0-rc.1.tgz", + "integrity": "sha512-MJ32ZQfG+RnaM+4Kf6xeUVBASIs/mZz9oGf3fWZm9bR/3fX8pdvgsiSMM7MEKlGXVd6v8N+uFcmpMOdDqSO42Q==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-card": "1.8.0", - "@umbraco-ui/uui-symbol-file": "1.8.0", - "@umbraco-ui/uui-symbol-folder": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-card": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-file": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-folder": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.8.0.tgz", - "integrity": "sha512-b6LiMCl/oFaW6MnPXBMCPqlVDHF/TT3LByQOTJ8rE+WHzY/zE9toVLy/LccxB62Ur/Hz7XakhU8xHaugH+zs3w==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.9.0-rc.1.tgz", + "integrity": "sha512-plpBLLajfStpES4Sax1RxosRZpo3929fZrCJxZgCQGGqNhl0RzHLQQ2UP8i0AHsmI2n8OKHYbaZWL/4X/F619g==", "dependencies": { - "@umbraco-ui/uui-avatar": "1.8.0", - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-card": "1.8.0" + "@umbraco-ui/uui-avatar": "1.9.0-rc.1", + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-card": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.8.0.tgz", - "integrity": "sha512-LxS0vLKZYNKsef/FgNXFh/CBauf+6Dgac+n5VyCu6FElh8UTP+NOeAA/4KEVSJh8gThJ0Fmb8qoMSFop+41wLg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.9.0-rc.1.tgz", + "integrity": "sha512-UtCWJAqfHfNZgxDnj81Ij63qXa/FDbL9kX+XA50a/5tAznGqtN8YPobJJduObLaaxNmnVK4BHSeuenkWiKwD0Q==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.8.2.tgz", - "integrity": "sha512-DKGmJw2JnqYDTY99ah94hBYI+PWC/dyRqpubuDuXecqFpUme1vzacu+rzjkp0VP97rUvO6v/OA4Sjjku3oDVuQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.9.0-rc.1.tgz", + "integrity": "sha512-riiWt46dHxUXW3IqIEtmByMGwMXtb90HbiSZU/BUJCupZAuROoFT6SaX6eyOOHXoC3nvUgvD6ceW1jB7jzIkog==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-boolean-input": "1.8.2", - "@umbraco-ui/uui-icon-registry-essential": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-boolean-input": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry-essential": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.8.0.tgz", - "integrity": "sha512-V3+iph2Vq58T9f4FoJvxsjq0LpH5VJhC2P2VkAWvMO1m528QOULDP+b5csYWH1pF78RxSZ5Lm042Dnw9XOqN2w==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.9.0-rc.1.tgz", + "integrity": "sha512-JLMCj4ewo0QL1elQ4MMJNeS26jHrRH7vdk8k1+8jGfL1heKD+T5qmGAzLnuzp9SwZfywGN3GTjyVMJCEfYiqJg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", + "@umbraco-ui/uui-base": "1.9.0-rc.1", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.8.0.tgz", - "integrity": "sha512-DQtKN4ivIRx54SYUhxdlbFf5ibmnp5/mscOiC98HObYVTeM9ZJUrKfFGTU9Qfekz3q+rPzzv7eec8E0Zb6qfwg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.9.0-rc.1.tgz", + "integrity": "sha512-R0bebkQXUW136XVcxLt8XbKKpudVAVN+avQOjMY5HwyATm3uneKo+jMcxhm7x+mHVa0J/SqEZHN52EQrhIU8JA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-popover-container": "1.8.0", + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-popover-container": "1.9.0-rc.1", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.8.0.tgz", - "integrity": "sha512-DHCFX0JZXqI6wp2fRe+lOd9TAJVzTC9ghDNP+qMGattsxRnTf/pxoYucW7F5ee/ggiBIsS8i47kFa2wDmausiA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.9.0-rc.1.tgz", + "integrity": "sha512-KjLNE5Cu+6pJgORYwQG9ZwOcTVS2TPTytaGMvJg1A+dH9zPW3xypAe5Y6fKTFEFqQwMH4wOAiVT5Efc2G6BXvQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.8.0.tgz", - "integrity": "sha512-z9RQ0R5E9SErqiY1/kU6Rnp+LQBM119OKqAexHo32cM/9iyzLIEUY4CwzCYE9/ogeXDgljXLTGX21jddCNCv9A==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.9.0-rc.1.tgz", + "integrity": "sha512-jlpmjHcoHczE5QZRepOUR1/lz+e/43orJV7UJDT/ZiPK7GzqgpWVGGM28Rv3omHmYTgee7WqHVfSw4uvzASCBA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-icon-registry-essential": "1.8.0", + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry-essential": "1.9.0-rc.1", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.8.0.tgz", - "integrity": "sha512-qCHYtHPhPsubrVn/cydmigbAde0fc+kJC7ZBxCcuJjyP+wiUhq2/d6dSfYumCcVw1N3Hyj7BRJ/8ZedUIZQ5/w==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.9.0-rc.1.tgz", + "integrity": "sha512-lpxHY1ekw+oecHJ4HDkp6FwIuZhXobomPOirDm5G/9fpJnn7ScDWhQRwRalDIUMpR2E79gid8k6J1pw8Mjyxog==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-color-swatch": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-color-swatch": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.8.0.tgz", - "integrity": "sha512-FVc3PlBYU8S48Zr75pig+5YXh05R3wRKdLl41l7vFBDGGWsgjIsM+vJ6LaM+VoshnTzUTOVvKLE/N0FNTVUvrg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.9.0-rc.1.tgz", + "integrity": "sha512-78CfWYNnyYL0XK+4PTTjA9thUeNAVaZr06iPI0DInm216uIZ+OD3+mBm3Hw9pqbCzjqKaGIs5HtJzZVGAZprHA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-button": "1.8.0", - "@umbraco-ui/uui-combobox-list": "1.8.0", - "@umbraco-ui/uui-icon": "1.8.0", - "@umbraco-ui/uui-popover-container": "1.8.0", - "@umbraco-ui/uui-scroll-container": "1.8.0", - "@umbraco-ui/uui-symbol-expand": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-button": "1.9.0-rc.1", + "@umbraco-ui/uui-combobox-list": "1.9.0-rc.1", + "@umbraco-ui/uui-icon": "1.9.0-rc.1", + "@umbraco-ui/uui-popover-container": "1.9.0-rc.1", + "@umbraco-ui/uui-scroll-container": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-expand": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.8.0.tgz", - "integrity": "sha512-3w353u7FdYNLCz6YV+Pk+lxlTeHd2H6rmxzwb+0BHCjbwaw9MLojbhE4JGTCpf/qtk54Xc8Dzg++aznKAYpbVw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.9.0-rc.1.tgz", + "integrity": "sha512-CnSKKe3p7yKwkBml5wSfCaTqbB4tQ+223v0noVWyNa27xCPpdsxc1NT4d0QBauVKFhpYDk+s4dRXamFYbN9qyw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.8.0.tgz", - "integrity": "sha512-9o9OGUXQK8D9i/VSmH3gUTvH7se+4Ey22dSfbn4Jzcbe6AyGmxKocr/8eZXdkIYwNvK2aUIz/b7GIEbQc4utbA==", + "version": "1.9.0-rc.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.9.0-rc.0.tgz", + "integrity": "sha512-H0GKWeYCkRKxYKxRn+Zx+1QTymJyBisLH/MZtAmbMGqNdyraBOaLrgifymmZPilwuE9+d6bm0JZgSG5jFqNZug==", "peerDependencies": { "lit": ">=2.8.0" } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.8.0.tgz", - "integrity": "sha512-QI/Oa7BJ7eEdHcy7hSuFhMPbbPitxnIb2BHVmQzy+YpBShrR3C1GW0FGcYFgJlI/S+jodf3A59VDnVL69gyliQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.9.0-rc.1.tgz", + "integrity": "sha512-Zw+LAWy24RQVS+N9YtFaMERnlSdow2Sc6nq/P6WbmHPioONJ9/StxeBaJg1jjGxDCuZMpDn3Fcu6BqpxKiQC5A==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-css": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-css": "1.9.0-rc.0" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.8.0.tgz", - "integrity": "sha512-iv4wEfb6QhCOm8lxg/zH7yrJuVSEEBGgAN67qdvZ9Tu2SFzUCGTzrUcBXlL+U10cbIlq7j6KKvSQvE/IHX40Tg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.9.0-rc.1.tgz", + "integrity": "sha512-JcWXXxXKPF1Dbf7EcMwUGXwmDciUeTFFRhkUR+GEhl7mGj7rq5LWX/6sctTQaKgmmd49iKNNM7A+yxgfWQoVWw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.8.0.tgz", - "integrity": "sha512-Fpl/aGprUbcdPngB6xpR8/i7o8HKAWNCUze+N1pXiIVBRXmthEWO6fSm4+LkkkRoZwvYqQSaeu6Mw+Sj+MzHGA==", + "version": "1.9.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.9.0-rc.2.tgz", + "integrity": "sha512-8zDwogJpzYh7G2yS4mvVTqUZOt+0JA1c9JiXHGN9PP808d2beEiAP2kqUlg7HQ6H5Muzn4wSW/+g6Z70zyQJJw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-file-dropzone": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.8.0.tgz", - "integrity": "sha512-WhE/9klwIUjch6PxF+DuFlu+ql0h9YbefMxj/xU4rGUTE/dK4CgA7eVQ/YfAp+WrdtwUFHyp3fThyJvfrodSgA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.9.0-rc.1.tgz", + "integrity": "sha512-zVEj9DJ9rXlkjaMtLlnNH3xVVt+D8Zom6OSzkVh595rMv2uGTwtfhX03SZoW78HgWDlthtSr1RyzkGBgpXFQ9g==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-symbol-file": "1.8.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.8.0", - "@umbraco-ui/uui-symbol-folder": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-file": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-folder": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.8.0.tgz", - "integrity": "sha512-9NtavsRoh9X39ezzLtwwbK77mUecavcjxP58Jdba/2/6wXRx+vx7qsWV5Rn3OC9XG4tZi6VLFFKahbV8N/jgjw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.9.0-rc.1.tgz", + "integrity": "sha512-x+xReBv78yqhFEgc9JLrBff4WlE1RU77vN9gfQIbcQaj6+0f+YzQ1VhGs6wDCtkTifLU8ZZADT4Qwje3Okln8g==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.8.1.tgz", - "integrity": "sha512-QHBZayR4T49MAyS9N2jy1rgQ5Yk1JpwoWvWBpbI/WDE718zTjwUJxbLfukq+NnJx7Q1DplZ+IHTnHZkInMC2GQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.9.0-rc.1.tgz", + "integrity": "sha512-BDPXd1hjKK8Ph3g98XbRYJEIdrr21cNnOdL4atHt+LbJNEmFOldBANOrX/UNJCfiYtB9T4tFxexrlFPf6OD3fA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-form-validation-message": "1.8.1" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-form-validation-message": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.8.1.tgz", - "integrity": "sha512-o4WfGHRtV+DrN064DtzyljRkUGYMYEkLHxxbawLowpdmdwyvLByaGOkxfuEJvHgPnncR02//gM04EjulEbGitw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.9.0-rc.1.tgz", + "integrity": "sha512-fiyPXemFSv72EeuzrIQbg/1lZd9ZnhrlSEAfM94O2lilPqV1DD/uqpqlboih8r2nI8V5QNHtc4t0lIiXfGU2Qg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.8.0.tgz", - "integrity": "sha512-hub+KNcwiy+SKxEpI/ei3w1Ficr1SWxcLfwL67MOKS5YyB6RDwSl2FOXx+MkttTAO7PvGBbAgkiiXEkI/rxivg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.9.0-rc.1.tgz", + "integrity": "sha512-MLmgo1Q26Ii3zvoyX3fAiZzd7kao4EjzmOnIkD26NwurMb8Z5cfHW/3jvAQ9GQ/h/4XSXKltLmTzZ7UF9AuVkA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.8.0.tgz", - "integrity": "sha512-+55qGgxOBlHmQerxIhKkKJYJgPwnXwsLOBVwF8oYIM1sV58bu7BrGQRUw/K0ytFavrFOb+Easkn62wqzisXsRQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.9.0-rc.1.tgz", + "integrity": "sha512-+slebtyr0g0evsEdMyovR77wBptrPV1VEK1xu9ukRxC4SrO6VBjy47qvQ1m8UIiboUOQvKS4vZ8/TgpDdKDXfw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-icon": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-icon": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.8.0.tgz", - "integrity": "sha512-6+bM30t3+YpknxIjcCHi07eS+MXMkDRP+GBfrUgULqH/EqnJN/OuwMzSdbwFuwzqxmC7thx74Zfl6+JBuIs9lw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.9.0-rc.1.tgz", + "integrity": "sha512-Jt6W4TMY7c4NZbfprgNbwtUP9IUPjkeAceplBVBLDuWFNZhxvBdTrEEfPz2XCBVdF9J5QsODD8PDGfQU5dCKiw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-icon-registry": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.8.0.tgz", - "integrity": "sha512-abtQbWWDT+3uo4KVaU+ZbDVKSNtB8r0C/3L7Ql/7xJ2BNI2oSUSAcWoSV6V8Vx0DYh1XWlEQpfSAbk5Fdr7u4w==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.9.0-rc.1.tgz", + "integrity": "sha512-owHhZiir+2YNJY3NGyRibkvvO4g/o7h+D32dg+zKsDME8qKo1wq66rnDEGP1QmAeaaW3J5FVxCJJl/N8Gyv9iw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.8.0.tgz", - "integrity": "sha512-20fXbIwjyLZWIVsqFt06ldQqA8sHEPm8Y0hmPwbb0nagYfjmIblIE1thT76JA95do7qcU50xGBN9mHt8KvPpQA==", + "version": "1.9.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.9.0-rc.2.tgz", + "integrity": "sha512-30KHt3F4ayCpckZdgxI72getwVpuBXWacIAO6Zzfsfy7S0pH2hsY9RB7VNjIhhdKeMt3ChmrU8dwcFin4kUtyg==", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.8.0", - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-button": "1.8.0", - "@umbraco-ui/uui-file-dropzone": "1.8.0", - "@umbraco-ui/uui-icon": "1.8.0", - "@umbraco-ui/uui-icon-registry-essential": "1.8.0" + "@umbraco-ui/uui-action-bar": "1.9.0-rc.1", + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-button": "1.9.0-rc.1", + "@umbraco-ui/uui-file-dropzone": "1.9.0-rc.2", + "@umbraco-ui/uui-icon": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry-essential": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.8.2.tgz", - "integrity": "sha512-GfEV2KsZ+VbHhz1zKGQfYfeSAe7P29p2VaSJZDqZmRial85J3qFRK0dLEUnkQ1x0XGwiE+OprK+EsoFq1vNpdQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.9.0-rc.1.tgz", + "integrity": "sha512-ceGfpayTwQSA8Mn0RnMDF1PSWgFDSXcsBl+CUDx8B7NeszlNleyGO7LueMCqN/KkH55Gca1PSgxZK/phRkTJew==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-button": "1.8.0", - "@umbraco-ui/uui-icon": "1.8.0", - "@umbraco-ui/uui-input": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-button": "1.9.0-rc.1", + "@umbraco-ui/uui-icon": "1.9.0-rc.1", + "@umbraco-ui/uui-input": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.8.0.tgz", - "integrity": "sha512-Ra7bR40GzjX11qobHsog2FPGd3FsPzgxPpGLFyMTHzDg2gchYU+KQKkmt6CTzGPgSFuN7DsEW0BMnFnWJ+2moQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.9.0-rc.1.tgz", + "integrity": "sha512-+404OqeGHtO/eOs4bJfp6FIghwI4o2jJgTdv3ik8VXNzueYccW8eyTZ9wBS3fSuqlv1k8fkEENXkdluHoGVQXw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-icon-registry-essential": "1.8.0", - "@umbraco-ui/uui-input": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry-essential": "1.9.0-rc.1", + "@umbraco-ui/uui-input": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.8.0.tgz", - "integrity": "sha512-XBO06bZbo7H39k33pm8EoWxm9MP/NXh7W430dLqB5E3q1EOO24PQw2voLsOyegVM3IqgKyMBTO7xHR8NmeZkyg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.9.0-rc.1.tgz", + "integrity": "sha512-KMl8SBzehbyBwYgtRXCF+OimgZdYCzx/KkoEHXAlsIb7Bxreb6lVntJwOqj5v+gohILyGyqYCCFjFyFA0BZYPg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.8.0.tgz", - "integrity": "sha512-Qj3CtfVIv3rVIanTbMvg6UAB2faWGu2mMtvVfmr9kkEP9MGfmA/xgQN94lKlDI7ic54FVkCV4N+1kA5yNkeDSQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.9.0-rc.1.tgz", + "integrity": "sha512-6zuQSHyDoRPR/KyP6E0NccDuGd8LAxq5ftJRGTNBzdBT/BCLQPcgQsJuLFtBbgKKp0Kk5nM/votkGdbvHd4P7g==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.8.0.tgz", - "integrity": "sha512-CL+n3Icp4ugfn7SBbhbYC4WTBQ+kT27WwJIesOcjw2lmt2l20RQUyBBbZAABx2ayyDuvIzEWnFEzWW8VyVworw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.9.0-rc.1.tgz", + "integrity": "sha512-HHzyIe6kpQER7Tb4egjskmvJmlB+Z7WfvEhBr97eZHgox6IXxRVebHz7oVsxe3kSf8RYp7BU+kGmT4BNI9ucuQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.8.0.tgz", - "integrity": "sha512-KuUtQ4r/wkbVl4IJVgUb9DCXvV1yvupDw6AAnWuOu7zexuzPfrl32cKBLlnNmhGqnEGcQonX6jf24Lf8T7W6Nw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.9.0-rc.1.tgz", + "integrity": "sha512-SoRvpK5OMrehmLSRRfzMpsDbGqCkWvFvy8TZI8+kseLH5pl73nbo55C1GAq4ZuXXFUdx4aZ9RK09IsWrGec94A==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.8.0.tgz", - "integrity": "sha512-L5RyH10Es/stG7CzNzS0bKOzCY+zLSwmqyh0dc8HwzZCvc6XtFHV0KgcxMjmtWWulLsQPgzIOIigf3wefr2VNQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.9.0-rc.1.tgz", + "integrity": "sha512-UyXNBwaK5npYhNNA/5BCB36AIiwN0pcj5rvSIbef+2yQU7NS7Xhh6ZK+d2xobk3Rs55gxB5v6eQyQWF1P6YQFQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.8.2.tgz", - "integrity": "sha512-8LaA1P+tSLvHqWGIpLv+75k9Xewq+CE5YscO/WFMPP6el+c/PtCyr2uhXhA/KVKqBorkV4+w7cgoANt79997Mw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.9.0-rc.1.tgz", + "integrity": "sha512-9WqxUPY61309i2V/QOD+smVU4d4TI6ANG6CHPOYUnYU91a7SC33jgs3XWk7XeTtLBzWkUktt/mzTZaMnyRMr2w==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-loader-bar": "1.8.0", - "@umbraco-ui/uui-symbol-expand": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-loader-bar": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-expand": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.8.0.tgz", - "integrity": "sha512-Cqd4pabMLnpnMEa35MKOwXCKQ+5okHYWdvdFRA8x1HqI3AEcz4FNx48nXVH94vhbELv8+fWFAPfrr1v0rvjK6w==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.9.0-rc.1.tgz", + "integrity": "sha512-vRTeAjowWPKSp2i7KTdJmKo8GYabBO4Nn/h8pbpkAK7ri+HurK6TKHy4ea8qN9aGEJUXv5BMjy2I5jEq5CqD7g==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.8.0.tgz", - "integrity": "sha512-SvnWMzbQcTDEN+XQJ0/lVCJ1wL+2L7LA9pfSxJgXIj/pB55Pf3Tt3zMnW8B7RT7i/74atMufaqSSKElZrcPfHQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.9.0-rc.1.tgz", + "integrity": "sha512-4+NFirjRu/TpmPaMCOWl3h1No7MPLW1EALslZmgyhSKf6pCBChz1p4EkXgqHoNYEUpDIYWgTNLLVFCzg5Wq4Uw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-button": "1.8.0", - "@umbraco-ui/uui-button-group": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-button": "1.9.0-rc.1", + "@umbraco-ui/uui-button-group": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.8.0.tgz", - "integrity": "sha512-bHERyYItLAvtWbpOdPgmuPFgYs2TuKImm3h04DtQRatYP4dq8wg0tftVyZK3k9TVfLMvStOy2EyzybTD+1ZmBg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.9.0-rc.1.tgz", + "integrity": "sha512-G94EWcXBT5YKPSZNRza7b4mFaPrIpM/ojAljC5a1NlrJ9B4aG1HXy1gvnD3kiecCbl/c95BMQCreZTjhEfvmcg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-popover-container": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.8.0.tgz", - "integrity": "sha512-FHaX4sIa7q4HTVzMr9w3Z6zuunPuDROnHjVS6QkovqHLEgQjeTQB8hGAxN6cd3QsFbgbtC9fzBo8zTn9yxJLmA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.9.0-rc.1.tgz", + "integrity": "sha512-NVvA4HLbxFj3Y83gPHb0c6kfJcMx/+o2r9E3ijDuKhMYnVVFikvv4+13Yy/5uQo8q40JJNtcZXdKXD9IyLTp3Q==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.8.0.tgz", - "integrity": "sha512-WX+YjiH0HCljtzTImR6Q8bf06wm+jcCgEOE10pMRri0r4nyBCAN7Zms23sHj6rR+S/oxoYcuREqdWXWP4eRfFA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.9.0-rc.1.tgz", + "integrity": "sha512-X6JbvJobSCXWCoRrvLrPTOcoaXXhdIMMyi5e7mNxvwUVb4VOr4f7aYFr+hp1fr5AH60caf5QbmHMDeJb1XtqTA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.8.0.tgz", - "integrity": "sha512-3kPWyc0ZbtAIeOHxAKudSslomg1zKy4RMgrfDeNumQhuCei0VWhVn76Xyfu/Gl2n4XnLIzZY3zv4XCaxwWvJZw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.9.0-rc.1.tgz", + "integrity": "sha512-U+E3y7TaNFvB760euygE1TR8gTF67dmQhkTDJqbtfX8eTPSFD59/2NUe796qsErFPCqICMBe8/SC3z648KJ66g==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.8.0.tgz", - "integrity": "sha512-ThDfLvxRMfP93HQobgLaglR860vQiwCM63PXp2igXWZl69ikDDa7HuraupEpmdL13VLKAv5L1BMue1ItC1x2MA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.9.0-rc.1.tgz", + "integrity": "sha512-a+pkGqpiA91DLZhq/i/zmnW9wpppxyCrYNja1s9dEE/+FU99Tu9sA62zPjCLw7T7jalzwUlvqvAYPg4LbNKHow==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.8.0.tgz", - "integrity": "sha512-mcw7faAXeG/2QfLeuYsB950seU0FQH5Pd+aSfi6zwgWkCasxKWLrlslVTP1U5zD5WFkNt4ls6RnMGZhN6bq7mQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.9.0-rc.1.tgz", + "integrity": "sha512-ZMR3r36B/hQ3w5kqPqFU8ptjwacC2xvjPPlHNKK1izgnycfZJF6cUiTk6G+BYnpJhFQV7Mf5YKUX/nLhLjKOsw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.8.0.tgz", - "integrity": "sha512-9iiTYVyw+dpO1gEB2oMJSe2DOVvA3a2uY5FLwkRgpAjvzbhD9hhyGLcVgtvM1rxUYc9SvJbGJXk2tPY4Nit3pA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.9.0-rc.1.tgz", + "integrity": "sha512-vXTI/4nhOywPspeSW3vSsdxP+o8XcmSm4iY1d9Xfyjeoyw+aJP+g89LVV5HXP1rbtF2Ru3frRsSvKieQuK4nAA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.8.0.tgz", - "integrity": "sha512-KOGy10QhPUQFNFNPkmqro1YqFg5Y5b2N/DwkcYP/xyu4Kc1f5FuE+Uo5L41i2KdbDP6O+Tz5gsU6HpPvpEAc7Q==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.9.0-rc.1.tgz", + "integrity": "sha512-c9zJYZzP+qaxfrcasE0jJaBg2VtE7W8xXSATnaavCa9G4HdEWBVrg64G8JF+vuJ7+A98ZuhG6+w23OWGSJqG3A==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-icon": "1.8.0", - "@umbraco-ui/uui-ref": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-icon": "1.9.0-rc.1", + "@umbraco-ui/uui-ref": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.8.0.tgz", - "integrity": "sha512-x7PicpHE7PPZrVDojKO5ornG7HZoRB9/pjCZWV+8wxPznyGmFvcJpbRQLdIVvvXVkL1a0c4uLY2CsUO+K52Rbg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.9.0-rc.1.tgz", + "integrity": "sha512-l2GToYlVvGC44CYJoypsbToYBP/WJQneRlJl2yReWOL4Cq4pFJlSN7G/flW68Q+rv9ubpXO30UetJCcCT+F0KQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-ref-node": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.8.0.tgz", - "integrity": "sha512-QjeC8DvgA/WFb3wOUXMOALK5SoKeDAvYqNp1wNvU5AMxJY+5CTfi6JNWKZsI4K+Mh3lfzPP+HaWx5MTwt5epNQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.9.0-rc.1.tgz", + "integrity": "sha512-7Za5lCUkxqCdP6u+yl1yZbFpuRgsKfW2STyrbMgcEKapv4jve4m2BnstEqFT33Itd3sY3mdsUWZiiUMYZNj9dA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-ref-node": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.8.0.tgz", - "integrity": "sha512-sm0xSru6pv8yK9qepzF5Wzzd1jarMBZFtzgqw5H65pGTP6pNhNG4GIkeXLfd2TH9g3e6biJNKAOFJ5w8Tz4O9A==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.9.0-rc.1.tgz", + "integrity": "sha512-FSixjy8MehGPe/c+acLwI2X7U1Z5Io8ITBhi2hXb8X8X66YWClzo8J1KoKiRhLqk6FClufpY2p5yYJkQmE2YQA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-ref-node": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.8.0.tgz", - "integrity": "sha512-z9l44zCER4KmNMSnCy6BFxXZ6awr/L405pJJJzqb3GAXsBip47pCzhYgxCbekB+xSY+E0hS1EuG1JJ5wn05yiQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.9.0-rc.1.tgz", + "integrity": "sha512-OyPPftRJDLvpMBkPuaP29wgWfUzi+KXTcZdnXthjGA2lIaRW5WXQpA2Ci8+iPxuuCcsEhalSHmqwruglKAeqyQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-ref-node": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.8.0.tgz", - "integrity": "sha512-bpWVBOm39tl5jY3Y+qn5dnikmnaAOrHEg2SBf/11d7aHOauEgDiJZQmM9BzjAeionaZrj4beYJw5szazaVkpDQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.9.0-rc.1.tgz", + "integrity": "sha512-0CFG7tMn5LHpKtqTmCC2Il2Y8ufpafTE3BCo2zDRbLKOF7uFDAGrFX+Kad3hla0dd1YLv7AL2AV06vz4tilipw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-ref-node": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.8.0.tgz", - "integrity": "sha512-Z91Me56phGFyt/hJaRDnXrorlYVjrL6WaUWRDZAi+mqqThFriG1DVeaFEewZ1yeD3Hy6haHanDa7dtwm2FLsBQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.9.0-rc.1.tgz", + "integrity": "sha512-lB36tup4tHx3JGtx42A1t0Ic9ynXitkZ/wz/6RmCpFKLF8j2p+U7CafbGPtr+PRD7QZ4kppVCHwr+ivuyERftg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-ref-node": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-ref-node": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.8.0.tgz", - "integrity": "sha512-PHxOZhsM53J3SQaXhH0euUwshr6Ka06iFEmtNKaqVe+nPwTjYHWHDuulvp7/qm/btjzSIrJqKgs02ft8wGqXwA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.9.0-rc.1.tgz", + "integrity": "sha512-H7RcMuF+KT4KKryWr9bVEEs8aegaD8gbSWLQLyTtpKMrDz/i/baw22D1dCQAhnbPyPJQvy0dnBYXuxsPI9IOBA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.8.0.tgz", - "integrity": "sha512-xFXo7IlAtofZCWIqnhyThIjP8ORRwo6786fv5yarayhqlKeAwJRD5t6QtX4z5z/1b/zW11oF2GkJzrzp4KN4vw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.9.0-rc.1.tgz", + "integrity": "sha512-4Ty2AdRywRB/W3ymHGN1FgCvLp0y3GgPtd1aw6wR8YyUf4J5wvv9Cv2q9A/s4mSvj+NnTPgXEVmBDp8hORhVdw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.8.2.tgz", - "integrity": "sha512-fE1BVuCu6uDlQJh5leFSWxSPhCnJGlW3vskRMdplCLbvmFK0dYjYNbNzLyVCRsENlXJVEAkIavsdETJ784ALoQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.9.0-rc.1.tgz", + "integrity": "sha512-E93cshk9+BIPK4fQcvWMAFGXdPYmHuCnQa2tS0vw/lVa93xGVyuQ5uRynhTvmHxtJjtWhjLA2PKCrcZVJRP3og==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.8.0.tgz", - "integrity": "sha512-AfpoR4dTOL4gEfP9lnEVymU3mlNfjFSuk8TGbqy0jVMTMbYeol5Bcl6jJFqqPd1npfgT7FPZH9zrMkcFogfSSw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.9.0-rc.1.tgz", + "integrity": "sha512-d29r1saV0Dw55lr/SmEL2rpEMHBjs8aEEknYBo1uL3pHOqoxhnIsno9zd5gH5v39uH3zy3PzLYxArPMA7Kj7hQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.8.0.tgz", - "integrity": "sha512-/2O0TNl+Sx/cCy2kQlSCOujvRwz+Rxg9JxyMX5Vc14ZqrVJ4FsD2S/jJWLtE2YJ+EtLoc15Zzw2GogZO7aBcLQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.9.0-rc.1.tgz", + "integrity": "sha512-BebopjEIBI8dXQZ2zGLH4HNCQOpwkhC2/YRNJ5uHYuSAz/5fNFqzydw+0PvQbBXiVTXgPZtcn6A8dxr7IjqEdA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.8.0.tgz", - "integrity": "sha512-n2QRKTEnvQQgiyTQ7uVbz7XsGL0HRwaEtLqEMbaON6oYCsGWFFsbp8QqyHdB8iBQSrlV9I1J4sS0e5Ry+W25YQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.9.0-rc.1.tgz", + "integrity": "sha512-2QRKpcTwRBwuCBV0DgBgaE1LMMC8V8mGnhKVjWzyUoGVD1nD4H73j73EMJgjP6vUTxEwYyXCZmiAry5sUJNCBg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.8.0.tgz", - "integrity": "sha512-KdFOrfVIwtjavoa+S5ro1gi2Er8IPqXnY6gpTRpAgfO/f+/ZRg6AwPKn4SCc7QqJ8ThHpsg8wki8WGiK04rfbA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.9.0-rc.1.tgz", + "integrity": "sha512-j0lq+qRwdoV5iuqtw7qY5e6jRuUR5uxG4lZhWFbcgFQl7wL/C4wbdzVOQNoo4MCFqEZDR0PCdbUpWgKAoJoV/A==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.8.0.tgz", - "integrity": "sha512-g7FIonq/5wHH2+e/+DhB+t3E4wu7dM4MrKxLsP6b8JmYz7Y0t9OlTBT5J+i3P8YnJKYY6i5V5Eip4QNWJqC+sQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.9.0-rc.1.tgz", + "integrity": "sha512-/yYLqVwg5QDtoKevLxgleSCEYaRR7edmSVm2eYNQjbEA8BXHHH02CDGoVybb/fegsd27mqE3jkiNxAe1JnV8XA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.8.0.tgz", - "integrity": "sha512-+/K59hTkBJr6bYOrTgPtvZEVsr59MPNwvIHhGm685WZPZrNA9dGPZrO9vnw1eyNq70XYuHkiNkmKUmna9mQmIA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.9.0-rc.1.tgz", + "integrity": "sha512-X1AY6VnPs+gCFQwyVu2ymAAzwXPEfh50jdfNiBVj3Icfq8OjFkqTATCRkclZEl7Q6ioZrZWj7Rvs9eRckvZ/mA==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.8.0.tgz", - "integrity": "sha512-BSWQ05XYJSS6WKpA6//QnSnMehV5py5j8bxl7bZzmrthr2SwyejwS+pGYq7rTqWw7BBk1mA8I7Zkl+kVph/7+g==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.9.0-rc.1.tgz", + "integrity": "sha512-T4e6Lzhd4T/sKQF9ShRU4sypymhyoK/rfnudT3zmQZ7jcTG2mVYW6nalHXurgOystQEMOE9kn0fvkA1PHqosDg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.8.0.tgz", - "integrity": "sha512-+IFJYlPsUvJYNDc8sWB4zan/dTCCj4vkqwXALW3xLSxpsKSvtSvXPzXK/i4YwaT4Azx4hfrWIW2cz6/h5JDonA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.9.0-rc.1.tgz", + "integrity": "sha512-MI+qQqwyPDM3Ox09cBiPC13zOZ58DCacOF+kswjbf7yIsoPbqxOwLHDZP2aJSE9oqrpJQ/nZw8SNr4xR7BjWSQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.8.0.tgz", - "integrity": "sha512-nbRoValRn17SadfpGKKT1RfyoRlCLhvij2BRMw1KyldztWlWGozPQSDjqhcEPSzJZCrNV76nIMbg5FLfsTl4iA==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.9.0-rc.1.tgz", + "integrity": "sha512-AmZrfO8puhFjHn++MdPfXKCiKb0ifn8h/N8hCw3CPBFmEGvmjLOmH/fxq48i5hCqW615vwzcHOV7jTmUldDn1A==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.8.0.tgz", - "integrity": "sha512-xnZvjjmRHJbyC9bd6LMYfHA8Jjb51GTJuFAd4j4S9NVZYomQDBFl7IKVWtUFzQvVzk93zJHVSWO8vmtNLQZreg==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.9.0-rc.1.tgz", + "integrity": "sha512-uU9covkzklnUGcKlxv8C9j1SwmpjQx+HmgSiDtS6ErWlQF6awXsCbmFFRAi/iCj6s9ZleeIpIkcf6PPGDk9VDg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-button": "1.8.0", - "@umbraco-ui/uui-popover-container": "1.8.0", - "@umbraco-ui/uui-symbol-more": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-button": "1.9.0-rc.1", + "@umbraco-ui/uui-popover-container": "1.9.0-rc.1", + "@umbraco-ui/uui-symbol-more": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.8.0.tgz", - "integrity": "sha512-5Dt7EsvACfs75bsncIDvqitXYub2Rfntbrc3gzXLHjqOQy2YBL5s/HNGz3xsf5msKuDAR0dmTyxhItaDAi7EkQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.9.0-rc.1.tgz", + "integrity": "sha512-3RTqNMT7yIu4xzwS6yVHovwAr1kTTaBShQEZHVIEcSbZyDv+vTtHNfpcJycpALFSXGQwIGfqGwEz6aBt7MFFgQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.8.0.tgz", - "integrity": "sha512-WYWiD3x1DXbsAALmTT2txoeeqiZ9J/FlkTGL1Wasu89jfm8bAgxUG5wuoa8SL4r79rAF+RUDrJPygeUqDm0N8A==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.9.0-rc.1.tgz", + "integrity": "sha512-+TiBEoHH2hPcgV6bphvkQcW2CSAJHP37cBv+P3ydkeN4HVoURqdk/1jTJ97J7okUbqbVmUi8xM6yNV0W56yHZw==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.8.0.tgz", - "integrity": "sha512-62q36/jggXp+GdRSzseQ7d63hUIXtHIXe/5bnSSHXcxxIcnbf9Sy3pkBkOYM7CXgBUUwt9T9IHLZ6eGw/6K9Xw==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.9.0-rc.1.tgz", + "integrity": "sha512-EHTJs5fH6cIBiB4Yh2d8dRX3wHDn7giaiFML1RZBri4QCELtYqy8YuZi938Wsf8gOC7y6fhDhPIC6M090ZaYqg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-button": "1.8.0", - "@umbraco-ui/uui-css": "1.8.0", - "@umbraco-ui/uui-icon": "1.8.0", - "@umbraco-ui/uui-icon-registry-essential": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-button": "1.9.0-rc.1", + "@umbraco-ui/uui-css": "1.9.0-rc.0", + "@umbraco-ui/uui-icon": "1.9.0-rc.1", + "@umbraco-ui/uui-icon-registry-essential": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.8.0.tgz", - "integrity": "sha512-NdILHgGvKFF+JZGejTJnXt1LdJIl/MxmPUj6+rvEGCO2SDhZmIOHjnIohT8HFytxmJqyWJpryPQjo6KJezRVbQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.9.0-rc.1.tgz", + "integrity": "sha512-4vooYHpDRl5WTISKdPZY/YCBnx345/cFGse6hXGPah7W3Frq1Wo5lRV8V22zwdOsiYmsTrPvQg9Oy74FvZi+8w==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-toast-notification": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-toast-notification": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.8.0.tgz", - "integrity": "sha512-NyGFv3kAcU8XMxLAyDhy3dt1oIHOwbAYO5+Utm4CFAAvcJzVTNn948Sp0dTdcfSjXjZG+3Ufv/Qb/OpcrybJ/w==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.9.0-rc.1.tgz", + "integrity": "sha512-Cu5O0vSuLpl7K5MCnK/zBH/MsDla0fkxYiXZdIH4ikQI37KmvoqVb+V0nJQNwf9HfxMkJ9KOoviR4dfPhHJk1A==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-css": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-css": "1.9.0-rc.0" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.8.2.tgz", - "integrity": "sha512-imjSbkHQy8pjzIOco2ts61sVtVLiu6JtXTaX8KxgSpGKZ/NofhJ48QbhRUx0qJ4l4Cm3KDC93x/2RzFG99LhkQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.9.0-rc.1.tgz", + "integrity": "sha512-J/8q1eQgnjuwDGyzPwSM+cf1mChHrj14RLJjVNQEG8FXyJuzFD4NhlrVmLa0U3sZbA2Szg6K1X0wVQOLP7Z6uQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0", - "@umbraco-ui/uui-boolean-input": "1.8.2" + "@umbraco-ui/uui-base": "1.9.0-rc.1", + "@umbraco-ui/uui-boolean-input": "1.9.0-rc.1" } }, "node_modules/@umbraco-ui/uui-visually-hidden": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.8.0.tgz", - "integrity": "sha512-3a4/B2uM3YfXjI9dyfSL2Z47ziwW7HuYoozNderKO/I7l0CgxgoHIOwF1sRb3QgOlsFhhfeKdndvU7SbD6tazQ==", + "version": "1.9.0-rc.1", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.9.0-rc.1.tgz", + "integrity": "sha512-S2ty8VETMrxRicrFR9cUUPSGQ0KOR+ITmzeQzcW67wD0KDPwbU56BnoMKmguuNfzziMWQZjLCz8DfQcnPU+NSg==", "dependencies": { - "@umbraco-ui/uui-base": "1.8.0" + "@umbraco-ui/uui-base": "1.9.0-rc.1" } }, "node_modules/@web/browser-logs": { @@ -11534,6 +11411,12 @@ "resolved": "https://registry.npmjs.org/element-internals-polyfill/-/element-internals-polyfill-1.3.11.tgz", "integrity": "sha512-SQLQNVY4wMdpnP/F/HtalJbpEenQd46Avtjm5hvUdeTs3QU0zHFNX5/AmtQIPPcfzePb0ipCkQGY4GwYJIhLJA==" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -11841,16 +11724,16 @@ } }, "node_modules/eslint": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.6.0.tgz", - "integrity": "sha512-ElQkdLMEEqQNM9Njff+2Y4q2afHk7JpkPvrd7Xh7xefwgQynqPxwf55J7di9+MEibWUGdNjFF9ITG9Pck5M84w==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.7.0.tgz", + "integrity": "sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", + "@eslint-community/regexpp": "^4.11.0", "@eslint/config-array": "^0.17.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.6.0", + "@eslint/js": "9.7.0", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", @@ -11859,7 +11742,7 @@ "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.1", + "eslint-scope": "^8.0.2", "eslint-visitor-keys": "^4.0.0", "espree": "^10.1.0", "esquery": "^1.5.0", @@ -12068,9 +11951,9 @@ } }, "node_modules/eslint-scope": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", - "integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -13112,21 +12995,24 @@ "dev": true }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", + "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" }, + "engines": { + "node": "20 || >=22" + }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -13159,15 +13045,15 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -14450,15 +14336,15 @@ } }, "node_modules/jackspeak": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.2.tgz", - "integrity": "sha512-qH3nOSj8q/8+Eg8LUPOq3C+6HWkpUioIjDsq1+D4zY91oZvpPttw8GwtF1nReRYKXl+1AORyFqtm2f5Q1SB6/Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", + "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": "14 >=14.21 || 16 >=16.20 || >=18" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -15390,9 +15276,9 @@ } }, "node_modules/lucide-static": { - "version": "0.407.0", - "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-0.407.0.tgz", - "integrity": "sha512-RkFYdnnkQ5K9/V7V1yY+KiZn0Ugc9b0r9I19yuGu8TRA7HcNzcpuP8Fq0+V5ariS8JMzYMgv0sQ5Thaualskeg==", + "version": "0.408.0", + "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-0.408.0.tgz", + "integrity": "sha512-XJioz3vKagiyA6qMDWkYqU1RUS/bMjqio0/TCOItievnV/C4wwgJZGAbk6eVDe6Wv+d0e9NbhS7Y8yMEpGkElQ==", "dev": true }, "node_modules/lunr": { @@ -15486,9 +15372,9 @@ } }, "node_modules/marked": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", - "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.2.tgz", + "integrity": "sha512-J6CPjP8pS5sgrRqxVRvkCIkZ6MFdRIjDkwUwgJ9nL2fbmM6qGQeB2C16hi8Cc9BOzj6xXzy0jyi0iPIfnMHYzA==", "bin": { "marked": "bin/marked.js" }, @@ -16493,9 +16379,9 @@ } }, "node_modules/monaco-editor": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.48.0.tgz", - "integrity": "sha512-goSDElNqFfw7iDHMg8WDATkfcyeLTNpBHQpO8incK6p5qZt5G/1j41X0xdGzpIkGojGXM+QiRQyLjnfDVvrpwA==" + "version": "0.50.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.50.0.tgz", + "integrity": "sha512-8CclLCmrRRh+sul7C08BmPBP3P8wVWfBHomsTcndxg5NRCEPfu/mc2AGU8k37ajjDVXcXFc12ORAMUkmk+lkFA==" }, "node_modules/mri": { "version": "1.2.0", @@ -17479,28 +17365,28 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dev": true, "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.2.tgz", - "integrity": "sha512-voV4dDrdVZVNz84n39LFKDaRzfwhdzJ7akpyXfTMxCgRUp07U3lcJUXRlhTKP17rgt09sUzLi5iCitpEAr+6ug==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", + "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", "dev": true, "engines": { - "node": "14 || 16 || 18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/path-to-regexp": { @@ -17607,12 +17493,12 @@ } }, "node_modules/playwright": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", - "integrity": "sha512-Hjrgae4kpSQBr98nhCj3IScxVeVUixqj+5oyif8TdIn2opTCPEzqAqNMeK42i3cWDCVu9MI+ZsGWw+gVR4ISBg==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.2.tgz", + "integrity": "sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==", "dev": true, "dependencies": { - "playwright-core": "1.45.1" + "playwright-core": "1.45.2" }, "bin": { "playwright": "cli.js" @@ -17625,9 +17511,9 @@ } }, "node_modules/playwright-core": { - "version": "1.45.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.1.tgz", - "integrity": "sha512-LF4CUUtrUu2TCpDw4mcrAIuYrEjVDfT1cHbJMfwnE2+1b8PZcFzPNgvZCvq2JfQ4aTjRCCHw5EJ2tmr2NSzdPg==", + "version": "1.45.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.2.tgz", + "integrity": "sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -17797,9 +17683,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -19408,18 +19294,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/string-width/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -19845,9 +19719,9 @@ "integrity": "sha512-okoJyxuPv1gzASxQDNgQbnUXOdAIyoOSXcXcZZu7tiW0PSKEdf3SdASxPBupRj+64/E3elHwVRnzSdo82Emqbg==" }, "node_modules/tinymce-i18n": { - "version": "24.7.8", - "resolved": "https://registry.npmjs.org/tinymce-i18n/-/tinymce-i18n-24.7.8.tgz", - "integrity": "sha512-WShFgJVHGQ3cQrZ6dHkFHb3S5o+1kLMpRa7qllUV+ZSqS1lldq1nadFgOHAr0KzWWYAMHDEow9O+cbKBlqMB+A==" + "version": "24.7.15", + "resolved": "https://registry.npmjs.org/tinymce-i18n/-/tinymce-i18n-24.7.15.tgz", + "integrity": "sha512-capZBGG8q5hSMb3C5SeVfr5SZmo7jv3mdLZPJdV8mNpe/DNCYcIzWQSFW7/CW1o9rpQ2xZz9DVSfLPLV8xCoNQ==" }, "node_modules/tmp": { "version": "0.0.33", @@ -20205,9 +20079,9 @@ "dev": true }, "node_modules/typedoc": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.3.tgz", - "integrity": "sha512-6d2Sw9disvvpdk4K7VNjKr5/3hzijtfQVHRthhDqJgnhMHy1wQz4yPMJVKXElvnZhFr0nkzo+GzjXDTRV5yLpg==", + "version": "0.26.4", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.4.tgz", + "integrity": "sha512-FlW6HpvULDKgc3rK04V+nbFyXogPV88hurarDPOjuuB5HAwuAlrCMQ5NeH7Zt68a/ikOKu6Z/0hFXAeC9xPccQ==", "dev": true, "dependencies": { "lunr": "^2.3.9", @@ -20264,14 +20138,14 @@ } }, "node_modules/typescript-eslint": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.0.tgz", - "integrity": "sha512-kaVRivQjOzuoCXU6+hLnjo3/baxyzWVO5GrnExkFzETRYJKVHYkrJglOu2OCm8Hi9RPDWX1PTNNTpU5KRV0+RA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.16.1.tgz", + "integrity": "sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "7.16.0", - "@typescript-eslint/parser": "7.16.0", - "@typescript-eslint/utils": "7.16.0" + "@typescript-eslint/eslint-plugin": "7.16.1", + "@typescript-eslint/parser": "7.16.1", + "@typescript-eslint/utils": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -20289,155 +20163,10 @@ } } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.0.tgz", - "integrity": "sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.0.tgz", - "integrity": "sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.0.tgz", - "integrity": "sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/visitor-keys": "7.16.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.0.tgz", - "integrity": "sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.0", - "@typescript-eslint/types": "7.16.0", - "@typescript-eslint/typescript-estree": "7.16.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.0.tgz", - "integrity": "sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.16.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/typescript-eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/typescript-eslint/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typescript-eslint/node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/typescript-json-schema": { - "version": "0.63.0", - "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.63.0.tgz", - "integrity": "sha512-vBfMBq4U/rZ5FIRi7u4o/YAdeRHsSabdGHogUlCPi0cYU0CGvS4Bdu8bSzyUsF+Kf5PTQUGh2TictJuQTDK6eQ==", + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.64.0.tgz", + "integrity": "sha512-Sew8llkYSzpxaMoGjpjD6NMFCr6DoWFHLs7Bz1LU48pzzi8ok8W+GZs9cG87IMBpC0UI7qwBMUI2um0LGxxLOg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", @@ -20903,9 +20632,9 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -21011,9 +20740,9 @@ } }, "node_modules/vite": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", - "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", @@ -21968,6 +21697,9 @@ "src/packages/block": { "name": "@umbraco-backoffice/block" }, + "src/packages/code-editor": { + "name": "@umbraco-backoffice/code-editor" + }, "src/packages/core": { "name": "@umbraco-backoffice/core" }, diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 6ad1b6d578..1521257aa7 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -22,7 +22,7 @@ "./block-rte": "./dist-cms/packages/block/block-rte/index.js", "./block-type": "./dist-cms/packages/block/block-type/index.js", "./block": "./dist-cms/packages/block/block/index.js", - "./code-editor": "./dist-cms/packages/templating/code-editor/index.js", + "./code-editor": "./dist-cms/packages/code-editor/index.js", "./collection": "./dist-cms/packages/core/collection/index.js", "./components": "./dist-cms/packages/core/components/index.js", "./content-type": "./dist-cms/packages/core/content-type/index.js", @@ -130,6 +130,7 @@ }, "workspaces": [ "./src/packages/block", + "./src/packages/code-editor", "./src/packages/core", "./src/packages/data-type", "./src/packages/dictionary", @@ -199,32 +200,32 @@ "dependencies": { "@types/diff": "^5.2.1", "@types/dompurify": "^3.0.5", - "@types/uuid": "^9.0.8", - "@umbraco-ui/uui": "1.8.2", - "@umbraco-ui/uui-css": "1.8.0", + "@types/uuid": "^10.0.0", + "@umbraco-ui/uui": "1.9.0-rc.2", + "@umbraco-ui/uui-css": "1.9.0-rc.0", "base64-js": "^1.5.1", "diff": "^5.2.0", - "dompurify": "^3.1.4", + "dompurify": "^3.1.6", "element-internals-polyfill": "^1.3.11", - "lit": "^3.1.3", - "marked": "^12.0.2", - "monaco-editor": "^0.48.0", + "lit": "^3.1.4", + "marked": "^13.0.2", + "monaco-editor": "^0.50.0", "rxjs": "^7.8.1", "tinymce": "^6.8.3", - "tinymce-i18n": "^24.5.8", - "uuid": "^9.0.1" + "tinymce-i18n": "^24.7.15", + "uuid": "^10.0.0" }, "devDependencies": { - "@babel/core": "^7.24.3", - "@eslint/js": "^9.6.0", - "@hey-api/openapi-ts": "^0.48.1", - "@mdx-js/react": "^3.0.0", + "@babel/core": "^7.24.9", + "@eslint/js": "^9.7.0", + "@hey-api/openapi-ts": "^0.48.3", + "@mdx-js/react": "^3.0.1", "@open-wc/testing": "^4.0.0", - "@playwright/test": "^1.45.1", - "@rollup/plugin-commonjs": "^25.0.7", + "@playwright/test": "^1.45.2", + "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-replace": "^5.0.5", + "@rollup/plugin-replace": "^5.0.7", "@storybook/addon-a11y": "^7.6.17", "@storybook/addon-actions": "^7.6.17", "@storybook/addon-essentials": "^7.6.17", @@ -232,45 +233,45 @@ "@storybook/mdx2-csf": "^1.1.0", "@storybook/web-components": "^7.6.17", "@storybook/web-components-vite": "^7.6.17", - "@types/chai": "^4.3.5", + "@types/chai": "^4.3.16", "@types/eslint__js": "^8.42.3", - "@types/mocha": "^10.0.1", + "@types/mocha": "^10.0.7", "@web/dev-server-esbuild": "^1.0.2", - "@web/dev-server-import-maps": "^0.2.0", - "@web/dev-server-rollup": "^0.6.3", - "@web/test-runner": "^0.18.1", + "@web/dev-server-import-maps": "^0.2.1", + "@web/dev-server-rollup": "^0.6.4", + "@web/test-runner": "^0.18.2", "@web/test-runner-playwright": "^0.11.0", "babel-loader": "^9.1.3", - "eslint": "^9.6.0", + "eslint": "^9.7.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-lit": "^1.14.0", "eslint-plugin-local-rules": "^3.0.2", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-wc": "^2.1.0", - "glob": "^10.3.10", - "globals": "^15.7.0", - "lucide-static": "^0.407.0", + "glob": "^11.0.0", + "globals": "^15.8.0", + "lucide-static": "^0.408.0", "msw": "^1.3.2", "playwright-msw": "^3.0.1", - "prettier": "3.3.2", + "prettier": "3.3.3", "react": "^18.2.0", "react-dom": "^18.2.0", "remark-gfm": "^3.0.1", - "rollup": "^4.14.1", + "rollup": "^4.18.1", "rollup-plugin-esbuild": "^6.1.1", "rollup-plugin-import-css": "^3.5.0", "rollup-plugin-web-worker-loader": "^1.6.1", "simple-icons": "^13.1.0", "storybook": "^7.6.17", "tiny-glob": "^0.2.9", - "tsc-alias": "^1.8.8", - "typedoc": "^0.26.3", + "tsc-alias": "^1.8.10", + "typedoc": "^0.26.4", "typescript": "^5.5.3", - "typescript-eslint": "^7.15.0", - "typescript-json-schema": "^0.63.0", - "vite": "^5.2.9", - "vite-plugin-static-copy": "^1.0.5", + "typescript-eslint": "^7.16.1", + "typescript-json-schema": "^0.64.0", + "vite": "^5.3.4", + "vite-plugin-static-copy": "^1.0.6", "vite-tsconfig-paths": "^4.3.2", "web-component-analyzer": "^2.0.0" }, diff --git a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts index e8544ac96a..b5b6c47879 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts @@ -13,6 +13,7 @@ import './components/index.js'; const CORE_PACKAGES = [ import('../../packages/block/umbraco-package.js'), + import('../../packages/code-editor/umbraco-package.js'), import('../../packages/data-type/umbraco-package.js'), import('../../packages/dictionary/umbraco-package.js'), import('../../packages/documents/umbraco-package.js'), diff --git a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts index 2c485d52da..e99105e99f 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts @@ -63,7 +63,7 @@ export class UmbUpgraderElement extends UmbLitElement { if (error) { this.errorMessage = - error instanceof ApiError ? (error.body as any).detail : error.message ?? 'Unknown error, please try again'; + error instanceof ApiError ? (error.body as any).detail : (error.message ?? 'Unknown error, please try again'); } else { history.pushState(null, '', 'section/content'); } diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/bs.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/bs.ts index 45c43ac734..1ff01c94bc 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/bs.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/bs.ts @@ -2219,8 +2219,8 @@ export default { forceHideContentEditor: 'Sakrij uređivač sadržaja', forceHideContentEditorHelp: 'Sakrijte dugme za uređivanje sadržaja i uređivač sadržaja iz preklapanja Block Editor.', - girdInlineEditing: 'Inline editovanje', - girdInlineEditingHelp: + gridInlineEditing: 'Inline editovanje', + gridInlineEditingHelp: 'Omogućava inline uređivanje za prvo svojstvo. Dodatna svojstva se mogu uređivati u prekrivaču.', blockHasChanges: 'Izmijenili ste ovaj sadržaj. Jeste li sigurni da ih želite odbaciti?', confirmCancelBlockCreationHeadline: 'Odbaciti kreiranje?', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/cy-gb.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/cy-gb.ts index 4515b586c5..7878e4d18f 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/cy-gb.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/cy-gb.ts @@ -2469,8 +2469,8 @@ export default { getSampleDescription: "Bydd hyn yn ychwanegu Blociau sylfaenol ac yn eich helpu i ddechrau gyda'r Golygydd Grid Bloc. Fe gewch Blociau ar gyfer Pennawd, Testun Cyfoethog, Delwedd, yn ogystal â Chynllun Dwy Golofn.", getSampleButton: 'Gosod', - girdInlineEditing: 'Golygu mewnol', - girdInlineEditingHelp: + gridInlineEditing: 'Golygu mewnol', + gridInlineEditingHelp: 'Yn galluogi golygu mewnol ar gyfer yr Eiddo cyntaf. Gellir golygu priodweddau ychwanegol yn y droshaen.', areaAllowedBlocksEmpty: 'Yn ddiofyn, caniateir pob math bloc mewn Ardal, Defnyddiwch yr opsiwn hwn i ganiatáu mathau dethol yn unig.', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts index 9ed617b177..29ba011438 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts @@ -328,7 +328,9 @@ export default { variantUnpublishNotAllowed: 'Unpublish is not allowed', }, blueprints: { - createBlueprintFrom: 'Opret en ny indholdsskabelon fra %0%', + createBlueprintFrom: "Opret en ny indholdsskabelon fra '%0%'", + createBlueprintItemUnder: "Opret en ny indholdsskabelon under '%0%'", + createBlueprintFolderUnder: "Opret en ny mappe under '%0%'", blankBlueprint: 'Blank', selectBlueprint: 'Vælg en indholdsskabelon', createdBlueprintHeading: 'Indholdsskabelon oprettet', @@ -2109,7 +2111,7 @@ export default { protectDescription: 'Opsæt offentlig adgang på %0%', rightsDescription: 'Opsæt rettigheder på %0%', sortDescription: 'Juster soterings rækkefølgen for %0%', - createblueprintDescription: 'Opret indholds skabelon baseret på %0%', + createblueprintDescription: 'Opret indholdsskabelon baseret på %0%', openContextMenu: 'Åben kontext menu for', currentLanguage: 'Aktivt sprog', switchLanguage: 'Skift sprog til', @@ -2237,7 +2239,7 @@ export default { addCustomStylesheet: 'Tilføj stylesheet', headlineEditorAppearance: 'Redigerings udseende', headlineDataModels: 'Data modeller', - headlineCatalogueAppearance: 'katalog udseende', + headlineCatalogueAppearance: 'Katalog udseende', labelBackgroundColor: 'Baggrunds farve', labelIconColor: 'Ikon farve', labelContentElementType: 'Indholds model', @@ -2268,8 +2270,8 @@ export default { headlineAdvanced: 'Avanceret', forceHideContentEditor: 'Skjul indholdseditoren', forceHideContentEditorHelp: 'Skjul indholds redigerings knappen samt indholdseditoren i Blok Redigerings vinduet', - girdInlineEditing: 'Direkte redigering', - girdInlineEditingHelp: + gridInlineEditing: 'Direkte redigering', + gridInlineEditingHelp: 'Tilføjer direkte redigering a det første felt. Yderligere felter optræder kun i redigerings vinduet.', blockHasChanges: 'Du har lavet ændringer til dette indhold. Er du sikker på at du vil kassere dem?', confirmCancelBlockCreationHeadline: 'Annuller oprettelse?', @@ -2532,4 +2534,18 @@ export default { routeNotFoundTitle: 'Ikke fundet', routeNotFoundDescription: 'Den side du leder efter kunne ikke findes. Kontroller adressen og prøv igen.', }, + codeEditor: { + label: 'Code editor', + languageConfigLabel: 'Sprog', + languageConfigDescription: 'Vælg sprog til syntax highlighting og IntelliSense.', + heightConfigLabel: 'Højde', + heightConfigDescription: 'Indstil højden på editorvinduet i pixels.', + lineNumbersConfigLabel: 'Linjenumre', + lineNumbersConfigDescription: 'Vis linjenumre i editorvinduet.', + minimapConfigLabel: 'Minimap', + minimapConfigDescription: 'Vis en minimap i editorvinduet.', + wordWrapConfigLabel: 'Ordbrydning', + wordWrapConfigDescription: + 'Slå ordbrydning til eller fra, så tekst automatisk brydes ved vinduets kant i stedet for at skabe en horisontal scrollbar.', + }, } as UmbLocalizationDictionary; diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts index ff6d54933f..c74158ac83 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts @@ -335,7 +335,9 @@ export default { variantUnpublishNotAllowed: 'Unpublish is not allowed', }, blueprints: { - createBlueprintFrom: 'Create a new Document Blueprint from %0%', + createBlueprintFrom: "Create a new Document Blueprint from '%0%'", + createBlueprintItemUnder: "Create a new item under '%0%'", + createBlueprintFolderUnder: "Create a new folder under '%0%'", blankBlueprint: 'Blank', selectBlueprint: 'Select a Document Blueprint', createdBlueprintHeading: 'Document Blueprint created', @@ -384,7 +386,7 @@ export default { create: { chooseNode: 'Where do you want to create the new %0%', createUnder: 'Create an item under', - createContentBlueprint: 'Select the Document Type you want to make a content blueprint for', + createContentBlueprint: 'Select the Document Type you want to make a Document Blueprint for', enterFolderName: 'Enter a folder name', updateData: 'Choose a type and a title', noDocumentTypes: @@ -1372,7 +1374,7 @@ export default { editMultiContentPublishedText: '%0% documents published and visible on the website', editVariantPublishedText: '%0% published and visible on the website', editMultiVariantPublishedText: '%0% documents published for languages %1% and visible on the website', - editBlueprintSavedHeader: 'Content Blueprint saved', + editBlueprintSavedHeader: 'Document Blueprint saved', editBlueprintSavedText: 'Changes have been successfully saved', editContentSavedHeader: 'Content saved', editContentSavedText: 'Remember to publish to make changes visible', @@ -1785,7 +1787,7 @@ export default { }, treeHeaders: { content: 'Content', - contentBlueprints: 'Content Blueprints', + contentBlueprints: 'Document Blueprints', media: 'Media', cacheBrowser: 'Cache Browser', contentRecycleBin: 'Recycle Bin', @@ -2177,7 +2179,7 @@ export default { protectDescription: 'Setup access restrictions on %0%', rightsDescription: 'Setup Permissions on %0%', sortDescription: 'Change sort order for %0%', - createblueprintDescription: 'Create Content Blueprint based on %0%', + createblueprintDescription: 'Create Document Blueprint based on %0%', openContextMenu: 'Open context menu for', currentLanguage: 'Current language', switchLanguage: 'Switch language to', @@ -2403,8 +2405,8 @@ export default { headlineAdvanced: 'Advanced', forceHideContentEditor: 'Hide content editor', forceHideContentEditorHelp: 'Hide the content edit button and the content editor from the Block Editor overlay', - girdInlineEditing: 'Inline editing', - girdInlineEditingHelp: + gridInlineEditing: 'Inline editing', + gridInlineEditingHelp: 'Enables inline editing for the first Property. Additional properties can be edited in the overlay.', blockHasChanges: 'You have made changes to this content. Are you sure you want to discard them?', confirmCancelBlockCreationHeadline: 'Discard creation?', @@ -2483,15 +2485,15 @@ export default { addColumnSpanOption: 'Add spanning %0% columns option', }, contentTemplatesDashboard: { - whatHeadline: 'What are Content Blueprints?', + whatHeadline: 'What are Document Blueprints?', whatDescription: - 'Content Blueprints are pre-defined content that can be selected when creating a new content node.', - createHeadline: 'How do I create a Content Blueprint?', + 'Document Blueprints are pre-defined content that can be selected when creating a new content node.', + createHeadline: 'How do I create a Document Blueprint?', createDescription: - '

There are two ways to create a Content Blueprint:

Once given a name, editors can start using the Content Blueprint as a foundation for their new page.

', - manageHeadline: 'How do I manage Content Blueprints?', + '

There are two ways to create a Document Blueprint:

Once given a name, editors can start using the Document Blueprint as a foundation for their new page.

', + manageHeadline: 'How do I manage Document Blueprints?', manageDescription: - 'You can edit and delete Content Blueprints from the "Content Blueprints" tree in the Settings section. Expand the Document Type which the Content Blueprint is based on and click it to edit or delete it.', + 'You can edit and delete Document Blueprints from the "Document Blueprints" tree in the Settings section. Expand the Document Type which the Document Blueprint is based on and click it to edit or delete it.', }, preview: { endLabel: 'End', @@ -2533,4 +2535,17 @@ export default { routeNotFoundTitle: 'Not found', routeNotFoundDescription: 'The requested route could not be found. Please check the URL and try again.', }, + codeEditor: { + label: 'Code editor', + languageConfigLabel: 'Language', + languageConfigDescription: 'Select the language for syntax highlighting and IntelliSense.', + heightConfigLabel: 'Height', + heightConfigDescription: 'Set the height of the code editor in pixels.', + lineNumbersConfigLabel: 'Line numbers', + lineNumbersConfigDescription: 'Show line numbers in the code editor.', + minimapConfigLabel: 'Minimap', + minimapConfigDescription: 'Show a minimap in the code editor.', + wordWrapConfigLabel: 'Word wrap', + wordWrapConfigDescription: 'Enable word wrapping in the code editor.', + }, } as UmbLocalizationDictionary; diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index 882a508481..0aca405fba 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -95,7 +95,7 @@ export default { sort: 'Allow access to change the sort order for nodes', translate: 'Allow access to translate a node', update: 'Allow access to save a node', - createblueprint: 'Allow access to create a Content Template', + createblueprint: 'Allow access to create a Document Blueprint', notify: 'Allow access to setup notifications for content nodes', }, apps: { @@ -343,14 +343,16 @@ export default { selectAllVariants: 'Select all variants', }, blueprints: { - createBlueprintFrom: 'Create a new Content Template from %0%', + createBlueprintFrom: "Create a new Document Blueprint from '%0%'", + createBlueprintItemUnder: "Create a new item under '%0%'", + createBlueprintFolderUnder: "Create a new folder under '%0%'", blankBlueprint: 'Blank', - selectBlueprint: 'Select a Content Template', - createdBlueprintHeading: 'Content Template created', - createdBlueprintMessage: "A Content Template was created from '%0%'", - duplicateBlueprintMessage: 'Another Content Template with the same name already exists', + selectBlueprint: 'Select a Document Blueprint', + createdBlueprintHeading: 'Document Blueprint created', + createdBlueprintMessage: "A Document Blueprint was created from '%0%'", + duplicateBlueprintMessage: 'Another Document Blueprint with the same name already exists', blueprintDescription: - 'A Content Template is predefined content that an editor can select to use as the\n basis for creating new content\n ', + 'A Document Blueprint is predefined content that an editor can select to use as the\n basis for creating new content\n ', }, media: { clickToUpload: 'Click to upload', @@ -393,7 +395,7 @@ export default { create: { chooseNode: 'Where do you want to create the new %0%', createUnder: 'Create an item under', - createContentBlueprint: 'Select the Document Type you want to make a content template for', + createContentBlueprint: 'Select the Document Type you want to make a Document Blueprint for', enterFolderName: 'Enter a folder name', updateData: 'Choose a type and a title', noDocumentTypes: @@ -1389,7 +1391,7 @@ export default { editContentPublishedFailedByParent: 'Content could not be published, because a parent page is not published', editContentPublishedHeader: 'Content published', editContentPublishedText: 'and visible on the website', - editBlueprintSavedHeader: 'Content Template saved', + editBlueprintSavedHeader: 'Document Blueprint saved', editBlueprintSavedText: 'Changes have been successfully saved', editContentSavedHeader: 'Content saved', editContentSavedText: 'Remember to publish to make changes visible', @@ -1836,7 +1838,7 @@ export default { }, treeHeaders: { content: 'Content', - contentBlueprints: 'Content Templates', + contentBlueprints: 'Document Blueprints', media: 'Media', cacheBrowser: 'Cache Browser', contentRecycleBin: 'Recycle Bin', @@ -1875,6 +1877,8 @@ export default { settingsGroup: 'Settings', templatingGroup: 'Templating', thirdPartyGroup: 'Third Party', + structureGroup: 'Structure', + advancedGroup: 'Advanced', webhooks: 'Webhooks', }, update: { @@ -2234,7 +2238,7 @@ export default { protectDescription: 'Setup access restrictions on %0%', rightsDescription: 'Setup Permissions on %0%', sortDescription: 'Change sort order for %0%', - createblueprintDescription: 'Create Content Template based on %0%', + createblueprintDescription: 'Create Document Blueprint based on %0%', openContextMenu: 'Open context menu for', currentLanguage: 'Current language', switchLanguage: 'Switch language to', @@ -2466,8 +2470,8 @@ export default { headlineAdvanced: 'Advanced', forceHideContentEditor: 'Hide content editor', forceHideContentEditorHelp: 'Hide the content edit button and the content editor from the Block Editor overlay.', - girdInlineEditing: 'Inline editing', - girdInlineEditingHelp: + gridInlineEditing: 'Inline editing', + gridInlineEditingHelp: 'Enables inline editing for the first Property. Additional properties can be edited in the overlay.', blockHasChanges: 'You have made changes to this content. Are you sure you want to discard them?', confirmCancelBlockCreationHeadline: 'Discard creation?', @@ -2548,15 +2552,15 @@ export default { labelInlineMode: 'Display inline with text', }, contentTemplatesDashboard: { - whatHeadline: 'What are Content Templates?', + whatHeadline: 'What are Document Blueprints?', whatDescription: - 'Content Templates are pre-defined content that can be selected when creating a new\n content node.\n ', - createHeadline: 'How do I create a Content Template?', + 'Document Blueprints are pre-defined content that can be selected when creating a new\n content node.\n ', + createHeadline: 'How do I create a Document Blueprint?', createDescription: - '\n

There are two ways to create a Content Template:

\n \n

Once given a name, editors can start using the Content Template as a foundation for their new page.

\n ', - manageHeadline: 'How do I manage Content Templates?', + '\n

There are two ways to create a Document Blueprint:

\n \n

Once given a name, editors can start using the Document Blueprint as a foundation for their new page.

\n ', + manageHeadline: 'How do I manage Document Blueprints?', manageDescription: - 'You can edit and delete Content Templates from the "Content Templates" tree in the\n Settings section. Expand the Document Type which the Content Template is based on and click it to edit or delete\n it.\n ', + 'You can edit and delete Document Blueprints from the "Document Blueprints" tree in the\n Settings section. Expand the Document Type which the Document Blueprint is based on and click it to edit or delete\n it.\n ', }, preview: { endLabel: 'End', @@ -2602,4 +2606,17 @@ export default { routeNotFoundTitle: 'Not found', routeNotFoundDescription: 'The requested route could not be found. Please check the URL and try again.', }, + codeEditor: { + label: 'Code editor', + languageConfigLabel: 'Language', + languageConfigDescription: 'Select the language for syntax highlighting and IntelliSense.', + heightConfigLabel: 'Height', + heightConfigDescription: 'Set the height of the code editor in pixels.', + lineNumbersConfigLabel: 'Line numbers', + lineNumbersConfigDescription: 'Show line numbers in the code editor.', + minimapConfigLabel: 'Minimap', + minimapConfigDescription: 'Show a minimap in the code editor.', + wordWrapConfigLabel: 'Word wrap', + wordWrapConfigDescription: 'Enable word wrapping in the code editor.', + }, } as UmbLocalizationDictionary; diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/es-es.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/es-es.ts index 5903b96f02..b51465d40b 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/es-es.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/es-es.ts @@ -751,9 +751,13 @@ export default { notifications: 'Notificaciones', }, packager: { + actions: 'Acciones', + created: 'Creada', + createPackage: 'Crear paquete', chooseLocalPackageText: 'Elige un paquete de tu máquina, seleccionando el botón Examinar
y localizando el paquete. Los paquetes de Umbraco normalmente tienen la extensión ".umb" o ".zip".', packageLicense: 'Licencia', + installed: 'Instalada', installedPackages: 'Paquetes instalados', noPackages: 'No tienes instalado ningún paquete', noPackagesDescription: @@ -890,6 +894,7 @@ export default { translation: 'Traducción', users: 'Usuarios', help: 'Ayuda', + packages: 'Paquetes', }, help: { theBestUmbracoVideoTutorials: 'Los mejores tutoriales en video para Umbraco', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/hr-hr.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/hr-hr.ts index 96ecf0829c..29b8e8b566 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/hr-hr.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/hr-hr.ts @@ -2279,8 +2279,8 @@ export default { headlineAdvanced: 'Napredno', forceHideContentEditor: 'Sakrij uređivač sadržaja', forceHideContentEditorHelp: 'Sakrij gumb za uređivanje sadržaja i uređivač sadržaja iz preklapanja Block Editor.', - girdInlineEditing: 'Inline uređivanje', - girdInlineEditingHelp: + gridInlineEditing: 'Inline uređivanje', + gridInlineEditingHelp: 'Omogućava inline uređivanje za prvo svojstvo. Dodatna svojstva se mogu uređivati u prekrivaču.', blockHasChanges: 'Izmijenili ste ovaj sadržaj. Jeste li sigurni da ih želite odbaciti?', confirmCancelBlockCreationHeadline: 'Odbaciti kreiranje?', diff --git a/src/Umbraco.Web.UI.Client/src/css/user-defined.css b/src/Umbraco.Web.UI.Client/src/css/user-defined.css deleted file mode 100644 index 35c48a145b..0000000000 --- a/src/Umbraco.Web.UI.Client/src/css/user-defined.css +++ /dev/null @@ -1 +0,0 @@ -/* This file can be overridden by placing a file with the same name in the /wwwroot/umbraco/backoffice/css folder of the website */ diff --git a/src/Umbraco.Web.UI.Client/src/external/monaco-editor/index.ts b/src/Umbraco.Web.UI.Client/src/external/monaco-editor/index.ts index ca2e3b1a7c..ecb84ae91a 100644 --- a/src/Umbraco.Web.UI.Client/src/external/monaco-editor/index.ts +++ b/src/Umbraco.Web.UI.Client/src/external/monaco-editor/index.ts @@ -13,20 +13,6 @@ import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker.js?worker import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker.js?worker'; /* eslint-enable */ -import { css, unsafeCSS } from '@umbraco-cms/backoffice/external/lit'; - -export const monacoEditorStyles = css` - ${unsafeCSS(styles)} -`; - -export const monacoJumpingCursorHack = css` - /* a hacky workaround this issue: https://github.com/microsoft/monaco-editor/issues/3217 - should probably be removed when the issue is fixed */ - .view-lines { - font-feature-settings: revert !important; - } -`; - const initializeWorkers = () => { self.MonacoEnvironment = { getWorker(workerId: string, label: string): Promise | Worker { @@ -50,3 +36,4 @@ const initializeWorkers = () => { initializeWorkers(); export * as monaco from 'monaco-editor'; +export { styles }; diff --git a/src/Umbraco.Web.UI.Client/src/external/router-slot/util/url.ts b/src/Umbraco.Web.UI.Client/src/external/router-slot/util/url.ts index f9a95d0897..8ca75dc55d 100644 --- a/src/Umbraco.Web.UI.Client/src/external/router-slot/util/url.ts +++ b/src/Umbraco.Web.UI.Client/src/external/router-slot/util/url.ts @@ -70,7 +70,7 @@ export function queryString(): string { * @returns Params */ export function query(): Query { - return toQuery(queryString().substr(1)); + return toQuery(queryString().substring(1)); } /** diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts index 0eaa8a1855..2f45cdca03 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/data-type/data-type.data.ts @@ -493,6 +493,23 @@ export const data: Array = [ }, ], }, + { + name: 'Code Editor', + id: 'dt-codeEditor', + parent: null, + editorAlias: 'Umbraco.Plain.String', + editorUiAlias: 'Umb.PropertyEditorUi.CodeEditor', + hasChildren: false, + isFolder: false, + canIgnoreStartNodes: false, + isDeletable: true, + values: [ + { + alias: 'language', + value: 'html', + }, + ], + }, { name: 'Markdown Editor', id: 'dt-markdownEditor', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts index ac9dabac6b..e8ef422e04 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document-type/document-type.data.ts @@ -713,6 +713,30 @@ export const data: Array = [ labelOnTop: false, }, }, + { + id: '34', + container: { + id: 'all-properties-group-key', + }, + alias: 'codeEditor', + name: 'Code Editor', + description: 'umb-code-editor configured with the `html` language.', + dataType: { + id: 'dt-codeEditor', + }, + variesByCulture: false, + variesBySegment: false, + sortOrder: 0, + validation: { + mandatory: true, + mandatoryMessage: null, + regEx: null, + regExMessage: null, + }, + appearance: { + labelOnTop: false, + }, + }, ], containers: [ { diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts index 1c0a6b60a2..2e3dce12d4 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/document/document.data.ts @@ -82,6 +82,36 @@ export const data: Array = [ `, }, }, + { + alias: 'codeEditor', + culture: null, + segment: null, + value: `

Lorem ipsum dolor sit amet consectetuer adipiscing elit

+
    +
  • Lorem ipsum dolor sit amet consectetuer.
  • +
  • Aenean commodo ligula eget dolor.
  • +
  • Aenean massa cum sociis natoque penatibus.
  • +
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing + elit. Aenean commodo ligula eget dolor. +

+

+

+ Lorem ipsum dolor sit amet, consectetuer + adipiscing elit. Aenean commodo ligula eget dolor. + Aenean massa strong. Cum sociis + natoque penatibus et magnis dis parturient montes, + nascetur ridiculus mus. Donec quam felis, ultricies + nec, pellentesque eu, pretium quis, sem. Nulla consequat + massa quis enim. Donec pede justo, fringilla vel, + aliquet nec, vulputate eget, arcu. In em + enim justo, rhoncus ut, imperdiet a, venenatis vitae, + justo. Nullam link + dictum felis eu pede mollis pretium. +
+

`, + }, { alias: 'email', culture: null, diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts index f072e4f164..7cc322ba99 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts @@ -30,8 +30,8 @@ export class UmbBlockGridEntryContext implements UmbBlockGridScalableContext { // - readonly columnSpan = this._layout.asObservablePart((x) => (x ? x.columnSpan ?? null : undefined)); - readonly rowSpan = this._layout.asObservablePart((x) => (x ? x.rowSpan ?? null : undefined)); + readonly columnSpan = this._layout.asObservablePart((x) => (x ? (x.columnSpan ?? null) : undefined)); + readonly rowSpan = this._layout.asObservablePart((x) => (x ? (x.rowSpan ?? null) : undefined)); readonly layoutAreas = this._layout.asObservablePart((x) => x?.areas); readonly columnSpanOptions = this._blockType.asObservablePart((x) => x?.columnSpanOptions ?? []); readonly areaTypeGridColumns = this._blockType.asObservablePart((x) => x?.areaGridColumns); diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts index 4bde355fa7..7d16db32d8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-layout-stylesheet/property-editor-ui-block-grid-layout-stylesheet.element.ts @@ -52,7 +52,7 @@ export class UmbPropertyEditorUIBlockGridLayoutStylesheetElement const validationLimit = config?.getValueByAlias('validationLimit'); this._limitMin = validationLimit?.min ?? 0; - this._limitMax = this.#singleItemMode ? 1 : validationLimit?.max ?? Infinity; + this._limitMax = this.#singleItemMode ? 1 : (validationLimit?.max ?? Infinity); } @state() diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-advanced.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-advanced.element.ts index 3efa9c4cc8..d34cf5d569 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-advanced.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/workspace/views/block-grid-type-workspace-view-advanced.element.ts @@ -7,31 +7,33 @@ import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension- export class UmbBlockGridTypeWorkspaceViewAdvancedElement extends UmbLitElement implements UmbWorkspaceViewElement { override render() { return html` - + - + + property-editor-ui-alias="Umb.PropertyEditorUi.EyeDropper" + .config=${[{ alias: 'showAlpha', value: true }]}> + property-editor-ui-alias="Umb.PropertyEditorUi.EyeDropper" + .config=${[{ alias: 'showAlpha', value: true }]}> + - + - + + property-editor-ui-alias="Umb.PropertyEditorUi.EyeDropper" + .config=${[{ alias: 'showAlpha', value: true }]}> + property-editor-ui-alias="Umb.PropertyEditorUi.EyeDropper" + .config=${[{ alias: 'showAlpha', value: true }]}> - + diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entry.context.ts index ce54601d05..82cb9a40a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entry.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/context/block-rte-entry.context.ts @@ -12,8 +12,8 @@ export class UmbBlockRteEntryContext extends UmbBlockEntryContext< UmbBlockRteTypeModel, UmbBlockRteLayoutModel > { - readonly displayInline = this._layout.asObservablePart((x) => (x ? x.displayInline ?? false : undefined)); - readonly displayInlineConfig = this._blockType.asObservablePart((x) => (x ? x.displayInline ?? false : undefined)); + readonly displayInline = this._layout.asObservablePart((x) => (x ? (x.displayInline ?? false) : undefined)); + readonly displayInlineConfig = this._blockType.asObservablePart((x) => (x ? (x.displayInline ?? false) : undefined)); readonly forceHideContentEditorInOverlay = this._blockType.asObservablePart( (x) => !!x?.forceHideContentEditorInOverlay, diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/views/block-rte-type-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/views/block-rte-type-workspace-view.element.ts index ec6823ce01..4d04293051 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/views/block-rte-type-workspace-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/workspace/views/block-rte-type-workspace-view.element.ts @@ -57,11 +57,13 @@ export class UmbBlockRteTypeWorkspaceViewSettingsElement extends UmbLitElement i + property-editor-ui-alias="Umb.PropertyEditorUi.EyeDropper" + .config=${[{ alias: 'showAlpha', value: true }]}> + property-editor-ui-alias="Umb.PropertyEditorUi.EyeDropper" + .config=${[{ alias: 'showAlpha', value: true }]}> ${this._iconFile ? html`` - : html``} + : html``} `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts index 697144899f..9dd27d8944 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts @@ -85,7 +85,7 @@ export abstract class UmbBlockEntryContext< public readonly blockType = this._blockType.asObservable(); public readonly contentElementTypeKey = this._blockType.asObservablePart((x) => x?.contentElementTypeKey); public readonly settingsElementTypeKey = this._blockType.asObservablePart((x) => - x ? x.settingsElementTypeKey ?? undefined : null, + x ? (x.settingsElementTypeKey ?? undefined) : null, ); _layout = new UmbObjectState(undefined); @@ -126,7 +126,7 @@ export abstract class UmbBlockEntryContext< #settings = new UmbObjectState(undefined); public readonly settings = this.#settings.asObservable(); private readonly settingsDataContentTypeKey = this.#settings.asObservablePart((x) => - x ? x.contentTypeKey ?? undefined : null, + x ? (x.contentTypeKey ?? undefined) : null, ); abstract readonly showContentEdit: Observable; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/code-editor.controller.ts similarity index 97% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.controller.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/code-editor.controller.ts index b1a417ebc5..a4c041da7a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/code-editor.controller.ts @@ -8,10 +8,11 @@ import type { UmbCodeEditorHost, UmbCodeEditorRange, UmbCodeEditorSelection, -} from './code-editor.model.js'; +} from './models/code-editor.model.js'; import { themes } from './themes/index.js'; import { monaco } from '@umbraco-cms/backoffice/external/monaco-editor'; import { UmbChangeEvent, UmbInputEvent } from '@umbraco-cms/backoffice/event'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; //TODO - consider firing change event on blur @@ -27,9 +28,11 @@ import { UmbChangeEvent, UmbInputEvent } from '@umbraco-cms/backoffice/event'; * @export * @class UmbCodeEditor */ -export class UmbCodeEditorController { +export class UmbCodeEditorController extends UmbControllerBase { #host: UmbCodeEditorHost; + #editor?: monaco.editor.IStandaloneCodeEditor; + /** * The monaco editor object. This is the actual monaco editor object. It is exposed for advanced usage, but mind the fact that editor might be swapped in the future for a different library, so use on your own responsibility. For more information see [monaco editor API](https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneCodeEditor.html). * @@ -41,6 +44,7 @@ export class UmbCodeEditorController { } #options: CodeEditorConstructorOptions = {}; + /** * The options used to create the editor. * @@ -63,6 +67,7 @@ export class UmbCodeEditorController { }; #position: UmbCodeEditorCursorPosition | null = null; + /** * Provides the current position of the cursor. * @@ -72,7 +77,9 @@ export class UmbCodeEditorController { get position() { return this.#position; } + #secondaryPositions: UmbCodeEditorCursorPosition[] = []; + /** * Provides positions of all the secondary cursors. * @@ -102,6 +109,7 @@ export class UmbCodeEditorController { this.#editor.setValue(newValue ?? ''); } } + /** * Provides the current model of the editor. For advanced usage. Bare in mind that in case of the monaco library being swapped in the future, this might not be available. For more information see [monaco editor model API](https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.ITextModel.html). * @@ -112,6 +120,7 @@ export class UmbCodeEditorController { if (!this.#editor) return null; return this.#editor.getModel(); } + /** * Creates an instance of UmbCodeEditor. You should instantiate this class through the `UmbCodeEditorHost` interface and that should happen when inside DOM nodes of the host container are available, otherwise the editor will not be able to initialize, for example in lit `firstUpdated` lifecycle hook. It will make host emit change and input events when the value of the editor changes. * @param {UmbCodeEditorHost} host @@ -119,6 +128,7 @@ export class UmbCodeEditorController { * @memberof UmbCodeEditor */ constructor(host: UmbCodeEditorHost, options?: CodeEditorConstructorOptions) { + super(host); this.#options = { ...options }; this.#host = host; this.#registerThemes(); @@ -144,6 +154,7 @@ export class UmbCodeEditorController { this.#editor?.onDidChangeModel(() => { this.#host.dispatchEvent(new UmbChangeEvent()); }); + this.#editor?.onDidChangeCursorPosition((e) => { this.#position = e.position; this.#secondaryPositions = e.secondaryPositions; @@ -184,14 +195,8 @@ export class UmbCodeEditorController { const mergedOptions = { ...this.#defaultMonacoOptions, ...this.#mapOptions(options) }; - this.#editor = monaco.editor.create(this.#host.container, { - ...mergedOptions, - value: this.#host.code ?? '', - language: this.#host.language, - theme: this.#host.theme, - readOnly: this.#host.readonly, - ariaLabel: this.#host.label, - }); + this.#editor = monaco.editor.create(this.#host.container, mergedOptions); + this.#initiateEvents(); } /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/code-editor.element.ts similarity index 54% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/components/code-editor.element.ts index c7858ecfda..128b78982a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/code-editor.element.ts @@ -1,12 +1,29 @@ -import { UmbCodeEditorController } from './code-editor.controller.js'; -import type { CodeEditorLanguage, CodeEditorSearchOptions, UmbCodeEditorHost } from './code-editor.model.js'; -import { CodeEditorTheme } from './code-editor.model.js'; +import type { UmbCodeEditorController } from '../code-editor.controller.js'; +import { + type CodeEditorConstructorOptions, + CodeEditorTheme, + UmbCodeEditorLoadedEvent, + type CodeEditorLanguage, + type CodeEditorSearchOptions, + type UmbCodeEditorHost, +} from '../models/index.js'; import { UMB_THEME_CONTEXT } from '@umbraco-cms/backoffice/themes'; -import { monacoEditorStyles, monacoJumpingCursorHack } from '@umbraco-cms/backoffice/external/monaco-editor'; import type { PropertyValues, Ref } from '@umbraco-cms/backoffice/external/lit'; -import { css, html, createRef, ref, customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { + createRef, + css, + customElement, + html, + property, + ref, + state, + unsafeCSS, + when, +} from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +const elementName = 'umb-code-editor'; + /** * A custom element that renders a code editor. Code editor is based on the Monaco Editor library. * The element will listen to the theme context and update the theme accordingly. @@ -20,8 +37,9 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; * @implements {UmbCodeEditorHost} * @fires input - Fired when the value of the editor changes. * @fires change - Fired when the entire model of editor is replaced. + * @fires loaded - Fired when the editor is loaded and ready to use. */ -@customElement('umb-code-editor') +@customElement(elementName) export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditorHost { private containerRef: Ref = createRef(); @@ -35,6 +53,7 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor get editor() { return this.#editor; } + /** * Theme of the editor. Default is light. Element will listen to the theme context and update the theme accordingly. * @@ -43,6 +62,7 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor */ @property() theme: CodeEditorTheme = CodeEditorTheme.Light; + /** * Language of the editor. Default is javascript. * @@ -51,16 +71,18 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor */ @property() language: CodeEditorLanguage = 'javascript'; + /** * Label of the editor. Default is 'Code Editor'. * * @memberof UmbCodeEditorElement */ @property() - label = 'Code Editor'; + label?: string; //TODO - this should be called a value #code = ''; + /** * Value of the editor. Default is empty string. * @@ -80,16 +102,56 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor } this.requestUpdate('code', oldValue); } + /** - * Whether the editor is readonly. Default is false. + * Whether the editor is readonly. * * @memberof UmbCodeEditorElement */ @property({ type: Boolean, attribute: 'readonly' }) readonly = false; + /** + * Whether to show line numbers. + * + * @memberof UmbCodeEditorElement + */ + @property({ type: Boolean, attribute: 'disable-line-numbers' }) + disableLineNumbers = false; + + /** + * Whether to show minimap. + * + * @memberof UmbCodeEditorElement + */ + @property({ type: Boolean, attribute: 'disable-minimap' }) + disableMinimap = false; + + /** + * Whether to enable word wrap. Default is false. + * + * @memberof UmbCodeEditorElement + */ + @property({ type: Boolean, attribute: 'word-wrap' }) + wordWrap = false; + + /** + * Whether to enable folding. Default is true. + * + * @memberof UmbCodeEditorElement + */ + @property({ type: Boolean, attribute: 'disable-folding' }) + disableFolding = false; + + @state() + private _loading = true; + + @state() + private _styles?: string; + constructor() { super(); + this.consumeContext(UMB_THEME_CONTEXT, (instance) => { this.observe( instance.theme, @@ -101,19 +163,49 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor }); } - override firstUpdated() { - this.#editor = new UmbCodeEditorController(this); + override async firstUpdated() { + const { styles } = await import('@umbraco-cms/backoffice/external/monaco-editor'); + this._styles = styles; + + const { UmbCodeEditorController } = await import('../code-editor.controller.js'); + + // Options + this.#editor = new UmbCodeEditorController(this, this.#constructorOptions()); + + this._loading = false; + this.dispatchEvent(new UmbCodeEditorLoadedEvent()); } protected override updated(_changedProperties: PropertyValues): void { - if (_changedProperties.has('theme') || _changedProperties.has('language')) { - this.#editor?.updateOptions({ - theme: this.theme, - language: this.language, - }); + if ( + _changedProperties.has('theme') || + _changedProperties.has('language') || + _changedProperties.has('disableLineNumbers') || + _changedProperties.has('disableMinimap') || + _changedProperties.has('wordWrap') || + _changedProperties.has('readonly') || + _changedProperties.has('code') || + _changedProperties.has('label') || + _changedProperties.has('disableFolding') + ) { + this.#editor?.updateOptions(this.#constructorOptions()); } } + #constructorOptions(): CodeEditorConstructorOptions { + return { + language: this.language, + theme: this.theme, + ariaLabel: this.label ?? this.localize.term('codeEditor_label'), + lineNumbers: !this.disableLineNumbers, + minimap: !this.disableMinimap, + wordWrap: this.wordWrap ? 'on' : 'off', + readOnly: this.readonly, + folding: !this.disableFolding, + value: this.code, + }; + } + #translateTheme(theme: string) { switch (theme) { case 'umb-light-theme': @@ -149,16 +241,34 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor } override render() { - return html`
`; + return html` + ${this.#renderStyles()} + ${when(this._loading, () => html`
`)} +
+ `; + } + + #renderStyles() { + if (!this._styles) return; + return html` + + `; } static override styles = [ - monacoEditorStyles, - monacoJumpingCursorHack, css` :host { display: block; } + + #loader-container { + display: grid; + place-items: center; + min-height: calc(100dvh - 260px); + } + #editor-container { width: var(--editor-width); height: var(--editor-height, 100%); @@ -167,6 +277,12 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor --vscode-scrollbarSlider-background: var(--uui-color-disabled-contrast); --vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7); --vscode-scrollbarSlider-activeBackground: rgba(0, 0, 0, 0.6); + + /* a hacky workaround this issue: https://github.com/microsoft/monaco-editor/issues/3217 + should probably be removed when the issue is fixed */ + .view-lines { + font-feature-settings: revert !important; + } } `, ]; @@ -174,6 +290,6 @@ export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditor declare global { interface HTMLElementTagNameMap { - 'umb-code-editor': UmbCodeEditorElement; + [elementName]: UmbCodeEditorElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/code-editor.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/code-editor.stories.ts new file mode 100644 index 0000000000..f9f096bf96 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/code-editor.stories.ts @@ -0,0 +1,247 @@ +import type { CodeEditorLanguage } from '../models/code-editor.model.js'; +import { CodeEditorTheme } from '../models/code-editor.model.js'; +import type { UmbCodeEditorElement } from './code-editor.element.js'; +import type { Meta, StoryObj } from '@storybook/web-components'; +import { html } from '@umbraco-cms/backoffice/external/lit'; + +import './code-editor.element.js'; + +const meta: Meta = { + title: 'Components/Code Editor', + component: 'umb-code-editor', + decorators: [(story) => html`
${story()}
`], + parameters: { layout: 'fullscreen' }, + argTypes: { + theme: { + control: 'select', + options: [ + CodeEditorTheme.Dark, + CodeEditorTheme.Light, + CodeEditorTheme.HighContrastLight, + CodeEditorTheme.HighContrastLight, + ], + }, + }, +}; + +const codeSnippets: Record = { + csharp: `using System; + +namespace HelloWorld; + +public class Program +{ + public static void Main() + { + Console.WriteLine("Hello World"); + } +}`, + javascript: `// Returns "banana" +('b' + 'a' + + 'a' + 'a').toLowerCase();`, + css: `:host { + display: flex; + background-color: var(--uui-color-background); + width: 100%; + height: 100%; + flex-direction: column; +} + +#header { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + height: 70px; + background-color: var(--uui-color-surface); + border-bottom: 1px solid var(--uui-color-border); + box-sizing: border-box; +} + +#headline { + display: block; + margin: 0 var(--uui-size-layout-1); +} + +#tabs { + margin-left: auto; +}`, + html: ` + + +Page Title + + + +

This is a Heading

+

This is a paragraph.

+ + +`, + razor: `@using Umbraco.Extensions +@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage +@{ + if (Model?.Areas.Any() != true) { return; } +} + +
+ @foreach (var area in Model.Areas) + { + @await Html.GetBlockGridItemAreaHtmlAsync(area) + } +
`, + markdown: ` +You will like those projects! + +--- + +# h1 Heading 8-) +## h2 Heading +### h3 Heading +#### h4 Heading +##### h5 Heading +###### h6 Heading + + +## Horizontal Rules + +___ + +--- + +*** + + +## Typographic replacements + +Enable typographer option to see result. + +(c) (C) (r) (R) (tm) (TM) (p) (P) +- + +test.. test... test..... test?..... test!.... + +!!!!!! ???? ,, -- --- + +"Smartypants, double quotes" and 'single quotes'`, + typescript: `import { UmbTemplateRepository } from '../repository/template.repository.js'; +import { UmbWorkspaceContextBase } from '../../../shared/components/workspace/workspace-context/workspace-context.js'; +import { UmbObjectState } from '@umbraco-cms/observable-api'; +import { TemplateModel } from '@umbraco-cms/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/controller'; + +export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext { + #data = new UmbObjectState(undefined); + data = this.#data.asObservable(); + name = this.#data.asObservablePart((data) => data?.name); + content = this.#data.asObservablePart((data) => data?.content); + + constructor(host: UmbControllerHostElement) { + super(host, 'Umb.Workspace.Template', new UmbTemplateRepository(host)); + } + + getData() { + return this.#data.getValue(); + } + + setName(value: string) { + this.#data.setValue({ ...this.#data.value, name: value }); + } + + setContent(value: string) { + this.#data.setValue({ ...this.#data.value, content: value }); + } + + async load(entityId: string) { + const { data } = await this.repository.requestByKey(entityId); + if (data) { + this.setIsNew(false); + this.#data.setValue(data); + } + } + + async createScaffold(parentId: string | null) { + const { data } = await this.repository.createScaffold(parentId); + if (!data) return; + this.setIsNew(true); + this.#data.setValue(data); + } +}`, + json: `{ + "compilerOptions": { + "module": "esnext", + "target": "esnext", + "lib": ["es2020", "dom", "dom.iterable"], + "declaration": true, + "emitDeclarationOnly": true, + "noEmitOnError": true, + "outDir": "./types", + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "forceConsistentCasingInFileNames": true, + "useDefineForClassFields": false, + "skipLibCheck": true, + "resolveJsonModule": true, + "baseUrl": ".", + "paths": { + "@umbraco-cms/css": ["libs/css/custom-properties.css"], + "@umbraco-cms/modal": ["src/core/modal"], + "@umbraco-cms/models": ["libs/models"], + "@umbraco-cms/backend-api": ["libs/backend-api"], + "@umbraco-cms/context-api": ["libs/context-api"], + "@umbraco-cms/controller": ["libs/controller"], + "@umbraco-cms/element": ["libs/element"], + "@umbraco-cms/extension-api": ["libs/extension-api"], + "@umbraco-cms/extension-registry": ["libs/extension-registry"], + "@umbraco-cms/notification": ["libs/notification"], + "@umbraco-cms/observable-api": ["libs/observable-api"], + "@umbraco-cms/events": ["libs/events"], + "@umbraco-cms/entity-action": ["libs/entity-action"], + "@umbraco-cms/workspace": ["libs/workspace"], + "@umbraco-cms/utils": ["libs/utils"], + "@umbraco-cms/router": ["libs/router"], + "@umbraco-cms/sorter": ["libs/sorter"], + "@umbraco-cms/test-utils": ["libs/test-utils"], + "@umbraco-cms/repository": ["libs/repository"], + "@umbraco-cms/resources": ["libs/resources"], + "@umbraco-cms/store": ["libs/store"], + "@umbraco-cms/components/*": ["src/backoffice/components/*"], + "@umbraco-cms/sections/*": ["src/backoffice/sections/*"] + } + }, + "include": ["src/**/*.ts", "apps/**/*.ts", "libs/**/*.ts", "e2e/**/*.ts"], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] +}`, +}; + +export default meta; +type Story = StoryObj; + +const [Csharp, Javascript, Css, Html, Razor, Markdown, Typescript, Json]: Story[] = Object.keys(codeSnippets).map( + (language) => { + return { + args: { + language: language as CodeEditorLanguage, + code: codeSnippets[language as CodeEditorLanguage], + }, + }; + }, +); + +const Themes: Story = { + args: { + language: 'javascript', + code: codeSnippets.javascript, + theme: CodeEditorTheme.Dark, + }, +}; + +export { Csharp, Javascript, Css, Html, Razor, Markdown, Typescript, Json, Themes }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/index.ts new file mode 100644 index 0000000000..3cfc04bfa2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/components/index.ts @@ -0,0 +1 @@ +export * from './code-editor.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/index.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/index.ts new file mode 100644 index 0000000000..60335eb6e1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/index.ts @@ -0,0 +1,11 @@ +export * from './components/index.js'; +export * from './models/index.js'; +export type { UmbCodeEditorController } from './code-editor.controller.js'; + +/** + * @deprecated Use `import from '@umbraco-cms/backoffice/code-editor';` directly. + * This function will be removed in Umbraco 15. + */ +export function loadCodeEditor() { + return import('@umbraco-cms/backoffice/code-editor'); +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/manifests.ts new file mode 100644 index 0000000000..929a1810ad --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as propertyEditorManifest } from './property-editor/manifests.js'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [propertyEditorManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/code-editor-loaded.event.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/code-editor-loaded.event.ts new file mode 100644 index 0000000000..9be89b5727 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/code-editor-loaded.event.ts @@ -0,0 +1,7 @@ +export class UmbCodeEditorLoadedEvent extends Event { + public static readonly TYPE = 'loaded'; + + public constructor() { + super(UmbCodeEditorLoadedEvent.TYPE, { bubbles: true, cancelable: false }); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.model.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/code-editor.model.ts similarity index 95% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.model.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/models/code-editor.model.ts index b1f28f2fae..30109cb436 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.model.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/code-editor.model.ts @@ -1,4 +1,14 @@ -export type CodeEditorLanguage = 'razor' | 'typescript' | 'javascript' | 'css' | 'markdown' | 'json' | 'html'; +import type { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +export type CodeEditorLanguage = + | 'csharp' + | 'razor' + | 'typescript' + | 'javascript' + | 'css' + | 'markdown' + | 'json' + | 'html'; export enum CodeEditorTheme { Light = 'umb-light', @@ -7,13 +17,13 @@ export enum CodeEditorTheme { HighContrastDark = 'umb-hc-dark', } -export interface UmbCodeEditorHost extends HTMLElement { +export interface UmbCodeEditorHost extends UmbLitElement { container: HTMLElement; language: CodeEditorLanguage; theme: CodeEditorTheme; code: string; readonly: boolean; - label: string; + label?: string; } export interface UmbCodeEditorCursorPosition { diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/index.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/index.ts new file mode 100644 index 0000000000..21c8883042 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/models/index.ts @@ -0,0 +1,2 @@ +export * from './code-editor-loaded.event.js'; +export * from './code-editor.model.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/package.json b/src/Umbraco.Web.UI.Client/src/packages/code-editor/package.json new file mode 100644 index 0000000000..9e80323c74 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/package.json @@ -0,0 +1,8 @@ +{ + "name": "@umbraco-backoffice/code-editor", + "private": true, + "type": "module", + "scripts": { + "build": "vite build" + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/manifests.ts new file mode 100644 index 0000000000..5e6142daa1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/manifests.ts @@ -0,0 +1,71 @@ +import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifest: ManifestPropertyEditorUi = { + type: 'propertyEditorUi', + alias: 'Umb.PropertyEditorUi.CodeEditor', + name: 'Code Editor Property Editor UI', + element: () => import('./property-editor-ui-code-editor.element.js'), + meta: { + label: 'Code Editor', + propertyEditorSchemaAlias: 'Umbraco.Plain.String', + icon: 'icon-code', + group: 'common', + settings: { + properties: [ + { + alias: 'language', + label: '#codeEditor_languageConfigLabel', + description: '{#codeEditor_languageConfigDescription}', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.Dropdown', + config: [ + { + alias: 'items', + value: [ + { name: 'C#', value: 'csharp' }, + { name: 'CSS', value: 'css' }, + { name: 'HTML', value: 'html' }, + { name: 'JavaScript', value: 'javascript' }, + { name: 'JSON', value: 'json' }, + { name: 'Markdown', value: 'markdown' }, + { name: 'Razor (CSHTML)', value: 'razor' }, + { name: 'TypeScript', value: 'typescript' }, + ], + }, + ], + }, + { + alias: 'height', + label: '#codeEditor_heightConfigLabel', + description: '{#codeEditor_heightConfigDescription}', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.Integer', + config: [{ alias: 'min', value: 0 }], + }, + { + alias: 'lineNumbers', + label: '#codeEditor_lineNumbersConfigLabel', + description: '{#codeEditor_lineNumbersConfigDescription}', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', + }, + { + alias: 'minimap', + label: '#codeEditor_minimapConfigLabel', + description: '{#codeEditor_minimapConfigDescription}', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', + }, + { + alias: 'wordWrap', + label: '#codeEditor_wordWrapConfigLabel', + description: '{#codeEditor_wordWrapConfigDescription}', + propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', + }, + ], + defaultData: [ + { alias: 'language', value: 'javascript' }, + { alias: 'height', value: 400 }, + { alias: 'lineNumbers', value: true }, + { alias: 'minimap', value: true }, + { alias: 'wordWrap', value: false }, + ], + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/property-editor-ui-code-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/property-editor-ui-code-editor.element.ts new file mode 100644 index 0000000000..971ed1111a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/property-editor-ui-code-editor.element.ts @@ -0,0 +1,83 @@ +import type { CodeEditorLanguage } from '../models/index.js'; +import type { UmbCodeEditorElement } from '../components/code-editor.element.js'; +import { css, customElement, html, property, state, styleMap } from '@umbraco-cms/backoffice/external/lit'; +import { UmbInputEvent } from '@umbraco-cms/backoffice/event'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; + +import '../components/code-editor.element.js'; + +const elementName = 'umb-property-editor-ui-code-editor'; + +@customElement(elementName) +export class UmbPropertyEditorUICodeEditorElement extends UmbLitElement implements UmbPropertyEditorUiElement { + #defaultLanguage: CodeEditorLanguage = 'javascript'; + + @state() + private _language?: CodeEditorLanguage = this.#defaultLanguage; + + @state() + private _height = 400; + + @state() + private _lineNumbers = true; + + @state() + private _minimap = true; + + @state() + private _wordWrap = false; + + @property() + value = ''; + + @property({ attribute: false }) + public set config(config: UmbPropertyEditorConfigCollection | undefined) { + if (!config) return; + + this._language = config?.getValueByAlias('language') ?? this.#defaultLanguage; + this._height = Number(config?.getValueByAlias('height')) || 400; + this._lineNumbers = config?.getValueByAlias('lineNumbers') ?? false; + this._minimap = config?.getValueByAlias('minimap') ?? false; + this._wordWrap = config?.getValueByAlias('wordWrap') ?? false; + } + + #onChange(event: UmbInputEvent & { target: UmbCodeEditorElement }) { + if (!(event instanceof UmbInputEvent)) return; + this.value = event.target.code; + this.dispatchEvent(new UmbPropertyValueChangeEvent()); + } + + override render() { + return html` + + + `; + } + + static override styles = [ + css` + umb-code-editor { + border-radius: var(--uui-border-radius); + border: 1px solid var(--uui-color-divider-emphasis); + } + `, + ]; +} + +export { UmbPropertyEditorUICodeEditorElement as element }; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbPropertyEditorUICodeEditorElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/property-editor-ui-code-editor.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/property-editor-ui-code-editor.stories.ts new file mode 100644 index 0000000000..6abed142e6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/property-editor/property-editor-ui-code-editor.stories.ts @@ -0,0 +1,17 @@ +import type { UmbPropertyEditorUICodeEditorElement } from './property-editor-ui-code-editor.element.js'; +import type { Meta, StoryObj } from '@storybook/web-components'; +import { html } from '@umbraco-cms/backoffice/external/lit'; + +import './property-editor-ui-code-editor.element.js'; + +const meta: Meta = { + title: 'Property Editor UIs/Code Editor', + component: 'umb-property-editor-ui-code-editor', + id: 'umb-property-editor-ui-code-editor', + decorators: [(story) => html`
${story()}
`], +}; + +export default meta; +type Story = StoryObj; + +export const Overview: Story = {}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.dark.theme.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.dark.theme.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.dark.theme.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.dark.theme.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.hc-dark.theme.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.hc-dark.theme.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.hc-dark.theme.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.hc-dark.theme.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.hc-light.theme.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.hc-light.theme.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.hc-light.theme.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.hc-light.theme.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.light.theme.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.light.theme.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/code-editor.light.theme.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/code-editor.light.theme.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/index.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/index.ts similarity index 92% rename from src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/index.ts index bcaa4ebea6..bf9894f126 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/themes/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/themes/index.ts @@ -1,4 +1,4 @@ -import type { CodeEditorTheme } from '../code-editor.model.js'; +import type { CodeEditorTheme } from '../models/code-editor.model.js'; import { UmbCodeEditorThemeHighContrastLight } from './code-editor.hc-light.theme.js'; import { UmbCodeEditorThemeHighContrastDark } from './code-editor.hc-dark.theme.js'; import { UmbCodeEditorThemeLight } from './code-editor.light.theme.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/umbraco-package.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/umbraco-package.ts new file mode 100644 index 0000000000..6dffa1cf54 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/umbraco-package.ts @@ -0,0 +1,8 @@ +export const extensions = [ + { + name: 'Umbraco Code Editor Bundle', + alias: 'Umb.Bundle.UmbracoCodeEditor', + type: 'bundle', + js: () => import('./manifests.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/code-editor/vite.config.ts b/src/Umbraco.Web.UI.Client/src/packages/code-editor/vite.config.ts new file mode 100644 index 0000000000..dbb19c1a26 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/code-editor/vite.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'vite'; +import { rmSync } from 'fs'; +import { getDefaultConfig } from '../../vite-config-base'; + +const dist = '../../../dist-cms/packages/code-editor'; + +// delete the unbundled dist folder +rmSync(dist, { recursive: true, force: true }); + +export default defineConfig({ + ...getDefaultConfig({ dist }), +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/collection/action/collection-action-button.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/collection/action/collection-action-button.element.ts index 4831180c80..6e33b5d692 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/collection/action/collection-action-button.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/collection/action/collection-action-button.element.ts @@ -65,17 +65,16 @@ export class UmbCollectionActionButtonElement extends UmbLitElement { } override render() { + const label = this.manifest?.meta.label ? this.localize.string(this.manifest.meta.label) : this.manifest?.name; return html` + look="outline" + label=${ifDefined(label)} + href=${ifDefined(this.manifest?.meta.href)} + .state=${this._buttonState} + @click=${this._onClick}> `; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-selection-actions.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-selection-actions.element.ts index 275702495d..c12a20a145 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-selection-actions.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/collection/components/collection-selection-actions.element.ts @@ -82,7 +82,7 @@ export class UmbCollectionSelectionActionsElement extends UmbLitElement { ${this._renderSelectionCount()} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/collection/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/collection/types.ts index ecd2225151..822d309abe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/collection/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/collection/types.ts @@ -1,5 +1,5 @@ -import type { ManifestCollection } from '@umbraco-cms/backoffice/extension-registry'; import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; +import type { ManifestCollection } from '@umbraco-cms/backoffice/extension-registry'; import type { UmbPaginationManager } from '@umbraco-cms/backoffice/utils'; export interface UmbCollectionBulkActionPermissions { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/body-layout/body-layout.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/body-layout/body-layout.element.ts index 73da9a5493..8c23db144a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/body-layout/body-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/body-layout/body-layout.element.ts @@ -18,6 +18,7 @@ import { * @slot - Slot for main content * @slot icon - Slot for icon * @slot name - Slot for name + * @slot header - Slot for header element * @slot footer - Slot for footer element * @slot footer-info - Slot for info in the footer * @slot actions - Slot for actions in the footer diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts index 2ae479cd9d..86150d93fa 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/icon/icon.element.ts @@ -1,6 +1,7 @@ import { extractUmbColorVariable } from '../../resources/extractUmbColorVariable.function.js'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { html, customElement, property, state, ifDefined, css } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, state, ifDefined, css, styleMap } from '@umbraco-cms/backoffice/external/lit'; +import type { StyleInfo } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; /** @@ -10,45 +11,60 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; */ @customElement('umb-icon') export class UmbIconElement extends UmbLitElement { + #color?: string; + #fallbackColor?: string; + @state() private _icon?: string; @state() - private _color?: string; + private _style: StyleInfo = {}; + /** + * Color alias or a color code directly.\ + * If a color has been set via the name property, this property will override it. + * */ @property({ type: String }) public set color(value: string) { - if (!value) return; - this.#setColorStyle(value); + this.#color = value; + this.#updateColorStyle(); } - public get color(): string { - return this._color ?? ''; - } - - #setColorStyle(value: string) { - const alias = value.replace('color-', ''); - const variable = extractUmbColorVariable(alias); - this._color = alias ? (variable ? `--uui-icon-color: var(${variable})` : `--uui-icon-color: ${alias}`) : undefined; + public get color(): string | undefined { + return this.#color || this.#fallbackColor; } + /** + * The icon name. Can be appended with a color.\ + * Example **icon-heart color-red** + */ @property({ type: String }) public set name(value: string | undefined) { - const [icon, alias] = value ? value.split(' ') : []; - - if (alias) { - this.#setColorStyle(alias); - } else { - this._color = undefined; - } - + const [icon, color] = value ? value.split(' ') : []; + this.#fallbackColor = color; this._icon = icon; + this.#updateColorStyle(); } public get name(): string | undefined { return this._icon; } + #updateColorStyle() { + const value = this.#color || this.#fallbackColor; + + if (!value) { + this._style = { '--uui-icon-color': 'inherit' }; + return; + } + + const color = value.replace('color-', ''); + const variable = extractUmbColorVariable(color); + const styling = variable ? `var(${variable})` : color; + + this._style = { '--uui-icon-color': styling }; + } + override render() { - return html``; + return html``; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-number-range/input-number-range.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-number-range/input-number-range.element.ts index da80a9e452..63a3b4a565 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-number-range/input-number-range.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-number-range/input-number-range.element.ts @@ -119,7 +119,7 @@ export class UmbInputNumberRangeElement extends UmbFormControlMixin(UmbLitElemen label=${this.maxLabel} min=${ifDefined(this.validationRange?.min)} max=${ifDefined(this.validationRange?.max)} - placeholder=${this.validationRange?.max === Infinity ? '∞' : this.validationRange?.max ?? ''} + placeholder=${this.validationRange?.max === Infinity ? '∞' : (this.validationRange?.max ?? '')} .value=${this._maxValue} @input=${this.#onMaxInput}> `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/split-panel/split-panel.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/split-panel/split-panel.element.ts index b24ae93638..ad36835d1d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/split-panel/split-panel.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/split-panel/split-panel.element.ts @@ -8,6 +8,7 @@ import { query, state, } from '@umbraco-cms/backoffice/external/lit'; +import { clamp } from '@umbraco-cms/backoffice/utils'; /** * Custom element for a split panel with adjustable divider. @@ -89,13 +90,9 @@ export class UmbSplitPanelElement extends LitElement { } } - #clamp(value: number, min: number, max: number) { - return Math.min(Math.max(value, min), max); - } - #setPosition(pos: number) { const { width } = this.mainElement.getBoundingClientRect(); - const localPos = this.#clamp(pos, 0, width); + const localPos = clamp(pos, 0, width); const percentagePos = (localPos / width) * 100; this.position = percentagePos + '%'; } @@ -127,7 +124,7 @@ export class UmbSplitPanelElement extends LitElement { const move = (event: PointerEvent) => { const { clientX } = event; const { left, width } = this.mainElement.getBoundingClientRect(); - const localPos = this.#clamp(clientX - left, 0, width); + const localPos = clamp(clientX - left, 0, width); const mappedPos = mapXAxisToSnap(localPos, width); this.#lockedPanelWidth = this.lock === 'start' ? mappedPos : width - mappedPos; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-workspace.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-workspace.context-token.ts index 8977bc8f59..cf2c295263 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-workspace.context-token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-workspace.context-token.ts @@ -1,5 +1,5 @@ -import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; export const UMB_CONTENT_WORKSPACE_CONTEXT = new UmbContextToken< UmbContentWorkspaceContext, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to-repository.interface.ts new file mode 100644 index 0000000000..2e1eb33be9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to-repository.interface.ts @@ -0,0 +1,7 @@ +import type { UmbRepositoryErrorResponse } from '../../../repository/types.js'; +import type { UmbBulkDuplicateToRequestArgs } from './types.js'; +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface UmbBulkDuplicateToRepository extends UmbApi { + requestBulkDuplicateTo(args: UmbBulkDuplicateToRequestArgs): Promise; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to.action.kind.ts new file mode 100644 index 0000000000..0a2d16168d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to.action.kind.ts @@ -0,0 +1,23 @@ +import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '../../default/default.action.kind.js'; +import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifest: UmbBackofficeManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.DuplicateTo', + matchKind: 'duplicateTo', + matchType: 'entityBulkAction', + manifest: { + ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, + type: 'entityBulkAction', + kind: 'duplicateTo', + api: () => import('./duplicate-to.action.js'), + weight: 700, + forEntityTypes: [], + meta: { + icon: 'icon-enter', + label: '#actions_copyTo', + bulkDuplicateRepositoryAlias: '', + treeAlias: '', + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to.action.ts new file mode 100644 index 0000000000..d865a17688 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/duplicate-to.action.ts @@ -0,0 +1,66 @@ +import type { UmbBulkDuplicateToRepository } from './duplicate-to-repository.interface.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { + UmbRequestReloadChildrenOfEntityEvent, + UmbRequestReloadStructureForEntityEvent, +} from '@umbraco-cms/backoffice/entity-action'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { UMB_TREE_PICKER_MODAL } from '@umbraco-cms/backoffice/tree'; +import type { MetaEntityBulkActionDuplicateToKind } from '@umbraco-cms/backoffice/extension-registry'; + +export class UmbMediaDuplicateEntityBulkAction extends UmbEntityBulkActionBase { + async execute() { + if (this.selection?.length === 0) return; + + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + + const modalContext = modalManager.open(this, UMB_TREE_PICKER_MODAL, { + data: { + foldersOnly: this.args.meta.foldersOnly, + hideTreeRoot: this.args.meta.hideTreeRoot, + treeAlias: this.args.meta.treeAlias, + }, + }); + + const value = await modalContext.onSubmit().catch(() => undefined); + if (!value?.selection?.length) return; + + const destinationUnique = value.selection[0]; + if (destinationUnique === undefined) throw new Error('Destination Unique is not available'); + + const bulkDuplicateRepository = await createExtensionApiByAlias( + this, + this.args.meta.bulkDuplicateRepositoryAlias, + ); + if (!bulkDuplicateRepository) throw new Error('Bulk Duplicate Repository is not available'); + + await bulkDuplicateRepository.requestBulkDuplicateTo({ + uniques: this.selection, + destination: { unique: destinationUnique }, + }); + + const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); + if (!entityContext) throw new Error('Entity Context is not available'); + + const entityType = entityContext.getEntityType(); + const unique = entityContext.getUnique(); + + if (entityType && unique !== undefined) { + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + if (!eventContext) throw new Error('Event Context is not available'); + + const args = { entityType, unique }; + + const reloadChildren = new UmbRequestReloadChildrenOfEntityEvent(args); + eventContext.dispatchEvent(reloadChildren); + + const reloadStructure = new UmbRequestReloadStructureForEntityEvent(args); + eventContext.dispatchEvent(reloadStructure); + } + } +} + +export { UmbMediaDuplicateEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/index.ts new file mode 100644 index 0000000000..bba0b41bb5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/index.ts @@ -0,0 +1,2 @@ +export type { UmbBulkDuplicateToRepository } from './duplicate-to-repository.interface.js'; +export type { UmbBulkDuplicateToRequestArgs } from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/manifests.ts new file mode 100644 index 0000000000..8f6bf64f0e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as duplicateToKindManifest } from './duplicate-to.action.kind.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [duplicateToKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/types.ts new file mode 100644 index 0000000000..c4434e3f64 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/duplicate-to/types.ts @@ -0,0 +1,6 @@ +export interface UmbBulkDuplicateToRequestArgs { + uniques: Array; + destination: { + unique: string | null; + }; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/index.ts new file mode 100644 index 0000000000..c70f79f940 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/index.ts @@ -0,0 +1,3 @@ +export * from './duplicate-to/index.js'; +export * from './move-to/index.js'; +export * from './trash/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/index.ts new file mode 100644 index 0000000000..d7dbc13a3b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/index.ts @@ -0,0 +1,2 @@ +export type { UmbBulkMoveToRepository } from './move-to-repository.interface.js'; +export type { UmbBulkMoveToRequestArgs } from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/manifests.ts new file mode 100644 index 0000000000..701878051e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as moveToKindManifest } from './move-to.action.kind.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [moveToKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to-repository.interface.ts new file mode 100644 index 0000000000..3345adb499 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to-repository.interface.ts @@ -0,0 +1,7 @@ +import type { UmbRepositoryErrorResponse } from '../../../repository/types.js'; +import type { UmbBulkMoveToRequestArgs } from './types.js'; +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface UmbBulkMoveToRepository extends UmbApi { + requestBulkMoveTo(args: UmbBulkMoveToRequestArgs): Promise; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to.action.kind.ts new file mode 100644 index 0000000000..a26a2d7302 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to.action.kind.ts @@ -0,0 +1,23 @@ +import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '../../default/default.action.kind.js'; +import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifest: UmbBackofficeManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.MoveTo', + matchKind: 'moveTo', + matchType: 'entityBulkAction', + manifest: { + ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, + type: 'entityBulkAction', + kind: 'moveTo', + api: () => import('./move-to.action.js'), + weight: 700, + forEntityTypes: [], + meta: { + icon: 'icon-enter', + label: '#actions_move', + bulkMoveRepositoryAlias: '', + treeAlias: '', + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to.action.ts new file mode 100644 index 0000000000..f248afe4e8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/move-to.action.ts @@ -0,0 +1,63 @@ +import type { UmbBulkMoveToRepository } from './move-to-repository.interface.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { + UmbRequestReloadChildrenOfEntityEvent, + UmbRequestReloadStructureForEntityEvent, +} from '@umbraco-cms/backoffice/entity-action'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { UMB_TREE_PICKER_MODAL } from '@umbraco-cms/backoffice/tree'; +import type { MetaEntityBulkActionMoveToKind } from '@umbraco-cms/backoffice/extension-registry'; + +export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase { + async execute() { + if (this.selection?.length === 0) return; + + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + + const modalContext = modalManager.open(this, UMB_TREE_PICKER_MODAL, { + data: { + foldersOnly: this.args.meta.foldersOnly, + hideTreeRoot: this.args.meta.hideTreeRoot, + treeAlias: this.args.meta.treeAlias, + }, + }); + + const value = await modalContext.onSubmit().catch(() => undefined); + if (!value?.selection?.length) return; + + const destinationUnique = value.selection[0]; + if (destinationUnique === undefined) throw new Error('Destination Unique is not available'); + + const bulkMoveRepository = await createExtensionApiByAlias( + this, + this.args.meta.bulkMoveRepositoryAlias, + ); + if (!bulkMoveRepository) throw new Error('Bulk Move Repository is not available'); + + await bulkMoveRepository.requestBulkMoveTo({ uniques: this.selection, destination: { unique: destinationUnique } }); + + const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); + if (!entityContext) throw new Error('Entity Context is not available'); + + const entityType = entityContext.getEntityType(); + const unique = entityContext.getUnique(); + + if (entityType && unique !== undefined) { + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + if (!eventContext) throw new Error('Event Context is not available'); + + const args = { entityType, unique }; + + const reloadChildren = new UmbRequestReloadChildrenOfEntityEvent(args); + eventContext.dispatchEvent(reloadChildren); + + const reloadStructure = new UmbRequestReloadStructureForEntityEvent(args); + eventContext.dispatchEvent(reloadStructure); + } + } +} + +export { UmbMediaMoveEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/types.ts new file mode 100644 index 0000000000..75a99ea4ee --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/move-to/types.ts @@ -0,0 +1,6 @@ +export interface UmbBulkMoveToRequestArgs { + uniques: Array; + destination: { + unique: string | null; + }; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/index.ts new file mode 100644 index 0000000000..8bed2d2b64 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/index.ts @@ -0,0 +1,2 @@ +export type { UmbBulkTrashRepository } from './trash-repository.interface.js'; +export type { UmbBulkTrashRequestArgs } from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts new file mode 100644 index 0000000000..f48d4f6879 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as trashKindManifest } from './trash.action.kind.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [trashKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash-repository.interface.ts new file mode 100644 index 0000000000..195b2f7724 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash-repository.interface.ts @@ -0,0 +1,7 @@ +import type { UmbRepositoryErrorResponse } from '../../../repository/types.js'; +import type { UmbBulkTrashRequestArgs } from './types.js'; +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface UmbBulkTrashRepository extends UmbApi { + requestBulkTrash(args: UmbBulkTrashRequestArgs): Promise; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.kind.ts new file mode 100644 index 0000000000..5cec1325a1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.kind.ts @@ -0,0 +1,22 @@ +import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '../../default/default.action.kind.js'; +import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifest: UmbBackofficeManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.Trash', + matchKind: 'trash', + matchType: 'entityBulkAction', + manifest: { + ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, + type: 'entityBulkAction', + kind: 'trash', + api: () => import('./trash.action.js'), + weight: 700, + forEntityTypes: [], + meta: { + icon: 'icon-trash', + label: '#actions_trash', + bulkTrashRepositoryAlias: '', + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.ts new file mode 100644 index 0000000000..70cbc7ffd5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.ts @@ -0,0 +1,53 @@ +import type { UmbBulkTrashRepository } from './trash-repository.interface.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { + UmbRequestReloadChildrenOfEntityEvent, + UmbRequestReloadStructureForEntityEvent, +} from '@umbraco-cms/backoffice/entity-action'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; +import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; +import type { MetaEntityBulkActionTrashKind } from '@umbraco-cms/backoffice/extension-registry'; + +export class UmbMediaTrashEntityBulkAction extends UmbEntityBulkActionBase { + async execute() { + if (this.selection?.length === 0) return; + + await umbConfirmModal(this._host, { + headline: `Trash`, + content: `Are you sure you want to move ${this.selection.length} ${this.selection.length === 1 ? 'item' : 'items'} to the recycle bin?`, + color: 'danger', + confirmLabel: 'Trash', + }); + + const bulkTrashRepository = await createExtensionApiByAlias( + this, + this.args.meta.bulkTrashRepositoryAlias, + ); + if (!bulkTrashRepository) throw new Error('Bulk Trash Repository is not available'); + + await bulkTrashRepository.requestBulkTrash({ uniques: this.selection }); + + const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); + if (!entityContext) throw new Error('Entity Context is not available'); + + const entityType = entityContext.getEntityType(); + const unique = entityContext.getUnique(); + + if (entityType && unique !== undefined) { + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + if (!eventContext) throw new Error('Event Context is not available'); + + const args = { entityType, unique }; + + const reloadChildren = new UmbRequestReloadChildrenOfEntityEvent(args); + eventContext.dispatchEvent(reloadChildren); + + const reloadStructure = new UmbRequestReloadStructureForEntityEvent(args); + eventContext.dispatchEvent(reloadStructure); + } + } +} + +export { UmbMediaTrashEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/types.ts new file mode 100644 index 0000000000..d128c53b7a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/types.ts @@ -0,0 +1,3 @@ +export interface UmbBulkTrashRequestArgs { + uniques: Array; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/default/default.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/default/default.action.kind.ts new file mode 100644 index 0000000000..2b13205e93 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/default/default.action.kind.ts @@ -0,0 +1,20 @@ +import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST: UmbBackofficeManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.Default', + matchKind: 'default', + matchType: 'entityBulkAction', + manifest: { + type: 'entityBulkAction', + kind: 'default', + weight: 1000, + element: () => import('../entity-bulk-action.element.js'), + meta: { + icon: '', + label: 'Default Entity Bulk Action', + }, + }, +}; + +export const manifest = UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/default/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/default/manifests.ts new file mode 100644 index 0000000000..3cb64a6f47 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/default/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as defaultKindManifest } from './default.action.kind.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [defaultKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action-element.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action-element.interface.ts new file mode 100644 index 0000000000..6cc4b315a9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action-element.interface.ts @@ -0,0 +1,3 @@ +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; + +export interface UmbEntityBulkActionElement extends UmbControllerHostElement {} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.element.ts index 20baaa6da0..0478595f71 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/entity-bulk-action.element.ts @@ -1,16 +1,25 @@ -import type { UmbEntityBulkActionBase } from './entity-bulk-action-base.js'; +import type { UmbEntityBulkAction } from './entity-bulk-action.interface.js'; +import type { UmbEntityBulkActionElement } from './entity-bulk-action-element.interface.js'; +import { html, customElement, property, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event'; -import { html, ifDefined, customElement, property } from '@umbraco-cms/backoffice/external/lit'; -import type { ManifestEntityBulkAction, MetaEntityBulkAction } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { + ManifestEntityBulkAction, + MetaEntityBulkActionDefaultKind, +} from '@umbraco-cms/backoffice/extension-registry'; -@customElement('umb-entity-bulk-action') -export class UmbEntityBulkActionElement< - MetaType extends MetaEntityBulkAction = MetaEntityBulkAction, - ApiType extends UmbEntityBulkActionBase = UmbEntityBulkActionBase, -> extends UmbLitElement { +const elementName = 'umb-entity-bulk-action'; + +@customElement(elementName) +export class UmbEntityBulkActionDefaultElement< + MetaType extends MetaEntityBulkActionDefaultKind = MetaEntityBulkActionDefaultKind, + ApiType extends UmbEntityBulkAction = UmbEntityBulkAction, + > + extends UmbLitElement + implements UmbEntityBulkActionElement +{ @property({ attribute: false }) - manifest?: ManifestEntityBulkAction; + manifest?: ManifestEntityBulkAction; api?: ApiType; @@ -22,16 +31,19 @@ export class UmbEntityBulkActionElement< } override render() { - return html``; + return html` + + ${when(this.manifest?.meta.icon, () => html``)} + ${this.localize.string(this.manifest?.meta.label ?? '')} + + `; } } +export default UmbEntityBulkActionDefaultElement; + declare global { interface HTMLElementTagNameMap { - 'umb-entity-bulk-action': UmbEntityBulkActionElement; + [elementName]: UmbEntityBulkActionDefaultElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts index 24e16cf0cb..bf14ffa917 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts @@ -1,4 +1,8 @@ export * from './types.js'; +export * from './common/index.js'; export * from './entity-bulk-action-base.js'; export * from './entity-bulk-action.element.js'; export * from './entity-bulk-action.interface.js'; +export type * from './entity-bulk-action-element.interface.js'; + +export { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from './default/default.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/manifests.ts new file mode 100644 index 0000000000..306185ef77 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/manifests.ts @@ -0,0 +1,12 @@ +import { manifests as defaultEntityBulkActionManifests } from './default/manifests.js'; +import { manifests as duplicateEntityBulkActionManifests } from './common/duplicate-to/manifests.js'; +import { manifests as moveToEntityBulkActionManifests } from './common/move-to/manifests.js'; +import { manifests as trashEntityBulkActionManifests } from './common/trash/manifests.js'; +import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + ...defaultEntityBulkActionManifests, + ...duplicateEntityBulkActionManifests, + ...moveToEntityBulkActionManifests, + ...trashEntityBulkActionManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-bulk-action.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-bulk-action.model.ts index 984aa12384..967a868949 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-bulk-action.model.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-bulk-action.model.ts @@ -1,6 +1,6 @@ import type { ConditionTypes } from '../conditions/types.js'; -import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbEntityBulkActionElement } from '../../entity-bulk-action/entity-bulk-action-element.interface.js'; +import type { UmbEntityBulkAction } from '@umbraco-cms/backoffice/entity-bulk-action'; import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api'; /** @@ -8,14 +8,31 @@ import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbr * For example for content you may wish to move one or more documents in bulk */ export interface ManifestEntityBulkAction - extends ManifestElementAndApi>, + extends ManifestElementAndApi>, ManifestWithDynamicConditions { type: 'entityBulkAction'; forEntityTypes: Array; meta: MetaType; } -export interface MetaEntityBulkAction { +export interface MetaEntityBulkAction {} + +export interface ManifestEntityBulkActionDefaultKind extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'default'; +} + +export interface MetaEntityBulkActionDefaultKind extends MetaEntityBulkAction { + /** + * An icon to represent the action to be performed + * + * @examples [ + * "icon-box", + * "icon-grid" + * ] + */ + icon: string; + /** * The friendly name of the action to perform * @@ -26,3 +43,40 @@ export interface MetaEntityBulkAction { */ label?: string; } + +// DUPLICATE TO +export interface ManifestEntityBulkActionDuplicateToKind + extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'duplicateTo'; +} + +export interface MetaEntityBulkActionDuplicateToKind extends ManifestEntityBulkAction { + bulkDuplicateRepositoryAlias: string; + hideTreeRoot?: boolean; + foldersOnly?: boolean; + treeAlias: string; +} + +// MOVE TO +export interface ManifestEntityBulkActionMoveToKind extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'moveTo'; +} + +export interface MetaEntityBulkActionMoveToKind extends MetaEntityBulkActionDefaultKind { + bulkMoveRepositoryAlias: string; + hideTreeRoot?: boolean; + foldersOnly?: boolean; + treeAlias: string; +} + +// TRASH +export interface ManifestEntityBulkActionTrashKind extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'trash'; +} + +export interface MetaEntityBulkActionTrashKind extends MetaEntityBulkActionDefaultKind { + bulkTrashRepositoryAlias: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-activity.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-activity.ts index 1a21c810d9..bbd5e59293 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-activity.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-activity.ts @@ -1,4 +1,4 @@ -export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` stroke-linecap="round" stroke-linejoin="round" > - - - + + + `; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-badge-add.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-badge-add.ts index 5bc24372e1..e8f7854d36 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-badge-add.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-badge-add.ts @@ -1,4 +1,4 @@ -export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` stroke-linecap="round" stroke-linejoin="round" > - - - + + + `; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-delete.ts b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-delete.ts index 063886e0de..554f3d6dc7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-delete.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/icon-registry/icons/icon-delete.ts @@ -1,4 +1,4 @@ -export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` +export default ` = [ ...settingsManifests, ...modalManifests, ...entityActionManifests, + ...entityBulkActionManifests, ...propertyActionManifests, ...serverFileSystemManifests, ...debugManifests, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/code-editor/code-editor-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/code-editor/code-editor-modal.element.ts index eac68b2669..bb7126baaf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/code-editor/code-editor-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/code-editor/code-editor-modal.element.ts @@ -1,22 +1,17 @@ import { css, html, ifDefined, customElement, query } from '@umbraco-cms/backoffice/external/lit'; -import { loadCodeEditor, type UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; -import type { UmbCodeEditorModalData, UmbCodeEditorModalValue } from '@umbraco-cms/backoffice/modal'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; +import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; +import type { UmbCodeEditorModalData, UmbCodeEditorModalValue } from '@umbraco-cms/backoffice/modal'; -@customElement('umb-code-editor-modal') +import '@umbraco-cms/backoffice/code-editor'; + +const elementName = 'umb-code-editor-modal'; + +@customElement(elementName) export class UmbCodeEditorModalElement extends UmbModalBaseElement { - #isCodeEditorReady = new UmbBooleanState(false); - isCodeEditorReady = this.#isCodeEditorReady.asObservable(); - @query('umb-code-editor') _codeEditor?: UmbCodeEditorElement; - constructor() { - super(); - this.#loadCodeEditor(); - } - #handleConfirm() { this.value = { content: this._codeEditor?.editor?.monacoEditor?.getValue() ?? '' }; this.modalContext?.submit(); @@ -25,45 +20,32 @@ export class UmbCodeEditorModalElement extends UmbModalBaseElement`; - } - - #renderLoading() { - return html`
- -
`; - } - override render() { return html` -
${this.isCodeEditorReady ? this.#renderCodeEditor() : this.#renderLoading()}
+
${this.#renderCodeEditor()}
- Cancel +
`; } + #renderCodeEditor() { + return html` + + `; + } + static override styles = [ css` #editor-box { @@ -83,6 +65,6 @@ export default UmbCodeEditorModalElement; declare global { interface HTMLElementTagNameMap { - 'umb-code-editor-modal': UmbCodeEditorModalElement; + [elementName]: UmbCodeEditorModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts index 0caeee481b..d38e3e0c94 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts @@ -71,7 +71,7 @@ export class UmbModalContext< args.data && defaultData ? (umbDeepMerge(args.data as UmbDeepPartialObject, defaultData) as ModalData) : // otherwise pick one of them: - (args.data as ModalData) ?? defaultData, + ((args.data as ModalData) ?? defaultData), ); const initValue = diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts index ba9327f050..f44e5da409 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu-with-entity-actions/section-sidebar-menu-with-entity-actions.element.ts @@ -21,15 +21,17 @@ umbExtensionsRegistry.register(manifestWithEntityActions); @customElement('umb-section-sidebar-menu-with-entity-actions') export class UmbSectionSidebarMenuWithEntityActionsElement extends UmbSectionSidebarMenuElement { override renderHeader() { - return html` `; + return html` + + `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu/section-sidebar-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu/section-sidebar-menu.element.ts index 69f3744ed7..4f84d80985 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu/section-sidebar-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-menu/section-sidebar-menu.element.ts @@ -30,15 +30,17 @@ export class UmbSectionSidebarMenuElement< manifest?: ManifestType; renderHeader() { - return html`

${this.manifest?.meta?.label}

`; + return html`

${this.localize.string(this.manifest?.meta?.label ?? '')}

`; } override render() { - return html`${this.renderHeader()} + return html` + ${this.renderHeader()} `; + default-element="umb-menu"> + `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts index 4431ec65bd..fa926a5a20 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/settings/manifests.ts @@ -32,7 +32,7 @@ export const manifests: Array = [ name: 'Structure Settings Sidebar Menu', weight: 300, meta: { - label: 'Structure', + label: '#treeHeaders_structureGroup', menu: 'Umb.Menu.StructureSettings', }, conditions: [ @@ -54,7 +54,7 @@ export const manifests: Array = [ name: 'Advanced Settings Sidebar Menu', weight: 100, meta: { - label: 'Advanced', + label: '#treeHeaders_advancedGroup', menu: 'Umb.Menu.AdvancedSettings', }, conditions: [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts index 31cc14987d..4107034ecc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts @@ -324,7 +324,7 @@ export class UmbSorterController; - - /** - * The workspace actions to filter the available actions by. - * @example ['Umb.WorkspaceAction.Document.Save', 'Umb.WorkspaceAction.Document.SaveAndPublishNew'] - */ - @property({ attribute: false }) - public set forWorkspaceActions(value: Array) { - if (value === this._forWorkspaceActions) return; - this._forWorkspaceActions = value; - this._filter = (action) => { - return Array.isArray(action.forWorkspaceActions) - ? action.forWorkspaceActions.some((alias) => this.forWorkspaceActions.includes(alias)) - : this.forWorkspaceActions.includes(action.forWorkspaceActions); - }; - this.#observeExtensions(); - } - public get forWorkspaceActions(): Array { - return this._forWorkspaceActions; - } - private _forWorkspaceActions: Array = []; - - @state() - _filter?: (action: ManifestWorkspaceActionMenuItem) => boolean; - @property() look: UUIInterfaceLook = 'secondary'; @property() color: UUIInterfaceColor = 'default'; - @state() - _items: Array> = []; + @property({ type: Array, attribute: false }) + items: Array> = []; @state() _popoverOpen = false; - #observeExtensions(): void { - this.#extensionsController?.destroy(); - if (this._filter) { - this.#extensionsController = new UmbExtensionsElementAndApiInitializer< - ManifestWorkspaceActionMenuItem, - 'workspaceActionMenuItem', - ManifestWorkspaceActionMenuItem - >( - this, - umbExtensionsRegistry, - 'workspaceActionMenuItem', - ExtensionApiArgsMethod, - this._filter, - (extensionControllers) => { - this._items = extensionControllers; - }, - undefined, // We can leave the alias to undefined, as we destroy this our selfs. - ); - //this.#extensionsController.elementProperties = this.#elProps; - } - } - #onPopoverToggle(event: ToggleEvent) { // TODO: This ignorer is just neede for JSON SCHEMA TO WORK, As its not updated with latest TS jet. // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -88,7 +27,7 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { } override render() { - return this._items && this._items.length > 0 + return this.items?.length ? html` - ${this._items.length > 0 - ? repeat( - this._items, - (ext) => ext.alias, - (ext) => ext.component, - ) - : ''} + ${repeat( + this.items, + (ext) => ext.alias, + (ext) => ext.component, + )} @@ -120,7 +57,7 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { : nothing; } - static override styles: CSSResultGroup = [ + static override styles = [ UmbTextStyles, css` :host { @@ -143,7 +80,6 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { #popover-trigger { --uui-button-padding-top-factor: 0.5; --uui-button-padding-bottom-factor: 0.1; - --uui-button-border-radius: 0; } `, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-action/common/submit/submit.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-action/common/submit/submit.action.ts index b6ecb71e7e..9a1fc41596 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-action/common/submit/submit.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-action/common/submit/submit.action.ts @@ -37,9 +37,3 @@ export class UmbSubmitWorkspaceAction extends UmbWorkspaceActionBase extends UmbLitElement { #manifest?: ManifestWorkspaceAction; #api?: ApiType; + #extensionsController?: UmbExtensionsElementAndApiInitializer< + ManifestWorkspaceActionMenuItem, + 'workspaceActionMenuItem', + ManifestWorkspaceActionMenuItem + >; @state() private _buttonState?: UUIButtonState; - @state() - private _aliases: Array = []; - @state() _href?: string; @@ -60,6 +68,9 @@ export class UmbWorkspaceActionElement< return this.#api; } + @state() + private _items: Array> = []; + /** * Create a list of original and overwritten aliases of workspace actions for the action. */ @@ -77,7 +88,8 @@ export class UmbWorkspaceActionElement< } } } - this._aliases = Array.from(aliases); + + this.#observeExtensions(Array.from(aliases)); } private async _onClick(event: MouseEvent) { @@ -108,27 +120,61 @@ export class UmbWorkspaceActionElement< ); } - override render() { + #observeExtensions(aliases: string[]): void { + this.#extensionsController?.destroy(); + this.#extensionsController = new UmbExtensionsElementAndApiInitializer< + ManifestWorkspaceActionMenuItem, + 'workspaceActionMenuItem', + ManifestWorkspaceActionMenuItem + >( + this, + umbExtensionsRegistry, + 'workspaceActionMenuItem', + ExtensionApiArgsMethod, + (action) => { + return Array.isArray(action.forWorkspaceActions) + ? action.forWorkspaceActions.some((alias) => aliases.includes(alias)) + : aliases.includes(action.forWorkspaceActions); + }, + (extensionControllers) => { + this._items = extensionControllers; + }, + undefined, // We can leave the alias to undefined, as we destroy this our selfs. + ); + } + + #renderButton() { return html` - - - - + `; } + + #renderActionMenu() { + return html` + + `; + } + + override render() { + return when( + this._items.length, + () => html` ${this.#renderButton()} ${this.#renderActionMenu()} `, + () => this.#renderButton(), + ); + } } export default UmbWorkspaceActionElement; @@ -138,3 +184,7 @@ declare global { 'umb-workspace-action': UmbWorkspaceActionElement; } } + +function ExtensionApiArgsMethod(manifest: ManifestWorkspaceActionMenuItem) { + return [{ meta: manifest.meta }]; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts index 3a8195caf2..bf13c6af6c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/components/workspace-editor/workspace-editor.element.ts @@ -14,7 +14,7 @@ import type { UmbRoute, UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from * @slot name - Slot for name * @slot footer - Slot for workspace footer * @slot actions - Slot for workspace footer actions - * @slot default - slot for main content + * @slot - slot for main content * @export * @class UmbWorkspaceEditor * @extends {UmbLitElement} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/variant-dataset-workspace-context.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/variant-dataset-workspace-context.interface.ts index f6f0adeb9c..e2f5803948 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/variant-dataset-workspace-context.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/contexts/tokens/variant-dataset-workspace-context.interface.ts @@ -29,9 +29,3 @@ export interface UmbVariantDatasetWorkspaceContext { + @state() + private _parentName?: string; + #createFolderAction?: UmbCreateFolderEntityAction; - override connectedCallback(): void { + #itemRepository = new UmbDocumentBlueprintFolderRepository(this); + + override async connectedCallback(): Promise { super.connectedCallback(); if (!this.data?.parent) throw new Error('A parent is required to create a folder'); + if (this.data.parent.unique) { + const { data: parent } = await this.#itemRepository.request(this.data.parent.unique.toString()); + this._parentName = parent?.name ?? this.localize.term('general_unknown'); + } else { + this._parentName = this.localize.term('treeHeaders_contentBlueprints'); + } + // TODO: render the info from this instance in the list of actions this.#createFolderAction = new UmbCreateFolderEntityAction(this, { unique: this.data.parent.unique, entityType: this.data.parent.entityType, meta: { icon: 'icon-folder', - label: 'New Folder...', + label: this.localize.term('create_newFolder'), folderRepositoryAlias: UMB_DOCUMENT_BLUEPRINT_FOLDER_REPOSITORY_ALIAS, }, }); @@ -54,14 +67,14 @@ export class UmbDocumentBlueprintOptionsCreateModalElement extends UmbModalBaseE override render() { return html` - - + + - + - Select the Document Type you want to make a content blueprint for + Select the Document Type you want to make a Document Blueprint for - + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/menu-item/manifests.ts index 331ed87793..1408066bdb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/menu-item/manifests.ts @@ -9,7 +9,7 @@ const menuItem: ManifestTypes = { weight: 100, meta: { treeAlias: UMB_DOCUMENT_BLUEPRINT_TREE_ALIAS, - label: 'Document Blueprints', + label: '#treeHeaders_contentBlueprints', menus: ['Umb.Menu.StructureSettings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts index 78052ff873..9d973193b9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts @@ -5,11 +5,14 @@ import type { UmbDocumentBlueprintTreeItemModel, UmbDocumentBlueprintTreeRootMod import { UmbTreeRepositoryBase } from '@umbraco-cms/backoffice/tree'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; +import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; export class UmbDocumentBlueprintTreeRepository extends UmbTreeRepositoryBase implements UmbApi { + #localize = new UmbLocalizationController(this); + constructor(host: UmbControllerHost) { super(host, UmbDocumentBlueprintTreeServerDataSource, UMB_DOCUMENT_BLUEPRINT_TREE_STORE_CONTEXT); } @@ -21,7 +24,7 @@ export class UmbDocumentBlueprintTreeRepository const data: UmbDocumentBlueprintTreeRootModel = { unique: null, entityType: UMB_DOCUMENT_BLUEPRINT_ROOT_ENTITY_TYPE, - name: 'Document Blueprints', + name: this.#localize.term('treeHeaders_contentBlueprints'), hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts index b95893b5be..871c12f2c8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts @@ -1,58 +1,53 @@ -import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS } from './manifests.js'; -import { html, customElement, css } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @customElement('umb-document-blueprint-root-workspace') export class UmbDocumentBlueprintRootWorkspaceElement extends UmbLitElement { override render() { - return html` -
- -

- What are Content Blueprints? -

+ return html` + + +

+ What are Document Blueprints? +

- Content Blueprints are pre-defined content that can be selected when creating a new content node. + Document Blueprints are pre-defined content that can be selected when creating a new content node. -

+

- How do I create a Content Blueprint? + How do I create a Document Blueprint? -

+

There are two ways to create a Content Blueprint:

  • - Right-click a content node and select "Create Content Blueprint" to create a new Content Blueprint. + Click "Create Document Blueprint" in the action menu on a content node to create a new Document + Blueprint.
  • - Right-click the Content Blueprints tree in the Settings section and select the Document Type you want to - create a Content Blueprint for. + Click the "+" button in the Document Blueprints tree in the Settings section and select the Document + Type you want to create a Document Blueprint for.
-

Once given a name, editors can start using the Content Blueprint as a foundation for their new page.

+

Once given a name, editors can start using the Document Blueprint as a foundation for their new page.

-

+

- How do I manage Content Blueprints? + How do I manage Document Blueprints? -

+ - You can edit and delete Content Blueprints from the "Content Blueprints" tree in the Settings section. - Expand the Document Type which the Content Blueprint is based on and click it to edit or delete it. + You can edit and delete Document Blueprints from the "Document Blueprints" tree in the Settings section. + Expand the Document Type which the Document Blueprint is based on and click it to edit or delete it.
-
-
`; + + `; } - static override styles = [ - css` - #wrapper { - margin: var(--uui-size-layout-1); - } - `, - ]; + static override styles = [UmbTextStyles]; } export default UmbDocumentBlueprintRootWorkspaceElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index aa48c508c8..de04460e28 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -138,10 +138,6 @@ export class UmbDocumentBlueprintWorkspaceContext ); }, }, - { - path: 'edit/null', - component: () => import('./document-blueprint-root-workspace.element.js'), - }, { path: 'edit/:unique', component: () => import('./document-blueprint-workspace-editor.element.js'), diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/manifests.ts index 070a1991fa..f3fb48883d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/workspace/manifests.ts @@ -1,5 +1,9 @@ -import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../entity.js'; -import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { + UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE, + UMB_DOCUMENT_BLUEPRINT_FOLDER_ENTITY_TYPE, + UMB_DOCUMENT_BLUEPRINT_ROOT_ENTITY_TYPE, +} from '../entity.js'; +import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; import type { ManifestTypes, ManifestWorkspace, @@ -20,6 +24,26 @@ const workspace: ManifestWorkspace = { }, }; +const rootWorkspace: ManifestWorkspace = { + type: 'workspace', + alias: 'Umb.Workspace.DocumentBlueprint.Root', + name: 'Document Blueprint Root Workspace', + element: () => import('./document-blueprint-root-workspace.element.js'), + meta: { + entityType: UMB_DOCUMENT_BLUEPRINT_ROOT_ENTITY_TYPE, + }, +}; + +const folderWorkspace: ManifestWorkspace = { + type: 'workspace', + alias: 'Umb.Workspace.DocumentBlueprint.Folder', + name: 'Document Blueprint Folder Workspace', + element: () => import('./document-blueprint-root-workspace.element.js'), + meta: { + entityType: UMB_DOCUMENT_BLUEPRINT_FOLDER_ENTITY_TYPE, + }, +}; + const workspaceViews: Array = [ { type: 'workspaceView', @@ -48,7 +72,7 @@ const workspaceActions: Array = [ alias: 'Umb.WorkspaceAction.DocumentBlueprint.Save', name: 'Save Document Workspace Action', weight: 80, - api: UmbSaveWorkspaceAction, + api: UmbSubmitWorkspaceAction, meta: { label: 'Save', look: 'primary', @@ -63,4 +87,10 @@ const workspaceActions: Array = [ }, ]; -export const manifests: Array = [workspace, ...workspaceViews, ...workspaceActions]; +export const manifests: Array = [ + rootWorkspace, + folderWorkspace, + workspace, + ...workspaceViews, + ...workspaceActions, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts index a2eb3f1b9c..d332df01e3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace.context.ts @@ -112,7 +112,7 @@ export class UmbDocumentTypeWorkspaceContext >; const parentEntityType = params.parentEntityType; const parentUnique = params.parentUnique === 'null' ? null : params.parentUnique; - const presetAlias = params.presetAlias === 'null' ? null : params.presetAlias ?? null; + const presetAlias = params.presetAlias === 'null' ? null : (params.presetAlias ?? null); if (parentUnique === undefined) { throw new Error('ParentUnique url parameter is required to create a document type'); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts index 0e39f542dc..50a05f3eb5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts @@ -112,7 +112,12 @@ export class UmbCreateDocumentCollectionActionElement extends UmbLitElement { if (this._allowedDocumentTypes.length !== 1) return; const item = this._allowedDocumentTypes[0]; - const label = (this.manifest?.meta.label ?? this.localize.term('general_create')) + ' ' + item.name; + const label = + (this.manifest?.meta.label + ? this.localize.string(this.manifest?.meta.label) + : this.localize.term('general_create')) + + ' ' + + item.name; return html` @@ -122,7 +127,9 @@ export class UmbCreateDocumentCollectionActionElement extends UmbLitElement { #renderDropdown() { if (!this._allowedDocumentTypes.length) return; - const label = this.manifest?.meta.label ?? this.localize.term('general_create'); + const label = this.manifest?.meta.label + ? this.localize.string(this.manifest?.meta.label) + : this.localize.term('general_create'); return html` diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/manifests.ts index 93063e75bd..23e86e6e81 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/action/manifests.ts @@ -9,7 +9,7 @@ export const createManifest: ManifestCollectionAction = { element: () => import('./create-document-collection-action.element.js'), weight: 100, meta: { - label: 'Create', + label: '#general_create', }, conditions: [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/delete/delete.action.ts deleted file mode 100644 index cb33417747..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/delete/delete.action.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; - -export class UmbDocumentDeleteEntityBulkAction extends UmbEntityBulkActionBase { - async execute() { - console.log('execute bulk delete'); - } -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/index.ts new file mode 100644 index 0000000000..313aac5e13 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/index.ts @@ -0,0 +1,4 @@ +export { + UmbBulkDuplicateToDocumentRepository, + UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS, +} from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/manifests.ts new file mode 100644 index 0000000000..2a76c43335 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/manifests.ts @@ -0,0 +1,36 @@ +import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../collection/index.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; +import { UMB_DOCUMENT_TREE_ALIAS } from '../../tree/manifests.js'; +import { UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS } from './repository/constants.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { + UMB_COLLECTION_ALIAS_CONDITION, + UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, +} from '@umbraco-cms/backoffice/collection'; +import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkDuplicateAction: ManifestTypes = { + type: 'entityBulkAction', + kind: 'duplicateTo', + alias: 'Umb.EntityBulkAction.Document.DuplicateTo', + name: 'Duplicate Document Entity Bulk Action', + weight: 30, + forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], + meta: { + bulkDuplicateRepositoryAlias: UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS, + treeAlias: UMB_DOCUMENT_TREE_ALIAS, + }, + conditions: [ + { + alias: UMB_COLLECTION_ALIAS_CONDITION, + match: UMB_DOCUMENT_COLLECTION_ALIAS, + }, + { + alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, + match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkCopy, + }, + ], +}; + +export const manifests: Array = [bulkDuplicateAction, ...repositoryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/constants.ts new file mode 100644 index 0000000000..7d568e55a5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/constants.ts @@ -0,0 +1 @@ +export const UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS = 'Umb.Repository.Document.BulkDuplicate'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/duplicate-to.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/duplicate-to.repository.ts new file mode 100644 index 0000000000..93ee2f7c4c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/duplicate-to.repository.ts @@ -0,0 +1,49 @@ +import { UmbDuplicateDocumentServerDataSource } from '../../../entity-actions/duplicate/repository/document-duplicate.server.data-source.js'; +import type { UmbBulkDuplicateToDocumentRequestArgs } from './types.js'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import type { UmbBulkDuplicateToRepository } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbRepositoryErrorResponse } from '@umbraco-cms/backoffice/repository'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbBulkDuplicateToDocumentRepository extends UmbRepositoryBase implements UmbBulkDuplicateToRepository { + #duplicateSource = new UmbDuplicateDocumentServerDataSource(this); + #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (notificationContext) => { + this.#notificationContext = notificationContext; + }); + } + + async requestBulkDuplicateTo(args: UmbBulkDuplicateToDocumentRequestArgs): Promise { + let count = 0; + + for (const unique of args.uniques) { + const { error } = await this.#duplicateSource.duplicate({ + unique, + destination: args.destination, + relateToOriginal: args.relateToOriginal, + includeDescendants: args.includeDescendants, + }); + + if (error) { + const notification = { data: { message: error.message } }; + this.#notificationContext?.peek('danger', notification); + } else { + count++; + } + } + + if (count > 0) { + const notification = { data: { message: `Duplicated ${count} ${count === 1 ? 'document' : 'documents'}` } }; + this.#notificationContext?.peek('positive', notification); + } + + return {}; + } +} + +export { UmbBulkDuplicateToDocumentRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/index.ts new file mode 100644 index 0000000000..0146de7515 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/index.ts @@ -0,0 +1,2 @@ +export { UmbBulkDuplicateToDocumentRepository } from './duplicate-to.repository.js'; +export { UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS } from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/manifests.ts new file mode 100644 index 0000000000..ac3e613940 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS } from './constants.js'; +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkDuplicateRepository: ManifestRepository = { + type: 'repository', + alias: UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS, + name: 'Bulk Duplicate Media Repository', + api: () => import('./duplicate-to.repository.js'), +}; + +export const manifests: Array = [bulkDuplicateRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/types.ts new file mode 100644 index 0000000000..a6fd9924cd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate-to/repository/types.ts @@ -0,0 +1,6 @@ +import type { UmbBulkDuplicateToRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; + +export interface UmbBulkDuplicateToDocumentRequestArgs extends UmbBulkDuplicateToRequestArgs { + relateToOriginal: boolean; + includeDescendants: boolean; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate/duplicate.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate/duplicate.action.ts deleted file mode 100644 index 2f3fdd2ad1..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/duplicate/duplicate.action.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; - -export class UmbDocumentDuplicateEntityBulkAction extends UmbEntityBulkActionBase { - async execute() { - console.log('execute bulk duplicate'); - } -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts index 1ea725ee64..4633aeb035 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts @@ -1,13 +1,16 @@ import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../collection/index.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; +import { manifests as duplicateToManifests } from './duplicate-to/manifests.js'; +import { manifests as moveToManifests } from './move-to/manifests.js'; +import { manifests as trashManifests } from './trash/manifests.js'; import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection'; -import type { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extension-registry'; +import type { ManifestEntityBulkAction, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; import { UMB_COLLECTION_ALIAS_CONDITION, UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, } from '@umbraco-cms/backoffice/collection'; -export const manifests: Array = [ +export const entityBulkActions: Array = [ { type: 'entityBulkAction', kind: 'default', @@ -16,7 +19,8 @@ export const manifests: Array = [ weight: 50, api: () => import('./publish/publish.action.js'), meta: { - label: 'Publish', + icon: 'icon-globe', + label: '#actions_publish', }, forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], conditions: [ @@ -38,7 +42,8 @@ export const manifests: Array = [ weight: 40, api: () => import('./unpublish/unpublish.action.js'), meta: { - label: 'Unpublish', + icon: 'icon-globe', + label: '#actions_unpublish', }, forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], conditions: [ @@ -52,76 +57,11 @@ export const manifests: Array = [ }, ], }, - /* TODO: implement bulk duplicate action - { - type: 'entityBulkAction', - kind: 'default', - alias: 'Umb.EntityBulkAction.Document.Duplicate', - name: 'Duplicate Document Entity Bulk Action', - weight: 30, - api: UmbDocumentDuplicateEntityBulkAction, - meta: { - label: 'Duplicate...', - }, - forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], - conditions: [ - { - alias: UMB_COLLECTION_ALIAS_CONDITION, - match: UMB_DOCUMENT_COLLECTION_ALIAS, - }, - { - alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, - match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkCopy, - }, - ], - }, - */ - /* TODO: implement bulk move action - { - type: 'entityBulkAction', - kind: 'default', - alias: 'Umb.EntityBulkAction.Document.MoveTo', - name: 'Move Document Entity Bulk Action', - weight: 20, - api: UmbMoveDocumentEntityBulkAction, - meta: { - label: 'Move', - }, - forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], - conditions: [ - { - alias: UMB_COLLECTION_ALIAS_CONDITION, - match: UMB_DOCUMENT_COLLECTION_ALIAS, - }, - { - alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, - match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkMove, - }, - ], - }, - */ - /* TODO: implement bulk trash action - { - type: 'entityBulkAction', - kind: 'default', - alias: 'Umb.EntityBulkAction.Document.Delete', - name: 'Delete Document Entity Bulk Action', - weight: 10, - api: UmbDocumentDeleteEntityBulkAction, - meta: { - label: 'Delete', - }, - forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], - conditions: [ - { - alias: UMB_COLLECTION_ALIAS_CONDITION, - match: UMB_DOCUMENT_COLLECTION_ALIAS, - }, - { - alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, - match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkDelete, - }, - ], - }, - */ +]; + +export const manifests: Array = [ + ...entityBulkActions, + ...duplicateToManifests, + ...moveToManifests, + ...trashManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/constants.ts new file mode 100644 index 0000000000..4037b48892 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/constants.ts @@ -0,0 +1 @@ +export const UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS = 'Umb.Repository.Media.BulkMove'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/index.ts new file mode 100644 index 0000000000..91b4f3a861 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/index.ts @@ -0,0 +1 @@ +export { UmbBulkMoveToDocumentRepository, UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS } from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/manifests.ts new file mode 100644 index 0000000000..9dfba6f60a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/manifests.ts @@ -0,0 +1,37 @@ +import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../collection/index.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; +import { UMB_DOCUMENT_TREE_ALIAS } from '../../tree/manifests.js'; + +import { UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS } from './repository/constants.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { + UMB_COLLECTION_ALIAS_CONDITION, + UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, +} from '@umbraco-cms/backoffice/collection'; +import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkMoveAction: ManifestTypes = { + type: 'entityBulkAction', + kind: 'moveTo', + alias: 'Umb.EntityBulkAction.Document.MoveTo', + name: 'Move Document Entity Bulk Action', + weight: 20, + forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], + meta: { + bulkMoveRepositoryAlias: UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS, + treeAlias: UMB_DOCUMENT_TREE_ALIAS, + }, + conditions: [ + { + alias: UMB_COLLECTION_ALIAS_CONDITION, + match: UMB_DOCUMENT_COLLECTION_ALIAS, + }, + { + alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, + match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkMove, + }, + ], +}; + +export const manifests: Array = [bulkMoveAction, ...repositoryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/constants.ts new file mode 100644 index 0000000000..1a97d3b4c2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/constants.ts @@ -0,0 +1 @@ +export const UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS = 'Umb.Repository.Document.BulkMove'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/index.ts new file mode 100644 index 0000000000..6d61dfcc9c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/index.ts @@ -0,0 +1,2 @@ +export { UmbBulkMoveToDocumentRepository } from './move-to.repository.js'; +export { UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS } from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/manifests.ts new file mode 100644 index 0000000000..b9e609a144 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS } from './constants.js'; +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkMoveRepository: ManifestRepository = { + type: 'repository', + alias: UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS, + name: 'Bulk Move Document Repository', + api: () => import('./move-to.repository.js'), +}; + +export const manifests: Array = [bulkMoveRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/move-to.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/move-to.repository.ts new file mode 100644 index 0000000000..f791fe10c1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move-to/repository/move-to.repository.ts @@ -0,0 +1,44 @@ +import { UmbMoveDocumentServerDataSource } from '../../../entity-actions/move-to/repository/document-move.server.data-source.js'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import type { UmbBulkMoveToRepository, UmbBulkMoveToRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbRepositoryErrorResponse } from '@umbraco-cms/backoffice/repository'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbBulkMoveToDocumentRepository extends UmbRepositoryBase implements UmbBulkMoveToRepository { + #moveSource = new UmbMoveDocumentServerDataSource(this); + #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (notificationContext) => { + this.#notificationContext = notificationContext; + }); + } + + async requestBulkMoveTo(args: UmbBulkMoveToRequestArgs): Promise { + let count = 0; + + const destination = args.destination; + for (const unique of args.uniques) { + const { error } = await this.#moveSource.moveTo({ unique, destination }); + + if (error) { + const notification = { data: { message: error.message } }; + this.#notificationContext?.peek('danger', notification); + } else { + count++; + } + } + + if (count > 0) { + const notification = { data: { message: `Moved ${count} ${count === 1 ? 'document' : 'documents'}` } }; + this.#notificationContext?.peek('positive', notification); + } + + return {}; + } +} + +export { UmbBulkMoveToDocumentRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move/move.action.ts deleted file mode 100644 index 0b8ea5fd05..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/move/move.action.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; - -export class UmbMoveDocumentEntityBulkAction extends UmbEntityBulkActionBase { - async execute() { - console.log(`execute bulk move`); - } -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/index.ts new file mode 100644 index 0000000000..996885d53b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/index.ts @@ -0,0 +1 @@ +export { UmbBulkTrashDocumentRepository, UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS } from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts new file mode 100644 index 0000000000..970f756d70 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts @@ -0,0 +1,34 @@ +import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../collection/index.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; +import { UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS } from './repository/constants.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { + UMB_COLLECTION_ALIAS_CONDITION, + UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, +} from '@umbraco-cms/backoffice/collection'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; +import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection'; + +const bulkTrashAction: ManifestTypes = { + type: 'entityBulkAction', + kind: 'trash', + alias: 'Umb.EntityBulkAction.Document.Trash', + name: 'Trash Document Entity Bulk Action', + weight: 10, + forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], + meta: { + bulkTrashRepositoryAlias: UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS, + }, + conditions: [ + { + alias: UMB_COLLECTION_ALIAS_CONDITION, + match: UMB_DOCUMENT_COLLECTION_ALIAS, + }, + { + alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, + match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkDelete, + }, + ], +}; + +export const manifests: Array = [bulkTrashAction, ...repositoryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/constants.ts new file mode 100644 index 0000000000..bfe20c8592 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/constants.ts @@ -0,0 +1 @@ +export const UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS = 'Umb.Repository.Document.BulkTrash'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/index.ts new file mode 100644 index 0000000000..170a602476 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/index.ts @@ -0,0 +1,2 @@ +export { UmbBulkTrashDocumentRepository } from './trash.repository.js'; +export { UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS } from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/manifests.ts new file mode 100644 index 0000000000..50639ff844 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS } from './constants.js'; +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkTrashRepository: ManifestRepository = { + type: 'repository', + alias: UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS, + name: 'Bulk Trash Document Repository', + api: () => import('./trash.repository.js'), +}; + +export const manifests: Array = [bulkTrashRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts new file mode 100644 index 0000000000..edd03d8400 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts @@ -0,0 +1,43 @@ +import { UmbDocumentRecycleBinServerDataSource } from '../../../recycle-bin/repository/document-recycle-bin.server.data-source.js'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import type { UmbBulkTrashRepository, UmbBulkTrashRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbRepositoryErrorResponse } from '@umbraco-cms/backoffice/repository'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbBulkTrashDocumentRepository extends UmbRepositoryBase implements UmbBulkTrashRepository { + #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; + #recycleBinSource = new UmbDocumentRecycleBinServerDataSource(this); + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (notificationContext) => { + this.#notificationContext = notificationContext; + }); + } + + async requestBulkTrash(args: UmbBulkTrashRequestArgs): Promise { + let count = 0; + + for (const unique of args.uniques) { + const { error } = await this.#recycleBinSource.trash({ unique }); + + if (error) { + const notification = { data: { message: error.message } }; + this.#notificationContext?.peek('danger', notification); + } else { + count++; + } + } + + if (count > 0) { + const notification = { data: { message: `Trashed ${count} ${count === 1 ? 'document' : 'documents'}` } }; + this.#notificationContext?.peek('positive', notification); + } + + return {}; + } +} + +export { UmbBulkTrashDocumentRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts index a47c9feae4..07d2dc03b6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/manifests.ts @@ -1,3 +1,9 @@ +import { + UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH, + UMB_USER_PERMISSION_DOCUMENT_UPDATE, + UMB_USER_PERMISSION_DOCUMENT_PUBLISH, +} from '../user-permissions/index.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS } from '@umbraco-cms/backoffice/recycle-bin'; import type { ManifestWorkspaces, @@ -7,12 +13,6 @@ import type { ManifestTypes, } from '@umbraco-cms/backoffice/extension-registry'; import { UMB_CONTENT_HAS_PROPERTIES_WORKSPACE_CONDITION } from '@umbraco-cms/backoffice/content'; -import { - UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH, - UMB_USER_PERMISSION_DOCUMENT_UPDATE, - UMB_USER_PERMISSION_DOCUMENT_PUBLISH, -} from '../user-permissions/index.js'; -import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; export const UMB_DOCUMENT_WORKSPACE_ALIAS = 'Umb.Workspace.Document'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/section/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/section/manifests.ts index b06ec7f7c6..32cac0418c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/section/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/section/manifests.ts @@ -30,7 +30,7 @@ const menuSectionSidebarApp: ManifestSectionSidebarAppMenuWithEntityActionsKind name: 'Content Sidebar Menu', weight: 100, meta: { - label: 'Content', + label: '#sections_content', menu: UMB_CONTENT_MENU_ALIAS, entityType: UMB_DOCUMENT_ROOT_ENTITY_TYPE, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/collection/action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/language/collection/action/manifests.ts index 4dfa891fbe..bf76be9c0d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/collection/action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/collection/action/manifests.ts @@ -8,7 +8,7 @@ export const createManifest: ManifestCollectionAction = { alias: 'Umb.CollectionAction.Language.Create', weight: 200, meta: { - label: 'Create', + label: '#general_create', href: 'section/settings/workspace/language/create', }, conditions: [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts index 30221b71ed..50a8874129 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/log-viewer/workspace/logviewer-workspace.context.ts @@ -124,7 +124,7 @@ export class UmbLogViewerWorkspaceContext extends UmbControllerBase implements U onChangeState = () => { const searchQuery = query(); - this.setFilterExpression(searchQuery.lq); + this.setFilterExpression(searchQuery.lq ?? ''); let validLogLevels: LogLevelModel[] = []; if (searchQuery.loglevels) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts index b50c8dfa27..c8135d7053 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/markdown-editor/components/input-markdown-editor/input-markdown.element.ts @@ -1,28 +1,27 @@ import { css, customElement, html, property, query, state, unsafeHTML } from '@umbraco-cms/backoffice/external/lit'; import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; -import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor'; import { marked } from '@umbraco-cms/backoffice/external/marked'; import { monaco } from '@umbraco-cms/backoffice/external/monaco-editor'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { DOMPurify } from '@umbraco-cms/backoffice/external/dompurify'; -import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; -import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; +import { UmbChangeEvent, type UmbInputEvent } from '@umbraco-cms/backoffice/event'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_MEDIA_PICKER_MODAL, UmbMediaUrlRepository } from '@umbraco-cms/backoffice/media'; -import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui'; +import { UmbCodeEditorLoadedEvent } from '@umbraco-cms/backoffice/code-editor'; import type { UmbCodeEditorController, UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; -import type { UmbModalManagerContext } from '@umbraco-cms/backoffice/modal'; import type { UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui'; +import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; + +const elementName = 'umb-input-markdown'; /** * @element umb-input-markdown * @fires change - when the value of the input changes */ - -@customElement('umb-input-markdown') -export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, '') { +@customElement(elementName) +export class UmbInputMarkdownElement extends UmbFormControlMixin(UmbLitElement, '') { protected override getFormElement() { return this._codeEditor; } @@ -35,7 +34,6 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, @property() overlaySize?: UUIModalSidebarSize; - #isCodeEditorReady = new UmbBooleanState(false); #editor?: UmbCodeEditorController; @query('umb-code-editor') @@ -44,33 +42,14 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, @state() private _actionExtensions: Array = []; - private _modalContext?: UmbModalManagerContext; - #mediaUrlRepository = new UmbMediaUrlRepository(this); - constructor() { - super(); - this.#loadCodeEditor(); + #onCodeEditorLoaded(event: UmbCodeEditorLoadedEvent) { + if (event.type !== UmbCodeEditorLoadedEvent.TYPE) return; - this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, (instance) => { - this._modalContext = instance; - }); - } - - async #loadCodeEditor() { try { - await loadCodeEditor(); - this.#editor = this._codeEditor?.editor; - this.#editor?.updateOptions({ - lineNumbers: false, - minimap: false, - folding: false, - }); // Prefer to update options before showing the editor, to avoid seeing the changes in the UI. - - this.#isCodeEditorReady.setValue(true); - // TODO: make all action into extensions this.observe(umbExtensionsRegistry.byType('monacoMarkdownEditorAction'), (manifests) => { manifests.forEach(async (manifest) => { @@ -93,7 +72,7 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, } } - async #loadActions() { + #loadActions() { //Note: UI Buttons have the keybindings hardcoded in its title. If you change the keybindings here, please update the render as well. this.#editor?.monacoEditor?.addAction({ label: 'Add Heading H1', @@ -198,14 +177,16 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, this.#editor?.monacoEditor?.focus(); } - #insertMedia() { + async #insertMedia() { const selection = this.#editor?.getSelections()[0]; if (!selection) return; const alt = this.#editor?.getValueInRange(selection) || 'enter image description here'; this._focusEditor(); // Focus before opening modal, otherwise cannot regain focus back after modal - const modalContext = this._modalContext?.open(this, UMB_MEDIA_PICKER_MODAL); + + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + const modalContext = modalManager.open(this, UMB_MEDIA_PICKER_MODAL); modalContext ?.onSubmit() @@ -214,7 +195,7 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, const uniques = value.selection; const { data: mediaUrls } = await this.#mediaUrlRepository.requestItems(uniques); - const mediaUrl = mediaUrls?.length ? mediaUrls[0].url ?? 'URL' : 'URL'; + const mediaUrl = mediaUrls?.length ? (mediaUrls[0].url ?? 'URL') : 'URL'; this.#editor?.monacoEditor?.executeEdits('', [ { @@ -411,9 +392,9 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, } } - #onInput(e: CustomEvent) { + #onInput(e: UmbInputEvent) { e.stopPropagation(); - this.value = this.#editor?.monacoEditor?.getValue() ?? ''; + this.value = this.#editor?.value ?? ''; this.dispatchEvent(new UmbChangeEvent()); } @@ -423,8 +404,12 @@ export class UmbInputMarkdownElement extends UUIFormControlMixin(UmbLitElement, + @loaded=${this.#onCodeEditorLoaded}> ${this.#renderPreview()} `; @@ -609,6 +594,6 @@ export default UmbInputMarkdownElement; declare global { interface HTMLElementTagNameMap { - 'umb-input-markdown': UmbInputMarkdownElement; + [elementName]: UmbInputMarkdownElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-section/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-section/manifests.ts index 0130791800..9e82e42749 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-section/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-section/manifests.ts @@ -31,7 +31,7 @@ const menuSectionSidebarApp: ManifestSectionSidebarApp = { name: 'Media Section Sidebar Menu', weight: 100, meta: { - label: 'Media', + label: '#sections_media', menu: UMB_MEDIA_MENU_ALIAS, entityType: UMB_MEDIA_ROOT_ENTITY_TYPE, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/action/create-media-collection-action.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/action/create-media-collection-action.element.ts index f0ac1e340c..349aef3f0d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/action/create-media-collection-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/collection/action/create-media-collection-action.element.ts @@ -106,7 +106,12 @@ export class UmbCreateMediaCollectionActionElement extends UmbLitElement { if (this._allowedMediaTypes.length !== 1) return; const item = this._allowedMediaTypes[0]; - const label = (this.manifest?.meta.label ?? this.localize.term('general_create')) + ' ' + item.name; + const label = + (this.manifest?.meta.label + ? this.localize.string(this.manifest?.meta.label) + : this.localize.term('general_create')) + + ' ' + + item.name; return html` diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/delete/delete.action.ts deleted file mode 100644 index 98d607aad4..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/delete/delete.action.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; - -export class UmbMediaDeleteEntityBulkAction extends UmbEntityBulkActionBase { - async execute() { - console.log(`execute delete for: ${this.selection}`); - - // TODO: show error - - // TODO: should we subscribe in cases like this? - /* - const { data } = await this.repository.requestItemsLegacy(this.selection); - - if (data) { - // TODO: use correct markup - const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); - const modalContext = modalManager.open(this, UMB_CONFIRM_MODAL, { - headline: `Deleting ${this.selection.length} items`, - content: html` - This will delete the following files: -
    - ${data.map((item) => html`
  • ${item.name}
  • `)} -
- `, - color: 'danger', - confirmLabel: 'Delete', - }); - - await modalContext.onSubmit(); - await this.repository?.trash(this.selection); - } - */ - } -} - -export { UmbMediaDeleteEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/duplicate/duplicate.action.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/duplicate/duplicate.action.ts deleted file mode 100644 index 28bfa324f3..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/duplicate/duplicate.action.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; - -export class UmbDuplicateMediaEntityBulkAction extends UmbEntityBulkActionBase { - async execute() { - console.log('execute bulk duplicate'); - } -} - -export { UmbDuplicateMediaEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts index 5690bb37a7..805c692d8e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts @@ -1,70 +1,5 @@ -import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js'; -import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection'; +import { manifests as moveToManifests } from './move-to/manifests.js'; +import { manifests as trashManifests } from './trash/manifests.js'; import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; -import { - UMB_COLLECTION_ALIAS_CONDITION, - UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, -} from '@umbraco-cms/backoffice/collection'; -export const manifests: Array = [ - { - type: 'entityBulkAction', - alias: 'Umb.EntityBulkAction.Media.Duplicate', - name: 'Duplicate Media Entity Bulk Action', - weight: 30, - api: () => import('./duplicate/duplicate.action.js'), - meta: { - label: 'Duplicate', - }, - conditions: [ - { - alias: UMB_COLLECTION_ALIAS_CONDITION, - match: UMB_MEDIA_COLLECTION_ALIAS, - }, - { - alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, - match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkCopy, - }, - ], - }, - { - type: 'entityBulkAction', - alias: 'Umb.EntityBulkAction.Media.MoveTo', - name: 'Move Media Entity Bulk Action', - weight: 20, - api: () => import('./move/move.action.js'), - meta: { - label: 'Move', - }, - conditions: [ - { - alias: UMB_COLLECTION_ALIAS_CONDITION, - match: UMB_MEDIA_COLLECTION_ALIAS, - }, - { - alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, - match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkMove, - }, - ], - }, - { - type: 'entityBulkAction', - alias: 'Umb.EntityBulkAction.Media.Delete', - name: 'Delete Media Entity Bulk Action', - weight: 10, - api: () => import('./delete/delete.action.js'), - meta: { - label: 'Delete', - }, - conditions: [ - { - alias: UMB_COLLECTION_ALIAS_CONDITION, - match: UMB_MEDIA_COLLECTION_ALIAS, - }, - { - alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, - match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkDelete, - }, - ], - }, -]; +export const manifests: Array = [...moveToManifests, ...trashManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/index.ts new file mode 100644 index 0000000000..7897faf401 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/index.ts @@ -0,0 +1 @@ +export { UmbBulkMoveToMediaRepository, UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS } from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/manifests.ts new file mode 100644 index 0000000000..a482026403 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/manifests.ts @@ -0,0 +1,36 @@ +import { UMB_MEDIA_COLLECTION_ALIAS } from '../../collection/index.js'; +import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; +import { UMB_MEDIA_TREE_ALIAS } from '../../tree/constants.js'; +import { UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS } from './repository/constants.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { + UMB_COLLECTION_ALIAS_CONDITION, + UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, +} from '@umbraco-cms/backoffice/collection'; +import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkMoveAction: ManifestTypes = { + type: 'entityBulkAction', + kind: 'moveTo', + alias: 'Umb.EntityBulkAction.Media.MoveTo', + name: 'Move Media Entity Bulk Action', + weight: 20, + forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], + meta: { + bulkMoveRepositoryAlias: UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS, + treeAlias: UMB_MEDIA_TREE_ALIAS, + }, + conditions: [ + { + alias: UMB_COLLECTION_ALIAS_CONDITION, + match: UMB_MEDIA_COLLECTION_ALIAS, + }, + { + alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, + match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkMove, + }, + ], +}; + +export const manifests: Array = [bulkMoveAction, ...repositoryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/constants.ts new file mode 100644 index 0000000000..4037b48892 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/constants.ts @@ -0,0 +1 @@ +export const UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS = 'Umb.Repository.Media.BulkMove'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/index.ts new file mode 100644 index 0000000000..55908dba95 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/index.ts @@ -0,0 +1,2 @@ +export { UmbBulkMoveToMediaRepository } from './move-to.repository.js'; +export { UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS } from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/manifests.ts new file mode 100644 index 0000000000..7f5b2ddb41 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS } from './constants.js'; +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkMoveRepository: ManifestRepository = { + type: 'repository', + alias: UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS, + name: 'Bulk Move Media Repository', + api: () => import('./move-to.repository.js'), +}; + +export const manifests: Array = [bulkMoveRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/move-to.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/move-to.repository.ts new file mode 100644 index 0000000000..a8ea03a439 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move-to/repository/move-to.repository.ts @@ -0,0 +1,44 @@ +import { UmbMoveMediaServerDataSource } from '../../../entity-actions/move-to/repository/media-move.server.data-source.js'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import type { UmbBulkMoveToRepository, UmbBulkMoveToRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbRepositoryErrorResponse } from '@umbraco-cms/backoffice/repository'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbBulkMoveToMediaRepository extends UmbRepositoryBase implements UmbBulkMoveToRepository { + #moveSource = new UmbMoveMediaServerDataSource(this); + #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (notificationContext) => { + this.#notificationContext = notificationContext; + }); + } + + async requestBulkMoveTo(args: UmbBulkMoveToRequestArgs): Promise { + let count = 0; + + const destination = args.destination; + for (const unique of args.uniques) { + const { error } = await this.#moveSource.moveTo({ unique, destination }); + + if (error) { + const notification = { data: { message: error.message } }; + this.#notificationContext?.peek('danger', notification); + } else { + count++; + } + } + + if (count > 0) { + const notification = { data: { message: `Moved ${count} media ${count === 1 ? 'item' : 'items'}` } }; + this.#notificationContext?.peek('positive', notification); + } + + return {}; + } +} + +export { UmbBulkMoveToMediaRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move/move.action.ts deleted file mode 100644 index e3cf5b03ec..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move/move.action.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { UMB_MEDIA_TREE_PICKER_MODAL } from '../../tree/index.js'; -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; -import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; - -export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase { - async execute() { - const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); - // TODO: the picker should be single picker by default - const modalContext = modalManager.open(this, UMB_MEDIA_TREE_PICKER_MODAL, { - data: { - multiple: false, - }, - value: { - selection: [], - }, - }); - if (modalContext) { - //const { selection } = await modalContext.onSubmit(); - //const destination = selection[0]; - //await this.repository?.move(this.selection, destination); - } - } -} - -export { UmbMediaMoveEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/index.ts new file mode 100644 index 0000000000..cdb28dce3b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/index.ts @@ -0,0 +1 @@ +export { UmbBulkTrashMediaRepository, UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS } from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts new file mode 100644 index 0000000000..6df781b6b4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts @@ -0,0 +1,34 @@ +import { UMB_MEDIA_COLLECTION_ALIAS } from '../../collection/index.js'; +import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; +import { UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS } from './repository/constants.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { + UMB_COLLECTION_ALIAS_CONDITION, + UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, +} from '@umbraco-cms/backoffice/collection'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; +import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection'; + +const bulkTrashAction: ManifestTypes = { + type: 'entityBulkAction', + kind: 'trash', + alias: 'Umb.EntityBulkAction.Media.Trash', + name: 'Trash Media Entity Bulk Action', + weight: 10, + forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], + meta: { + bulkTrashRepositoryAlias: UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS, + }, + conditions: [ + { + alias: UMB_COLLECTION_ALIAS_CONDITION, + match: UMB_MEDIA_COLLECTION_ALIAS, + }, + { + alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION, + match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkDelete, + }, + ], +}; + +export const manifests: Array = [bulkTrashAction, ...repositoryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/constants.ts new file mode 100644 index 0000000000..6fe1f4fae1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/constants.ts @@ -0,0 +1 @@ +export const UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS = 'Umb.Repository.Media.BulkTrash'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/index.ts new file mode 100644 index 0000000000..fe460293cf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/index.ts @@ -0,0 +1,2 @@ +export { UmbBulkTrashMediaRepository } from './trash.repository.js'; +export { UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS } from './constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/manifests.ts new file mode 100644 index 0000000000..7f18a39a56 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS } from './constants.js'; +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +const bulkTrashRepository: ManifestRepository = { + type: 'repository', + alias: UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS, + name: 'Bulk Trash Media Repository', + api: () => import('./trash.repository.js'), +}; + +export const manifests: Array = [bulkTrashRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts new file mode 100644 index 0000000000..d84cd3e956 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts @@ -0,0 +1,43 @@ +import { UmbMediaRecycleBinServerDataSource } from '../../../recycle-bin/repository/media-recycle-bin.server.data-source.js'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import type { UmbBulkTrashRepository, UmbBulkTrashRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbRepositoryErrorResponse } from '@umbraco-cms/backoffice/repository'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbBulkTrashMediaRepository extends UmbRepositoryBase implements UmbBulkTrashRepository { + #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; + #recycleBinSource = new UmbMediaRecycleBinServerDataSource(this); + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (notificationContext) => { + this.#notificationContext = notificationContext; + }); + } + + async requestBulkTrash(args: UmbBulkTrashRequestArgs): Promise { + let count = 0; + + for (const unique of args.uniques) { + const { error } = await this.#recycleBinSource.trash({ unique }); + + if (error) { + const notification = { data: { message: error.message } }; + this.#notificationContext?.peek('danger', notification); + } else { + count++; + } + } + + if (count > 0) { + const notification = { data: { message: `Trashed ${count} media ${count === 1 ? 'item' : 'items'}` } }; + this.#notificationContext?.peek('positive', notification); + } + + return {}; + } +} + +export { UmbBulkTrashMediaRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/section-view/media-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/section-view/media-section-view.element.ts index 8a1f3c6a11..c4effb5844 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/section-view/media-section-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/section-view/media-section-view.element.ts @@ -1,20 +1,23 @@ -import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js'; import { UmbMediaCollectionRepository } from '../collection/repository/index.js'; +import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js'; +import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbCollectionElement } from '@umbraco-cms/backoffice/collection'; import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type'; +import { UmbEntityContext } from '@umbraco-cms/backoffice/entity'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import type { UmbCollectionBulkActionPermissions, UmbCollectionConfiguration, } from '@umbraco-cms/backoffice/collection'; import type { UmbDataTypeDetailModel } from '@umbraco-cms/backoffice/data-type'; import type { UmbRoute } from '@umbraco-cms/backoffice/router'; -import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; @customElement('umb-media-section-view') export class UmbMediaSectionViewElement extends UmbLitElement { #dataTypeDetailRepository = new UmbDataTypeDetailRepository(this); + #entityContext = new UmbEntityContext(this); #mediaCollectionRepository = new UmbMediaCollectionRepository(this); @state() @@ -24,6 +27,9 @@ export class UmbMediaSectionViewElement extends UmbLitElement { super(); this.#defineRoutes(); + + this.#entityContext.setEntityType(UMB_MEDIA_ENTITY_TYPE); + this.#entityContext.setUnique(null); } async #defineRoutes() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/bulk-action-permissions/permissions.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/bulk-action-permissions/permissions.element.ts index ce8aa14191..01ea17b4e2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/bulk-action-permissions/permissions.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/config/bulk-action-permissions/permissions.element.ts @@ -76,7 +76,7 @@ export class UmbPropertyEditorUICollectionPermissionsElement this.#onChange(e, 'allowBulkCopy')} - label="Allow bulk copy (content only)"> + label="Allow bulk duplicate (content only)"> this.#onChange(e, 'allowBulkMove')} @@ -84,7 +84,7 @@ export class UmbPropertyEditorUICollectionPermissionsElement this.#onChange(e, 'allowBulkDelete')} - label="Allow bulk delete">`; + label="Allow bulk trash">`; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts index 652dee33be..db9afdce7d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts @@ -1,6 +1,6 @@ import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbInputDateElement } from '@umbraco-cms/backoffice/components'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; @@ -42,13 +42,16 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement implemen @property() value?: string; + @state() + private _inputValue?: string; + public set config(config: UmbPropertyEditorConfigCollection | undefined) { if (!config) return; // Format string prevalue/config const format = config.getValueByAlias('format'); - const hasTime = format?.includes('H') || format?.includes('m'); - const hasSeconds = format?.includes('s'); + const hasTime = (format?.includes('H') || format?.includes('m')) ?? false; + const hasSeconds = format?.includes('s') ?? false; this._inputType = hasTime ? 'datetime-local' : 'date'; // Based on the type of format string change the UUI-input type @@ -62,7 +65,7 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement implemen this._min = config.getValueByAlias('min'); this._max = config.getValueByAlias('max'); - this._step = config.getValueByAlias('step') ?? hasSeconds ? 1 : undefined; + this._step = (config.getValueByAlias('step') ?? hasSeconds) ? 1 : undefined; if (this.value) { this.#formatValue(this.value); @@ -70,33 +73,59 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement implemen } #onChange(event: CustomEvent & { target: UmbInputDateElement }) { - this.#formatValue(event.target.value.toString()); + let value = event.target.value.toString(); + + if (!value) { + this.#syncValue(undefined); + return; + } + + switch (this._inputType) { + case 'time': + value = `0001-01-01 ${value}`; + break; + case 'date': + value = `${value} 00:00:00`; + break; + case 'datetime-local': + value = value.replace('T', ' '); + break; + } + + this.#syncValue(value); } /** * Formats the value depending on the input type. */ #formatValue(value: string) { - // Check that the value is a valid date - const valueToDate = new Date(value); - if (isNaN(valueToDate.getTime())) { - console.warn('[Umbraco.DatePicker] The value is not a valid date.', value); + this._inputValue = undefined; + + if (isNaN(new Date(value).getTime())) { + console.warn(`[UmbDatePicker] Invalid date: ${value}`); return; } - // Replace the potential time demoninator 'T' with a whitespace for backwards compatibility - value = value.replace('T', ' '); - - // If the inputType is 'date', we need to make sure the value doesn't have a time - if (this._inputType === 'date' && value.includes(' ')) { - value = value.split(' ')[0]; + const dateSplit = value.split(' '); + if (dateSplit.length !== 2) { + console.warn(`[UmbDatePicker] Invalid date: ${value}`); + return; } - // If the inputType is 'time', we need to remove the date part of the value - if (this._inputType === 'time' && value.includes(' ')) { - value = value.split(' ')[1]; + switch (this._inputType) { + case 'time': + this._inputValue = dateSplit[1]; + break; + case 'date': + this._inputValue = dateSplit[0]; + break; + default: + this._inputValue = dateSplit.join('T'); + break; } + } + #syncValue(value?: string) { const valueHasChanged = this.value !== value; if (valueHasChanged) { this.value = value; @@ -107,7 +136,7 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement implemen override render() { return html` { await expect(element).shadowDom.to.be.accessible(defaultA11yConfig); }); } + + describe('input', () => { + it('should format the value to a datetime-local', async () => { + element.value = '2024-05-03 10:44:00'; + element.config = new UmbPropertyEditorConfigCollection([{ alias: 'format', value: 'YYYY-MM-dd HH:mm:ss' }]); + await element.updateComplete; + expect((element as any)._inputValue).to.equal('2024-05-03T10:44:00'); + }); + + it('should format the value to a date', async () => { + element.value = '2024-05-03 10:44:00'; + element.config = new UmbPropertyEditorConfigCollection([{ alias: 'format', value: 'YYYY-MM-dd' }]); + await element.updateComplete; + expect((element as any)._inputValue).to.equal('2024-05-03'); + }); + + it('should format the value to a time', async () => { + element.value = '2024-05-03 10:44:00'; + element.config = new UmbPropertyEditorConfigCollection([{ alias: 'format', value: 'HH:mm' }]); + await element.updateComplete; + expect((element as any)._inputValue).to.equal('10:44:00'); + }); + + it('should disregard a non-datetime value', async () => { + element.value = '03/05/2024 10:44:00'; + await element.updateComplete; + expect((element as any)._inputValue).to.be.undefined; + }); + }); + + describe('output', () => { + it('should format the value to a datetime-local', async () => { + inputElement.value = '2024-05-03T10:44:00'; + inputElement.dispatchEvent(new CustomEvent('change')); + await element.updateComplete; + expect(element.value).to.equal('2024-05-03 10:44:00'); + }); + + it('should format the value to a date', async () => { + element.config = new UmbPropertyEditorConfigCollection([{ alias: 'format', value: 'YYYY-MM-dd' }]); + await element.updateComplete; + inputElement.value = '2024-05-03'; + inputElement.dispatchEvent(new CustomEvent('change')); + await element.updateComplete; + expect(element.value).to.equal('2024-05-03 00:00:00'); + }); + + it('should format the value to a time', async () => { + element.config = new UmbPropertyEditorConfigCollection([{ alias: 'format', value: 'HH:mm' }]); + await element.updateComplete; + inputElement.value = '10:44:00'; + inputElement.dispatchEvent(new CustomEvent('change')); + await element.updateComplete; + expect(element.value).to.equal('0001-01-01 10:44:00'); + }); + + it('should be able to clear the value', async () => { + element.value = '2024-05-03 10:44:00'; + await element.updateComplete; + inputElement.value = ''; + inputElement.dispatchEvent(new CustomEvent('change')); + await element.updateComplete; + expect(element.value).to.be.undefined; + }); + }); }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/text-box/property-editor-ui-text-box.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/text-box/property-editor-ui-text-box.element.ts index cfbe53ce95..2e3397c100 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/text-box/property-editor-ui-text-box.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/text-box/property-editor-ui-text-box.element.ts @@ -1,13 +1,5 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { - css, - html, - customElement, - state, - ifDefined, - type PropertyValueMap, - property, -} from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, ifDefined, property } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { @@ -54,12 +46,11 @@ export class UmbPropertyEditorUITextBoxElement this._placeholder = config?.getValueByAlias('placeholder'); } - protected override firstUpdated(_changedProperties: PropertyValueMap | Map): void { - super.firstUpdated(_changedProperties); + protected override firstUpdated(): void { this.addFormControlElement(this.shadowRoot!.querySelector('uui-input')!); } - private onChange(e: Event) { + #onInput(e: InputEvent) { const newValue = (e.target as HTMLInputElement).value; if (newValue === this.value) return; this.value = newValue; @@ -73,7 +64,7 @@ export class UmbPropertyEditorUITextBoxElement placeholder=${ifDefined(this._placeholder)} inputMode=${ifDefined(this._inputMode)} maxlength=${ifDefined(this._maxChars)} - @input=${this.onChange} + @input=${this.#onInput} ?readonly=${this.readonly}>`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/textarea/property-editor-ui-textarea.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/textarea/property-editor-ui-textarea.element.ts index 7b734b09e5..182b88a721 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/textarea/property-editor-ui-textarea.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/textarea/property-editor-ui-textarea.element.ts @@ -1,16 +1,17 @@ -import { css, customElement, html, property, state, styleMap } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, ifDefined, property, state, styleMap } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; import type { StyleInfo } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; -import type { UUITextareaElement } from '@umbraco-cms/backoffice/external/uui'; +import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @customElement('umb-property-editor-ui-textarea') -export class UmbPropertyEditorUITextareaElement extends UmbLitElement implements UmbPropertyEditorUiElement { - @property() - value = ''; - +export class UmbPropertyEditorUITextareaElement + extends UmbFormControlMixin(UmbLitElement, undefined) + implements UmbPropertyEditorUiElement +{ /** * Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content. * @type {boolean} @@ -47,8 +48,14 @@ export class UmbPropertyEditorUITextareaElement extends UmbLitElement implements }; } - #onInput(event: InputEvent & { target: UUITextareaElement }) { - this.value = event.target.value as string; + protected override firstUpdated(): void { + this.addFormControlElement(this.shadowRoot!.querySelector('uui-textarea')!); + } + + #onInput(event: InputEvent) { + const newValue = (event.target as HTMLTextAreaElement).value; + if (newValue === this.value) return; + this.value = newValue; this.dispatchEvent(new UmbPropertyValueChangeEvent()); } @@ -58,15 +65,16 @@ export class UmbPropertyEditorUITextareaElement extends UmbLitElement implements label="Textarea" style=${styleMap(this._css)} .autoHeight=${this._rows ? false : true} - .maxlength=${this._maxChars} - .rows=${this._rows} + maxlength=${ifDefined(this._maxChars)} + rows=${ifDefined(this._rows)} .value=${this.value ?? ''} @input=${this.#onInput} ?readonly=${this.readonly}> `; } - static override styles = [ + static styles = [ + UmbTextStyles, css` uui-textarea { width: 100%; diff --git a/src/Umbraco.Web.UI.Client/src/packages/static-file/property-editors/static-file-picker/property-editor-ui-static-file-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/static-file/property-editors/static-file-picker/property-editor-ui-static-file-picker.element.ts index 163f7ea304..c12bd81ba4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/static-file/property-editors/static-file-picker/property-editor-ui-static-file-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/static-file/property-editors/static-file-picker/property-editor-ui-static-file-picker.element.ts @@ -44,7 +44,7 @@ export class UmbPropertyEditorUIStaticFilePickerElement extends UmbLitElement im const validationLimit = config?.getValueByAlias('validationLimit'); this._limitMin = validationLimit?.min ?? 0; - this._limitMax = this.#singleItemMode ? 1 : validationLimit?.max ?? Infinity; + this._limitMax = this.#singleItemMode ? 1 : (validationLimit?.max ?? Infinity); } @state() diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.stories.ts deleted file mode 100644 index c006085c91..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.stories.ts +++ /dev/null @@ -1,236 +0,0 @@ -import type { UmbCodeEditorElement } from './code-editor.element.js'; -import type { CodeEditorLanguage } from './code-editor.model.js'; -import { CodeEditorTheme } from './code-editor.model.js'; -import type { Meta, StoryObj } from '@storybook/web-components'; -import { html } from '@umbraco-cms/backoffice/external/lit'; - -import './code-editor.element.js'; - -const meta: Meta = { - title: 'Components/Code Editor', - component: 'umb-code-editor', - decorators: [(story) => html`
${story()}
`], - parameters: { layout: 'fullscreen' }, - argTypes: { - theme: { - control: 'select', - options: [ - CodeEditorTheme.Dark, - CodeEditorTheme.Light, - CodeEditorTheme.HighContrastLight, - CodeEditorTheme.HighContrastLight, - ], - }, - }, -}; - -const codeSnippets: Record = { - javascript: `// Returns "banana" - ('b' + 'a' + + 'a' + 'a').toLowerCase();`, - css: `:host { - display: flex; - background-color: var(--uui-color-background); - width: 100%; - height: 100%; - flex-direction: column; - } - - #header { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - height: 70px; - background-color: var(--uui-color-surface); - border-bottom: 1px solid var(--uui-color-border); - box-sizing: border-box; - } - - #headline { - display: block; - margin: 0 var(--uui-size-layout-1); - } - - #tabs { - margin-left: auto; - }`, - html: ` - - - Page Title - - - -

This is a Heading

-

This is a paragraph.

- - - `, - razor: `@using Umbraco.Extensions - @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage - @{ - if (Model?.Areas.Any() != true) { return; } - } - -
- @foreach (var area in Model.Areas) - { - @await Html.GetBlockGridItemAreaHtmlAsync(area) - } -
`, - markdown: ` - You will like those projects! - - --- - - # h1 Heading 8-) - ## h2 Heading - ### h3 Heading - #### h4 Heading - ##### h5 Heading - ###### h6 Heading - - - ## Horizontal Rules - - ___ - - --- - - *** - - - ## Typographic replacements - - Enable typographer option to see result. - - (c) (C) (r) (R) (tm) (TM) (p) (P) +- - - test.. test... test..... test?..... test!.... - - !!!!!! ???? ,, -- --- - - "Smartypants, double quotes" and 'single quotes'`, - typescript: `import { UmbTemplateRepository } from '../repository/template.repository.js'; - import { UmbWorkspaceContextBase } from '../../../shared/components/workspace/workspace-context/workspace-context.js'; - import { UmbObjectState } from '@umbraco-cms/observable-api'; - import { TemplateModel } from '@umbraco-cms/backend-api'; - import { UmbControllerHostElement } from '@umbraco-cms/controller'; - - export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext { - #data = new UmbObjectState(undefined); - data = this.#data.asObservable(); - name = this.#data.asObservablePart((data) => data?.name); - content = this.#data.asObservablePart((data) => data?.content); - - constructor(host: UmbControllerHostElement) { - super(host, 'Umb.Workspace.Template', new UmbTemplateRepository(host)); - } - - getData() { - return this.#data.getValue(); - } - - setName(value: string) { - this.#data.setValue({ ...this.#data.value, name: value }); - } - - setContent(value: string) { - this.#data.setValue({ ...this.#data.value, content: value }); - } - - async load(entityId: string) { - const { data } = await this.repository.requestByKey(entityId); - if (data) { - this.setIsNew(false); - this.#data.setValue(data); - } - } - - async createScaffold(parentId: string | null) { - const { data } = await this.repository.createScaffold(parentId); - if (!data) return; - this.setIsNew(true); - this.#data.setValue(data); - } - }`, - json: `{ - "compilerOptions": { - "module": "esnext", - "target": "esnext", - "lib": ["es2020", "dom", "dom.iterable"], - "declaration": true, - "emitDeclarationOnly": true, - "noEmitOnError": true, - "outDir": "./types", - "strict": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "moduleResolution": "node", - "isolatedModules": true, - "allowSyntheticDefaultImports": true, - "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "useDefineForClassFields": false, - "skipLibCheck": true, - "resolveJsonModule": true, - "baseUrl": ".", - "paths": { - "@umbraco-cms/css": ["libs/css/custom-properties.css"], - "@umbraco-cms/modal": ["src/core/modal"], - "@umbraco-cms/models": ["libs/models"], - "@umbraco-cms/backend-api": ["libs/backend-api"], - "@umbraco-cms/context-api": ["libs/context-api"], - "@umbraco-cms/controller": ["libs/controller"], - "@umbraco-cms/element": ["libs/element"], - "@umbraco-cms/extension-api": ["libs/extension-api"], - "@umbraco-cms/extension-registry": ["libs/extension-registry"], - "@umbraco-cms/notification": ["libs/notification"], - "@umbraco-cms/observable-api": ["libs/observable-api"], - "@umbraco-cms/events": ["libs/events"], - "@umbraco-cms/entity-action": ["libs/entity-action"], - "@umbraco-cms/workspace": ["libs/workspace"], - "@umbraco-cms/utils": ["libs/utils"], - "@umbraco-cms/router": ["libs/router"], - "@umbraco-cms/sorter": ["libs/sorter"], - "@umbraco-cms/test-utils": ["libs/test-utils"], - "@umbraco-cms/repository": ["libs/repository"], - "@umbraco-cms/resources": ["libs/resources"], - "@umbraco-cms/store": ["libs/store"], - "@umbraco-cms/components/*": ["src/backoffice/components/*"], - "@umbraco-cms/sections/*": ["src/backoffice/sections/*"] - } - }, - "include": ["src/**/*.ts", "apps/**/*.ts", "libs/**/*.ts", "e2e/**/*.ts"], - "references": [ - { - "path": "./tsconfig.node.json" - } - ] - }`, -}; - -export default meta; -type Story = StoryObj; - -const [Javascript, Css, Html, Razor, Markdown, Typescript, Json]: Story[] = Object.keys(codeSnippets).map( - (language) => { - return { - args: { - language: language as CodeEditorLanguage, - code: codeSnippets[language as CodeEditorLanguage], - }, - }; - }, -); - -const Themes: Story = { - args: { - language: 'javascript', - code: codeSnippets.javascript, - theme: CodeEditorTheme.Dark, - }, -}; - -export { Javascript, Css, Html, Razor, Markdown, Typescript, Json, Themes }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/index.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/index.ts deleted file mode 100644 index 75222eb351..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type { UmbCodeEditorElement } from './code-editor.element.js'; -export type { UmbCodeEditorController } from './code-editor.controller.js'; - -export function loadCodeEditor() { - return import('./code-editor.element.js'); -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/menu/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/menu/manifests.ts index 7bc48cda16..e5dab05ce6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/menu/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/menu/manifests.ts @@ -15,7 +15,7 @@ const menuSectionSidebarApp: ManifestTypes = { name: 'Templating Section Sidebar Menu', weight: 200, meta: { - label: 'Templating', + label: '#treeHeaders_templatingGroup', menu: 'Umb.Menu.Templating', }, conditions: [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace-editor.element.ts index 693080676c..28c87e47ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace-editor.element.ts @@ -1,14 +1,14 @@ -import type { UmbTemplatingInsertMenuElement } from '../../local-components/insert-menu/index.js'; import { getQuerySnippet } from '../../utils/index.js'; +import type { UmbTemplatingInsertMenuElement } from '../../local-components/insert-menu/index.js'; import { UMB_PARTIAL_VIEW_WORKSPACE_CONTEXT } from './partial-view-workspace.context-token.js'; -import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; -import { css, html, customElement, query, state, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, query, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_TEMPLATE_QUERY_BUILDER_MODAL } from '@umbraco-cms/backoffice/template'; import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; +import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; -// import local components +import '@umbraco-cms/backoffice/code-editor'; import '../../local-components/insert-menu/index.js'; @customElement('umb-partial-view-workspace-editor') @@ -19,9 +19,6 @@ export class UmbPartialViewWorkspaceEditorElement extends UmbLitElement { @state() private _content?: string | null = ''; - @state() - private _ready: boolean = false; - @state() private _isNew?: boolean; @@ -43,10 +40,6 @@ export class UmbPartialViewWorkspaceEditorElement extends UmbLitElement { this._content = content; }); - this.observe(this.#workspaceContext.isCodeEditorReady, (isReady) => { - this._ready = isReady; - }); - this.observe(this.#workspaceContext.isNew, (isNew) => { this._isNew = isNew; }); @@ -83,45 +76,45 @@ export class UmbPartialViewWorkspaceEditorElement extends UmbLitElement { .catch(() => undefined); } - #renderCodeEditor() { - return html``; + override render() { + if (this._isNew === undefined) return; + return html` + +
+ +
+ +
+ + + + Query builder + +
+ ${this.#renderCodeEditor()} +
+
+ `; } - override render() { - return this._isNew !== undefined - ? html` -
- -
- -
- - - Query builder - -
- ${this._ready - ? this.#renderCodeEditor() - : html`
- -
`} -
-
` - : nothing; + #renderCodeEditor() { + return html` + + `; } static override styles = [ @@ -132,12 +125,6 @@ export class UmbPartialViewWorkspaceEditorElement extends UmbLitElement { height: 100%; } - #loader-container { - display: grid; - place-items: center; - min-height: calc(100dvh - 360px); - } - umb-code-editor { --editor-height: calc(100dvh - 300px); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts index 598e91175a..f7b51a2b4e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts @@ -2,14 +2,13 @@ import { UmbPartialViewDetailRepository } from '../repository/partial-view-detai import type { UmbPartialViewDetailModel } from '../types.js'; import { UMB_PARTIAL_VIEW_ENTITY_TYPE } from '../entity.js'; import { UmbPartialViewWorkspaceEditorElement } from './partial-view-workspace-editor.element.js'; -import { UmbBooleanState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbRoutableWorkspaceContext, UmbSubmittableWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; import { UmbSubmittableWorkspaceContextBase, UmbWorkspaceIsNewRedirectController, } from '@umbraco-cms/backoffice/workspace'; -import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import { PartialViewService } from '@umbraco-cms/backoffice/external/backend-api'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; @@ -36,12 +35,8 @@ export class UmbPartialViewWorkspaceContext readonly name = this.#data.asObservablePart((data) => data?.name); readonly content = this.#data.asObservablePart((data) => data?.content); - #isCodeEditorReady = new UmbBooleanState(false); - readonly isCodeEditorReady = this.#isCodeEditorReady.asObservable(); - constructor(host: UmbControllerHost) { super(host, 'Umb.Workspace.PartialView'); - this.#loadCodeEditor(); this.routes.setRoutes([ { @@ -89,15 +84,6 @@ export class UmbPartialViewWorkspaceContext this.#data.setValue(undefined); } - async #loadCodeEditor() { - try { - await loadCodeEditor(); - this.#isCodeEditorReady.setValue(true); - } catch (error) { - console.error(error); - } - } - getUnique() { const data = this.getData(); if (!data) throw new Error('Data is missing'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace-editor.element.ts index 91f0c7177f..0c9e13b5d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace-editor.element.ts @@ -1,9 +1,10 @@ import { UMB_SCRIPT_WORKSPACE_CONTEXT } from './script-workspace.context-token.js'; -import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; -import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit'; -import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; +import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; +import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; + +import '@umbraco-cms/backoffice/code-editor'; @customElement('umb-script-workspace-editor') export class UmbScriptWorkspaceEditorElement extends UmbLitElement { @@ -13,9 +14,6 @@ export class UmbScriptWorkspaceEditorElement extends UmbLitElement { @state() private _content?: string | null = ''; - @state() - private _ready?: boolean = false; - @state() private _isNew?: boolean; @@ -35,10 +33,6 @@ export class UmbScriptWorkspaceEditorElement extends UmbLitElement { this._content = content; }); - this.observe(this.#context.isCodeEditorReady, (isReady) => { - this._ready = isReady; - }); - this.observe(this.#context.isNew, (isNew) => { this._isNew = isNew; }); @@ -57,53 +51,46 @@ export class UmbScriptWorkspaceEditorElement extends UmbLitElement { this.#context?.setContent(value); } - #renderCodeEditor() { - return html``; + override render() { + if (this._isNew === undefined) return; + return html` + +
+ + +
+ + +
+ ${this.#renderCodeEditor()} +
+
+ `; } - override render() { - return this._isNew !== undefined - ? html` -
- -
- - -
- ${this._ready - ? this.#renderCodeEditor() - : html`
- -
`} -
-
` - : nothing; + #renderCodeEditor() { + return html` + + `; } static override styles = [ - UmbTextStyles, css` :host { display: block; width: 100%; } - #loader-container { - display: grid; - place-items: center; - min-height: calc(100dvh - 260px); - } - umb-code-editor { --editor-height: calc(100dvh - 260px); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace.context.ts index b037442377..9baaac04a3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/workspace/script-workspace.context.ts @@ -3,7 +3,7 @@ import type { UmbScriptDetailModel } from '../types.js'; import { UMB_SCRIPT_ENTITY_TYPE } from '../entity.js'; import { UMB_SCRIPT_WORKSPACE_ALIAS } from './manifests.js'; import { UmbScriptWorkspaceEditorElement } from './script-workspace-editor.element.js'; -import { UmbBooleanState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbSubmittableWorkspaceContextBase, @@ -11,7 +11,6 @@ import { type UmbSubmittableWorkspaceContext, UmbWorkspaceIsNewRedirectController, } from '@umbraco-cms/backoffice/workspace'; -import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbRequestReloadChildrenOfEntityEvent, @@ -37,12 +36,8 @@ export class UmbScriptWorkspaceContext readonly name = this.#data.asObservablePart((data) => data?.name); readonly content = this.#data.asObservablePart((data) => data?.content); - #isCodeEditorReady = new UmbBooleanState(false); - readonly isCodeEditorReady = this.#isCodeEditorReady.asObservable(); - constructor(host: UmbControllerHost) { super(host, UMB_SCRIPT_WORKSPACE_ALIAS); - this.#loadCodeEditor(); this.routes.setRoutes([ { @@ -76,15 +71,6 @@ export class UmbScriptWorkspaceContext this.#data.setValue(undefined); } - async #loadCodeEditor() { - try { - await loadCodeEditor(); - this.#isCodeEditorReady.setValue(true); - } catch (error) { - console.error(error); - } - } - getEntityType(): string { return UMB_SCRIPT_ENTITY_TYPE; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts index dfce9f5627..d68dc8824c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts @@ -10,8 +10,7 @@ import { type UmbRoutableWorkspaceContext, } from '@umbraco-cms/backoffice/workspace'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbBooleanState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; -import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor'; +import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbRequestReloadChildrenOfEntityEvent, @@ -36,12 +35,8 @@ export class UmbStylesheetWorkspaceContext readonly name = this.#data.asObservablePart((data) => data?.name); readonly content = this.#data.asObservablePart((data) => data?.content); - #isCodeEditorReady = new UmbBooleanState(false); - readonly isCodeEditorReady = this.#isCodeEditorReady.asObservable(); - constructor(host: UmbControllerHost) { super(host, UMB_STYLESHEET_WORKSPACE_ALIAS); - this.#loadCodeEditor(); this.routes.setRoutes([ { @@ -76,15 +71,6 @@ export class UmbStylesheetWorkspaceContext this.#data.setValue(undefined); } - async #loadCodeEditor() { - try { - await loadCodeEditor(); - this.#isCodeEditorReady.setValue(true); - } catch (error) { - console.error(error); - } - } - getEntityType(): string { return UMB_STYLESHEET_ENTITY_TYPE; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/code-editor/stylesheet-code-editor-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/code-editor/stylesheet-code-editor-workspace-view.element.ts index 34b0a862b2..d97573336b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/code-editor/stylesheet-code-editor-workspace-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/code-editor/stylesheet-code-editor-workspace-view.element.ts @@ -5,14 +5,13 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import '@umbraco-cms/backoffice/code-editor'; + @customElement('umb-stylesheet-code-editor-workspace-view') export class UmbStylesheetCodeEditorWorkspaceViewElement extends UmbLitElement { @state() private _content?: string | null = ''; - @state() - private _ready?: boolean = false; - #stylesheetWorkspaceContext?: UmbStylesheetWorkspaceContext; constructor() { @@ -24,10 +23,6 @@ export class UmbStylesheetCodeEditorWorkspaceViewElement extends UmbLitElement { this.observe(this.#stylesheetWorkspaceContext.content, (content) => { this._content = content; }); - - this.observe(this.#stylesheetWorkspaceContext.isCodeEditorReady, (isReady) => { - this._ready = isReady; - }); }); } @@ -37,25 +32,23 @@ export class UmbStylesheetCodeEditorWorkspaceViewElement extends UmbLitElement { this.#stylesheetWorkspaceContext?.setContent(value); } - #renderCodeEditor() { - return html``; - } - override render() { return html`
- ${this._ready - ? this.#renderCodeEditor() - : html`
- -
`} + ${this.#renderCodeEditor()}
`; } + #renderCodeEditor() { + return html` + + `; + } + static override styles = [ UmbTextStyles, css` @@ -64,12 +57,6 @@ export class UmbStylesheetCodeEditorWorkspaceViewElement extends UmbLitElement { width: 100%; } - #loader-container { - display: grid; - place-items: center; - min-height: calc(100dvh - 300px); - } - umb-code-editor { --editor-height: calc(100dvh - 300px); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace-editor.element.ts index cdc9e97eb6..cd891a0e0a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace-editor.element.ts @@ -13,7 +13,7 @@ import { Subject, debounceTime } from '@umbraco-cms/backoffice/external/rxjs'; import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; import { UMB_TEMPLATE_PICKER_MODAL } from '@umbraco-cms/backoffice/template'; -// import local components +import '@umbraco-cms/backoffice/code-editor'; import '../../local-components/insert-menu/index.js'; @customElement('umb-template-workspace-editor') @@ -29,9 +29,6 @@ export class UmbTemplateWorkspaceEditorElement extends UmbLitElement { @state() private _alias?: string | null = ''; - @state() - private _ready?: boolean = false; - @state() private _masterTemplateName?: string | null = null; @@ -76,10 +73,6 @@ export class UmbTemplateWorkspaceEditorElement extends UmbLitElement { this.#isNew = !!isNew; }); - this.observe(this.#templateWorkspaceContext.isCodeEditorReady, (isReady) => { - this._ready = isReady; - }); - this.inputQuery$.pipe(debounceTime(250)).subscribe((nameInputValue) => { this.#templateWorkspaceContext?.setName(nameInputValue); if (this.#isNew) this.#templateWorkspaceContext?.setAlias(toCamelCase(nameInputValue)); @@ -182,54 +175,54 @@ export class UmbTemplateWorkspaceEditorElement extends UmbLitElement { `; } - #renderCodeEditor() { - return html``; - } - override render() { // TODO: add correct UI elements - return html` - - - + return html` + + + + - -
${this.#renderMasterTemplatePicker()}
-
- - - ${this.localize.term('template_queryBuilder')} - - - ${this.localize.term('template_insertSections')} - -
+ +
${this.#renderMasterTemplatePicker()}
+
+ + + ${this.localize.term('template_queryBuilder')} + + + ${this.localize.term('template_insertSections')} + +
- ${this._ready - ? this.#renderCodeEditor() - : html`
- -
`} -
-
`; + ${this.#renderCodeEditor()} + +
+ `; + } + + #renderCodeEditor() { + return html` + + `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace.context.ts index ea4f07ffab..6fe2bff6b8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/workspace/template-workspace.context.ts @@ -3,13 +3,12 @@ import type { UmbTemplateItemModel } from '../repository/index.js'; import { UmbTemplateDetailRepository, UmbTemplateItemRepository } from '../repository/index.js'; import { UMB_TEMPLATE_WORKSPACE_ALIAS } from './manifests.js'; import { UmbTemplateWorkspaceEditorElement } from './template-workspace-editor.element.js'; -import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor'; import type { UmbRoutableWorkspaceContext, UmbSubmittableWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; import { UmbSubmittableWorkspaceContextBase, UmbWorkspaceIsNewRedirectController, } from '@umbraco-cms/backoffice/workspace'; -import { UmbBooleanState, UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { @@ -40,12 +39,8 @@ export class UmbTemplateWorkspaceContext readonly entityType = this.#data.asObservablePart((data) => data?.entityType); masterTemplateUnique = this.#data.asObservablePart((data) => data?.masterTemplate?.unique); - #isCodeEditorReady = new UmbBooleanState(false); - isCodeEditorReady = this.#isCodeEditorReady.asObservable(); - constructor(host: UmbControllerHost) { super(host, UMB_TEMPLATE_WORKSPACE_ALIAS); - this.#loadCodeEditor(); this.routes.setRoutes([ { @@ -79,15 +74,6 @@ export class UmbTemplateWorkspaceContext this.#data.setValue(undefined); } - async #loadCodeEditor() { - try { - await loadCodeEditor(); - this.#isCodeEditorReady.setValue(true); - } catch (error) { - console.error(error); - } - } - getEntityType(): string { return 'template'; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/vite.config.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/vite.config.ts index 4f5b9cd8e9..983feeb6ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/vite.config.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/vite.config.ts @@ -11,7 +11,6 @@ export default defineConfig({ ...getDefaultConfig({ dist, entry: { - 'code-editor/index': 'code-editor/index.ts', 'entry-point': 'entry-point.ts', 'partial-views/index': 'partial-views/index.ts', 'scripts/index': 'scripts/index.ts', diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/utils/index.ts index 21a5ac4fb3..4b3642e472 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/utils/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/utils/index.ts @@ -14,5 +14,4 @@ export const UmbUserStateFilter = Object.freeze({ LOCKED_OUT: 'LockedOut', INVITED: 'Invited', INACTIVE: 'Inactive', - ALL: 'All', }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/webhook/collection/action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/webhook/collection/action/manifests.ts index 241ef08add..219c359da4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/webhook/collection/action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/webhook/collection/action/manifests.ts @@ -8,7 +8,7 @@ export const createManifest: ManifestCollectionAction = { alias: 'Umb.CollectionAction.Webhook.Create', weight: 200, meta: { - label: 'Create', + label: '#general_create', href: 'section/settings/workspace/webhook/create', }, conditions: [ diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index 53b2db2515..0c726f16e7 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -48,7 +48,7 @@ DON'T EDIT THIS FILE DIRECTLY. It is generated by /devops/tsconfig/index.js "@umbraco-cms/backoffice/block-rte": ["./src/packages/block/block-rte/index.ts"], "@umbraco-cms/backoffice/block-type": ["./src/packages/block/block-type/index.ts"], "@umbraco-cms/backoffice/block": ["./src/packages/block/block/index.ts"], - "@umbraco-cms/backoffice/code-editor": ["./src/packages/templating/code-editor/index.ts"], + "@umbraco-cms/backoffice/code-editor": ["./src/packages/code-editor/index.ts"], "@umbraco-cms/backoffice/collection": ["./src/packages/core/collection/index.ts"], "@umbraco-cms/backoffice/components": ["./src/packages/core/components/index.ts"], "@umbraco-cms/backoffice/content-type": ["./src/packages/core/content-type/index.ts"], diff --git a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs index c25f693d7b..b44df4a70f 100644 --- a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs +++ b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs @@ -62,7 +62,6 @@ export default { window.__UMBRACO_TEST_RUN_A11Y_TEST = ${(!devMode).toString()}; -