Merge branch 'main' into feature/property-editor-config-models

This commit is contained in:
Mads Rasmussen
2023-01-05 10:52:58 +01:00
committed by GitHub
160 changed files with 1287 additions and 1943 deletions

View File

@@ -33,7 +33,8 @@
"no-var": "error",
"import/no-unresolved": "error",
"import/order": "warn",
"local-rules/bad-type-import": "error"
"local-rules/bad-type-import": "error",
"local-rules/no-direct-api-import": "warn"
},
"settings": {
"import/parsers": {

View File

@@ -4,6 +4,12 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"command": "npx eslint",
"name": "Debug eslint",
"request": "launch",
"type": "node-terminal"
},
{
"type": "chrome",
"request": "launch",

View File

@@ -4,8 +4,8 @@
* A eslint rule that ensures the use of the `import type` operator from the `src/core/models/index.ts` file.
*/
// eslint-disable-next-line no-undef
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
/** @type {import('eslint').Rule.RuleModule} */
'bad-type-import': {
meta: {
type: 'problem',
@@ -20,7 +20,7 @@ module.exports = {
create: function (context) {
return {
ImportDeclaration: function (node) {
if (node.source.parent.importKind !== 'type' && (node.source.value.endsWith('/models') || node.source.value.endsWith('/generated-schema') || node.source.value === 'router-slot/model')) {
if (node.source.parent.importKind !== 'type' && (node.source.value.endsWith('/models') || node.source.value === 'router-slot/model')) {
const sourceCode = context.getSourceCode();
const nodeSource = sourceCode.getText(node);
context.report({
@@ -32,5 +32,37 @@ module.exports = {
},
};
}
},
/** @type {import('eslint').Rule.RuleModule} */
'no-direct-api-import': {
meta: {
type: 'suggestion',
docs: {
description: 'Ensures that any API resources from the `@umbraco-cms/backend-api` module are not used directly. Instead you should use the `tryExecuteAndNotify` function from the `@umbraco-cms/resources` module.',
category: 'Best Practices',
recommended: true
},
fixable: 'code',
schema: [],
},
create: function (context) {
return {
// If methods called on *Resource classes are not already wrapped with `await tryExecuteAndNotify()`, then we should suggest to wrap them.
CallExpression: function (node) {
if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name.endsWith('Resource') && node.callee.property.type === 'Identifier' && node.callee.property.name !== 'constructor') {
const hasTryExecuteAndNotify = node.parent && node.parent.callee && (node.parent.callee.name === 'tryExecute' || node.parent.callee.name === 'tryExecuteAndNotify');
if (!hasTryExecuteAndNotify) {
context.report({
node,
message: 'Wrap this call with `tryExecuteAndNotify()`. Make sure to `await` the result.',
fix: fixer => [fixer.insertTextBefore(node, 'tryExecuteAndNotify(this, '), fixer.insertTextAfter(node, ')')],
});
}
}
}
};
},
}
};

View File

@@ -26,7 +26,7 @@
"uuid": "^9.0.0"
},
"devDependencies": {
"@babel/core": "^7.20.7",
"@babel/core": "^7.20.12",
"@mdx-js/react": "^2.2.1",
"@open-wc/testing": "^3.1.7",
"@playwright/test": "^1.29.1",
@@ -42,14 +42,14 @@
"@types/mocha": "^10.0.0",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"@typescript-eslint/parser": "^5.47.0",
"@typescript-eslint/parser": "^5.48.0",
"@web/dev-server-esbuild": "^0.3.3",
"@web/dev-server-import-maps": "^0.0.7",
"@web/test-runner": "^0.15.0",
"@web/test-runner-playwright": "^0.9.0",
"babel-loader": "^9.1.0",
"babel-loader": "^9.1.2",
"eslint": "^8.31.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-prettier": "^8.6.0",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-lit": "^1.7.2",
@@ -140,25 +140,25 @@
}
},
"node_modules/@babel/core": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz",
"integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==",
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz",
"integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.20.7",
"@babel/helper-compilation-targets": "^7.20.7",
"@babel/helper-module-transforms": "^7.20.7",
"@babel/helper-module-transforms": "^7.20.11",
"@babel/helpers": "^7.20.7",
"@babel/parser": "^7.20.7",
"@babel/template": "^7.20.7",
"@babel/traverse": "^7.20.7",
"@babel/traverse": "^7.20.12",
"@babel/types": "^7.20.7",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"json5": "^2.2.1",
"json5": "^2.2.2",
"semver": "^6.3.0"
},
"engines": {
@@ -381,9 +381,9 @@
}
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz",
"integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==",
"version": "7.20.11",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
"integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
"dev": true,
"dependencies": {
"@babel/helper-environment-visitor": "^7.18.9",
@@ -392,7 +392,7 @@
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/template": "^7.20.7",
"@babel/traverse": "^7.20.7",
"@babel/traverse": "^7.20.10",
"@babel/types": "^7.20.7"
},
"engines": {
@@ -1961,9 +1961,9 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.20.8",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.8.tgz",
"integrity": "sha512-/RNkaYDeCy4MjyV70+QkSHhxbvj2JO/5Ft2Pa880qJOG8tWrqcT/wXUuCCv43yogfqPzHL77Xu101KQPf4clnQ==",
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
"integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.18.6",
@@ -4081,24 +4081,6 @@
"node": ">=8"
}
},
"node_modules/@storybook/builder-webpack4/node_modules/schema-utils": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.4",
"ajv": "^6.12.2",
"ajv-keywords": "^3.4.1"
},
"engines": {
"node": ">= 8.9.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
}
},
"node_modules/@storybook/builder-webpack4/node_modules/tapable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
@@ -6425,53 +6407,6 @@
}
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
"integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
"integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -6488,14 +6423,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.0.tgz",
"integrity": "sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz",
"integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.47.0",
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/typescript-estree": "5.47.0",
"@typescript-eslint/scope-manager": "5.48.0",
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/typescript-estree": "5.48.0",
"debug": "^4.3.4"
},
"engines": {
@@ -6515,13 +6450,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz",
"integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
"integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/visitor-keys": "5.47.0"
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6558,7 +6493,7 @@
}
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
"node_modules/@typescript-eslint/types": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
"integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
@@ -6571,7 +6506,7 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
"integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
@@ -6598,78 +6533,6 @@
}
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz",
"integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz",
"integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/visitor-keys": "5.47.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -6711,80 +6574,6 @@
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
"integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
"integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
"integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/utils/node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -6801,12 +6590,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz",
"integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -8915,9 +8704,9 @@
"dev": true
},
"node_modules/babel-loader": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.0.tgz",
"integrity": "sha512-Antt61KJPinUMwHwIIz9T5zfMgevnfZkEVWYDWlG888fgdvRRGD0JTuf/fFozQnfT+uq64sk1bmdHDy/mOEWnA==",
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz",
"integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==",
"dev": true,
"dependencies": {
"find-cache-dir": "^3.3.2",
@@ -11384,9 +11173,9 @@
}
},
"node_modules/css-loader/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -12705,9 +12494,9 @@
}
},
"node_modules/eslint-config-prettier": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz",
"integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==",
"dev": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
@@ -15519,9 +15308,9 @@
}
},
"node_modules/html-webpack-plugin/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -17101,9 +16890,9 @@
"dev": true
},
"node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
@@ -25756,9 +25545,9 @@
}
},
"node_modules/tsconfig-paths/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -28065,9 +27854,9 @@
"dev": true
},
"node_modules/webpack/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -28694,25 +28483,25 @@
"dev": true
},
"@babel/core": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz",
"integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==",
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz",
"integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==",
"dev": true,
"requires": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.20.7",
"@babel/helper-compilation-targets": "^7.20.7",
"@babel/helper-module-transforms": "^7.20.7",
"@babel/helper-module-transforms": "^7.20.11",
"@babel/helpers": "^7.20.7",
"@babel/parser": "^7.20.7",
"@babel/template": "^7.20.7",
"@babel/traverse": "^7.20.7",
"@babel/traverse": "^7.20.12",
"@babel/types": "^7.20.7",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"json5": "^2.2.1",
"json5": "^2.2.2",
"semver": "^6.3.0"
}
},
@@ -28881,9 +28670,9 @@
}
},
"@babel/helper-module-transforms": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz",
"integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==",
"version": "7.20.11",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
"integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
"dev": true,
"requires": {
"@babel/helper-environment-visitor": "^7.18.9",
@@ -28892,7 +28681,7 @@
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/template": "^7.20.7",
"@babel/traverse": "^7.20.7",
"@babel/traverse": "^7.20.10",
"@babel/types": "^7.20.7"
}
},
@@ -29945,9 +29734,9 @@
}
},
"@babel/traverse": {
"version": "7.20.8",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.8.tgz",
"integrity": "sha512-/RNkaYDeCy4MjyV70+QkSHhxbvj2JO/5Ft2Pa880qJOG8tWrqcT/wXUuCCv43yogfqPzHL77Xu101KQPf4clnQ==",
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
"integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.18.6",
@@ -31457,17 +31246,6 @@
"p-limit": "^2.2.0"
}
},
"schema-utils": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.4",
"ajv": "^6.12.2",
"ajv-keywords": "^3.4.1"
}
},
"tapable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
@@ -33295,32 +33073,6 @@
"tsutils": "^3.21.0"
},
"dependencies": {
"@typescript-eslint/scope-manager": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
"integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0"
}
},
"@typescript-eslint/types": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
"integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
"dev": true
},
"@typescript-eslint/visitor-keys": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
}
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -33333,25 +33085,25 @@
}
},
"@typescript-eslint/parser": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.0.tgz",
"integrity": "sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz",
"integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.47.0",
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/typescript-estree": "5.47.0",
"@typescript-eslint/scope-manager": "5.48.0",
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/typescript-estree": "5.48.0",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz",
"integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
"integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/visitor-keys": "5.47.0"
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0"
}
},
"@typescript-eslint/type-utils": {
@@ -33364,64 +33116,22 @@
"@typescript-eslint/utils": "5.48.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
"dependencies": {
"@typescript-eslint/types": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
"integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
"integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
}
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"@typescript-eslint/types": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz",
"integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
"integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz",
"integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
"integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/visitor-keys": "5.47.0",
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -33456,47 +33166,6 @@
"semver": "^7.3.7"
},
"dependencies": {
"@typescript-eslint/scope-manager": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
"integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0"
}
},
"@typescript-eslint/types": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
"integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
"integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.48.0",
"@typescript-eslint/visitor-keys": "5.48.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
}
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -33509,12 +33178,12 @@
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.47.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz",
"integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==",
"version": "5.48.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
"integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.47.0",
"@typescript-eslint/types": "5.48.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -35360,9 +35029,9 @@
"dev": true
},
"babel-loader": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.0.tgz",
"integrity": "sha512-Antt61KJPinUMwHwIIz9T5zfMgevnfZkEVWYDWlG888fgdvRRGD0JTuf/fFozQnfT+uq64sk1bmdHDy/mOEWnA==",
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.2.tgz",
"integrity": "sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==",
"dev": true,
"requires": {
"find-cache-dir": "^3.3.2",
@@ -37299,9 +36968,9 @@
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@@ -38350,9 +38019,9 @@
}
},
"eslint-config-prettier": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
"integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz",
"integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==",
"dev": true
},
"eslint-import-resolver-node": {
@@ -40431,9 +40100,9 @@
},
"dependencies": {
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@@ -41581,9 +41250,9 @@
"dev": true
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"jsonfile": {
@@ -48223,9 +47892,9 @@
},
"dependencies": {
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@@ -49797,9 +49466,9 @@
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"

View File

@@ -39,7 +39,7 @@
"lint:fix": "npm run lint -- --fix",
"format": "prettier 'src/**/*.ts'",
"format:fix": "npm run format -- --write",
"generate:api": "openapi --input https://raw.githubusercontent.com/umbraco/Umbraco-CMS/v11/dev/src/Umbraco.Cms.ManagementApi/OpenApi.json --output src/core/backend-api --postfix Resource --useOptions",
"generate:api": "openapi --input https://raw.githubusercontent.com/umbraco/Umbraco-CMS/v13/dev/src/Umbraco.Cms.Api.Management/OpenApi.json --output src/core/backend-api --postfix Resource --useOptions",
"generate:api-dev": "openapi --input http://localhost:9000/umbraco/swagger/v1/swagger.json --output src/core/backend-api --postfix Resource --useOptions",
"storybook": "npm run wc-analyze && start-storybook -p 6006",
"build-storybook": "npm run wc-analyze && build-storybook",
@@ -71,7 +71,7 @@
"uuid": "^9.0.0"
},
"devDependencies": {
"@babel/core": "^7.20.7",
"@babel/core": "^7.20.12",
"@mdx-js/react": "^2.2.1",
"@open-wc/testing": "^3.1.7",
"@playwright/test": "^1.29.1",
@@ -87,14 +87,14 @@
"@types/mocha": "^10.0.0",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.48.0",
"@typescript-eslint/parser": "^5.47.0",
"@typescript-eslint/parser": "^5.48.0",
"@web/dev-server-esbuild": "^0.3.3",
"@web/dev-server-import-maps": "^0.0.7",
"@web/test-runner": "^0.15.0",
"@web/test-runner-playwright": "^0.9.0",
"babel-loader": "^9.1.0",
"babel-loader": "^9.1.2",
"eslint": "^8.31.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-prettier": "^8.6.0",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-lit": "^1.7.2",

View File

@@ -1,28 +1,29 @@
import './core/css/custom-properties.css';
// TODO: remove these imports when they are part of UUI
import '@umbraco-ui/uui-color-swatch';
import '@umbraco-ui/uui-color-swatches';
import '@umbraco-ui/uui-modal';
import '@umbraco-ui/uui-modal-container';
import '@umbraco-ui/uui-modal-dialog';
import '@umbraco-ui/uui-modal-sidebar';
import '@umbraco-ui/uui-color-swatch';
import '@umbraco-ui/uui-color-swatches';
import 'router-slot';
import 'element-internals-polyfill';
import 'router-slot';
import './auth';
// TODO: remove these imports when they are part of UUI
import type { Guard, IRoute } from 'router-slot/model';
import { UUIIconRegistryEssential } from '@umbraco-ui/uui';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { UmbIconStore } from '@umbraco-cms/stores/icon/icon.store';
import { UmbLitElement } from './core/element/lit-element.element';
import { tryExecuteAndNotify } from './core/resources/tryExecuteAndNotify.method';
import { OpenAPI, RuntimeLevel, ServerResource } from '@umbraco-cms/backend-api';
import { UmbContextProviderMixin } from '@umbraco-cms/context-api';
import './auth';
import { UmbIconStore } from '@umbraco-cms/stores/icon/icon.store';
@customElement('umb-app')
export class UmbApp extends UmbContextProviderMixin(LitElement) {
export class UmbApp extends UmbLitElement {
static styles = css`
:host {
overflow: hidden;
@@ -95,14 +96,8 @@ export class UmbApp extends UmbContextProviderMixin(LitElement) {
}
private async _setInitStatus() {
try {
const serverStatus = await ServerResource.getServerStatus();
if (serverStatus.serverStatus) {
this._runtimeLevel = serverStatus.serverStatus;
}
} catch (error) {
console.log(error);
}
const { data } = await tryExecuteAndNotify(this, ServerResource.getServerStatus());
this._runtimeLevel = data?.serverStatus ?? RuntimeLevel.UNKNOWN;
}
private _redirect() {

View File

@@ -3,11 +3,10 @@ import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbInputListBase } from '../../../backoffice/shared/components/input-list-base/input-list-base';
import type { UserGroupEntity } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbUserGroupStore } from 'src/backoffice/users/user-groups/user-group.store';
@customElement('umb-input-user-group')
export class UmbInputPickerUserGroupElement extends UmbObserverMixin(UmbInputListBase) {
export class UmbInputPickerUserGroupElement extends UmbInputListBase {
static styles = [
UUITextStyles,
css`
@@ -53,7 +52,7 @@ export class UmbInputPickerUserGroupElement extends UmbObserverMixin(UmbInputLis
private _observeUserGroups() {
if (this.value.length > 0 && this._userGroupStore) {
this.observe<Array<UserGroupEntity>>(
this.observe(
this._userGroupStore.getByKeys(this.value),
(userGroups) => (this._userGroups = userGroups)
);

View File

@@ -2,12 +2,11 @@ import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, nothing, PropertyValueMap } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbInputListBase } from '../../../backoffice/shared/components/input-list-base/input-list-base';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { UserEntity } from '@umbraco-cms/models';
import { UmbUserStore } from 'src/backoffice/users/users/user.store';
@customElement('umb-input-user')
export class UmbPickerUserElement extends UmbObserverMixin(UmbInputListBase) {
export class UmbPickerUserElement extends UmbInputListBase {
static styles = [
UUITextStyles,
css`
@@ -56,6 +55,7 @@ export class UmbPickerUserElement extends UmbObserverMixin(UmbInputListBase) {
private _observeUser() {
if (!this._userStore) return;
// TODO: Fix type mismatch:
this.observe<Array<UserEntity>>(this._userStore.getByKeys(this.value), (users) => {
this._users = users;
});

View File

@@ -1,13 +1,10 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement } from 'lit/decorators.js';
import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-external-login-provider-test')
export class UmbExternalLoginProviderTestElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbExternalLoginProviderTestElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`

View File

@@ -1,13 +1,10 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement } from 'lit/decorators.js';
import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-external-login-provider-test2')
export class UmbExternalLoginProviderTest2Element extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbExternalLoginProviderTest2Element extends UmbLitElement {
static styles = [
UUITextStyles,
css`

View File

@@ -1,6 +1,6 @@
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UmbModalService } from '../core/modal';
import { UmbNotificationService } from '../core/notification';
@@ -21,8 +21,6 @@ import { UmbDocumentBlueprintStore } from './documents/document-blueprints/docum
import { UmbSectionStore } from './shared/components/section/section.store';
import { UmbDataTypeStore } from './settings/data-types/data-type.store';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
// Domains
import './settings';
import './documents';
@@ -33,9 +31,10 @@ import './users';
import './packages';
import './search';
import './shared';
import { UmbLitElement } from '@umbraco-cms/element';
@defineElement('umb-backoffice')
export class UmbBackofficeElement extends UmbContextConsumerMixin(UmbContextProviderMixin(LitElement)) {
export class UmbBackofficeElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`

View File

@@ -1,8 +1,9 @@
import { UmbWorkspaceNodeContext } from '../../../shared/components/workspace/workspace-context/workspace-node.context';
import { UmbWorkspaceContentContext } from '../../../shared/components/workspace/workspace-content/workspace-content.context';
import {
UmbDocumentTypeStore,
UmbDocumentTypeStoreItemType,
} from 'src/backoffice/documents/document-types/document-type.store';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
const DefaultDocumentTypeData = {
key: '',
@@ -15,11 +16,11 @@ const DefaultDocumentTypeData = {
properties: [],
} as UmbDocumentTypeStoreItemType;
export class UmbWorkspaceDocumentTypeContext extends UmbWorkspaceNodeContext<
export class UmbWorkspaceDocumentTypeContext extends UmbWorkspaceContentContext<
UmbDocumentTypeStoreItemType,
UmbDocumentTypeStore
> {
constructor(target: HTMLElement, entityKey: string) {
super(target, DefaultDocumentTypeData, 'umbDocumentTypeStore', entityKey, 'documentType');
constructor(host: UmbControllerHostInterface, entityKey: string) {
super(host, DefaultDocumentTypeData, 'umbDocumentTypeStore', entityKey, 'documentType');
}
}

View File

@@ -1,20 +1,16 @@
import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { distinctUntilChanged } from 'rxjs';
import { UmbWorkspaceDocumentTypeContext } from './document-type-workspace.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import type { DocumentTypeDetails } from '@umbraco-cms/models';
import { UmbModalService } from 'src/core/modal';
import '../../../shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element';
import { UmbLitElement } from '@umbraco-cms/element';
import type { UmbWorkspaceEntityElement } from 'src/backoffice/shared/components/workspace/workspace-entity-element.interface';
@customElement('umb-document-type-workspace')
export class UmbDocumentTypeWorkspaceElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbDocumentTypeWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement {
static styles = [
UUITextStyles,
css`
@@ -75,17 +71,6 @@ export class UmbDocumentTypeWorkspaceElement extends UmbContextProviderMixin(
});
}
connectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.connectedCallback();
}
disconnectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.disconnectedCallback();
}
protected _provideWorkspace() {
if (this._entityKey) {
this._workspaceContext = new UmbWorkspaceDocumentTypeContext(this, this._entityKey);
@@ -97,8 +82,9 @@ export class UmbDocumentTypeWorkspaceElement extends UmbContextProviderMixin(
private async _observeWorkspace() {
if (!this._workspaceContext) return;
this.observe<DocumentTypeDetails>(this._workspaceContext.data.pipe(distinctUntilChanged()), (data) => {
this._documentType = data;
this.observe(this._workspaceContext.data.pipe(distinctUntilChanged()), (data) => {
// TODO: make method to identify if data is of type DocumentTypeDetails
this._documentType = (data as DocumentTypeDetails);
});
}
@@ -125,7 +111,7 @@ export class UmbDocumentTypeWorkspaceElement extends UmbContextProviderMixin(
render() {
return html`
<umb-workspace-entity alias="Umb.Workspace.DocumentType">
<umb-workspace-layout alias="Umb.Workspace.DocumentType">
<div id="header" slot="header">
<uui-button id="icon" @click=${this._handleIconClick} compact>
<uui-icon
@@ -139,7 +125,7 @@ export class UmbDocumentTypeWorkspaceElement extends UmbContextProviderMixin(
</div>
<div slot="footer">Keyboard Shortcuts</div>
</umb-workspace-entity>
</umb-workspace-layout>
`;
}
}

View File

@@ -1,18 +1,17 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, state } from 'lit/decorators.js';
import { distinctUntilChanged } from 'rxjs';
import { UmbWorkspaceDocumentTypeContext } from '../../document-type-workspace.context';
import type { DocumentTypeDetails } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { UmbDocumentTypeStoreItemType } from '../../../document-type.store';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-workspace-view-document-type-design')
export class UmbWorkspaceViewDocumentTypeDesignElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbWorkspaceViewDocumentTypeDesignElement extends UmbLitElement {
static styles = [UUITextStyles, css``];
@state()
_documentType?: DocumentTypeDetails;
_documentType?: UmbDocumentTypeStoreItemType | null;
private _workspaceContext?: UmbWorkspaceDocumentTypeContext;
@@ -28,7 +27,7 @@ export class UmbWorkspaceViewDocumentTypeDesignElement extends UmbContextConsume
private _observeDocumentType() {
if (!this._workspaceContext) return;
this.observe<DocumentTypeDetails>(this._workspaceContext.data.pipe(distinctUntilChanged()), (documentType) => {
this.observe(this._workspaceContext.data.pipe(distinctUntilChanged()), (documentType) => {
this._documentType = documentType;
});
}

View File

@@ -4,10 +4,9 @@ import { customElement } from 'lit/decorators.js';
import { UmbModalService } from '../../../../../core/modal';
import { UmbDocumentStore } from '../../document.store';
import UmbTreeItemActionElement from '../../../../shared/components/tree/action/tree-item-action.element';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
@customElement('umb-tree-action-document-delete')
export default class UmbTreeActionDocumentDeleteElement extends UmbContextConsumerMixin(UmbTreeItemActionElement) {
export default class UmbTreeActionDocumentDeleteElement extends UmbTreeItemActionElement {
static styles = [UUITextStyles, css``];
private _modalService?: UmbModalService;

View File

@@ -1,5 +1,6 @@
import { UmbWorkspaceNodeContext } from '../../../shared/components/workspace/workspace-context/workspace-node.context';
import { UmbWorkspaceContentContext } from '../../../shared/components/workspace/workspace-content/workspace-content.context';
import type { UmbDocumentStore, UmbDocumentStoreItemType } from 'src/backoffice/documents/documents/document.store';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
const DefaultDocumentData = {
key: '',
@@ -30,8 +31,8 @@ const DefaultDocumentData = {
],
} as UmbDocumentStoreItemType;
export class UmbWorkspaceDocumentContext extends UmbWorkspaceNodeContext<UmbDocumentStoreItemType, UmbDocumentStore> {
constructor(target: HTMLElement, entityKey: string) {
super(target, DefaultDocumentData, 'umbDocumentStore', entityKey, 'document');
export class UmbWorkspaceDocumentContext extends UmbWorkspaceContentContext<UmbDocumentStoreItemType, UmbDocumentStore> {
constructor(host: UmbControllerHostInterface, entityKey: string) {
super(host, DefaultDocumentData, 'umbDocumentStore', entityKey, 'document');
}
}

View File

@@ -1,14 +1,11 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { UmbWorkspaceDocumentContext } from './document-workspace.context';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-document-workspace')
export class UmbDocumentWorkspaceElement extends UmbObserverMixin(
UmbContextConsumerMixin(UmbContextProviderMixin(LitElement))
) {
export class UmbDocumentWorkspaceElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -32,16 +29,6 @@ export class UmbDocumentWorkspaceElement extends UmbObserverMixin(
private _workspaceContext?: UmbWorkspaceDocumentContext;
connectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.connectedCallback();
}
disconnectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.disconnectedCallback();
}
protected _provideWorkspace() {
if (this._entityKey) {

View File

@@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import '../../../shared/components/workspace/workspace-entity/workspace-entity.element';
import '../../../shared/components/workspace/workspace-layout/workspace-layout.element';
@customElement('umb-media-type-workspace')
export class UmbMediaTypeWorkspaceElement extends LitElement {
@@ -21,7 +21,7 @@ export class UmbMediaTypeWorkspaceElement extends LitElement {
id!: string;
render() {
return html`<umb-workspace-entity alias="Umb.Workspace.MediaType">Media Type Workspace</umb-workspace-entity>`;
return html`<umb-workspace-layout alias="Umb.Workspace.MediaType">Media Type Workspace</umb-workspace-layout>`;
}
}

View File

@@ -1,5 +1,6 @@
import { UmbWorkspaceNodeContext } from '../../../shared/components/workspace/workspace-context/workspace-node.context';
import { UmbWorkspaceContentContext } from '../../../shared/components/workspace/workspace-content/workspace-content.context';
import type { UmbMediaStore, UmbMediaStoreItemType } from 'src/backoffice/media/media/media.store';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
const DefaultMediaData = {
key: '',
@@ -30,8 +31,8 @@ const DefaultMediaData = {
],
} as UmbMediaStoreItemType;
export class UmbWorkspaceMediaContext extends UmbWorkspaceNodeContext<UmbMediaStoreItemType, UmbMediaStore> {
constructor(target: HTMLElement, entityKey: string) {
super(target, DefaultMediaData, 'umbMediaStore', entityKey, 'media');
export class UmbWorkspaceMediaContext extends UmbWorkspaceContentContext<UmbMediaStoreItemType, UmbMediaStore> {
constructor(host: UmbControllerHostInterface, entityKey: string) {
super(host, DefaultMediaData, 'umbMediaStore', entityKey, 'media');
}
}

View File

@@ -1,11 +1,11 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { UmbWorkspaceMediaContext } from './media-workspace.context';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-media-workspace')
export class UmbMediaWorkspaceElement extends UmbContextConsumerMixin(UmbContextProviderMixin(LitElement)) {
export class UmbMediaWorkspaceElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -29,19 +29,9 @@ export class UmbMediaWorkspaceElement extends UmbContextConsumerMixin(UmbContext
private _workspaceContext?: UmbWorkspaceMediaContext;
connectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.connectedCallback();
}
disconnectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.disconnectedCallback();
}
protected _provideWorkspace() {
if (this._entityKey) {
this._workspaceContext?.destroy();
this._workspaceContext = new UmbWorkspaceMediaContext(this, this._entityKey);
this.provideContext('umbWorkspaceContext', this._workspaceContext);
}

View File

@@ -20,7 +20,7 @@ export class UmbMemberGroupWorkspaceElement extends LitElement {
render() {
return html`
<umb-workspace-entity alias="Umb.Workspace.MemberGroup">Member Group Workspace</umb-workspace-entity>
<umb-workspace-layout alias="Umb.Workspace.MemberGroup">Member Group Workspace</umb-workspace-layout>
`;
}
}

View File

@@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import '../../../shared/components/workspace/workspace-entity/workspace-entity.element';
import '../../../shared/components/workspace/workspace-layout/workspace-layout.element';
@customElement('umb-member-type-workspace')
export class UmbMemberTypeWorkspaceElement extends LitElement {
@@ -21,7 +21,7 @@ export class UmbMemberTypeWorkspaceElement extends LitElement {
id!: string;
render() {
return html` <umb-workspace-entity alias="Umb.Workspace.MemberType">Member Type Workspace</umb-workspace-entity> `;
return html` <umb-workspace-layout alias="Umb.Workspace.MemberType">Member Type Workspace</umb-workspace-layout> `;
}
}

View File

@@ -19,7 +19,7 @@ export class UmbMemberWorkspaceElement extends LitElement {
id!: string;
render() {
return html` <umb-workspace-entity alias="Umb.Workspace.Member">Member Workspace</umb-workspace-entity> `;
return html` <umb-workspace-layout alias="Umb.Workspace.Member">Member Workspace</umb-workspace-layout> `;
}
}

View File

@@ -16,8 +16,8 @@ export class UmbWorkspacePackageBuilderElement extends LitElement {
];
render() {
return html`<umb-workspace-entity alias="Umb.Workspace.PackageBuilder"
>PACKAGE BUILDER</umb-workspace-entity
return html`<umb-workspace-layout alias="Umb.Workspace.PackageBuilder"
>PACKAGE BUILDER</umb-workspace-layout
> `;
}
}

View File

@@ -16,7 +16,7 @@ export class UmbWorkspacePackageElement extends LitElement {
];
render() {
return html`<umb-workspace-entity alias="Umb.Workspace.Package">PACKAGE Workspace</umb-workspace-entity> `;
return html`<umb-workspace-layout alias="Umb.Workspace.Package">PACKAGE Workspace</umb-workspace-layout> `;
}
}

View File

@@ -1,13 +1,13 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { IRoute, IRoutingInfo } from 'router-slot';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { ManifestWorkspace } from '@umbraco-cms/models';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-created-packages-section-view')
export class UmbCreatedPackagesSectionViewElement extends UmbObserverMixin(LitElement) {
export class UmbCreatedPackagesSectionViewElement extends UmbLitElement {
@state()
private _routes: IRoute[] = [];
@@ -16,7 +16,7 @@ export class UmbCreatedPackagesSectionViewElement extends UmbObserverMixin(LitEl
constructor() {
super();
this.observe<ManifestWorkspace[]>(umbExtensionsRegistry?.extensionsOfType('workspace'), (workspaceExtensions) => {
this.observe(umbExtensionsRegistry?.extensionsOfType('workspace'), (workspaceExtensions) => {
this._workspaces = workspaceExtensions;
this._createRoutes();
});

View File

@@ -1,9 +1,8 @@
import { html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
@customElement('umb-packages-created-item')
export class UmbPackagesCreatedItem extends UmbContextConsumerMixin(LitElement) {
export class UmbPackagesCreatedItem extends LitElement {
@property({ type: Object })
package!: any;

View File

@@ -1,13 +1,13 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { IRoute, IRoutingInfo } from 'router-slot';
import type { ManifestWorkspace } from '@umbraco-cms/models';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-installed-packages-section-view')
export class UmbInstalledPackagesSectionViewElement extends UmbObserverMixin(LitElement) {
export class UmbInstalledPackagesSectionViewElement extends UmbLitElement {
@state()
private _routes: IRoute[] = [];
@@ -16,7 +16,7 @@ export class UmbInstalledPackagesSectionViewElement extends UmbObserverMixin(Lit
constructor() {
super();
this.observe<ManifestWorkspace[]>(umbExtensionsRegistry?.extensionsOfType('workspace'), (workspaceExtensions) => {
this.observe(umbExtensionsRegistry?.extensionsOfType('workspace'), (workspaceExtensions) => {
this._workspaces = workspaceExtensions;
this._createRoutes();
});

View File

@@ -1,4 +1,4 @@
import { html, LitElement, nothing } from 'lit';
import { html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { firstValueFrom, map } from 'rxjs';
@@ -6,11 +6,11 @@ import type { UmbModalService } from '../../../../../core/modal';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestPackageView } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-packages-installed-item')
export class UmbPackagesInstalledItem extends UmbContextConsumerMixin(LitElement) {
export class UmbPackagesInstalledItem extends UmbLitElement {
@property({ type: Object })
package!: any; // TODO: Use real type

View File

@@ -1,14 +1,14 @@
import { html, LitElement, css, nothing } from 'lit';
import { html, css, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { IRoute, IRoutingInfo, path } from 'router-slot';
import { UmbDashboardExamineIndexElement } from './views/section-view-examine-indexers';
import { UmbDashboardExamineSearcherElement } from './views/section-view-examine-searchers';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-dashboard-examine-management')
export class UmbDashboardExamineManagementElement extends UmbContextConsumerMixin(LitElement) {
export class UmbDashboardExamineManagementElement extends UmbLitElement {
static styles = [
css`
a {

View File

@@ -1,20 +1,19 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { UUIButtonState } from '@umbraco-ui/uui-button';
import { UmbModalService } from '../../../../../core/modal';
import { UmbNotificationService } from '../../../../../core/notification';
import { UmbNotificationDefaultData } from '../../../../../core/notification/layouts/default';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import './section-view-examine-searchers';
import { ApiError, Index, IndexerResource, ProblemDetails } from '@umbraco-cms/backend-api';
import { Index, IndexerResource } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
@customElement('umb-dashboard-examine-index')
export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(LitElement) {
export class UmbDashboardExamineIndexElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -93,30 +92,24 @@ export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(Lit
@state()
private _loading = true;
private _notificationService?: UmbNotificationService;
private _modalService?: UmbModalService;
constructor() {
super();
this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => {
this._notificationService = instances['umbNotificationService'];
this.consumeAllContexts(['umbModalService'], (instances) => {
this._modalService = instances['umbModalService'];
});
}
private async _getIndexData() {
try {
this._indexData = await IndexerResource.getIndexerByIndexName({ indexName: this.indexName });
if (!this._indexData?.isHealthy) {
this._buttonState = 'waiting';
}
} catch (e) {
if (e instanceof ApiError) {
const error = e as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch index' };
this._notificationService?.peek('danger', { data });
}
const { data } = await tryExecuteAndNotify(
this,
IndexerResource.getIndexerByIndexName({ indexName: this.indexName })
);
this._indexData = data;
if (!this._indexData?.isHealthy) {
this._buttonState = 'waiting';
}
this._loading = false;
}
@@ -144,18 +137,17 @@ export class UmbDashboardExamineIndexElement extends UmbContextConsumerMixin(Lit
}
private async _rebuild() {
this._buttonState = 'waiting';
try {
await IndexerResource.postIndexerByIndexNameRebuild({ indexName: this.indexName });
this._buttonState = 'success';
await this._getIndexData();
} catch (e) {
const { error } = await tryExecuteAndNotify(
this,
IndexerResource.postIndexerByIndexNameRebuild({ indexName: this.indexName })
);
if (error) {
this._buttonState = 'failed';
if (e instanceof ApiError) {
const error = e as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.message ?? 'Rebuild error' };
this._notificationService?.peek('danger', { data });
}
return;
}
this._buttonState = 'success';
await this._getIndexData();
}
render() {

View File

@@ -1,15 +1,13 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbNotificationService } from '../../../../../core/notification';
import { UmbNotificationDefaultData } from '../../../../../core/notification/layouts/default';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { ApiError, ProblemDetails, Searcher, Index, IndexerResource, SearcherResource } from '@umbraco-cms/backend-api';
import { Index, IndexerResource, Searcher, SearcherResource } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
@customElement('umb-dashboard-examine-overview')
export class UmbDashboardExamineOverviewElement extends UmbContextConsumerMixin(LitElement) {
export class UmbDashboardExamineOverviewElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -65,16 +63,6 @@ export class UmbDashboardExamineOverviewElement extends UmbContextConsumerMixin(
@state()
private _loadingSearchers = false;
private _notificationService?: UmbNotificationService;
constructor() {
super();
this.consumeAllContexts(['umbNotificationService'], (instances) => {
this._notificationService = instances['umbNotificationService'];
});
}
connectedCallback() {
super.connectedCallback();
this._getIndexers();
@@ -83,31 +71,15 @@ export class UmbDashboardExamineOverviewElement extends UmbContextConsumerMixin(
private async _getIndexers() {
this._loadingIndexers = true;
try {
const indexers = await IndexerResource.getIndexer({ take: 9999, skip: 0 });
this._indexers = indexers.items;
} catch (e) {
if (e instanceof ApiError) {
const error = e as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch indexers' };
this._notificationService?.peek('danger', { data });
}
}
const { data } = await tryExecuteAndNotify(this, IndexerResource.getIndexer({ take: 9999, skip: 0 }));
this._indexers = data?.items ?? [];
this._loadingIndexers = false;
}
private async _getSearchers() {
this._loadingSearchers = true;
try {
const searchers = await SearcherResource.getSearcher({ take: 9999, skip: 0 });
this._searchers = searchers.items;
} catch (e) {
if (e instanceof ApiError) {
const error = e as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch searchers' };
this._notificationService?.peek('danger', { data });
}
}
const { data } = await tryExecuteAndNotify(this, SearcherResource.getSearcher({ take: 9999, skip: 0 }));
this._searchers = data?.items ?? [];
this._loadingSearchers = false;
}

View File

@@ -1,14 +1,12 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state, query, property } from 'lit/decorators.js';
import { UmbModalService } from '../../../../../core/modal';
import { UmbNotificationService } from '../../../../../core/notification';
import { UmbNotificationDefaultData } from '../../../../../core/notification/layouts/default';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { ApiError, ProblemDetails, SearchResult, SearcherResource, Field } from '@umbraco-cms/backend-api';
import { SearchResult, SearcherResource, Field } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
import './modal-views/fields-viewer.element';
import './modal-views/fields-settings.element';
@@ -19,7 +17,7 @@ interface ExposedSearchResultField {
}
@customElement('umb-dashboard-examine-searcher')
export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin(LitElement) {
export class UmbDashboardExamineSearcherElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -103,7 +101,6 @@ export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin(
`,
];
private _notificationService?: UmbNotificationService;
private _modalService?: UmbModalService;
@property()
@@ -123,15 +120,14 @@ export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin(
constructor() {
super();
this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => {
this._notificationService = instances['umbNotificationService'];
this._modalService = instances['umbModalService'];
this.consumeContext('umbModalService', (instance) => {
this._modalService = instance;
});
}
private _onNameClick() {
const data: UmbNotificationDefaultData = { message: 'TODO: Open workspace for this' }; // TODO
this._notificationService?.peek('warning', { data });
// TODO:
alert('TODO: Open workspace for ' + this.searcherName);
}
private _onKeyPress(e: KeyboardEvent) {
@@ -141,22 +137,19 @@ export class UmbDashboardExamineSearcherElement extends UmbContextConsumerMixin(
private async _onSearch() {
if (!this._searchInput.value.length) return;
this._searchLoading = true;
try {
const res = await SearcherResource.getSearcherBySearcherNameQuery({
const { data } = await tryExecuteAndNotify(
this,
SearcherResource.getSearcherBySearcherNameQuery({
searcherName: this.searcherName,
term: this._searchInput.value,
take: 100,
skip: 0,
});
this._searchResults = res.items;
this._updateFieldFilter();
} catch (e) {
if (e instanceof ApiError) {
const error = e as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.message ?? 'Could not fetch search results' };
this._notificationService?.peek('danger', { data });
}
}
})
);
this._searchResults = data?.items ?? [];
this._updateFieldFilter();
this._searchLoading = false;
}

View File

@@ -1,15 +1,14 @@
import { UUIButtonState } from '@umbraco-ui/uui';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbNotificationService } from '../../../../core/notification';
import { UmbNotificationDefaultData } from '../../../../core/notification/layouts/default';
import { ApiError, ModelsBuilder, ModelsBuilderResource, ModelsMode, ProblemDetails } from '@umbraco-cms/backend-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { ModelsBuilder, ModelsBuilderResource, ModelsMode } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
@customElement('umb-dashboard-models-builder')
export class UmbDashboardModelsBuilderElement extends UmbContextConsumerMixin(LitElement) {
export class UmbDashboardModelsBuilderElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -41,8 +40,6 @@ export class UmbDashboardModelsBuilderElement extends UmbContextConsumerMixin(Li
`,
];
private _notificationService?: UmbNotificationService;
@state()
private _modelsBuilder?: ModelsBuilder;
@@ -55,26 +52,15 @@ export class UmbDashboardModelsBuilderElement extends UmbContextConsumerMixin(Li
constructor() {
super();
this._getDashboardData();
this.consumeAllContexts(['umbNotificationService'], (instances) => {
this._notificationService = instances['umbNotificationService'];
});
}
private async _getDashboardData() {
try {
const modelsBuilder = await ModelsBuilderResource.getModelsBuilderDashboard();
this._modelsBuilder = modelsBuilder;
const { data } = await tryExecuteAndNotify(this, ModelsBuilderResource.getModelsBuilderDashboard());
if (data) {
this._modelsBuilder = data;
return true;
} catch (e) {
if (e instanceof ApiError) {
const error = e as ProblemDetails;
const data: UmbNotificationDefaultData = {
message: error.message ?? 'Something went wrong',
};
this._notificationService?.peek('danger', { data });
}
return false;
}
return false;
}
private async _onGenerateModels() {
@@ -84,20 +70,13 @@ export class UmbDashboardModelsBuilderElement extends UmbContextConsumerMixin(Li
}
private async _postGenerateModels() {
try {
await ModelsBuilderResource.postModelsBuilderBuild();
this._getDashboardData();
return true;
} catch (e) {
if (e instanceof ApiError) {
const error = e as ProblemDetails;
const data: UmbNotificationDefaultData = {
message: error.message ?? 'Model generation failed',
};
this._notificationService?.peek('danger', { data });
}
const { error } = await tryExecuteAndNotify(this, ModelsBuilderResource.postModelsBuilderBuild());
if (error) {
return false;
}
this._getDashboardData();
return true;
}
private async _onDashboardReload() {

View File

@@ -1,11 +1,12 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { ProfilingResource, ProfilingStatus } from '@umbraco-cms/backend-api';
import { ProfilingResource } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from 'src/core/resources/tryExecuteAndNotify.method';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-dashboard-performance-profiling')
export class UmbDashboardPerformanceProfilingElement extends LitElement {
export class UmbDashboardPerformanceProfilingElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`

View File

@@ -1,17 +1,16 @@
import { UUIButtonState } from '@umbraco-ui/uui';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbModalService } from '../../../../core/modal';
import { UmbNotificationService } from '../../../../core/notification';
import { UmbNotificationDefaultData } from '../../../../core/notification/layouts/default';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { ApiError, ProblemDetails, PublishedCacheResource } from '@umbraco-cms/backend-api';
import { PublishedCacheResource } from '@umbraco-cms/backend-api';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-dashboard-published-status')
export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(LitElement) {
export class UmbDashboardPublishedStatusElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -39,14 +38,12 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(
@state()
private _buttonStateCollect: UUIButtonState = undefined;
private _notificationService?: UmbNotificationService;
private _modalService?: UmbModalService;
constructor() {
super();
this.consumeAllContexts(['umbNotificationService', 'umbModalService'], (instances) => {
this._notificationService = instances['umbNotificationService'];
this.consumeAllContexts(['umbModalService'], (instances) => {
this._modalService = instances['umbModalService'];
});
}
@@ -57,19 +54,13 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(
}
// Refresh
private async _getPublishedStatus() {
try {
const data = await PublishedCacheResource.getPublishedCacheStatus();
const { data } = await tryExecuteAndNotify(this, PublishedCacheResource.getPublishedCacheStatus());
if (data) {
this._publishedStatusText = data;
} catch (e) {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.detail ?? 'Something went wrong' };
this._notificationService?.peek('danger', { data });
}
}
}
private async _onRefreshCacheHandler() {
this._buttonState = 'waiting';
await this._getPublishedStatus();
@@ -80,19 +71,14 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(
private async _reloadMemoryCache() {
this._buttonStateReload = 'waiting';
this._buttonState = 'waiting';
try {
await PublishedCacheResource.postPublishedCacheReload();
const { error } = await tryExecuteAndNotify(this, PublishedCacheResource.postPublishedCacheReload());
if (error) {
this._buttonStateReload = 'failed';
this._buttonState = 'failed';
} else {
this._buttonStateReload = 'success';
this._getPublishedStatus();
this._buttonState = 'success';
} catch (e) {
this._buttonStateReload = 'failed';
this._buttonState = 'failed';
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.detail ?? 'Something went wrong' };
this._notificationService?.peek('danger', { data });
}
}
}
private async _onReloadCacheHandler() {
@@ -102,7 +88,7 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(
color: 'danger',
confirmLabel: 'Continue',
});
modalHandler?.onClose().then(({ confirmed }: any) => {
modalHandler?.onClose().then(({ confirmed }) => {
if (confirmed) this._reloadMemoryCache();
});
}
@@ -110,18 +96,14 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(
// Rebuild
private async _rebuildDatabaseCache() {
this._buttonStateRebuild = 'waiting';
try {
await PublishedCacheResource.postPublishedCacheRebuild();
this._buttonStateRebuild = 'success';
} catch (e) {
const { error } = await tryExecuteAndNotify(this, PublishedCacheResource.postPublishedCacheRebuild());
if (error) {
this._buttonStateRebuild = 'failed';
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.detail ?? 'Something went wrong' };
this._notificationService?.peek('danger', { data });
}
} else {
this._buttonStateRebuild = 'success';
}
}
private async _onRebuildCacheHandler() {
const modalHandler = this._modalService?.confirm({
headline: 'Rebuild',
@@ -129,25 +111,21 @@ export class UmbDashboardPublishedStatusElement extends UmbContextConsumerMixin(
color: 'danger',
confirmLabel: 'Continue',
});
modalHandler?.onClose().then(({ confirmed }: any) => {
modalHandler?.onClose().then(({ confirmed }) => {
if (confirmed) this._rebuildDatabaseCache();
});
}
//Collect
private async _cacheCollect() {
try {
await PublishedCacheResource.postPublishedCacheCollect();
this._buttonStateCollect = 'success';
} catch (e) {
const { error } = await tryExecuteAndNotify(this, PublishedCacheResource.postPublishedCacheCollect());
if (error) {
this._buttonStateCollect = 'failed';
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
const data: UmbNotificationDefaultData = { message: error.data.detail ?? 'Something went wrong' };
this._notificationService?.peek('danger', { data });
}
} else {
this._buttonStateCollect = 'success';
}
}
private async _onSnapshotCacheHandler() {
this._buttonStateCollect = 'waiting';
await this._cacheCollect();

View File

@@ -1,12 +1,14 @@
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { UUIButtonState } from '@umbraco-ui/uui';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import { customElement, state } from 'lit/decorators.js';
import { ApiError, ProblemDetails, Telemetry, TelemetryLevel, TelemetryResource } from '@umbraco-cms/backend-api';
import { Telemetry, TelemetryLevel, TelemetryResource } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
@customElement('umb-dashboard-telemetry')
export class UmbDashboardTelemetryElement extends LitElement {
export class UmbDashboardTelemetryElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -38,46 +40,32 @@ export class UmbDashboardTelemetryElement extends LitElement {
}
private async _setup() {
try {
const consentLevels = await TelemetryResource.getTelemetry({skip: 0, take: 3});
this._telemetryLevels = consentLevels.items ?? [];
} catch (e) {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
this._errorMessage = error.detail;
}
}
const telemetryLevels = await tryExecuteAndNotify(this, TelemetryResource.getTelemetry({ skip: 0, take: 3 }));
this._telemetryLevels = telemetryLevels.data?.items ?? [];
try {
const consentSetting = await TelemetryResource.getTelemetryLevel();
this._telemetryFormData = consentSetting.telemetryLevel ?? TelemetryLevel.BASIC;
} catch (e) {
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
this._errorMessage = error.detail;
}
}
const telemetryLevel = await tryExecuteAndNotify(this, TelemetryResource.getTelemetryLevel());
this._telemetryFormData = telemetryLevel.data?.telemetryLevel ?? TelemetryLevel.BASIC;
}
private _handleSubmit = async (e: CustomEvent<SubmitEvent>) => {
e.stopPropagation();
this._buttonState = 'waiting';
try {
await TelemetryResource.postTelemetryLevel({
const { error } = await tryExecuteAndNotify(
this,
TelemetryResource.postTelemetryLevel({
requestBody: { telemetryLevel: this._telemetryFormData },
});
this._buttonState = 'success';
} catch (e) {
})
);
if (error) {
this._buttonState = 'failed';
if (e instanceof ApiError) {
const error = e.body as ProblemDetails;
if (e.status === 400) {
this._errorMessage = error.detail || 'Unknown error, please try again';
}
} else {
this._errorMessage = 'Unknown error, please try again';
}
this._errorMessage = error.detail;
return;
}
this._buttonState = 'success';
};
private _handleChange(e: InputEvent) {
@@ -146,7 +134,12 @@ export class UmbDashboardTelemetryElement extends LitElement {
will be fully anonymized.
</p>
${this._renderSettingSlider()}
<uui-button look="primary" color="positive" label="Save telemetry settings" @click="${this._handleSubmit}" .state=${this._buttonState}>
<uui-button
look="primary"
color="positive"
label="Save telemetry settings"
@click="${this._handleSubmit}"
.state=${this._buttonState}>
Save
</uui-button>
</div>

View File

@@ -4,10 +4,9 @@ import { customElement } from 'lit/decorators.js';
import { UmbModalService } from '../../../../../../core/modal';
import { UmbDataTypeStore } from '../../../data-type.store';
import UmbTreeItemActionElement from '../../../../../shared/components/tree/action/tree-item-action.element';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
@customElement('umb-tree-action-data-type-delete')
export default class UmbTreeActionDataTypeDeleteElement extends UmbContextConsumerMixin(UmbTreeItemActionElement) {
export default class UmbTreeActionDataTypeDeleteElement extends UmbTreeItemActionElement {
static styles = [UUITextStyles, css``];
private _modalService?: UmbModalService;

View File

@@ -1,14 +1,14 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement } from 'lit/decorators.js';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import type { ManifestTreeItemAction } from '@umbraco-cms/models';
import '../../../shared/components/tree/navigator/tree-navigator.element';
import { UmbDataTypeStore } from 'src/backoffice/settings/data-types/data-type.store';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-tree-data-types')
export class UmbTreeDataTypesElement extends UmbContextProviderMixin(UmbContextConsumerMixin(LitElement)) {
export class UmbTreeDataTypesElement extends UmbLitElement {
constructor() {
super();

View File

@@ -1,18 +1,18 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbModalService } from '../../../../../../core/modal';
import { UmbWorkspaceDataTypeContext } from '../../workspace-data-type.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestPropertyEditorUI, DataTypeDetails } from '@umbraco-cms/models';
import { UmbDataTypeStoreItemType } from '../../../data-type.store';
import type { DataTypeDetails, ManifestPropertyEditorUI } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import '../../../../../shared/property-editors/shared/property-editor-config/property-editor-config.element';
import '../../../../../shared/components/ref-property-editor-ui/ref-property-editor-ui.element';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-workspace-view-data-type-edit')
export class UmbWorkspaceViewDataTypeEditElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbWorkspaceViewDataTypeEditElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -55,12 +55,15 @@ export class UmbWorkspaceViewDataTypeEditElement extends UmbContextConsumerMixin
}
private _observeDataType() {
if (!this._workspaceContext) return;
if (!this._workspaceContext) {
return;
}
this.observe<DataTypeDetails>(this._workspaceContext.data, (dataType) => {
this._dataType = dataType;
this.observe(this._workspaceContext.data, (dataType) => {
if (!dataType) return;
if (!this._dataType) return;
// TODO: handle if model is not of the type wanted.
this._dataType = dataType as DataTypeDetails;
if (this._dataType.propertyEditorUIAlias !== this._propertyEditorUIAlias) {
this._observePropertyEditorUI(this._dataType.propertyEditorUIAlias);
@@ -75,7 +78,7 @@ export class UmbWorkspaceViewDataTypeEditElement extends UmbContextConsumerMixin
private _observePropertyEditorUI(propertyEditorUIAlias: string | null) {
if (!propertyEditorUIAlias) return;
this.observe<ManifestPropertyEditorUI>(
this.observe(
umbExtensionsRegistry.getByAlias<ManifestPropertyEditorUI>(propertyEditorUIAlias),
(propertyEditorUI) => {
this._propertyEditorUIName = propertyEditorUI?.meta.label ?? propertyEditorUI?.name ?? '';

View File

@@ -1,14 +1,13 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { distinctUntilChanged } from 'rxjs';
import { UmbWorkspaceDataTypeContext } from '../../workspace-data-type.context';
import type { DataTypeDetails } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-workspace-view-data-type-info')
export class UmbWorkspaceViewDataTypeInfoElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbWorkspaceViewDataTypeInfoElement extends UmbLitElement {
static styles = [UUITextStyles, css``];
@state()
@@ -28,8 +27,12 @@ export class UmbWorkspaceViewDataTypeInfoElement extends UmbContextConsumerMixin
private _observeDataType() {
if (!this._workspaceContext) return;
this.observe<DataTypeDetails>(this._workspaceContext.data.pipe(distinctUntilChanged()), (dataType) => {
this._dataType = dataType;
this.observe(this._workspaceContext.data.pipe(distinctUntilChanged()), (dataType) => {
if(!dataType) return;
// TODO: handle if model is not of the type wanted.
// TODO: Make method to identify wether data is of type DataTypeDetails
this._dataType = (dataType as DataTypeDetails);
});
}

View File

@@ -1,6 +1,7 @@
import { UmbWorkspaceNodeContext } from '../../../shared/components/workspace/workspace-context/workspace-node.context';
import { UmbWorkspaceContentContext } from '../../../shared/components/workspace/workspace-content/workspace-content.context';
import type { UmbDataTypeStore, UmbDataTypeStoreItemType } from 'src/backoffice/settings/data-types/data-type.store';
import type { DataTypeDetails } from '@umbraco-cms/models';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
const DefaultDataTypeData = {
key: '',
@@ -14,9 +15,9 @@ const DefaultDataTypeData = {
data: [],
} as UmbDataTypeStoreItemType;
export class UmbWorkspaceDataTypeContext extends UmbWorkspaceNodeContext<UmbDataTypeStoreItemType, UmbDataTypeStore> {
constructor(target: HTMLElement, entityKey: string) {
super(target, DefaultDataTypeData, 'umbDataTypeStore', entityKey, 'dataType');
export class UmbWorkspaceDataTypeContext extends UmbWorkspaceContentContext<UmbDataTypeStoreItemType, UmbDataTypeStore> {
constructor(host: UmbControllerHostInterface, entityKey: string) {
super(host, DefaultDataTypeData, 'umbDataTypeStore', entityKey, 'dataType');
}
public setPropertyValue(propertyAlias: string, value: any) {

View File

@@ -1,23 +1,17 @@
import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { distinctUntilChanged } from 'rxjs';
import { UmbDataTypeStore } from '../data-type.store';
import { UmbWorkspaceDataTypeContext } from './workspace-data-type.context';
import type { DataTypeDetails } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/element';
/**
* @element umb-workspace-data-type
* @description - Element for displaying a Data Type Workspace
*/
@customElement('umb-workspace-data-type')
export class UmbWorkspaceDataTypeElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbWorkspaceDataTypeElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -55,17 +49,6 @@ export class UmbWorkspaceDataTypeElement extends UmbContextProviderMixin(
this.addEventListener('property-value-change', this._onPropertyValueChange);
}
connectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.connectedCallback();
}
disconnectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.disconnectedCallback();
}
protected _provideWorkspace() {
if (this._entityKey) {
this._workspaceContext = new UmbWorkspaceDataTypeContext(this, this._entityKey);
@@ -77,7 +60,7 @@ export class UmbWorkspaceDataTypeElement extends UmbContextProviderMixin(
private _observeWorkspace() {
if (!this._workspaceContext) return;
this.observe<DataTypeDetails>(this._workspaceContext.data.pipe(distinctUntilChanged()), (dataType) => {
this.observe(this._workspaceContext.data.pipe(distinctUntilChanged()), (dataType) => {
if (dataType && dataType.name !== this._dataTypeName) {
this._dataTypeName = dataType.name ?? '';
}
@@ -102,9 +85,9 @@ export class UmbWorkspaceDataTypeElement extends UmbContextProviderMixin(
render() {
return html`
<umb-workspace-entity alias="Umb.Workspace.DataType">
<umb-workspace-layout alias="Umb.Workspace.DataType">
<uui-input id="header" slot="header" .value=${this._dataTypeName} @input="${this._handleInput}"></uui-input>
</umb-workspace-entity>
</umb-workspace-layout>
`;
}
}

View File

@@ -1,15 +1,14 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { isManifestElementNameType } from '@umbraco-cms/extensions-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestTypes } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-extension-root-workspace')
export class UmbExtensionRootWorkspaceElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbExtensionRootWorkspaceElement extends UmbLitElement {
@state()
private _extensions: Array<ManifestTypes> = [];
private _extensions?: Array<ManifestTypes> = undefined;
connectedCallback(): void {
super.connectedCallback();
@@ -17,14 +16,14 @@ export class UmbExtensionRootWorkspaceElement extends UmbContextConsumerMixin(Um
}
private _observeExtensions() {
this.observe<Array<ManifestTypes>>(umbExtensionsRegistry.extensions, (extensions) => {
this._extensions = [...extensions];
this.observe(umbExtensionsRegistry.extensions, (extensions) => {
this._extensions = extensions || undefined;
});
}
render() {
return html`
<umb-workspace-entity headline="Extensions" alias="Umb.Workspace.ExtensionRoot">
<umb-workspace-layout headline="Extensions" alias="Umb.Workspace.ExtensionRoot">
<uui-box>
<p>List of currently loaded extensions</p>
<uui-table>
@@ -35,7 +34,7 @@ export class UmbExtensionRootWorkspaceElement extends UmbContextConsumerMixin(Um
<uui-table-head-cell>Actions</uui-table-head-cell>
</uui-table-head>
${this._extensions.map(
${this._extensions?.map(
(extension) => html`
<uui-table-row>
<uui-table-cell>${extension.type}</uui-table-cell>
@@ -53,7 +52,7 @@ export class UmbExtensionRootWorkspaceElement extends UmbContextConsumerMixin(Um
)}
</uui-table>
</uui-box>
</umb-workspace-entity>
</umb-workspace-layout>
`;
}
}

View File

@@ -1,13 +1,13 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import type { UmbCollectionContext } from '../collection.context';
import type { ManifestCollectionBulkAction } from '@umbraco-cms/models';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-collection-bulk-action-media-delete')
export class UmbCollectionBulkActionDeleteElement extends UmbContextConsumerMixin(LitElement) {
export class UmbCollectionBulkActionDeleteElement extends UmbLitElement {
static styles = [UUITextStyles, css``];
// TODO: make a UmbCollectionContextMedia:

View File

@@ -1,13 +1,12 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import type { UmbCollectionContext } from './collection.context';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { MediaDetails } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-collection-selection-actions')
export class UmbCollectionSelectionActionsElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbCollectionSelectionActionsElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -57,11 +56,11 @@ export class UmbCollectionSelectionActionsElement extends UmbContextConsumerMixi
if (!this._collectionContext) return;
// TODO: Make sure it only updates on length change.
this.observe<Array<MediaDetails>>(this._collectionContext.data, (mediaItems) => {
this.observe(this._collectionContext.data, (mediaItems) => {
this._nodesLength = mediaItems.length;
});
this.observe<Array<string>>(this._collectionContext.selection, (selection) => {
this.observe(this._collectionContext.selection, (selection) => {
this._selectionLength = selection.length;
});
}

View File

@@ -1,15 +1,15 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { map } from 'rxjs';
import { TooltipMenuItem } from '../components/tooltip-menu';
import '../components/tooltip-menu/tooltip-menu.element';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { ManifestCollectionView } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-collection-toolbar')
export class UmbCollectionToolbarElement extends UmbObserverMixin(LitElement) {
export class UmbCollectionToolbarElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -71,15 +71,13 @@ export class UmbCollectionToolbarElement extends UmbObserverMixin(LitElement) {
}
private _observeCollectionViews() {
this.observe<Array<ManifestCollectionView>>(
umbExtensionsRegistry?.extensionsOfType('collectionView').pipe(
this.observe<ManifestCollectionView[]>(
umbExtensionsRegistry.extensionsOfType('collectionView').pipe(
map((extensions) => {
return extensions.filter((extension) => extension.meta.entityType === 'media');
})
),
(layouts) => {
console.log('layouts', layouts);
if (layouts?.length === 0) return;
this._layouts = layouts;
if (!this._currentLayout) {

View File

@@ -1,21 +1,23 @@
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { BehaviorSubject, Observable } from 'rxjs';
import { ContentTreeItem } from '@umbraco-cms/backend-api';
import { UmbContextConsumer } from '@umbraco-cms/context-api';
import { UmbTreeDataStore } from '@umbraco-cms/stores/store';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
import { UmbContextConsumerController } from 'src/core/context-api/consume/context-consumer.controller';
import { UmbObserverController } from 'src/core/observable-api/observer.controller';
export class UmbCollectionContext<
DataType extends ContentTreeItem,
StoreType extends UmbTreeDataStore<DataType> = UmbTreeDataStore<DataType>
> {
private _target: HTMLElement;
private _host: UmbControllerHostInterface;
private _entityKey: string | null;
protected _storeConsumer!: UmbContextConsumer;
private _store?: StoreType;
protected _dataObserver?: UmbObserverController<DataType[]>;
private _data: BehaviorSubject<Array<DataType>> = new BehaviorSubject(<Array<DataType>>[]);
public readonly data: Observable<Array<DataType>> = this._data.asObservable();
protected _dataObserver?: Subscription;
private _selection: BehaviorSubject<Array<string>> = new BehaviorSubject(<Array<string>>[]);
public readonly selection: Observable<Array<string>> = this._selection.asObservable();
@@ -26,11 +28,11 @@ export class UmbCollectionContext<
public readonly search: Observable<string> = this._search.asObservable();
*/
constructor(target: HTMLElement, entityKey: string | null, storeAlias: string) {
this._target = target;
constructor(host: UmbControllerHostInterface, entityKey: string | null, storeAlias: string) {
this._host = host;
this._entityKey = entityKey;
this._storeConsumer = new UmbContextConsumer(this._target, storeAlias, (_instance: StoreType) => {
new UmbContextConsumerController(this._host, storeAlias, (_instance: StoreType) => {
this._store = _instance;
if (!this._store) {
// TODO: if we keep the type assumption of _store existing, then we should here make sure to break the application in a good way.
@@ -40,14 +42,6 @@ export class UmbCollectionContext<
});
}
connectedCallback() {
this._storeConsumer.hostConnected();
}
disconnectedCallback() {
this._storeConsumer.hostDisconnected();
}
public getData() {
return this._data.getValue();
}
@@ -63,13 +57,19 @@ export class UmbCollectionContext<
return;
}
this._dataObserver?.destroy();
if (this._entityKey) {
this._dataObserver = this._store.getTreeItemChildren(this._entityKey).subscribe((nodes) => {
this._data.next(nodes);
this._dataObserver = new UmbObserverController(this._host, this._store.getTreeItemChildren(this._entityKey), (nodes) => {
if(nodes) {
this._data.next(nodes);
}
});
} else {
this._dataObserver = this._store.getTreeRoot().subscribe((nodes) => {
this._data.next(nodes);
this._dataObserver = new UmbObserverController(this._host, this._store.getTreeRoot(), (nodes) => {
if(nodes) {
this._data.next(nodes);
}
});
}
}

View File

@@ -1,5 +1,5 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state, property } from 'lit/decorators.js';
import { map } from 'rxjs';
import './collection-selection-actions.element';
@@ -7,12 +7,12 @@ import './collection-toolbar.element';
import type { UmbCollectionContext } from './collection.context';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import type { ManifestCollectionView, MediaDetails } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
import type { UmbObserverController } from 'src/core/observable-api/observer.controller';
@customElement('umb-collection')
export class UmbCollectionElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbCollectionElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -34,7 +34,7 @@ export class UmbCollectionElement extends UmbContextConsumerMixin(UmbObserverMix
private _routes: Array<any> = [];
@state()
private _selection: Array<string> = [];
private _selection?: Array<string> | null;
private _collectionContext?: UmbCollectionContext<MediaDetails>;
@@ -48,7 +48,7 @@ export class UmbCollectionElement extends UmbContextConsumerMixin(UmbObserverMix
this._observeCollectionViews();
}
private _collectionViewUnsubscribe?: () => void;
private _collectionViewUnsubscribe?: UmbObserverController<Array<ManifestCollectionView>>;
constructor() {
super();
@@ -62,35 +62,37 @@ export class UmbCollectionElement extends UmbContextConsumerMixin(UmbObserverMix
private _observeCollectionContext() {
if (!this._collectionContext) return;
this.observe<Array<string>>(this._collectionContext.selection, (selection) => {
this.observe(this._collectionContext.selection, (selection) => {
this._selection = selection;
});
}
private _observeCollectionViews() {
this._collectionViewUnsubscribe?.();
this._collectionViewUnsubscribe = this.observe<Array<ManifestCollectionView>>(
this._collectionViewUnsubscribe?.destroy();
this._collectionViewUnsubscribe = this.observe(
// TODO: could we make some helper methods for this scenario:
umbExtensionsRegistry?.extensionsOfType('collectionView').pipe(
map((extensions) => {
return extensions.filter((extension) => extension.meta.entityType === this._entityType);
})
),
(views) => {
if (views?.length === 0) return;
this._createRoutes(views);
}
);
}
private _createRoutes(views: ManifestCollectionView[]) {
private _createRoutes(views: ManifestCollectionView[] | null) {
this._routes = [];
this._routes = views.map((view) => {
return {
path: `${view.meta.pathName}`,
component: () => createExtensionElement(view),
};
});
if(views) {
this._routes = views.map((view) => {
return {
path: `${view.meta.pathName}`,
component: () => createExtensionElement(view),
};
});
}
this._routes.push({
path: '**',
@@ -103,7 +105,7 @@ export class UmbCollectionElement extends UmbContextConsumerMixin(UmbObserverMix
<umb-body-layout no-header-background>
<umb-collection-toolbar slot="header"></umb-collection-toolbar>
<router-slot id="router-slot" .routes="${this._routes}"></router-slot>
${this._selection.length > 0
${this._selection && this._selection.length > 0
? html`<umb-collection-selection-actions slot="footer"></umb-collection-selection-actions>`
: nothing}
</umb-body-layout>

View File

@@ -1,18 +1,15 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import '../collection.element';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbMediaStore, UmbMediaStoreItemType } from 'src/backoffice/media/media/media.store';
import { UmbCollectionContext } from 'src/backoffice/shared/collection/collection.context';
import type { ManifestDashboardCollection } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-dashboard-collection')
export class UmbDashboardCollectionElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbDashboardCollectionElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -42,14 +39,6 @@ export class UmbDashboardCollectionElement extends UmbContextProviderMixin(
this._collectionContext = new UmbCollectionContext(this, null, manifestMeta.storeAlias);
this.provideContext('umbCollectionContext', this._collectionContext);
}
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._collectionContext?.connectedCallback();
}
disconnectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._collectionContext?.disconnectedCallback();
}
render() {

View File

@@ -1,14 +1,13 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import type { UmbCollectionContext } from '../collection.context';
import type { MediaDetails } from '@umbraco-cms/models';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-collection-view-media-grid')
export class UmbCollectionViewsMediaGridElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbCollectionViewsMediaGridElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -66,19 +65,19 @@ export class UmbCollectionViewsMediaGridElement extends UmbContextConsumerMixin(
];
@state()
private _mediaItems: Array<MediaDetails> = [];
private _mediaItems?: Array<MediaDetails>;
@state()
private _selection: Array<string> = [];
private _selection?: Array<string>;
private _collectionContext?: UmbCollectionContext<MediaDetails>;
constructor() {
super();
document.addEventListener('dragenter', (e) => {
document.addEventListener('dragenter', () => {
this.toggleAttribute('dragging', true);
});
document.addEventListener('dragleave', (e) => {
document.addEventListener('dragleave', () => {
this.toggleAttribute('dragging', false);
});
document.addEventListener('drop', (e) => {
@@ -95,11 +94,11 @@ export class UmbCollectionViewsMediaGridElement extends UmbContextConsumerMixin(
private _observeCollectionContext() {
if (!this._collectionContext) return;
this.observe<Array<MediaDetails>>(this._collectionContext.data, (mediaItems) => {
this.observe(this._collectionContext.data, (mediaItems) => {
this._mediaItems = mediaItems.sort((a, b) => (a.hasChildren === b.hasChildren ? 0 : a ? -1 : 1));
});
this.observe<Array<string>>(this._collectionContext.selection, (selection) => {
this.observe(this._collectionContext.selection, (selection) => {
this._selection = selection;
});
}
@@ -118,7 +117,7 @@ export class UmbCollectionViewsMediaGridElement extends UmbContextConsumerMixin(
}
private _isSelected(mediaItem: MediaDetails) {
return this._selection.includes(mediaItem.key);
return this._selection?.includes(mediaItem.key);
}
private _renderMediaItem(item: MediaDetails) {
@@ -126,7 +125,7 @@ export class UmbCollectionViewsMediaGridElement extends UmbContextConsumerMixin(
//TODO: fix the file extension when media items have a file extension.
return html`<uui-card-media
selectable
?select-only=${this._selection.length > 0}
?select-only=${this._selection && this._selection.length > 0}
?selected=${this._isSelected(item)}
@open=${() => this._handleOpenItem(item)}
@selected=${() => this._handleSelect(item)}
@@ -145,11 +144,11 @@ export class UmbCollectionViewsMediaGridElement extends UmbContextConsumerMixin(
label="Drop files here"
accept=""></uui-file-dropzone>
<div id="media-files">
${repeat(
${this._mediaItems ? repeat(
this._mediaItems,
(file, index) => file.key + index,
(file) => this._renderMediaItem(file)
)}
) : ''}
</div>
`;
}

View File

@@ -1,20 +1,19 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import type { UmbCollectionContext } from '../collection.context';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { MediaDetails } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-collection-view-media-table')
export class UmbCollectionViewMediaTableElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbCollectionViewMediaTableElement extends UmbLitElement {
static styles = [UUITextStyles, css``];
@state()
private _mediaItems: Array<MediaDetails> = [];
private _mediaItems?: Array<MediaDetails>;
@state()
private _selection: Array<string> = [];
private _selection?: Array<string>;
private _collectionContext?: UmbCollectionContext<MediaDetails>;
@@ -29,11 +28,11 @@ export class UmbCollectionViewMediaTableElement extends UmbContextConsumerMixin(
private _observeCollectionContext() {
if (!this._collectionContext) return;
this.observe<Array<MediaDetails>>(this._collectionContext.data, (nodes) => {
this.observe(this._collectionContext.data, (nodes) => {
this._mediaItems = nodes;
});
this.observe<Array<string>>(this._collectionContext.selection, (selection) => {
this.observe(this._collectionContext.selection, (selection) => {
this._selection = selection;
});
}
@@ -43,8 +42,8 @@ export class UmbCollectionViewMediaTableElement extends UmbContextConsumerMixin(
<div>
<h3>Selected Media Items:</h3>
<ul>
${this._selection.map((key) => {
const mediaItem = this._mediaItems.find((item) => item.key === key);
${this._selection?.map((key) => {
const mediaItem = this._mediaItems?.find((item) => item.key === key);
return html`<li>${mediaItem?.name}</li>`;
})}
</ul>

View File

@@ -1,16 +1,13 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, CSSResultGroup, html, LitElement } from 'lit';
import { css, CSSResultGroup, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import { UmbSectionStore } from '../section/section.store';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import type { ManifestSection } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-backoffice-header-sections')
export class UmbBackofficeHeaderSections extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbBackofficeHeaderSections extends UmbLitElement {
static styles: CSSResultGroup = [
UUITextStyles,
css`
@@ -90,7 +87,7 @@ export class UmbBackofficeHeaderSections extends UmbContextProviderMixin(
private _observeSections() {
if (!this._sectionStore) return;
this.observe<ManifestSection[]>(this._sectionStore?.getAllowed(), (allowedSections) => {
this.observe(this._sectionStore.getAllowed(), (allowedSections) => {
this._sections = allowedSections;
this._visibleSections = this._sections;
});
@@ -99,7 +96,7 @@ export class UmbBackofficeHeaderSections extends UmbContextProviderMixin(
private _observeCurrentSection() {
if (!this._sectionStore) return;
this.observe<string>(this._sectionStore.currentAlias, (currentSectionAlias) => {
this.observe(this._sectionStore.currentAlias, (currentSectionAlias) => {
this._currentSectionAlias = currentSectionAlias;
});
}

View File

@@ -1,18 +1,17 @@
import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { state } from 'lit/decorators.js';
import { IRoutingInfo } from 'router-slot';
import { UmbSectionStore } from '../section/section.store';
import { UmbSectionContext } from '../section/section.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import type { ManifestSection } from '@umbraco-cms/models';
import { UmbSectionElement } from 'src/backoffice/shared/components/section/section.element';
import { UmbLitElement } from '@umbraco-cms/element';
@defineElement('umb-backoffice-main')
export class UmbBackofficeMain extends UmbContextProviderMixin(UmbContextConsumerMixin(UmbObserverMixin(LitElement))) {
export class UmbBackofficeMain extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -51,7 +50,7 @@ export class UmbBackofficeMain extends UmbContextProviderMixin(UmbContextConsume
private async _observeSections() {
if (!this._sectionStore) return;
this.observe<ManifestSection[]>(this._sectionStore?.getAllowed(), (sections) => {
this.observe(this._sectionStore.getAllowed(), (sections) => {
this._sections = sections;
if (!sections) return;
this._createRoutes();

View File

@@ -1,13 +1,12 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, CSSResultGroup, html, LitElement } from 'lit';
import { css, CSSResultGroup, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { UmbModalHandler, UmbModalService } from '../../../../core/modal';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-backoffice-modal-container')
export class UmbBackofficeModalContainer extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbBackofficeModalContainer extends UmbLitElement {
static styles: CSSResultGroup = [
UUITextStyles,
css`
@@ -18,7 +17,7 @@ export class UmbBackofficeModalContainer extends UmbContextConsumerMixin(UmbObse
];
@state()
private _modals: UmbModalHandler[] = [];
private _modals?: UmbModalHandler[];
private _modalService?: UmbModalService;
@@ -34,7 +33,7 @@ export class UmbBackofficeModalContainer extends UmbContextConsumerMixin(UmbObse
private _observeModals() {
if (!this._modalService) return;
this.observe<UmbModalHandler[]>(this._modalService.modals, (modals) => {
this.observe(this._modalService.modals, (modals) => {
this._modals = modals;
});
}
@@ -42,7 +41,7 @@ export class UmbBackofficeModalContainer extends UmbContextConsumerMixin(UmbObse
render() {
return html`
<uui-modal-container>
${repeat(this._modals, (modalHandler) => html`${modalHandler.element}`)}
${this._modals ? repeat(this._modals, (modalHandler) => html`${modalHandler.element}`) : ''}
</uui-modal-container>
`;
}

View File

@@ -1,13 +1,12 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, CSSResultGroup, html, LitElement } from 'lit';
import { css, CSSResultGroup, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import type { UmbNotificationHandler, UmbNotificationService } from '../../../../core/notification';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-backoffice-notification-container')
export class UmbBackofficeNotificationContainer extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbBackofficeNotificationContainer extends UmbLitElement {
static styles: CSSResultGroup = [
UUITextStyles,
css`
@@ -24,7 +23,7 @@ export class UmbBackofficeNotificationContainer extends UmbContextConsumerMixin(
];
@state()
private _notifications: UmbNotificationHandler[] = [];
private _notifications?: UmbNotificationHandler[];
private _notificationService?: UmbNotificationService;
@@ -40,7 +39,7 @@ export class UmbBackofficeNotificationContainer extends UmbContextConsumerMixin(
private _observeNotifications() {
if (!this._notificationService) return;
this.observe<UmbNotificationHandler[]>(this._notificationService.notifications, (notifications) => {
this.observe(this._notificationService.notifications, (notifications) => {
this._notifications = notifications;
});
}
@@ -48,11 +47,11 @@ export class UmbBackofficeNotificationContainer extends UmbContextConsumerMixin(
render() {
return html`
<uui-toast-notification-container bottom-up id="notifications">
${repeat(
${this._notifications ? repeat(
this._notifications,
(notification: UmbNotificationHandler) => notification.key,
(notification) => html`${notification.element}`
)}
) : ''}
</uui-toast-notification-container>
`;
}

View File

@@ -1,19 +1,18 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { customElement, property, state } from 'lit/decorators.js';
import { EMPTY, of, switchMap } from 'rxjs';
import { UmbDataTypeStore } from '../../../settings/data-types/data-type.store';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { ContentProperty, ManifestTypes } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import '../entity-property/entity-property.element';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-content-property')
export class UmbContentPropertyElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbContentPropertyElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -56,7 +55,7 @@ export class UmbContentPropertyElement extends UmbContextConsumerMixin(UmbObserv
private _observeDataType() {
if (!this._dataTypeStore || !this._property) return;
this.observe<ManifestTypes>(
this.observe(
this._dataTypeStore.getByKey(this._property.dataTypeKey).pipe(
switchMap((dataType) => {
if (!dataType?.propertyEditorUIAlias) return EMPTY;

View File

@@ -1,5 +1,5 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, PropertyValueMap } from 'lit';
import { css, html, PropertyValueMap } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { UmbWorkspacePropertyContext } from './workspace-property.context';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
@@ -8,9 +8,8 @@ import type { ManifestPropertyEditorUI, ManifestTypes } from '@umbraco-cms/model
import '../../property-actions/shared/property-action-menu/property-action-menu.element';
import 'src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.element';
import { UmbContextProviderController } from 'src/core/context-api/provide/context-provider.controller';
import { UmbControllerHostMixin } from 'src/core/controller/controller-host.mixin';
import { UmbObserverController } from 'src/core/observable-api/observer.controller';
import { UmbLitElement } from '@umbraco-cms/element';
/**
* @element umb-entity-property
@@ -20,7 +19,7 @@ import { UmbObserverController } from 'src/core/observable-api/observer.controll
// TODO: get rid of the other mixins:
@customElement('umb-entity-property')
export class UmbEntityPropertyElement extends UmbControllerHostMixin(LitElement) {
export class UmbEntityPropertyElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -122,14 +121,13 @@ export class UmbEntityPropertyElement extends UmbControllerHostMixin(LitElement)
// TODO: How to get proper default value?
private _propertyContext = new UmbWorkspacePropertyContext<string>("");
private propertyEditorUIObserver?: UmbObserverController;
private propertyEditorUIObserver?: UmbObserverController<ManifestTypes>;
constructor() {
super();
// TODO: make it easier to create a provider, unless a context should just extends a provider-controller?
new UmbContextProviderController(this, 'umbPropertyContext', this._propertyContext);
this.provideContext('umbPropertyContext', this._propertyContext);
this._observePropertyEditorUI();
this.addEventListener('property-editor-change', this._onPropertyEditorChange as any as EventListener);
@@ -137,7 +135,7 @@ export class UmbEntityPropertyElement extends UmbControllerHostMixin(LitElement)
private _observePropertyEditorUI() {
this.propertyEditorUIObserver?.destroy();
this.propertyEditorUIObserver = new UmbObserverController<ManifestTypes>(this, umbExtensionsRegistry.getByAlias(this.propertyEditorUIAlias), (manifest) => {
this.propertyEditorUIObserver = new UmbObserverController(this, umbExtensionsRegistry.getByAlias(this.propertyEditorUIAlias), (manifest) => {
if (manifest?.type === 'propertyEditorUI') {
this._gotData(manifest);
}

View File

@@ -1,11 +1,11 @@
import { LitElement, nothing } from 'lit';
import { nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { map } from 'rxjs';
import { repeat } from 'lit/directives/repeat.js';
import { ManifestTypes, umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { createExtensionElement, isManifestElementNameType } from '@umbraco-cms/extensions-api';
import { ManifestBase, ManifestTypes, umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { isManifestElementableType } from 'src/core/extensions-api/is-manifest-elementable-type.function';
import { UmbLitElement } from '@umbraco-cms/element';
type InitializedExtensionItem = {alias: string, weight: number, component: HTMLElement|null}
@@ -15,10 +15,10 @@ type InitializedExtensionItem = {alias: string, weight: number, component: HTMLE
* @slot default - slot for inserting additional things into this slot.
* @export
* @class UmbExtensionSlot
* @extends {UmbObserverMixin(LitElement)}
* @extends {UmbLitElement}
*/
@customElement('umb-extension-slot')
export class UmbExtensionSlotElement extends UmbObserverMixin(LitElement) {
export class UmbExtensionSlotElement extends UmbLitElement {
@state()
private _extensions:InitializedExtensionItem[] = [];
@@ -27,17 +27,8 @@ export class UmbExtensionSlotElement extends UmbObserverMixin(LitElement) {
public type= "";
@property({ type: Object, attribute: false })
public filter: (manifest:ManifestTypes) => boolean = () => true;
constructor() {
super();
/*
this.extensionManager = new ExtensionManager(this, (x) => {x.meta.entityType === this.entityType}, (extensionManifests) => {
this._createElement(extensionManifests[0]);
});
*/
}
public filter: (manifest: any) => boolean = () => true;
connectedCallback(): void {
super.connectedCallback();

View File

@@ -8,7 +8,7 @@ import './content-property/content-property.element';
import './table/table.element';
import './code-block/code-block.element';
import './extension-slot/extension-slot.element';
import './workspace/workspace-entity/workspace-entity.element';
import './workspace/workspace-layout/workspace-layout.element';
import './section/section-main/section-main.element';
import './section/section-sidebar/section-sidebar.element';
import './section/section.element';

View File

@@ -1,17 +1,18 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { property } from 'lit/decorators.js';
import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar';
import { UmbPickerData } from '../../../../core/modal/layouts/modal-layout-picker-base';
import { UmbModalService, UmbModalType } from '../../../../core/modal';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
//TODO: These should probably be imported dynamically.
import '../../../../core/modal/layouts/picker-section/picker-layout-section.element';
import '../../../../core/modal/layouts/picker-user-group/picker-layout-user-group.element';
import '../../../../core/modal/layouts/picker-user/picker-layout-user.element';
import { UmbLitElement } from '@umbraco-cms/element';
/** TODO: Make use of UUI FORM Mixin, to make it easily take part of a form. */
export class UmbInputListBase extends UmbContextConsumerMixin(LitElement) {
export class UmbInputListBase extends UmbLitElement {
@property({ type: Array })
public value: Array<string> = [];

View File

@@ -57,6 +57,7 @@ export class UmbInputPickerSectionElement extends UmbInputListBase {
selectionUpdated() {
this._observeSections();
// TODO: Use proper event class:
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
}

View File

@@ -1,12 +1,10 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { IRoutingInfo } from 'router-slot';
import { first, map } from 'rxjs';
import { UmbSectionContext } from '../section.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type {
ManifestDashboard,
ManifestDashboardCollection,
@@ -14,9 +12,10 @@ import type {
ManifestWithMeta,
} from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-section-dashboards')
export class UmbSectionDashboardsElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbSectionDashboardsElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -47,7 +46,7 @@ export class UmbSectionDashboardsElement extends UmbContextConsumerMixin(UmbObse
];
@state()
private _dashboards: Array<ManifestDashboard | ManifestDashboardCollection> = [];
private _dashboards?: Array<ManifestDashboard | ManifestDashboardCollection>;
@state()
private _currentDashboardPathname = '';
@@ -73,19 +72,21 @@ export class UmbSectionDashboardsElement extends UmbContextConsumerMixin(UmbObse
private _observeSectionContext() {
if (!this._sectionContext) return;
this.observe<ManifestSection>(this._sectionContext.data.pipe(first()), (section) => {
this._currentSectionAlias = section.alias;
this._currentSectionPathname = section.meta.pathname;
this._observeDashboards();
this.observe(this._sectionContext.data.pipe(first()), (section) => {
if(section) {
this._currentSectionAlias = section.alias;
this._currentSectionPathname = section.meta.pathname;
this._observeDashboards();
}
});
}
private _observeDashboards() {
if (!this._currentSectionAlias) return;
this.observe<ManifestDashboard[]>(
this.observe(
umbExtensionsRegistry
?.extensionsOfTypes(['dashboard', 'dashboardCollection'])
?.extensionsOfTypes<(ManifestDashboard | ManifestDashboardCollection)>(['dashboard', 'dashboardCollection'])
.pipe(
map((extensions) =>
extensions.filter((extension) =>
@@ -94,8 +95,7 @@ export class UmbSectionDashboardsElement extends UmbContextConsumerMixin(UmbObse
)
),
(dashboards) => {
if (dashboards?.length === 0) return;
this._dashboards = dashboards;
this._dashboards = dashboards || undefined;
this._createRoutes();
}
);
@@ -104,35 +104,38 @@ export class UmbSectionDashboardsElement extends UmbContextConsumerMixin(UmbObse
private _createRoutes() {
this._routes = [];
this._routes = this._dashboards.map((dashboard) => {
return {
path: `${dashboard.meta.pathname}`,
component: () => {
if (dashboard.type === 'dashboardCollection') {
return import('src/backoffice/shared/collection/dashboards/dashboard-collection.element');
}
return createExtensionElement(dashboard);
},
setup: (component: Promise<HTMLElement> | HTMLElement, info: IRoutingInfo) => {
this._currentDashboardPathname = info.match.route.path;
// When its using import, we get an element, when using createExtensionElement we get a Promise.
(component as any).manifest = dashboard;
if ((component as any).then) {
(component as any).then((el: any) => (el.manifest = dashboard));
}
},
};
});
if(this._dashboards) {
this._routes = this._dashboards.map((dashboard) => {
return {
path: `${dashboard.meta.pathname}`,
component: () => {
if (dashboard.type === 'dashboardCollection') {
return import('src/backoffice/shared/collection/dashboards/dashboard-collection.element');
}
return createExtensionElement(dashboard);
},
setup: (component: Promise<HTMLElement> | HTMLElement, info: IRoutingInfo) => {
this._currentDashboardPathname = info.match.route.path;
// When its using import, we get an element, when using createExtensionElement we get a Promise.
// TODO: this is a bit hacky, can we do it in a more appropriate way
(component as any).manifest = dashboard;
if ((component as any).then) {
(component as any).then((el: any) => (el.manifest = dashboard));
}
},
};
});
this._routes.push({
path: '**',
redirectTo: this._dashboards?.[0]?.meta.pathname,
});
this._routes.push({
path: '**',
redirectTo: this._dashboards?.[0]?.meta.pathname,
});
}
}
private _renderNavigation() {
return html`
${this._dashboards?.length > 1
${this._dashboards && this._dashboards.length > 1
? html`
<uui-tab-group id="tabs">
${this._dashboards.map(

View File

@@ -1,15 +1,14 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbSectionContext } from '../section.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { ManifestSection } from '@umbraco-cms/models';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import '../../tree/context-menu/tree-context-menu.service';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-section-sidebar')
export class UmbSectionSidebarElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbSectionSidebarElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -49,7 +48,7 @@ export class UmbSectionSidebarElement extends UmbContextConsumerMixin(UmbObserve
private _observeSectionContext() {
if (!this._sectionContext) return;
this.observe<ManifestSection>(this._sectionContext.data, (section) => {
this.observe(this._sectionContext.data, (section) => {
this._sectionLabel = section.meta.label || section.name;
this._sectionPathname = section.meta.pathname;
});

View File

@@ -1,21 +1,20 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { map, switchMap, EMPTY, of } from 'rxjs';
import { UmbSectionContext } from '../section.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import '../../tree/tree-extension.element';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-section-trees')
export class UmbSectionTreesElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbSectionTreesElement extends UmbLitElement {
static styles = [UUITextStyles];
@state()
private _treeAliases: Array<string> = [];
private _treeAliases?: Array<string>;
private _sectionContext?: UmbSectionContext;
@@ -31,30 +30,30 @@ export class UmbSectionTreesElement extends UmbContextConsumerMixin(UmbObserverM
private _observeTrees() {
if (!this._sectionContext) return;
this.observe<string[]>(
this.observe(
this._sectionContext?.data.pipe(
switchMap((section) => {
if (!section) return EMPTY;
return (
umbExtensionsRegistry
?.extensionsOfType('tree')
.extensionsOfType('tree')
.pipe(
map((trees) =>
trees.filter((tree) => tree.meta.sections.includes(section.alias)).map((tree) => tree.alias)
)
) ?? of([])
)
);
})
),
(treeAliases) => {
this._treeAliases = treeAliases;
this._treeAliases = treeAliases || undefined;
}
);
}
render() {
return html`${this._treeAliases.map((treeAlias) => html`<umb-tree alias="${treeAlias}"></umb-tree>`)} `;
return html`${this._treeAliases?.map((treeAlias) => html`<umb-tree alias="${treeAlias}"></umb-tree>`)} `;
}
}

View File

@@ -1,14 +1,14 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { EMPTY, map, of, Subscription, switchMap } from 'rxjs';
import { UmbSectionContext } from '../section.context';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestSectionView } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-section-views')
export class UmbSectionViewsElement extends UmbContextConsumerMixin(LitElement) {
export class UmbSectionViewsElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`

View File

@@ -18,15 +18,15 @@ export class UmbSectionContext {
public readonly data = this._data.asObservable();
// TODO: what is the best context to put this in?
private _activeTree = new ReplaySubject<ManifestTree>(1);
private _activeTree = new ReplaySubject<ManifestTree | undefined>(1);
public readonly activeTree = this._activeTree.asObservable();
// TODO: what is the best context to put this in?
private _activeTreeItem = new ReplaySubject<Entity>(1);
private _activeTreeItem = new ReplaySubject<Entity | undefined>(1);
public readonly activeTreeItem = this._activeTreeItem.asObservable();
// TODO: what is the best context to put this in?
private _activeView = new ReplaySubject<ManifestSectionView>(1);
private _activeView = new ReplaySubject<ManifestSectionView | undefined>(1);
public readonly activeView = this._activeView.asObservable();
constructor(section: ManifestSection) {

View File

@@ -1,20 +1,20 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { map, switchMap, EMPTY, of } from 'rxjs';
import { IRoutingInfo } from 'router-slot';
import type { UmbWorkspaceEntityElement } from '../workspace/workspace-entity-element.interface';
import { UmbSectionContext } from './section.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestTree, ManifestSectionView, ManifestWorkspace } from '@umbraco-cms/models';
import './section-trees/section-trees.element.ts';
import './section-views/section-views.element.ts';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-section')
export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbSectionElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -36,12 +36,12 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(
private _routes: Array<any> = [];
@state()
private _trees: Array<ManifestTree> = [];
private _trees?: Array<ManifestTree>;
private _workspaces: Array<ManifestWorkspace> = [];
private _workspaces?: Array<ManifestWorkspace>;
@state()
private _views: Array<ManifestSectionView> = [];
private _views?: Array<ManifestSectionView>;
private _sectionContext?: UmbSectionContext;
@@ -60,7 +60,7 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(
private _observeTrees() {
if (!this._sectionContext) return;
this.observe<ManifestTree[]>(
this.observe(
this._sectionContext?.data.pipe(
switchMap((section) => {
if (!section) return EMPTY;
@@ -77,7 +77,7 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(
}
);
this.observe<ManifestWorkspace[]>(umbExtensionsRegistry?.extensionsOfType('workspace'), (workspaceExtensions) => {
this.observe(umbExtensionsRegistry.extensionsOfType('workspace'), (workspaceExtensions) => {
this._workspaces = workspaceExtensions;
this._createTreeRoutes();
});
@@ -96,9 +96,9 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(
routes.push({
path: `${workspace.meta.entityType}/:key`,
component: () => createExtensionElement(workspace),
setup: (component: Promise<HTMLElement>, info: IRoutingInfo) => {
component.then((el: HTMLElement) => {
(el as any).entityKey = info.match.params.key;
setup: (component: Promise<UmbWorkspaceEntityElement>, info: IRoutingInfo) => {
component.then((el) => {
el.entityKey = info.match.params.key;
});
},
});
@@ -118,7 +118,7 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(
private _observeViews() {
if (!this._sectionContext) return;
this.observe<ManifestSectionView[]>(
this.observe(
this._sectionContext.data.pipe(
switchMap((section) => {
if (!section) return EMPTY;
@@ -137,9 +137,10 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(
})
),
(views) => {
this._views = views;
if (this._views.length === 0) return;
this._createViewRoutes();
if(views.length > 0) {
this._views = views;
this._createViewRoutes();
}
}
);
}
@@ -156,25 +157,29 @@ export class UmbSectionElement extends UmbContextConsumerMixin(UmbObserverMixin(
};
}) ?? [];
this._routes.push({
path: '**',
redirectTo: 'view/' + this._views?.[0]?.meta.pathname,
});
if(this._views && this._views.length > 0) {
this._routes.push({
path: '**',
redirectTo: 'view/' + this._views?.[0]?.meta.pathname,
});
}
}
render() {
return html`
${this._trees.length > 0
${this._trees && this._trees.length > 0
? html`
<umb-section-sidebar>
<umb-section-trees></umb-section-trees>
</umb-section-sidebar>
<umb-section-sidebar>
<umb-section-trees></umb-section-trees>
</umb-section-sidebar>
`
: nothing}
<umb-section-main>
${this._views.length > 0 ? html`<umb-section-views></umb-section-views>` : nothing}
${this._routes.length > 0
? html` <router-slot id="router-slot" .routes="${this._routes}"></router-slot> `
${this._views && this._views.length > 0
? html`<umb-section-views></umb-section-views>`
: nothing}
${this._routes && this._routes.length > 0
? html`<router-slot id="router-slot" .routes="${this._routes}"></router-slot>`
: nothing}
<slot></slot>
</umb-section-main>

View File

@@ -1,11 +1,9 @@
import { LitElement } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { UmbSectionContext } from '../../section/section.context';
import { UmbTreeContextMenuPageService } from '../context-menu/tree-context-menu-page.service';
import { UmbTreeContextMenuService } from '../context-menu/tree-context-menu.service';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { Entity, ManifestTreeItemAction, ManifestTree } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
export type ActionPageEntity = {
key: string;
@@ -13,7 +11,7 @@ export type ActionPageEntity = {
};
@customElement('umb-tree-item-action')
export default class UmbTreeItemActionElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export default class UmbTreeItemActionElement extends UmbLitElement {
@property({ attribute: false })
public treeAction?: ManifestTreeItemAction;
@@ -49,7 +47,7 @@ export default class UmbTreeItemActionElement extends UmbContextConsumerMixin(Um
private _observeEntity() {
if (!this._actionPageService) return;
this.observe<ActionPageEntity>(this._actionPageService.entity, (entity) => {
this.observe(this._actionPageService.entity, (entity) => {
this._entity = entity;
});
}
@@ -57,7 +55,7 @@ export default class UmbTreeItemActionElement extends UmbContextConsumerMixin(Um
private _observeActiveTree() {
if (!this._sectionContext) return;
this.observe<ManifestTree>(this._sectionContext.activeTree, (tree) => {
this.observe(this._sectionContext.activeTree, (tree) => {
this._activeTree = tree;
});
}
@@ -65,7 +63,7 @@ export default class UmbTreeItemActionElement extends UmbContextConsumerMixin(Um
private _observeActiveTreeItem() {
if (!this._sectionContext) return;
this.observe<Entity>(this._sectionContext.activeTreeItem, (treeItem) => {
this.observe(this._sectionContext.activeTreeItem, (treeItem) => {
this._activeTreeItem = treeItem;
});
}

View File

@@ -1,15 +1,14 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, state } from 'lit/decorators.js';
import { map } from 'rxjs';
import { UmbSectionContext } from '../../section/section.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { Entity, ManifestTreeItemAction, ManifestTree } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-tree-context-menu-page-action-list')
export class UmbTreeContextMenuPageActionListElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbTreeContextMenuPageActionListElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -29,7 +28,7 @@ export class UmbTreeContextMenuPageActionListElement extends UmbContextConsumerM
];
@state()
private _actions: Array<ManifestTreeItemAction> = [];
private _actions?: Array<ManifestTreeItemAction>;
@state()
private _activeTree?: ManifestTree;
@@ -53,12 +52,12 @@ export class UmbTreeContextMenuPageActionListElement extends UmbContextConsumerM
private _observeTreeItemActions() {
if (!this._sectionContext) return;
this.observe<ManifestTreeItemAction[]>(
this.observe(
umbExtensionsRegistry
.extensionsOfType('treeItemAction')
.pipe(map((actions) => actions.filter((action) => action.meta.trees.includes(this._activeTree?.alias || '')))),
(actions) => {
this._actions = actions;
this._actions = actions || undefined;
}
);
}
@@ -67,7 +66,7 @@ export class UmbTreeContextMenuPageActionListElement extends UmbContextConsumerM
if (!this._sectionContext) return;
this.observe(this._sectionContext.activeTree, (tree) => {
this._activeTree = tree;
this._activeTree = tree || undefined;
});
}
@@ -75,12 +74,12 @@ export class UmbTreeContextMenuPageActionListElement extends UmbContextConsumerM
if (!this._sectionContext) return;
this.observe(this._sectionContext.activeTreeItem, (treeItem) => {
this._activeTreeItem = treeItem;
this._activeTreeItem = treeItem || undefined;
});
}
private _renderActions() {
return this._actions.map((action) => {
return this._actions?.map((action) => {
return html`<umb-tree-item-action-extension .treeAction=${action}></umb-tree-item-action-extension> `;
});
}

View File

@@ -1,12 +1,12 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, LitElement, nothing, PropertyValueMap } from 'lit';
import { css, nothing, PropertyValueMap } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { BehaviorSubject, Observable } from 'rxjs';
import UmbTreeItemActionElement, { ActionPageEntity } from '../action/tree-item-action.element';
import { UmbContextProviderMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-tree-context-menu-page-service')
export class UmbTreeContextMenuPageService extends UmbContextProviderMixin(LitElement) {
export class UmbTreeContextMenuPageService extends UmbLitElement {
static styles = [UUITextStyles, css``];
@property({ type: Object })

View File

@@ -1,11 +1,11 @@
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { ActionPageEntity } from '../action/tree-item-action.element';
import { UmbContextProviderMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-tree-context-menu-service')
export class UmbTreeContextMenuService extends UmbContextProviderMixin(LitElement) {
export class UmbTreeContextMenuService extends UmbLitElement {
static styles = [
UUITextStyles,
css`

View File

@@ -1,19 +1,19 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { repeat } from 'lit/directives/repeat.js';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { UmbSectionContext } from '../../section/section.context';
import { UmbTreeContext } from '../tree.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import type { Entity, ManifestSection, ManifestTree } from '@umbraco-cms/models';
import type { Entity, ManifestTree } from '@umbraco-cms/models';
import { UmbTreeDataStore } from '@umbraco-cms/stores/store';
import '../tree-item.element';
import { UmbLitElement } from '@umbraco-cms/element';
import { DocumentTreeItem } from '@umbraco-cms/backend-api';
@customElement('umb-tree-navigator')
export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbContextProviderMixin(UmbObserverMixin(LitElement))) {
export class UmbTreeNavigator extends UmbLitElement {
static styles = [UUITextStyles, css``];
private _storeContextAlias = '';
@@ -31,7 +31,7 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbContextProvider
private _loading = true;
@state()
private _items: Entity[] = [];
private _items: DocumentTreeItem[] = [];
@state()
private _tree?: ManifestTree;
@@ -39,7 +39,7 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbContextProvider
@state()
private _href?: string;
private _store?: UmbTreeDataStore<unknown>;
private _store?: UmbTreeDataStore<DocumentTreeItem>;
private _sectionContext?: UmbSectionContext;
constructor() {
@@ -77,7 +77,7 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbContextProvider
this._loading = true;
this.observe<Entity[]>(this._store.getTreeRoot(), (rootItems) => {
this.observe(this._store.getTreeRoot(), (rootItems) => {
if (rootItems?.length === 0) return;
this._items = rootItems;
this._loading = false;
@@ -87,7 +87,7 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbContextProvider
private _observeSection() {
if (!this._sectionContext) return;
this.observe<ManifestSection>(this._sectionContext?.data, (section) => {
this.observe(this._sectionContext?.data, (section) => {
this._href = this._constructPath(section.meta.pathname, this._tree?.meta.rootNodeEntityType);
});
}
@@ -110,11 +110,12 @@ export class UmbTreeNavigator extends UmbContextConsumerMixin(UmbContextProvider
}
private _renderRootItems() {
// TODO: Fix Type Mismatch ` as Entity` in this template:
return html`
${repeat(
this._items,
(item) => item.key,
(item) => html`<umb-tree-item .treeItem=${item} .loading=${this._loading}></umb-tree-item>`
(item) => html`<umb-tree-item .treeItem=${item as Entity} .loading=${this._loading}></umb-tree-item>`
)}
`;
}

View File

@@ -1,30 +1,29 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { UUIMenuItemEvent } from '@umbraco-ui/uui';
import { map } from 'rxjs';
import { map, Observable } from 'rxjs';
import { repeat } from 'lit/directives/repeat.js';
import { UmbSectionContext } from '../section/section.context';
import type { UmbTreeContextBase } from './tree.context';
import { UmbTreeContextMenuService } from './context-menu/tree-context-menu.service';
import type { Entity, ManifestSection } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { Entity } from '@umbraco-cms/models';
import { UmbTreeDataStore } from '@umbraco-cms/stores/store';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-tree-item')
export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbTreeItem extends UmbLitElement {
static styles = [UUITextStyles, css``];
@property({ type: Object, attribute: false })
treeItem!: Entity;
@state()
private _childItems: Entity[] = [];
private _childItems?: Entity[];
@state()
private _href? = '';
private _href?:string;
@state()
private _loading = false;
@@ -87,26 +86,26 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle
private _observeSection() {
if (!this._sectionContext) return;
this.observe<ManifestSection>(this._sectionContext?.data, (section) => {
this._href = this._constructPath(section.meta.pathname, this.treeItem.type, this.treeItem.key);
this.observe(this._sectionContext?.data, (section) => {
this._href = this._constructPath(section?.meta.pathname || '', this.treeItem.type, this.treeItem.key);
});
}
private _observeSelectable() {
if (!this._treeContext) return;
this.observe<boolean>(this._treeContext.selectable, (value) => {
this._selectable = value;
this.observe(this._treeContext.selectable, (value) => {
this._selectable = value || false;
});
}
private _observeIsSelected() {
if (!this._treeContext) return;
this.observe<boolean>(
this.observe(
this._treeContext.selection.pipe(map((keys) => keys?.includes(this.treeItem.key))),
(isSelected) => {
this._selected = isSelected;
this._selected = isSelected || false;
}
);
}
@@ -114,8 +113,8 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle
private _observeActiveTreeItem() {
if (!this._sectionContext) return;
this.observe<Entity>(this._sectionContext?.activeTreeItem, (treeItem) => {
this._isActive = treeItem.key === this.treeItem.key;
this.observe(this._sectionContext?.activeTreeItem, (treeItem) => {
this._isActive = treeItem?.key === this.treeItem.key;
});
}
@@ -126,7 +125,7 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle
private _onShowChildren(event: UUIMenuItemEvent) {
event.stopPropagation();
if (this._childItems.length > 0) return;
if (this._childItems && this._childItems.length > 0) return;
this._observeChildren();
}
@@ -135,8 +134,8 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle
this._loading = true;
this.observe<Entity[]>(this._store.getTreeItemChildren(this.treeItem.key), (childItems) => {
if (childItems?.length === 0) return;
// TODO: we should do something about these types, stop having our own version of Entity.
this.observe(this._store.getTreeItemChildren(this.treeItem.key) as Observable<Entity[]>, (childItems) => {
this._childItems = childItems;
this._loading = false;
});
@@ -144,11 +143,11 @@ export class UmbTreeItem extends UmbContextConsumerMixin(UmbObserverMixin(LitEle
private _renderChildItems() {
return html`
${repeat(
${this._childItems ? repeat(
this._childItems,
(item) => item.key,
(item) => html`<umb-tree-item .treeItem=${item}></umb-tree-item>`
)}
) : ''}
`;
}

View File

@@ -1,16 +1,16 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { when } from 'lit-html/directives/when.js';
import { customElement, property, state } from 'lit/decorators.js';
import { map } from 'rxjs';
import { UmbTreeContextBase } from './tree.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import type { ManifestTree } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbDataStore } from '@umbraco-cms/stores/store';
import { UmbLitElement } from '@umbraco-cms/element';
import { UmbContextProviderController } from 'src/core/context-api/provide/context-provider.controller';
@customElement('umb-tree')
export class UmbTreeElement extends UmbContextProviderMixin(UmbContextConsumerMixin(UmbObserverMixin(LitElement))) {
export class UmbTreeElement extends UmbLitElement {
private _alias = '';
@property({ type: String, reflect: true })
get alias() {
@@ -55,6 +55,7 @@ export class UmbTreeElement extends UmbContextProviderMixin(UmbContextConsumerMi
private _tree?: ManifestTree;
private _treeContext?: UmbTreeContextBase;
private _treeContextProvider?: UmbContextProviderController;
connectedCallback(): void {
super.connectedCallback();
@@ -64,34 +65,35 @@ export class UmbTreeElement extends UmbContextProviderMixin(UmbContextConsumerMi
private _observeTree() {
if (!this.alias) return;
this.observe<ManifestTree>(
this.observe(
umbExtensionsRegistry
.extensionsOfType('tree')
.pipe(map((trees) => trees.find((tree) => tree.alias === this.alias))),
(tree) => {
if (this._tree?.alias === tree.alias) return;
(tree => {
this._tree = tree;
this._provideTreeContext();
if (this._tree.meta.storeContextAlias) {
if(tree) {
this._provideTreeContext();
this._provideStore();
}
}
);
));
}
private _provideTreeContext() {
if (!this._tree || this._treeContext) return;
// TODO: if a new tree comes around, which is different, then we should clean up and re provide.
this._treeContext = new UmbTreeContextBase(this._tree);
this._treeContext.setSelectable(this.selectable);
this._treeContext.setSelection(this.selection);
this.provideContext('umbTreeContext', this._treeContext);
}
private _provideStore() {
// TODO: Clean up store, if already existing.
if (!this._tree?.meta.storeContextAlias) return;
this.consumeContext(this._tree.meta.storeContextAlias, (store: UmbDataStore<unknown>) =>

View File

@@ -1,20 +1,20 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import type { UUIButtonState } from '@umbraco-ui/uui';
import type { UmbWorkspaceNodeContext } from '../../workspace-context/workspace-node.context';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { UmbWorkspaceContentContext } from '../../workspace-content/workspace-content.context';
import { UmbLitElement } from '@umbraco-cms/element';
import type { ManifestWorkspaceAction } from '@umbraco-cms/models';
@customElement('umb-workspace-action-node-save')
export class UmbWorkspaceActionNodeSaveElement extends UmbContextConsumerMixin(LitElement) {
export class UmbWorkspaceActionNodeSaveElement extends UmbLitElement {
static styles = [UUITextStyles, css``];
@state()
private _saveButtonState?: UUIButtonState;
private _workspaceContext?: UmbWorkspaceNodeContext;
private _workspaceContext?: UmbWorkspaceContentContext;
public manifest?: ManifestWorkspaceAction;

View File

@@ -1,20 +1,17 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement } from 'lit/decorators.js';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import type { UmbWorkspaceNodeContext } from '../../../workspace-context/workspace-node.context';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { UmbWorkspaceContentContext } from '../../workspace-content.context';
import { UmbCollectionContext } from 'src/backoffice/shared/collection/collection.context';
import { UmbMediaStore, UmbMediaStoreItemType } from 'src/backoffice/media/media/media.store';
import 'src/backoffice/shared/components/content-property/content-property.element';
import 'src/backoffice/shared/collection/dashboards/dashboard-collection.element';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-workspace-view-collection')
export class UmbWorkspaceViewCollectionElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbWorkspaceViewCollectionElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -25,7 +22,7 @@ export class UmbWorkspaceViewCollectionElement extends UmbContextProviderMixin(
`,
];
private _workspaceContext?: UmbWorkspaceNodeContext;
private _workspaceContext?: UmbWorkspaceContentContext;
private _collectionContext?: UmbCollectionContext<UmbMediaStoreItemType, UmbMediaStore>;
@@ -38,17 +35,6 @@ export class UmbWorkspaceViewCollectionElement extends UmbContextProviderMixin(
});
}
connectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._collectionContext?.connectedCallback();
}
disconnectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._collectionContext?.disconnectedCallback();
}
protected _provideWorkspace() {
if (this._workspaceContext?.entityKey != null) {
this._collectionContext = new UmbCollectionContext(
@@ -56,7 +42,6 @@ export class UmbWorkspaceViewCollectionElement extends UmbContextProviderMixin(
this._workspaceContext.entityKey,
this._workspaceContext.getStore().storeAlias
);
this._collectionContext.connectedCallback();
this.provideContext('umbCollectionContext', this._collectionContext);
}
}

View File

@@ -1,16 +1,15 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, state } from 'lit/decorators.js';
import { distinctUntilChanged } from 'rxjs';
import type { UmbWorkspaceNodeContext } from '../../../workspace-context/workspace-node.context';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { UmbWorkspaceContentContext } from '../../workspace-content.context';
import type { ContentProperty, ContentPropertyData, DocumentDetails, MediaDetails } from '@umbraco-cms/models';
import '../../../../content-property/content-property.element';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-workspace-view-content-edit')
export class UmbWorkspaceViewContentEditElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbWorkspaceViewContentEditElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -27,7 +26,7 @@ export class UmbWorkspaceViewContentEditElement extends UmbContextConsumerMixin(
@state()
_data: ContentPropertyData[] = [];
private _workspaceContext?: UmbWorkspaceNodeContext;
private _workspaceContext?: UmbWorkspaceContentContext<DocumentDetails | MediaDetails>;
constructor() {
super();
@@ -41,7 +40,7 @@ export class UmbWorkspaceViewContentEditElement extends UmbContextConsumerMixin(
private _observeContent() {
if (!this._workspaceContext) return;
this.observe<DocumentDetails | MediaDetails>(
this.observe(
this._workspaceContext.data.pipe(distinctUntilChanged()),
(content) => {
this._properties = content.properties;

View File

@@ -1,14 +1,13 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, state } from 'lit/decorators.js';
import { distinctUntilChanged } from 'rxjs';
import type { UmbWorkspaceNodeContext } from '../../../workspace-context/workspace-node.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { UmbWorkspaceContentContext } from '../../workspace-content.context';
import type { DocumentDetails, MediaDetails } from '@umbraco-cms/models';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-workspace-view-content-info')
export class UmbWorkspaceViewContentInfoElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbWorkspaceViewContentInfoElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -22,7 +21,7 @@ export class UmbWorkspaceViewContentInfoElement extends UmbContextConsumerMixin(
@state()
private _nodeName = '';
private _workspaceContext?: UmbWorkspaceNodeContext;
private _workspaceContext?: UmbWorkspaceContentContext<DocumentDetails | MediaDetails>;
constructor() {
super();
@@ -37,7 +36,7 @@ export class UmbWorkspaceViewContentInfoElement extends UmbContextConsumerMixin(
private _observeContent() {
if (!this._workspaceContext) return;
this.observe<DocumentDetails | MediaDetails>(this._workspaceContext.data.pipe(distinctUntilChanged()), (node) => {
this.observe(this._workspaceContext.data.pipe(distinctUntilChanged()), (node) => {
this._nodeName = node.name as string;
});
}

View File

@@ -1,32 +1,33 @@
import { UmbNotificationService } from '../../../../../core/notification';
import { UmbNotificationDefaultData } from '../../../../../core/notification/layouts/default';
import { UmbWorkspaceWithStoreContext } from './workspace-with-store.context';
import { UmbWorkspaceWithStoreContext } from '../workspace-context/workspace-with-store.context';
import { UmbNodeStoreBase } from '@umbraco-cms/stores/store';
import { ContentTreeItem } from '@umbraco-cms/backend-api';
import { UmbContextConsumer } from '@umbraco-cms/context-api';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
import { UmbContextConsumerController } from 'src/core/context-api/consume/context-consumer.controller';
// TODO: Consider if its right to have this many class-inheritance of WorkspaceContext
export class UmbWorkspaceNodeContext<
export class UmbWorkspaceContentContext<
ContentTypeType extends ContentTreeItem = ContentTreeItem,
StoreType extends UmbNodeStoreBase<ContentTypeType> = UmbNodeStoreBase<ContentTypeType>
> extends UmbWorkspaceWithStoreContext<ContentTypeType, StoreType> {
protected _notificationService?: UmbNotificationService;
protected _notificationConsumer!: UmbContextConsumer;
public entityKey: string;
public entityType: string;
constructor(
target: HTMLElement,
host: UmbControllerHostInterface,
defaultData: ContentTypeType,
storeAlias: string,
entityKey: string,
entityType: string
) {
super(target, defaultData, storeAlias);
super(host, defaultData, storeAlias);
this._notificationConsumer = new UmbContextConsumer(
this._target,
new UmbContextConsumerController(
host,
'umbNotificationService',
(_instance: UmbNotificationService) => {
this._notificationService = _instance;
@@ -37,18 +38,8 @@ export class UmbWorkspaceNodeContext<
this.entityType = entityType;
}
connectedCallback() {
super.connectedCallback();
this._notificationConsumer.hostConnected();
}
disconnectedCallback() {
super.connectedCallback();
this._notificationConsumer.hostDisconnected();
}
protected _onStoreSubscription(): void {
this._dataObserver = this._store.getByKey(this.entityKey).subscribe((content) => {
this._store.getByKey(this.entityKey).subscribe((content) => {
if (!content) return; // TODO: Handle nicely if there is no content data.
this.update(content as any);
});

View File

@@ -1,27 +1,30 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui';
import { distinctUntilChanged } from 'rxjs';
import type { UmbWorkspaceNodeContext } from '../workspace-context/workspace-node.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import type { UmbWorkspaceContentContext } from './workspace-content.context';
import type { DocumentDetails, MediaDetails } from '@umbraco-cms/models';
import '../workspace-entity/workspace-entity.element';
import '../workspace-layout/workspace-layout.element';
// Lazy load
// TODO: Make this dynamic, use load-extensions method to loop over extensions for this node.
import './views/edit/workspace-view-content-edit.element';
import './views/info/workspace-view-content-info.element';
import type { UmbNodeStoreBase } from '@umbraco-cms/stores/store';
import { UmbLitElement } from '@umbraco-cms/element';
type ContentTypeTypes = DocumentDetails | MediaDetails;
/**
* TODO: IMPORTANT TODO: Get rid of the content workspace. Instead we aim to get separate components that can be composed by each workspace.
* Example. Document Workspace would use a Variant-component(variant component would talk directly to the workspace-context)
* As well breadcrumbs etc.
*
*/
@customElement('umb-workspace-content')
export class UmbWorkspaceContentElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbWorkspaceContentElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -72,7 +75,7 @@ export class UmbWorkspaceContentElement extends UmbContextProviderMixin(
@state()
_content?: ContentTypeTypes;
private _workspaceContext?: UmbWorkspaceNodeContext<ContentTypeTypes, UmbNodeStoreBase<ContentTypeTypes>>;
private _workspaceContext?: UmbWorkspaceContentContext<ContentTypeTypes, UmbNodeStoreBase<ContentTypeTypes>>;
constructor() {
super();
@@ -88,7 +91,7 @@ export class UmbWorkspaceContentElement extends UmbContextProviderMixin(
private async _observeWorkspace() {
if (!this._workspaceContext) return;
this.observe<ContentTypeTypes>(this._workspaceContext.data.pipe(distinctUntilChanged()), (data) => {
this.observe(this._workspaceContext.data.pipe(distinctUntilChanged()), (data) => {
this._content = data;
});
}
@@ -153,7 +156,7 @@ export class UmbWorkspaceContentElement extends UmbContextProviderMixin(
render() {
return html`
<umb-workspace-entity alias=${this.alias}>
<umb-workspace-layout alias=${this.alias}>
<div id="header" slot="header">
<uui-input id="name-input" .value=${this._content?.name} @input="${this._handleInput}">
<!-- Implement Variant Selector -->
@@ -187,7 +190,7 @@ export class UmbWorkspaceContentElement extends UmbContextProviderMixin(
</div>
<div id="footer" slot="footer">Breadcrumbs</div>
</umb-workspace-entity>
</umb-workspace-layout>
`;
}
}

View File

@@ -1,24 +1,24 @@
import { Subscription } from 'rxjs';
import { UmbWorkspaceContext } from './workspace.context';
import { UmbContextConsumer } from '@umbraco-cms/context-api';
import { UmbDataStoreBase } from '@umbraco-cms/stores/store';
import { ContentTreeItem } from '@umbraco-cms/backend-api';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
import { UmbContextConsumerController } from 'src/core/context-api/consume/context-consumer.controller';
// TODO: Consider if its right to have this many class-inheritance of WorkspaceContext
export abstract class UmbWorkspaceWithStoreContext<
DataType extends ContentTreeItem,
StoreType extends UmbDataStoreBase<DataType>
> extends UmbWorkspaceContext<DataType> {
protected _storeConsumer!: UmbContextConsumer;
protected _store!: StoreType; // TODO: Double check its right to assume it here, at least from a type perspective?
protected _dataObserver?: Subscription;
//protected _dataObserver?: Subscription;
constructor(target: HTMLElement, defaultData: DataType, storeAlias: string) {
super(target, defaultData);
constructor(host: UmbControllerHostInterface, defaultData: DataType, storeAlias: string) {
super(host, defaultData);
// TODO: consider if store alias should be configurable of manifest:
this._storeConsumer = new UmbContextConsumer(this._target, storeAlias, (_instance: StoreType) => {
new UmbContextConsumerController(host, storeAlias, (_instance: StoreType) => {
this._store = _instance;
if (!this._store) {
// TODO: if we keep the type assumption of _store existing, then we should here make sure to break the application in a good way.
@@ -28,14 +28,6 @@ export abstract class UmbWorkspaceWithStoreContext<
});
}
connectedCallback() {
this._storeConsumer.hostConnected();
}
disconnectedCallback() {
this._storeConsumer.hostDisconnected();
}
protected abstract _onStoreSubscription(): void;
/* {
this._dataObserver = this._store.getByKey(this.entityKey).subscribe((content) => {
@@ -61,6 +53,7 @@ export abstract class UmbWorkspaceWithStoreContext<
}
*/
/*
public destroy(): void {
super.destroy();
if (this._storeConsumer) {
@@ -71,4 +64,5 @@ export abstract class UmbWorkspaceWithStoreContext<
this._dataObserver?.unsubscribe();
}
}
*/
}

View File

@@ -1,11 +1,10 @@
import { BehaviorSubject, Observable } from "rxjs";
import { UmbControllerHostInterface } from "src/core/controller/controller-host.mixin";
export abstract class UmbWorkspaceContext<DataType> {
protected _target!:HTMLElement;
protected _host: UmbControllerHostInterface;
// TODO: figure out how fine grained we want to make our observables.
// TODO: add interface
@@ -13,8 +12,8 @@ export abstract class UmbWorkspaceContext<DataType> {
public readonly data: Observable<DataType>;
constructor(target:HTMLElement, defaultData: DataType) {
this._target = target;
constructor(host:UmbControllerHostInterface, defaultData: DataType) {
this._host = host;
this._data = new BehaviorSubject<DataType>(defaultData);
this.data = this._data.asObservable();

View File

@@ -0,0 +1,3 @@
export interface UmbWorkspaceEntityElement {
set entityKey(key: string);
}

View File

@@ -1,32 +1,31 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { IRoutingInfo, RouterSlot } from 'router-slot';
import { map } from 'rxjs';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestWithMeta, ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/models';
import type { ManifestWorkspaceAction, ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/models';
import '../../body-layout/body-layout.element';
import '../../extension-slot/extension-slot.element';
import { UmbLitElement } from '@umbraco-cms/element';
/**
* @element umb-workspace-entity
* @element umb-workspace-layout
* @description
* @slot icon - Slot for rendering the entity icon
* @slot name - Slot for rendering the entity name
* @slot footer - Slot for rendering the entity footer
* @slot actions - Slot for rendering the entity actions
* @slot icon - Slot for rendering the icon
* @slot name - Slot for rendering the name
* @slot footer - Slot for rendering the workspace footer
* @slot actions - Slot for rendering the workspace actions
* @slot default - slot for main content
* @export
* @class UmbWorkspaceEntity
* @extends {UmbContextConsumerMixin(LitElement)}
* @class UmbWorkspaceLayout
* @extends {UmbLitElement}
*/
@customElement('umb-workspace-entity')
export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
@customElement('umb-workspace-layout')
export class UmbWorkspaceLayout extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -56,6 +55,9 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
`,
];
@property()
public headline = '';
/**
* Alias of the workspace. The Layout will render the workspace views that are registered for this workspace alias.
* @public
@@ -63,9 +65,6 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
* @attr
* @default ''
*/
@property()
public headline = '';
@property()
public alias = '';
@@ -90,12 +89,12 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
}
private _observeWorkspaceViews() {
this.observe<ManifestWorkspaceView[]>(
this.observe(
umbExtensionsRegistry
.extensionsOfTypes(['workspaceView', 'workspaceViewCollection'])
.extensionsOfTypes<ManifestWorkspaceView>(['workspaceView', 'workspaceViewCollection'])
.pipe(
map((extensions) =>
extensions.filter((extension) => (extension as ManifestWithMeta).meta.workspaces.includes(this.alias))
extensions.filter((extension) => (extension).meta.workspaces.includes(this.alias))
)
),
(workspaceViews) => {
@@ -106,15 +105,16 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
}
private async _createRoutes() {
this._routes = [];
if (this._workspaceViews.length > 0) {
this._routes = [];
this._routes = this._workspaceViews.map((view) => {
return {
path: `view/${view.meta.pathname}`,
component: () => {
if (view.type === 'workspaceViewCollection') {
console.log('!!!!!workspaceViewCollection');
return import(
'src/backoffice/shared/components/workspace/workspace-content/views/collection/workspace-view-collection.element'
);
@@ -134,7 +134,7 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
this._routes.push({
path: '**',
redirectTo: `view/${this._workspaceViews?.[0].meta.pathname}`,
redirectTo: `view/${this._workspaceViews[0].meta.pathname}`,
});
this.requestUpdate();
@@ -154,7 +154,7 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
private _renderTabs() {
return html`
${this._workspaceViews?.length > 0
${this._workspaceViews.length > 0
? html`
<uui-tab-group slot="tabs">
${this._workspaceViews.map(
@@ -187,7 +187,7 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
<umb-extension-slot
slot="actions"
type="workspaceAction"
.filter=${(extension: any) => extension.meta.workspaces.includes(this.alias)}></umb-extension-slot>
.filter=${(extension: ManifestWorkspaceAction) => extension.meta.workspaces.includes(this.alias)}></umb-extension-slot>
<slot name="actions" slot="actions"></slot>
</umb-body-layout>
`;
@@ -196,6 +196,6 @@ export class UmbWorkspaceEntity extends UmbContextConsumerMixin(UmbObserverMixin
declare global {
interface HTMLElementTagNameMap {
'umb-workspace-entity': UmbWorkspaceEntity;
'umb-workspace-layout': UmbWorkspaceLayout;
}
}

View File

@@ -1,21 +1,21 @@
import './workspace-entity.element';
import './workspace-layout.element';
import { Meta, Story } from '@storybook/web-components';
import { html } from 'lit-html';
import type { UmbWorkspaceEntity } from './workspace-entity.element';
import type { UmbWorkspaceLayout } from './workspace-layout.element';
export default {
title: 'Workspaces/Shared/Editor Entity Layout',
component: 'umb-workspace-entity',
id: 'umb-workspace-entity',
component: 'umb-workspace-layout',
id: 'umb-workspace-layout',
} as Meta;
export const AAAOverview: Story<UmbWorkspaceEntity> = () => html` <umb-workspace-entity>
export const AAAOverview: Story<UmbWorkspaceLayout> = () => html` <umb-workspace-layout>
<div slot="icon"><uui-button color="" look="placeholder">Icon slot</uui-button></div>
<div slot="name"><uui-button color="" look="placeholder">Name slot</uui-button></div>
<div slot="footer"><uui-button color="" look="placeholder">Footer slot</uui-button></div>
<div slot="actions"><uui-button color="" look="placeholder">Actions slot</uui-button></div>
<uui-button color="" look="placeholder">Default slot</uui-button>
</umb-workspace-entity>`;
</umb-workspace-layout>`;
AAAOverview.storyName = 'Overview';

View File

@@ -1,11 +1,11 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { UmbPropertyActionMenuContext } from '../shared/property-action-menu/property-action-menu.context';
import { UmbPropertyAction } from '../shared/property-action/property-action.model';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-property-action-clear')
export class UmbPropertyActionClearElement extends UmbContextConsumerMixin(LitElement) implements UmbPropertyAction {
export class UmbPropertyActionClearElement extends UmbLitElement implements UmbPropertyAction {
@property()
value = '';

View File

@@ -1,12 +1,13 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import type { UmbNotificationDefaultData } from '../../../../core/notification/layouts/default';
import type { UmbNotificationService } from '../../../../core/notification';
import type { UmbPropertyAction } from '../shared/property-action/property-action.model';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-property-action-copy')
export class UmbPropertyActionCopyElement extends UmbContextConsumerMixin(LitElement) implements UmbPropertyAction {
export class UmbPropertyActionCopyElement extends UmbLitElement implements UmbPropertyAction {
@property()
value = '';

View File

@@ -1,19 +1,16 @@
import { css, CSSResultGroup, html, LitElement } from 'lit';
import { css, CSSResultGroup, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { map } from 'rxjs';
import { UUITextStyles } from '@umbraco-ui/uui';
import { UmbPropertyActionMenuContext } from './property-action-menu.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestPropertyAction } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import '../property-action/property-action.element';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-property-action-menu')
export class UmbPropertyActionMenuElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbPropertyActionMenuElement extends UmbLitElement {
static styles: CSSResultGroup = [
UUITextStyles,
css`
@@ -68,7 +65,7 @@ export class UmbPropertyActionMenuElement extends UmbContextProviderMixin(
}
private _observePropertyActions() {
this.observe<ManifestPropertyAction[]>(
this.observe(
umbExtensionsRegistry
.extensionsOfType('propertyAction')
.pipe(
@@ -85,7 +82,7 @@ export class UmbPropertyActionMenuElement extends UmbContextProviderMixin(
}
private _observePropertyActionMenuOpenState() {
this.observe<boolean>(this._propertyActionMenuContext.isOpen, (value) => {
this.observe(this._propertyActionMenuContext.isOpen, (value) => {
this._open = value;
});
}
@@ -101,7 +98,7 @@ export class UmbPropertyActionMenuElement extends UmbContextProviderMixin(
render() {
return html`
${this._actions?.length > 0
${this._actions.length > 0
? html`
<uui-popover id="popover" placement="bottom-start" .open=${this._open} @close="${this._handleClose}">
<uui-button

View File

@@ -1,20 +1,19 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import type { ManifestTypes, PropertyEditorConfigDefaultData, PropertyEditorConfigProperty } from '@umbraco-cms/models';
import type { PropertyEditorConfigDefaultData, PropertyEditorConfigProperty } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import '../../../components/entity-property/entity-property.element';
import { UmbLitElement } from '@umbraco-cms/element';
/**
* @element umb-property-editor-config
* @description - Element for displaying the configuration for a Property Editor based on a Property Editor UI Alias and a Property Editor Model alias.
*/
@customElement('umb-property-editor-config')
export class UmbPropertyEditorConfigElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbPropertyEditorConfigElement extends UmbLitElement {
static styles = [UUITextStyles];
/**
@@ -59,7 +58,7 @@ export class UmbPropertyEditorConfigElement extends UmbContextConsumerMixin(UmbO
private _observePropertyEditorUIConfig() {
if (!this._propertyEditorUIAlias) return;
this.observe<ManifestTypes>(umbExtensionsRegistry.getByAlias(this.propertyEditorUIAlias), (manifest) => {
this.observe(umbExtensionsRegistry.getByAlias(this.propertyEditorUIAlias), (manifest) => {
if (manifest?.type === 'propertyEditorUI') {
this._observePropertyEditorModelConfig(manifest.meta.propertyEditorModel);
this._propertyEditorUIConfigProperties = manifest?.meta.config?.properties || [];
@@ -73,7 +72,7 @@ export class UmbPropertyEditorConfigElement extends UmbContextConsumerMixin(UmbO
private _observePropertyEditorModelConfig(propertyEditorModelAlias?: string) {
if (!propertyEditorModelAlias) return;
this.observe<ManifestTypes>(umbExtensionsRegistry.getByAlias(propertyEditorModelAlias), (manifest) => {
this.observe(umbExtensionsRegistry.getByAlias(propertyEditorModelAlias), (manifest) => {
if (manifest?.type === 'propertyEditorModel') {
this._propertyEditorModelConfigProperties = manifest?.meta.config?.properties || [];
this._propertyEditorModelConfigDefaultData = manifest?.meta.config?.defaultData || [];

View File

@@ -1,16 +1,15 @@
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property, state } from 'lit/decorators.js';
import { ifDefined } from 'lit-html/directives/if-defined.js';
import type { UmbModalService } from 'src/core/modal';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbDocumentStore } from 'src/backoffice/documents/documents/document.store';
import { FolderTreeItem } from '@umbraco-cms/backend-api';
import { UmbLitElement } from '@umbraco-cms/element';
// TODO: rename to Document Picker
@customElement('umb-property-editor-ui-content-picker')
export class UmbPropertyEditorUIContentPickerElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbPropertyEditorUIContentPickerElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -42,7 +41,7 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbContextConsumerM
public config = [];
@state()
private _items: Array<FolderTreeItem> = [];
private _items?: Array<FolderTreeItem>;
private _modalService?: UmbModalService;
private _documentStore?: UmbDocumentStore;
@@ -60,7 +59,7 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbContextConsumerM
private _observePickedDocuments() {
if (!this._documentStore) return;
// TODO: consider changing this to the list data endpoint when it is available
this.observe<FolderTreeItem[]>(this._documentStore.getTreeItems(this.value), (items) => {
this.observe(this._documentStore.getTreeItems(this.value), (items) => {
this._items = items;
});
}
@@ -109,7 +108,7 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbContextConsumerM
}
render() {
return html`${this._items.map((item) => this._renderItem(item))}
return html`${this._items?.map((item) => this._renderItem(item))}
<uui-button id="add-button" look="placeholder" @click=${this._openPicker} label="open">Add</uui-button>`;
}
}

View File

@@ -1,14 +1,14 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property } from 'lit/decorators.js';
import type { UmbModalService } from 'src/core/modal';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
/**
* @element umb-property-editor-ui-icon-picker
*/
@customElement('umb-property-editor-ui-icon-picker')
export class UmbPropertyEditorUIIconPickerElement extends UmbContextConsumerMixin(LitElement) {
export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement {
static styles = [UUITextStyles];
@property()

View File

@@ -1,12 +1,11 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property } from 'lit/decorators.js';
import { UmbControllerHostMixin } from 'src/core/controller/controller-host.mixin';
import { UmbContextConsumerController } from 'src/core/context-api/consume/context-consumer.controller';
import { UmbWorkspacePropertyContext } from 'src/backoffice/shared/components/entity-property/workspace-property.context';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-property-editor-ui-textarea')
export class UmbPropertyEditorUITextareaElement extends UmbControllerHostMixin(LitElement) {
export class UmbPropertyEditorUITextareaElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`
@@ -27,7 +26,7 @@ export class UmbPropertyEditorUITextareaElement extends UmbControllerHostMixin(L
constructor() {
super();
new UmbContextConsumerController(this, 'umbPropertyContext', (instance) => {
this.consumeContext('umbPropertyContext', (instance) => {
this.propertyContext = instance;
});
}

View File

@@ -20,7 +20,7 @@ export class UmbWorkspaceDictionaryElement extends LitElement {
render() {
return html`
<umb-workspace-entity alias="Umb.Workspace.Dictionary">Dictionary Workspace</umb-workspace-entity>
<umb-workspace-layout alias="Umb.Workspace.Dictionary">Dictionary Workspace</umb-workspace-layout>
`;
}
}

View File

@@ -1,14 +1,13 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, CSSResultGroup, html, LitElement } from 'lit';
import { css, CSSResultGroup, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UmbCurrentUserStore } from './current-user.store';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { UserDetails } from '@umbraco-cms/models';
import { UmbModalService } from 'src/core/modal';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-current-user-header-app')
export class UmbCurrentUserHeaderApp extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
export class UmbCurrentUserHeaderApp extends UmbLitElement {
static styles: CSSResultGroup = [
UUITextStyles,
css`
@@ -36,7 +35,7 @@ export class UmbCurrentUserHeaderApp extends UmbContextConsumerMixin(UmbObserver
private async _observeCurrentUser() {
if (!this._currentUserStore) return;
this.observe<UserDetails>(this._currentUserStore.currentUser, (currentUser) => {
this.observe(this._currentUserStore.currentUser, (currentUser) => {
this._currentUser = currentUser;
});
}

View File

@@ -1,13 +1,10 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement } from 'lit/decorators.js';
import { UmbContextProviderMixin, UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-user-dashboard-test')
export class UmbUserDashboardTestElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbUserDashboardTestElement extends UmbLitElement {
static styles = [
UUITextStyles,
css`

View File

@@ -1,12 +1,12 @@
import { css, html, LitElement } from 'lit';
import { css, html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import type { UUIButtonState } from '@umbraco-ui/uui';
import type { UmbWorkspaceUserContext } from '../../../users/workspace/user-workspace.context';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-workspace-action-user-group-save')
export class UmbWorkspaceActionUserGroupSaveElement extends UmbContextConsumerMixin(LitElement) {
export class UmbWorkspaceActionUserGroupSaveElement extends UmbLitElement {
static styles = [UUITextStyles, css``];
@state()

View File

@@ -1,5 +1,6 @@
import { UmbWorkspaceNodeContext } from '../../../shared/components/workspace/workspace-context/workspace-node.context';
import { UmbWorkspaceContentContext } from '../../../shared/components/workspace/workspace-content/workspace-content.context';
import type { UmbUserGroupStore, UmbUserGroupStoreItemType } from 'src/backoffice/users/user-groups/user-group.store';
import { UmbControllerHostInterface } from 'src/core/controller/controller-host.mixin';
const DefaultDataTypeData = {
key: '',
@@ -13,11 +14,11 @@ const DefaultDataTypeData = {
users: [],
} as UmbUserGroupStoreItemType;
export class UmbWorkspaceUserGroupContext extends UmbWorkspaceNodeContext<
export class UmbWorkspaceUserGroupContext extends UmbWorkspaceContentContext<
UmbUserGroupStoreItemType,
UmbUserGroupStore
> {
constructor(target: HTMLElement, entityKey: string) {
super(target, DefaultDataTypeData, 'umbUserStore', entityKey, 'userGroup');
constructor(host: UmbControllerHostInterface, entityKey: string) {
super(host, DefaultDataTypeData, 'umbUserStore', entityKey, 'userGroup');
}
}

View File

@@ -1,23 +1,22 @@
import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui';
import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement, nothing } from 'lit';
import { css, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { distinctUntilChanged } from 'rxjs';
import { UmbWorkspaceUserGroupContext } from './user-group-workspace.context';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/context-api';
import type { ManifestWorkspaceAction, UserDetails, UserGroupDetails } from '@umbraco-cms/models';
import type { ManifestWorkspaceAction, UserGroupDetails } from '@umbraco-cms/models';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { UmbUserStore } from 'src/backoffice/users/users/user.store';
import type { UmbUserStore } from 'src/backoffice/users/users/user.store';
import 'src/auth/components/input-user/input-user.element';
import 'src/backoffice/shared/components/input-section/input-section.element';
import { UmbLitElement } from '@umbraco-cms/element';
import { UmbWorkspaceEntityElement } from 'src/backoffice/shared/components/workspace/workspace-entity-element.interface';
@customElement('umb-user-group-workspace')
export class UmbUserGroupWorkspaceElement extends UmbContextProviderMixin(
UmbContextConsumerMixin(UmbObserverMixin(LitElement))
) {
export class UmbUserGroupWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement {
static styles = [
UUITextStyles,
css`
@@ -217,17 +216,6 @@ export class UmbUserGroupWorkspaceElement extends UmbContextProviderMixin(
});
}
connectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.connectedCallback();
}
disconnectedCallback(): void {
super.connectedCallback();
// TODO: avoid this connection, our own approach on Lit-Controller could be handling this case.
this._workspaceContext?.disconnectedCallback();
}
protected _provideWorkspace() {
if (this._entityKey) {
this._workspaceContext = new UmbWorkspaceUserGroupContext(this, this._entityKey);
@@ -262,8 +250,7 @@ export class UmbUserGroupWorkspaceElement extends UmbContextProviderMixin(
private _observeUserGroup() {
if (!this._workspaceContext) return;
this.observe<UserGroupDetails>(this._workspaceContext.data.pipe(distinctUntilChanged()), (userGroup) => {
if (!this._userGroup) return;
this.observe(this._workspaceContext.data.pipe(distinctUntilChanged()), (userGroup) => {
this._userGroup = userGroup;
});
}
@@ -273,7 +260,8 @@ export class UmbUserGroupWorkspaceElement extends UmbContextProviderMixin(
// TODO: Create method to only get users from this userGroup
// TODO: Find a better way to only call this once at the start
this.observe(this._userStore.getAll(), (users: Array<UserDetails>) => {
this.observe(this._userStore.getAll(), (users) => {
// TODO: handle if there is no users.
if (!this._userKeys && users.length > 0) {
this._userKeys = users.filter((user) => user.userGroups.includes(this.entityKey)).map((user) => user.key);
this._updateProperty('users', this._userKeys);
@@ -399,13 +387,13 @@ export class UmbUserGroupWorkspaceElement extends UmbContextProviderMixin(
if (!this._userGroup) return nothing;
return html`
<umb-workspace-entity alias="Umb.Workspace.UserGroup">
<umb-workspace-layout alias="Umb.Workspace.UserGroup">
<uui-input id="name" slot="header" .value=${this._userGroup.name} @input="${this._handleInput}"></uui-input>
<div id="main">
<div id="left-column">${this.renderLeftColumn()}</div>
<div id="right-column">${this.renderRightColumn()}</div>
</div>
</umb-workspace-entity>
</umb-workspace-layout>
`;
}
}

View File

@@ -1,12 +1,11 @@
import { html, LitElement } from 'lit';
import { html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import type { ManifestSection } from '@umbraco-cms/models';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { UmbTableItem } from 'src/backoffice/shared/components/table';
import { UmbLitElement } from '@umbraco-cms/element';
@customElement('umb-user-group-table-sections-column-layout')
export class UmbUserGroupTableSectionsColumnLayoutElement extends UmbObserverMixin(LitElement) {
export class UmbUserGroupTableSectionsColumnLayoutElement extends UmbLitElement {
@property({ type: Object, attribute: false })
item!: UmbTableItem;
@@ -23,7 +22,7 @@ export class UmbUserGroupTableSectionsColumnLayoutElement extends UmbObserverMix
}
private observeSectionNames() {
this.observe<Array<ManifestSection>>(umbExtensionsRegistry.extensionsOfType('section'), (sections) => {
this.observe(umbExtensionsRegistry.extensionsOfType('section'), (sections) => {
this._sectionsNames = sections.filter((x) => this.value.includes(x.alias)).map((x) => x.meta.label || x.name);
});
}

Some files were not shown because too many files have changed in this diff Show More