diff --git a/src/Umbraco.Web.UI.Client/.eslintrc.json b/src/Umbraco.Web.UI.Client/.eslintrc.json index 7725f81d2c..88caa66773 100644 --- a/src/Umbraco.Web.UI.Client/.eslintrc.json +++ b/src/Umbraco.Web.UI.Client/.eslintrc.json @@ -2,6 +2,12 @@ "ignorePatterns": ["vite.*.ts"], "root": true, "plugins": ["eslint-plugin-local-rules"], + "parserOptions": { + "ecmaVersion": "latest" + }, + "env": { + "es6": true + }, "overrides": [ { "files": ["**/*.ts"], @@ -35,6 +41,9 @@ "local-rules/bad-type-import": "error", "local-rules/no-direct-api-import": "warn", "local-rules/prefer-import-aliases": "error", + "local-rules/enforce-element-suffix-on-element-class-name": "error", + "local-rules/prefer-umbraco-cms-imports": "error", + "local-rules/no-external-imports": "error", "@typescript-eslint/no-non-null-assertion": "off" }, "settings": { diff --git a/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ambitious-stone-0033b3603.yml b/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ambitious-stone-0033b3603.yml index ee460e8053..0ec823c46f 100644 --- a/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ambitious-stone-0033b3603.yml +++ b/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ambitious-stone-0033b3603.yml @@ -9,6 +9,9 @@ on: # branches: # - main +env: + NODE_OPTIONS: --max_old_space_size=16384 + jobs: build_and_deploy_job: if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') diff --git a/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ashy-bay-09f36a803.yml b/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ashy-bay-09f36a803.yml index 3e9e2ceaaa..76b6ecd96c 100644 --- a/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ashy-bay-09f36a803.yml +++ b/src/Umbraco.Web.UI.Client/.github/workflows/azure-static-web-apps-ashy-bay-09f36a803.yml @@ -9,6 +9,9 @@ on: # branches: # - main +env: + NODE_OPTIONS: --max_old_space_size=16384 + jobs: build_and_deploy_job: if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') diff --git a/src/Umbraco.Web.UI.Client/.github/workflows/build_test.yml b/src/Umbraco.Web.UI.Client/.github/workflows/build_test.yml index 9f2304afbc..4456c4f876 100644 --- a/src/Umbraco.Web.UI.Client/.github/workflows/build_test.yml +++ b/src/Umbraco.Web.UI.Client/.github/workflows/build_test.yml @@ -15,6 +15,9 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: +env: + NODE_OPTIONS: --max_old_space_size=16384 + jobs: build: @@ -34,6 +37,7 @@ jobs: - run: npm ci --no-audit --no-fund --prefer-offline - run: npm run lint - run: npm run build + # - run: npm run build:libs - run: sudo npx playwright install-deps - run: npm test - name: Upload Code Coverage reports diff --git a/src/Umbraco.Web.UI.Client/.github/workflows/npm-publish-github-packages.yml b/src/Umbraco.Web.UI.Client/.github/workflows/npm-publish-github-packages.yml new file mode 100644 index 0000000000..62c7b01446 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/.github/workflows/npm-publish-github-packages.yml @@ -0,0 +1,72 @@ +# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created +# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages +# The @umbraco-cms scope is owned by Umbraco HQ + +name: Node.js Libraries Package + +on: + push: + branches: [ main ] + paths: + - 'libs/**' + - 'package.json' + - 'package-lock.json' + - '.github/workflows/npm-publish-github-packages.yml' + - './rollup-libs.config.js' + - 'src/**/*.element.ts' + pull_request: + branches: [ main ] + paths: + - 'libs/**' + - 'package.json' + - 'package-lock.json' + - '.github/workflows/npm-publish-github-packages.yml' + - './rollup-libs.config.js' + - 'src/**/*.element.ts' + workflow_dispatch: + +env: + NODE_OPTIONS: --max-old-space-size=16384 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'npm' + - run: npm ci + - run: npm run build:libs + - uses: actions/upload-artifact@v3 + with: + name: artifact + path: ./dist/libs + + publish-npm: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + needs: build + runs-on: ubuntu-latest + concurrency: + group: npm-publish + cancel-in-progress: true + steps: + - uses: actions/download-artifact@v3 + with: + name: artifact + - uses: actions/setup-node@v3 + with: + node-version: 18 + registry-url: https://registry.npmjs.org/ + scope: '@umbraco-cms' + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + - name: Version and publish + run: | + SHA_SHORT=$(echo $GITHUB_SHA | cut -c1-8) + npm whoami + npm version 1.0.0-next.$SHA_SHORT --allow-same-version --no-git-tag-version + npm publish --tag next --access public + env: + NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/src/Umbraco.Web.UI.Client/.gitignore b/src/Umbraco.Web.UI.Client/.gitignore index 48fcabe2ce..d2ebc9b225 100644 --- a/src/Umbraco.Web.UI.Client/.gitignore +++ b/src/Umbraco.Web.UI.Client/.gitignore @@ -41,3 +41,8 @@ playwright/.cache/ storybook-static/ custom-elements.json + +# JSON for HTML Custom Data +# https://github.com/runem/web-component-analyzer#vscode +# https://github.com/microsoft/vscode-custom-data +vscode-html-custom-data.json \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/.nvmrc b/src/Umbraco.Web.UI.Client/.nvmrc index 2ef3430431..932b2b01d7 100644 --- a/src/Umbraco.Web.UI.Client/.nvmrc +++ b/src/Umbraco.Web.UI.Client/.nvmrc @@ -1 +1 @@ -18.14 +18.15 diff --git a/src/Umbraco.Web.UI.Client/.storybook/preview.js b/src/Umbraco.Web.UI.Client/.storybook/preview.js index ae238d9981..822d951f3a 100644 --- a/src/Umbraco.Web.UI.Client/.storybook/preview.js +++ b/src/Umbraco.Web.UI.Client/.storybook/preview.js @@ -1,13 +1,10 @@ import '@umbraco-ui/uui-css/dist/uui-css.css'; -import '../libs/css/custom-properties.css'; +import '../src/core/css/custom-properties.css'; +import 'element-internals-polyfill'; import '@umbraco-ui/uui'; -import '@umbraco-ui/uui-modal'; -import '@umbraco-ui/uui-modal-container'; -import '@umbraco-ui/uui-modal-dialog'; -import '@umbraco-ui/uui-modal-sidebar'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { initialize, mswDecorator } from 'msw-storybook-addon'; import { setCustomElements } from '@storybook/web-components'; @@ -17,11 +14,11 @@ import { UmbDocumentStore } from '../src/backoffice/documents/documents/reposito import { UmbDocumentTreeStore } from '../src/backoffice/documents/documents/repository/document.tree.store.ts'; import customElementManifests from '../custom-elements.json'; -import { UmbIconStore } from '../libs/store/icon/icon.store'; +import { UmbIconStore } from '../src/core/stores/icon/icon.store'; import { onUnhandledRequest } from '../src/core/mocks/browser'; import { handlers } from '../src/core/mocks/browser-handlers'; import { UMB_MODAL_CONTEXT_TOKEN, UmbModalContext } from '../libs/modal'; -import { UmbLitElement } from '../libs/element'; +import { UmbLitElement } from '../src/core/lit-element'; import { umbExtensionsRegistry } from '../libs/extensions-api'; diff --git a/src/Umbraco.Web.UI.Client/.vscode/settings.json b/src/Umbraco.Web.UI.Client/.vscode/settings.json index 196b1d2b83..badd3c2f00 100644 --- a/src/Umbraco.Web.UI.Client/.vscode/settings.json +++ b/src/Umbraco.Web.UI.Client/.vscode/settings.json @@ -1,6 +1,6 @@ { "cssVariables.lookupFiles": ["node_modules/@umbraco-ui/uui-css/dist/custom-properties.css"], - "cSpell.words": ["combobox", "variantable"], + "cSpell.words": ["combobox", "templating", "variantable"], "exportall.config.folderListener": [], "exportall.config.relExclusion": [] } diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/auth-layout.element.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/auth-layout.element.ts index 562a927ed5..8ad4209637 100644 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/auth-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/apps/auth/src/auth-layout.element.ts @@ -1,10 +1,10 @@ -import {css, CSSResultGroup, html, LitElement, unsafeCSS} from 'lit'; +import { css, CSSResultGroup, html, LitElement, unsafeCSS } from 'lit'; import { customElement } from 'lit/decorators.js'; import logoImg from '/umbraco_logomark_white.svg'; import loginImg from '/login.jpeg'; @customElement('umb-auth-layout') -export class UmbAuthLayout extends LitElement { +export class UmbAuthLayoutElement extends LitElement { static styles: CSSResultGroup = [ css` #background { @@ -69,6 +69,6 @@ export class UmbAuthLayout extends LitElement { declare global { interface HTMLElementTagNameMap { - 'umb-auth-layout': UmbAuthLayout; + 'umb-auth-layout': UmbAuthLayoutElement; } } diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/manifests.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/manifests.ts index 2e780045be..956ebae221 100644 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/manifests.ts +++ b/src/Umbraco.Web.UI.Client/apps/auth/src/external-login-providers/manifests.ts @@ -1,5 +1,5 @@ // TODO: could these be renamed as login providers? -import type { ManifestExternalLoginProvider } from '@umbraco-cms/models'; +import type { ManifestExternalLoginProvider } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/index.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/index.ts index c86d00fb89..ac1d861af1 100644 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/index.ts +++ b/src/Umbraco.Web.UI.Client/apps/auth/src/index.ts @@ -1,9 +1,9 @@ -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; import { manifests as externalLoginProviders } from './external-login-providers/manifests'; import '@umbraco-ui/uui-css/dist/uui-css.css'; -import '@umbraco-cms/css'; +import '@umbraco-cms/backoffice/css'; import '@umbraco-ui/uui'; import './login.element'; diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/login.element.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/login.element.ts index d63b68f72d..018d87b14d 100644 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/login.element.ts +++ b/src/Umbraco.Web.UI.Client/apps/auth/src/login.element.ts @@ -6,7 +6,7 @@ import { ifDefined } from 'lit/directives/if-defined.js'; import './auth-layout.element'; @customElement('umb-login') -export default class UmbLogin extends LitElement { +export default class UmbLoginElement extends LitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -113,6 +113,6 @@ export default class UmbLogin extends LitElement { declare global { interface HTMLElementTagNameMap { - 'umb-login': UmbLogin; + 'umb-login': UmbLoginElement; } } diff --git a/src/Umbraco.Web.UI.Client/apps/auth/src/login.test.ts b/src/Umbraco.Web.UI.Client/apps/auth/src/login.test.ts index 4908a6342e..2b2d0a2ded 100644 --- a/src/Umbraco.Web.UI.Client/apps/auth/src/login.test.ts +++ b/src/Umbraco.Web.UI.Client/apps/auth/src/login.test.ts @@ -1,16 +1,16 @@ import { expect, fixture, html } from '@open-wc/testing'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; -import UmbLogin from './login.element'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; +import UmbLoginElement from './login.element'; describe('UmbLogin', () => { - let element: UmbLogin; + let element: UmbLoginElement; beforeEach(async () => { element = await fixture(html``); }); it('is defined with its own instance', () => { - expect(element).to.be.instanceOf(UmbLogin); + expect(element).to.be.instanceOf(UmbLoginElement); }); it('passes the a11y audit', async () => { diff --git a/src/Umbraco.Web.UI.Client/devops/plop/templates/property-editor-ui/stories.ts.hbs b/src/Umbraco.Web.UI.Client/devops/plop/templates/property-editor-ui/stories.ts.hbs index 639e3b1fa8..69c46995b8 100644 --- a/src/Umbraco.Web.UI.Client/devops/plop/templates/property-editor-ui/stories.ts.hbs +++ b/src/Umbraco.Web.UI.Client/devops/plop/templates/property-editor-ui/stories.ts.hbs @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { {{className extensionType name}} } from './{{ extensionFilename extensionType name }}.element'; import './{{ extensionFilename extensionType name }}.element'; diff --git a/src/Umbraco.Web.UI.Client/e2e/installer.spec.ts b/src/Umbraco.Web.UI.Client/e2e/installer.spec.ts index 82ff532414..cc6845ff00 100644 --- a/src/Umbraco.Web.UI.Client/e2e/installer.spec.ts +++ b/src/Umbraco.Web.UI.Client/e2e/installer.spec.ts @@ -1,7 +1,7 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; -import { ProblemDetailsModel, RuntimeLevelModel, ServerStatusModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { ProblemDetailsModel, RuntimeLevelModel, ServerStatusResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { expect, test } from './test'; test.describe('installer tests', () => { @@ -12,7 +12,7 @@ test.describe('installer tests', () => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ serverStatus: RuntimeLevelModel.INSTALL, }) ); diff --git a/src/Umbraco.Web.UI.Client/e2e/upgrader.spec.ts b/src/Umbraco.Web.UI.Client/e2e/upgrader.spec.ts index debb44f6cd..07fcffe006 100644 --- a/src/Umbraco.Web.UI.Client/e2e/upgrader.spec.ts +++ b/src/Umbraco.Web.UI.Client/e2e/upgrader.spec.ts @@ -1,6 +1,6 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; -import { ProblemDetailsModel, RuntimeLevelModel, ServerStatusModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { ProblemDetailsModel, RuntimeLevelModel, ServerStatusResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { expect, test } from './test'; test.describe('upgrader tests', () => { @@ -11,7 +11,7 @@ test.describe('upgrader tests', () => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ serverStatus: RuntimeLevelModel.UPGRADE, }) ); diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs index 1ec3bed82c..ed1c5036cd 100644 --- a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -20,18 +20,21 @@ module.exports = { create: function (context) { return { ImportDeclaration: function (node) { - if (node.source.parent.importKind !== 'type' && (node.source.value.endsWith('/models') || 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({ node, message: 'Use `import type` instead of `import`.', - fix: fixer => fixer.replaceText(node, nodeSource.replace('import', 'import type')), + fix: (fixer) => fixer.replaceText(node, nodeSource.replace('import', 'import type')), }); } }, }; - } + }, }, /** @type {import('eslint').Rule.RuleModule} */ @@ -39,9 +42,10 @@ module.exports = { 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.', + description: + 'Ensures that any API resources from the `@umbraco-cms/backoffice/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 + recommended: true, }, fixable: 'code', schema: [], @@ -50,19 +54,30 @@ module.exports = { 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 ( + 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, ')')], + fix: (fixer) => [ + fixer.insertTextBefore(node, 'tryExecuteAndNotify(this, '), + fixer.insertTextAfter(node, ')'), + ], }); } } - } + }, }; - }, }, @@ -71,9 +86,10 @@ module.exports = { meta: { type: 'suggestion', docs: { - description: 'Ensures that the application does not rely on file system paths for imports. Instead, use import aliases or relative imports. This also solves a problem where GitHub fails on the test runner step.', + description: + 'Ensures that the application does not rely on file system paths for imports. Instead, use import aliases or relative imports. This also solves a problem where GitHub fails on the test runner step.', category: 'Best Practices', - recommended: true + recommended: true, }, schema: [], }, @@ -83,11 +99,110 @@ module.exports = { if (node.source.value.startsWith('src/')) { context.report({ node, - message: 'Prefer using import aliases or relative imports instead of absolute imports. Example: `import { MyComponent } from "src/components/MyComponent";` should be `import { MyComponent } from "@components/MyComponent";`' + message: + 'Prefer using import aliases or relative imports instead of absolute imports. Example: `import { MyComponent } from "src/components/MyComponent";` should be `import { MyComponent } from "@components/MyComponent";`', }); } }, }; - } + }, + }, + + /** @type {import('eslint').Rule.RuleModule} */ + 'enforce-element-suffix-on-element-class-name': { + meta: { + type: 'suggestion', + docs: { + description: 'Enforce Element class name to end with "Element".', + category: 'Naming', + recommended: true, + }, + schema: [], + }, + create: function (context) { + return { + ClassDeclaration(node) { + // check if the class extends HTMLElement, LitElement, or UmbLitElement + const isExtendingElement = + node.superClass && ['HTMLElement', 'LitElement', 'UmbLitElement'].includes(node.superClass.name); + // check if the class name ends with 'Element' + const isClassNameValid = node.id.name.endsWith('Element'); + + if (isExtendingElement && !isClassNameValid) { + context.report({ + node, + message: "Element class name should end with 'Element'.", + // There us no fixer on purpose because it's not safe to rename the class. We want to do that trough the refactoring tool. + }); + } + }, + }; + }, + }, + + // TODO: Its not bullet proof, but it will catch most/some cases. + /** @type {import('eslint').Rule.RuleModule} */ + 'prefer-umbraco-cms-imports': { + meta: { + type: 'suggestion', + docs: { + description: 'Replace relative imports to libs/... with @umbraco-cms/backoffice/...', + category: 'Best Practices', + recommended: true, + }, + fixable: 'code', + schema: [], + }, + create: function (context) { + const libsRegex = /(\.\.\/)*libs\/(.*)/; + return { + ImportDeclaration: function (node) { + const sourceValue = node.source.value; + if (sourceValue.startsWith('libs/') || libsRegex.test(sourceValue)) { + const importPath = sourceValue.replace(libsRegex, (match, p1, p2) => { + return `@umbraco-cms/backoffice/${p2}`; + }); + context.report({ + node, + message: `Use import alias @umbraco-cms/backoffice instead of relative path "${sourceValue}".`, + fix: function (fixer) { + return fixer.replaceTextRange(node.source.range, `'${importPath}'`); + }, + }); + } + }, + }; + }, + }, + + /** @type {import('eslint').Rule.RuleModule} */ + 'no-external-imports': { + meta: { + type: 'problem', + docs: { + description: + 'Ensures that the application does not rely on imports from external packages. Instead, use the @umbraco-cms/backoffice libs.', + recommended: true, + }, + fixable: 'code', + schema: [], + }, + create: function (context) { + return { + ImportDeclaration: function (node) { + // Check for imports from "router-slot" + if (node.source.value.startsWith('router-slot')) { + context.report({ + node, + message: + 'Use the `@umbraco-cms/backoffice/router` package instead of importing directly from "router-slot" because we might change that dependency in the future.', + fix: (fixer) => { + return fixer.replaceTextRange(node.source.range, `'@umbraco-cms/backoffice/router'`); + }, + }); + } + }, + }; + }, }, }; diff --git a/src/Umbraco.Web.UI.Client/libs/README.md b/src/Umbraco.Web.UI.Client/libs/README.md new file mode 100644 index 0000000000..8796b8f582 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/README.md @@ -0,0 +1,168 @@ +# @umbraco-cms/backoffice + +This package contains the types for the libraries for Umbraco 13. + +## Installation + +```bash +npm install -D @umbraco-cms/backoffice +``` + +## Usage + +### Vanilla JavaScript + +Create an umbraco-package.json file in the root of your package. + +```json +{ + "name": "My.Package", + "version": "0.1.0", + "extensions": [ + { + "type": "dashboard", + "alias": "my.custom.dashboard", + "name": "My Dashboard", + "js": "/App_Plugins/MyPackage/dashboard.js", + "weight": -1, + "meta": { + "label": "My Dashboard", + "pathname": "my-dashboard" + }, + "conditions": { + "sections": ["Umb.Section.Content"] + } + } + ] +} +``` + +Then create a dashboard.js file the same folder. + +```javascript +import { UmbElementMixin } from '@umbraco-cms/backoffice/element'; +import { UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; + +const template = document.createElement('template'); +template.innerHTML = ` + + + +

Welcome to my dashboard

+

Example of vanilla JS code

+ + +
+`; + +export default class MyDashboardElement extends UmbElementMixin(HTMLElement) { + /** @type {import('@umbraco-cms/backoffice/notification').UmbNotificationContext} */ + #notificationContext; + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.shadowRoot.appendChild(template.content.cloneNode(true)); + + this.shadowRoot.getElementById('clickMe').addEventListener('click', this.onClick.bind(this)); + + this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (_instance) => { + this.#notificationContext = _instance; + }); + } + + onClick = () => { + this.#notificationContext?.peek('positive', { data: { headline: 'Hello' } }); + }; +} + +customElements.define('my-custom-dashboard', MyDashboardElement); +``` + +### TypeScript with Lit + +First install Lit and Vite. This command will create a new folder called `my-package` which will have the Vite tooling and Lit for WebComponent development setup. + +```bash +npm create vite@latest -- --template lit-ts my-package +``` + +Go to the new folder and install the backoffice package. + +```bash +cd my-package +npm install -D @umbraco-cms/backoffice +``` + +Then go to the element located in `src/my-element.ts` and replace it with the following code. + +```typescript +// src/my-element.ts +import { LitElement, html } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; + +@customElement('my-element') +export default class MyElement extends UmbElementMixin(LitElement) { + + private _notificationContext?: UmbNotificationContext; + + constructor() { + super(); + this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (_instance) => { + this._notificationContext = _instance; + }); + } + + onClick() { + this._notificationContext?.peek('positive', { data: { message: '#h5yr' } }); + } + + render() { + return html` + +

A TypeScript Lit Dashboard

+ this.onClick()}> +
+ `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'my-element': MyElement; + } +} +``` + +Finally add an umbraco-package.json file in the root of your package folder `my-package`. + +```json +{ + "name": "My.Package", + "version": "0.1.0", + "extensions": [ + { + "type": "dashboard", + "alias": "my.custom.dashboard", + "name": "My Dashboard", + "js": "/App_Plugins/MyPackage/dist/my-package.js", + "weight": -1, + "meta": { + "label": "My Dashboard", + "pathname": "my-dashboard" + }, + "conditions": { + "sections": ["Umb.Section.Content"] + } + } + ] +} +``` diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/backend-api/rollup.config.js deleted file mode 100644 index 44c6c08405..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/rollup.config.js +++ /dev/null @@ -1,4 +0,0 @@ -import config from '../../utils/rollup.config.js'; -export default [ - ...config, -]; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/core/CancelablePromise.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/core/CancelablePromise.ts index 800d901ec4..26ad303915 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/core/CancelablePromise.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/core/CancelablePromise.ts @@ -2,122 +2,127 @@ /* tslint:disable */ /* eslint-disable */ export class CancelError extends Error { - constructor(message: string) { - super(message); - this.name = 'CancelError'; - } - public get isCancelled(): boolean { - return true; - } + constructor(message: string) { + super(message); + this.name = 'CancelError'; + } + + public get isCancelled(): boolean { + return true; + } } export interface OnCancel { - readonly isResolved: boolean; - readonly isRejected: boolean; - readonly isCancelled: boolean; + readonly isResolved: boolean; + readonly isRejected: boolean; + readonly isCancelled: boolean; - (cancelHandler: () => void): void; + (cancelHandler: () => void): void; } export class CancelablePromise implements Promise { - readonly [Symbol.toStringTag]!: string; + readonly [Symbol.toStringTag]!: string; - private _isResolved: boolean; - private _isRejected: boolean; - private _isCancelled: boolean; - private readonly _cancelHandlers: (() => void)[]; - private readonly _promise: Promise; - private _resolve?: (value: T | PromiseLike) => void; - private _reject?: (reason?: any) => void; + private _isResolved: boolean; + private _isRejected: boolean; + private _isCancelled: boolean; + private readonly _cancelHandlers: (() => void)[]; + private readonly _promise: Promise; + private _resolve?: (value: T | PromiseLike) => void; + private _reject?: (reason?: any) => void; - constructor( - executor: (resolve: (value: T | PromiseLike) => void, reject: (reason?: any) => void, onCancel: OnCancel) => void - ) { - this._isResolved = false; - this._isRejected = false; - this._isCancelled = false; - this._cancelHandlers = []; - this._promise = new Promise((resolve, reject) => { - this._resolve = resolve; - this._reject = reject; + constructor( + executor: ( + resolve: (value: T | PromiseLike) => void, + reject: (reason?: any) => void, + onCancel: OnCancel + ) => void + ) { + this._isResolved = false; + this._isRejected = false; + this._isCancelled = false; + this._cancelHandlers = []; + this._promise = new Promise((resolve, reject) => { + this._resolve = resolve; + this._reject = reject; - const onResolve = (value: T | PromiseLike): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isResolved = true; - this._resolve?.(value); - }; + const onResolve = (value: T | PromiseLike): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isResolved = true; + this._resolve?.(value); + }; - const onReject = (reason?: any): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isRejected = true; - this._reject?.(reason); - }; + const onReject = (reason?: any): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isRejected = true; + this._reject?.(reason); + }; - const onCancel = (cancelHandler: () => void): void => { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._cancelHandlers.push(cancelHandler); - }; + const onCancel = (cancelHandler: () => void): void => { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._cancelHandlers.push(cancelHandler); + }; - Object.defineProperty(onCancel, 'isResolved', { - get: (): boolean => this._isResolved, - }); + Object.defineProperty(onCancel, 'isResolved', { + get: (): boolean => this._isResolved, + }); - Object.defineProperty(onCancel, 'isRejected', { - get: (): boolean => this._isRejected, - }); + Object.defineProperty(onCancel, 'isRejected', { + get: (): boolean => this._isRejected, + }); - Object.defineProperty(onCancel, 'isCancelled', { - get: (): boolean => this._isCancelled, - }); + Object.defineProperty(onCancel, 'isCancelled', { + get: (): boolean => this._isCancelled, + }); - return executor(onResolve, onReject, onCancel as OnCancel); - }); - } + return executor(onResolve, onReject, onCancel as OnCancel); + }); + } - public then( - onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, - onRejected?: ((reason: any) => TResult2 | PromiseLike) | null - ): Promise { - return this._promise.then(onFulfilled, onRejected); - } + public then( + onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onRejected?: ((reason: any) => TResult2 | PromiseLike) | null + ): Promise { + return this._promise.then(onFulfilled, onRejected); + } - public catch( - onRejected?: ((reason: any) => TResult | PromiseLike) | null - ): Promise { - return this._promise.catch(onRejected); - } + public catch( + onRejected?: ((reason: any) => TResult | PromiseLike) | null + ): Promise { + return this._promise.catch(onRejected); + } - public finally(onFinally?: (() => void) | null): Promise { - return this._promise.finally(onFinally); - } + public finally(onFinally?: (() => void) | null): Promise { + return this._promise.finally(onFinally); + } - public cancel(): void { - if (this._isResolved || this._isRejected || this._isCancelled) { - return; - } - this._isCancelled = true; - if (this._cancelHandlers.length) { - try { - for (const cancelHandler of this._cancelHandlers) { - cancelHandler(); - } - } catch (error) { - console.warn('Cancellation threw an error', error); - return; - } - } - this._cancelHandlers.length = 0; - this._reject?.(new CancelError('Request aborted')); - } + public cancel(): void { + if (this._isResolved || this._isRejected || this._isCancelled) { + return; + } + this._isCancelled = true; + if (this._cancelHandlers.length) { + try { + for (const cancelHandler of this._cancelHandlers) { + cancelHandler(); + } + } catch (error) { + console.warn('Cancellation threw an error', error); + return; + } + } + this._cancelHandlers.length = 0; + this._reject?.(new CancelError('Request aborted')); + } - public get isCancelled(): boolean { - return this._isCancelled; - } + public get isCancelled(): boolean { + return this._isCancelled; + } } diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/index.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/index.ts index dd1647bd85..9919e60217 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/index.ts @@ -10,165 +10,232 @@ export type { AuditLogBaseModel } from './models/AuditLogBaseModel'; export type { AuditLogResponseModel } from './models/AuditLogResponseModel'; export type { AuditLogWithUsernameResponseModel } from './models/AuditLogWithUsernameResponseModel'; export { AuditTypeModel } from './models/AuditTypeModel'; -export type { ConsentLevelModel } from './models/ConsentLevelModel'; +export type { ChangePasswordUserRequestModel } from './models/ChangePasswordUserRequestModel'; +export type { ConsentLevelPresentationModel } from './models/ConsentLevelPresentationModel'; +export type { ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel } from './models/ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel'; export { ContentStateModel } from './models/ContentStateModel'; -export type { ContentTreeItemModel } from './models/ContentTreeItemModel'; +export type { ContentTreeItemResponseModel } from './models/ContentTreeItemResponseModel'; export type { ContentTypeCleanupModel } from './models/ContentTypeCleanupModel'; export type { ContentTypeCompositionModel } from './models/ContentTypeCompositionModel'; export { ContentTypeCompositionTypeModel } from './models/ContentTypeCompositionTypeModel'; +export type { ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel } from './models/ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel'; +export type { ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel } from './models/ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel'; export type { ContentTypeSortModel } from './models/ContentTypeSortModel'; -export type { ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel } from './models/ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel'; export type { ContentUrlInfoModel } from './models/ContentUrlInfoModel'; -export type { ContentViewModelBaseDocumentValueDocumentVariantModel } from './models/ContentViewModelBaseDocumentValueDocumentVariantModel'; -export type { CultureModel } from './models/CultureModel'; -export type { DatabaseInstallModel } from './models/DatabaseInstallModel'; -export type { DatabaseSettingsModel } from './models/DatabaseSettingsModel'; -export type { DataTypeCopyModel } from './models/DataTypeCopyModel'; -export type { DataTypeCreateModel } from './models/DataTypeCreateModel'; -export type { DataTypeModel } from './models/DataTypeModel'; +export type { CopyDataTypeRequestModel } from './models/CopyDataTypeRequestModel'; +export type { CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel } from './models/CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel'; +export type { CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel } from './models/CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel'; +export type { CreateDataTypeRequestModel } from './models/CreateDataTypeRequestModel'; +export type { CreateDictionaryItemRequestModel } from './models/CreateDictionaryItemRequestModel'; +export type { CreateDocumentRequestModel } from './models/CreateDocumentRequestModel'; +export type { CreateFolderRequestModel } from './models/CreateFolderRequestModel'; +export type { CreateLanguageRequestModel } from './models/CreateLanguageRequestModel'; +export type { CreateMediaRequestModel } from './models/CreateMediaRequestModel'; +export type { CreatePackageRequestModel } from './models/CreatePackageRequestModel'; +export type { CreateRelationTypeRequestModel } from './models/CreateRelationTypeRequestModel'; +export type { CreateTemplateRequestModel } from './models/CreateTemplateRequestModel'; +export type { CreateUserRequestModel } from './models/CreateUserRequestModel'; +export type { CreateUserResponseModel } from './models/CreateUserResponseModel'; +export type { CultureReponseModel } from './models/CultureReponseModel'; +export type { DatabaseInstallResponseModel } from './models/DatabaseInstallResponseModel'; +export type { DatabaseSettingsPresentationModel } from './models/DatabaseSettingsPresentationModel'; +export type { DataTypeItemResponseModel } from './models/DataTypeItemResponseModel'; export type { DataTypeModelBaseModel } from './models/DataTypeModelBaseModel'; -export type { DataTypeMoveModel } from './models/DataTypeMoveModel'; -export type { DataTypePropertyModel } from './models/DataTypePropertyModel'; +export type { DataTypePropertyPresentationModel } from './models/DataTypePropertyPresentationModel'; export type { DataTypePropertyReferenceModel } from './models/DataTypePropertyReferenceModel'; -export type { DataTypeReferenceModel } from './models/DataTypeReferenceModel'; -export type { DataTypeUpdateModel } from './models/DataTypeUpdateModel'; -export type { DictionaryImportModel } from './models/DictionaryImportModel'; -export type { DictionaryItemCreateModel } from './models/DictionaryItemCreateModel'; -export type { DictionaryItemModel } from './models/DictionaryItemModel'; +export type { DataTypeReferenceResponseModel } from './models/DataTypeReferenceResponseModel'; +export type { DataTypeResponseModel } from './models/DataTypeResponseModel'; +export type { DictionaryItemItemResponseModel } from './models/DictionaryItemItemResponseModel'; export type { DictionaryItemModelBaseModel } from './models/DictionaryItemModelBaseModel'; -export type { DictionaryItemsImportModel } from './models/DictionaryItemsImportModel'; +export type { DictionaryItemResponseModel } from './models/DictionaryItemResponseModel'; export type { DictionaryItemTranslationModel } from './models/DictionaryItemTranslationModel'; -export type { DictionaryItemUpdateModel } from './models/DictionaryItemUpdateModel'; -export type { DictionaryMoveModel } from './models/DictionaryMoveModel'; -export type { DictionaryOverviewModel } from './models/DictionaryOverviewModel'; -export type { DictionaryUploadModel } from './models/DictionaryUploadModel'; +export type { DictionaryOverviewResponseModel } from './models/DictionaryOverviewResponseModel'; export { DirectionModel } from './models/DirectionModel'; -export type { DocumentBlueprintTreeItemModel } from './models/DocumentBlueprintTreeItemModel'; -export type { DocumentModel } from './models/DocumentModel'; -export type { DocumentTreeItemModel } from './models/DocumentTreeItemModel'; -export type { DocumentTypeModel } from './models/DocumentTypeModel'; -export type { DocumentTypePropertyTypeContainerModel } from './models/DocumentTypePropertyTypeContainerModel'; -export type { DocumentTypePropertyTypeModel } from './models/DocumentTypePropertyTypeModel'; -export type { DocumentTypeTreeItemModel } from './models/DocumentTypeTreeItemModel'; +export type { DisableUserRequestModel } from './models/DisableUserRequestModel'; +export type { DocumentBlueprintResponseModel } from './models/DocumentBlueprintResponseModel'; +export type { DocumentBlueprintTreeItemResponseModel } from './models/DocumentBlueprintTreeItemResponseModel'; +export type { DocumentItemResponseModel } from './models/DocumentItemResponseModel'; +export type { DocumentNotificationResponseModel } from './models/DocumentNotificationResponseModel'; +export type { DocumentResponseModel } from './models/DocumentResponseModel'; +export type { DocumentTreeItemResponseModel } from './models/DocumentTreeItemResponseModel'; +export type { DocumentTypeItemResponseModel } from './models/DocumentTypeItemResponseModel'; +export type { DocumentTypePropertyTypeContainerResponseModel } from './models/DocumentTypePropertyTypeContainerResponseModel'; +export type { DocumentTypePropertyTypeResponseModel } from './models/DocumentTypePropertyTypeResponseModel'; +export type { DocumentTypeResponseModel } from './models/DocumentTypeResponseModel'; +export type { DocumentTypeTreeItemResponseModel } from './models/DocumentTypeTreeItemResponseModel'; export type { DocumentValueModel } from './models/DocumentValueModel'; -export type { DocumentVariantModel } from './models/DocumentVariantModel'; -export type { EntityTreeItemModel } from './models/EntityTreeItemModel'; -export type { FieldModel } from './models/FieldModel'; -export type { FileSystemTreeItemModel } from './models/FileSystemTreeItemModel'; -export type { FolderCreateModel } from './models/FolderCreateModel'; -export type { FolderModel } from './models/FolderModel'; +export type { DocumentVariantRequestModel } from './models/DocumentVariantRequestModel'; +export type { DocumentVariantResponseModel } from './models/DocumentVariantResponseModel'; +export type { DomainPresentationModel } from './models/DomainPresentationModel'; +export type { DomainsPresentationModelBaseModel } from './models/DomainsPresentationModelBaseModel'; +export type { DomainsResponseModel } from './models/DomainsResponseModel'; +export type { EnableUserRequestModel } from './models/EnableUserRequestModel'; +export type { EntityTreeItemResponseModel } from './models/EntityTreeItemResponseModel'; +export type { FieldPresentationModel } from './models/FieldPresentationModel'; +export type { FileItemResponseModelBaseModel } from './models/FileItemResponseModelBaseModel'; +export type { FileSystemTreeItemPresentationModel } from './models/FileSystemTreeItemPresentationModel'; export type { FolderModelBaseModel } from './models/FolderModelBaseModel'; -export type { FolderTreeItemModel } from './models/FolderTreeItemModel'; -export type { FolderUpdateModel } from './models/FolderUpdateModel'; -export type { HealthCheckActionModel } from './models/HealthCheckActionModel'; -export type { HealthCheckGroupModel } from './models/HealthCheckGroupModel'; -export type { HealthCheckGroupModelBaseModel } from './models/HealthCheckGroupModelBaseModel'; -export type { HealthCheckGroupWithResultModel } from './models/HealthCheckGroupWithResultModel'; +export type { FolderReponseModel } from './models/FolderReponseModel'; +export type { FolderTreeItemResponseModel } from './models/FolderTreeItemResponseModel'; +export type { HealthCheckActionRequestModel } from './models/HealthCheckActionRequestModel'; +export type { HealthCheckGroupPresentationBaseModel } from './models/HealthCheckGroupPresentationBaseModel'; +export type { HealthCheckGroupPresentationModel } from './models/HealthCheckGroupPresentationModel'; +export type { HealthCheckGroupResponseModel } from './models/HealthCheckGroupResponseModel'; +export type { HealthCheckGroupWithResultResponseModel } from './models/HealthCheckGroupWithResultResponseModel'; export type { HealthCheckModel } from './models/HealthCheckModel'; export type { HealthCheckModelBaseModel } from './models/HealthCheckModelBaseModel'; -export type { HealthCheckResultModel } from './models/HealthCheckResultModel'; -export type { HealthCheckWithResultModel } from './models/HealthCheckWithResultModel'; +export type { HealthCheckResultResponseModel } from './models/HealthCheckResultResponseModel'; +export type { HealthCheckWithResultPresentationModel } from './models/HealthCheckWithResultPresentationModel'; export { HealthStatusModel } from './models/HealthStatusModel'; -export type { HelpPageModel } from './models/HelpPageModel'; -export type { IndexModel } from './models/IndexModel'; -export type { InstallModel } from './models/InstallModel'; -export type { InstallSettingsModel } from './models/InstallSettingsModel'; -export type { LanguageCreateModel } from './models/LanguageCreateModel'; -export type { LanguageModel } from './models/LanguageModel'; +export type { HelpPageResponseModel } from './models/HelpPageResponseModel'; +export type { ImportDictionaryRequestModel } from './models/ImportDictionaryRequestModel'; +export type { IndexResponseModel } from './models/IndexResponseModel'; +export type { InstallSettingsResponseModel } from './models/InstallSettingsResponseModel'; +export type { InstallVResponseModel } from './models/InstallVResponseModel'; +export type { InviteUserRequestModel } from './models/InviteUserRequestModel'; +export type { ItemResponseModelBaseModel } from './models/ItemResponseModelBaseModel'; +export type { LanguageItemResponseModel } from './models/LanguageItemResponseModel'; export type { LanguageModelBaseModel } from './models/LanguageModelBaseModel'; -export type { LanguageUpdateModel } from './models/LanguageUpdateModel'; -export type { LoggerModel } from './models/LoggerModel'; -export type { LogLevelCountsModel } from './models/LogLevelCountsModel'; +export type { LanguageResponseModel } from './models/LanguageResponseModel'; +export type { LoggerResponseModel } from './models/LoggerResponseModel'; +export type { LogLevelCountsReponseModel } from './models/LogLevelCountsReponseModel'; export { LogLevelModel } from './models/LogLevelModel'; -export type { LogMessageModel } from './models/LogMessageModel'; -export type { LogMessagePropertyModel } from './models/LogMessagePropertyModel'; -export type { LogTemplateModel } from './models/LogTemplateModel'; -export type { ModelsBuilderModel } from './models/ModelsBuilderModel'; +export type { LogMessagePropertyPresentationModel } from './models/LogMessagePropertyPresentationModel'; +export type { LogMessageResponseModel } from './models/LogMessageResponseModel'; +export type { LogTemplateResponseModel } from './models/LogTemplateResponseModel'; +export type { MediaItemResponseModel } from './models/MediaItemResponseModel'; +export type { MediaTypeItemResponseModel } from './models/MediaTypeItemResponseModel'; +export type { MediaTypePropertyTypeContainerResponseModel } from './models/MediaTypePropertyTypeContainerResponseModel'; +export type { MediaTypePropertyTypeResponseModel } from './models/MediaTypePropertyTypeResponseModel'; +export type { MediaTypeResponseModel } from './models/MediaTypeResponseModel'; +export type { MediaValueModel } from './models/MediaValueModel'; +export type { MediaVariantRequestModel } from './models/MediaVariantRequestModel'; +export type { MediaVariantResponseModel } from './models/MediaVariantResponseModel'; +export type { MemberGroupItemReponseModel } from './models/MemberGroupItemReponseModel'; +export type { MemberTypeItemResponseModel } from './models/MemberTypeItemResponseModel'; +export type { ModelsBuilderResponseModel } from './models/ModelsBuilderResponseModel'; export { ModelsModeModel } from './models/ModelsModeModel'; +export type { MoveDataTypeRequestModel } from './models/MoveDataTypeRequestModel'; +export type { MoveDictionaryRequestModel } from './models/MoveDictionaryRequestModel'; +export type { ObjectTypeResponseModel } from './models/ObjectTypeResponseModel'; export type { OkResultModel } from './models/OkResultModel'; export { OperatorModel } from './models/OperatorModel'; -export type { OutOfDateStatusModel } from './models/OutOfDateStatusModel'; +export type { OutOfDateStatusResponseModel } from './models/OutOfDateStatusResponseModel'; export { OutOfDateTypeModel } from './models/OutOfDateTypeModel'; -export type { PackageCreateModel } from './models/PackageCreateModel'; -export type { PackageDefinitionModel } from './models/PackageDefinitionModel'; -export type { PackageManifestModel } from './models/PackageManifestModel'; -export type { PackageMigrationStatusModel } from './models/PackageMigrationStatusModel'; +export type { PackageDefinitionResponseModel } from './models/PackageDefinitionResponseModel'; +export type { PackageManifestResponseModel } from './models/PackageManifestResponseModel'; +export type { PackageMigrationStatusResponseModel } from './models/PackageMigrationStatusResponseModel'; export type { PackageModelBaseModel } from './models/PackageModelBaseModel'; -export type { PackageUpdateModel } from './models/PackageUpdateModel'; export type { PagedAuditLogResponseModel } from './models/PagedAuditLogResponseModel'; export type { PagedAuditLogWithUsernameResponseModel } from './models/PagedAuditLogWithUsernameResponseModel'; -export type { PagedContentTreeItemModel } from './models/PagedContentTreeItemModel'; -export type { PagedCultureModel } from './models/PagedCultureModel'; -export type { PagedDictionaryOverviewModel } from './models/PagedDictionaryOverviewModel'; -export type { PagedDocumentBlueprintTreeItemModel } from './models/PagedDocumentBlueprintTreeItemModel'; -export type { PagedDocumentTreeItemModel } from './models/PagedDocumentTreeItemModel'; -export type { PagedDocumentTypeTreeItemModel } from './models/PagedDocumentTypeTreeItemModel'; -export type { PagedEntityTreeItemModel } from './models/PagedEntityTreeItemModel'; -export type { PagedFileSystemTreeItemModel } from './models/PagedFileSystemTreeItemModel'; -export type { PagedFolderTreeItemModel } from './models/PagedFolderTreeItemModel'; -export type { PagedHealthCheckGroupModelBaseModel } from './models/PagedHealthCheckGroupModelBaseModel'; -export type { PagedHelpPageModel } from './models/PagedHelpPageModel'; -export type { PagedIndexModel } from './models/PagedIndexModel'; -export type { PagedLanguageModel } from './models/PagedLanguageModel'; -export type { PagedLoggerModel } from './models/PagedLoggerModel'; -export type { PagedLogMessageModel } from './models/PagedLogMessageModel'; -export type { PagedLogTemplateModel } from './models/PagedLogTemplateModel'; -export type { PagedPackageDefinitionModel } from './models/PagedPackageDefinitionModel'; -export type { PagedPackageMigrationStatusModel } from './models/PagedPackageMigrationStatusModel'; -export type { PagedRecycleBinItemModel } from './models/PagedRecycleBinItemModel'; -export type { PagedRedirectUrlModel } from './models/PagedRedirectUrlModel'; -export type { PagedRelationItemModel } from './models/PagedRelationItemModel'; -export type { PagedRelationModel } from './models/PagedRelationModel'; -export type { PagedSavedLogSearchModel } from './models/PagedSavedLogSearchModel'; -export type { PagedSearcherModel } from './models/PagedSearcherModel'; -export type { PagedSearchResultModel } from './models/PagedSearchResultModel'; -export type { PagedTelemetryModel } from './models/PagedTelemetryModel'; -export type { PagedUserGroupModel } from './models/PagedUserGroupModel'; +export type { PagedContentTreeItemResponseModel } from './models/PagedContentTreeItemResponseModel'; +export type { PagedCultureReponseModel } from './models/PagedCultureReponseModel'; +export type { PagedDictionaryOverviewResponseModel } from './models/PagedDictionaryOverviewResponseModel'; +export type { PagedDocumentBlueprintTreeItemResponseModel } from './models/PagedDocumentBlueprintTreeItemResponseModel'; +export type { PagedDocumentTreeItemResponseModel } from './models/PagedDocumentTreeItemResponseModel'; +export type { PagedDocumentTypeTreeItemResponseModel } from './models/PagedDocumentTypeTreeItemResponseModel'; +export type { PagedEntityTreeItemResponseModel } from './models/PagedEntityTreeItemResponseModel'; +export type { PagedFileSystemTreeItemPresentationModel } from './models/PagedFileSystemTreeItemPresentationModel'; +export type { PagedFolderTreeItemResponseModel } from './models/PagedFolderTreeItemResponseModel'; +export type { PagedHealthCheckGroupResponseModel } from './models/PagedHealthCheckGroupResponseModel'; +export type { PagedHelpPageResponseModel } from './models/PagedHelpPageResponseModel'; +export type { PagedIndexResponseModel } from './models/PagedIndexResponseModel'; +export type { PagedLanguageResponseModel } from './models/PagedLanguageResponseModel'; +export type { PagedLoggerResponseModel } from './models/PagedLoggerResponseModel'; +export type { PagedLogMessageResponseModel } from './models/PagedLogMessageResponseModel'; +export type { PagedLogTemplateResponseModel } from './models/PagedLogTemplateResponseModel'; +export type { PagedObjectTypeResponseModel } from './models/PagedObjectTypeResponseModel'; +export type { PagedPackageDefinitionResponseModel } from './models/PagedPackageDefinitionResponseModel'; +export type { PagedPackageMigrationStatusResponseModel } from './models/PagedPackageMigrationStatusResponseModel'; +export type { PagedRecycleBinItemResponseModel } from './models/PagedRecycleBinItemResponseModel'; +export type { PagedRedirectUrlResponseModel } from './models/PagedRedirectUrlResponseModel'; +export type { PagedRelationItemResponseModel } from './models/PagedRelationItemResponseModel'; +export type { PagedRelationResponseModel } from './models/PagedRelationResponseModel'; +export type { PagedSavedLogSearchResponseModel } from './models/PagedSavedLogSearchResponseModel'; +export type { PagedSearcherResponseModel } from './models/PagedSearcherResponseModel'; +export type { PagedSearchResultResponseModel } from './models/PagedSearchResultResponseModel'; +export type { PagedTelemetryResponseModel } from './models/PagedTelemetryResponseModel'; +export type { PagedUserGroupPresentationModel } from './models/PagedUserGroupPresentationModel'; +export type { PagedUserResponseModel } from './models/PagedUserResponseModel'; +export type { PartialViewItemResponseModel } from './models/PartialViewItemResponseModel'; export type { ProblemDetailsModel } from './models/ProblemDetailsModel'; -export type { ProfilingStatusModel } from './models/ProfilingStatusModel'; +export type { ProfilingStatusRequestModel } from './models/ProfilingStatusRequestModel'; +export type { ProfilingStatusResponseModel } from './models/ProfilingStatusResponseModel'; export type { PropertyTypeAppearanceModel } from './models/PropertyTypeAppearanceModel'; -export type { PropertyTypeContainerViewModelBaseModel } from './models/PropertyTypeContainerViewModelBaseModel'; +export type { PropertyTypeContainerResponseModelBaseModel } from './models/PropertyTypeContainerResponseModelBaseModel'; +export type { PropertyTypeResponseModelBaseModel } from './models/PropertyTypeResponseModelBaseModel'; export type { PropertyTypeValidationModel } from './models/PropertyTypeValidationModel'; -export type { PropertyTypeViewModelBaseModel } from './models/PropertyTypeViewModelBaseModel'; -export type { RecycleBinItemModel } from './models/RecycleBinItemModel'; +export type { RecycleBinItemResponseModel } from './models/RecycleBinItemResponseModel'; export { RedirectStatusModel } from './models/RedirectStatusModel'; -export type { RedirectUrlModel } from './models/RedirectUrlModel'; -export type { RedirectUrlStatusModel } from './models/RedirectUrlStatusModel'; -export type { RelationItemModel } from './models/RelationItemModel'; -export type { RelationModel } from './models/RelationModel'; +export type { RedirectUrlResponseModel } from './models/RedirectUrlResponseModel'; +export type { RedirectUrlStatusResponseModel } from './models/RedirectUrlStatusResponseModel'; +export type { RelationItemResponseModel } from './models/RelationItemResponseModel'; +export type { RelationResponseModel } from './models/RelationResponseModel'; +export type { RelationTypeBaseModel } from './models/RelationTypeBaseModel'; +export type { RelationTypeItemResponseModel } from './models/RelationTypeItemResponseModel'; +export type { RelationTypeResponseModel } from './models/RelationTypeResponseModel'; export { RuntimeLevelModel } from './models/RuntimeLevelModel'; -export type { SavedLogSearchModel } from './models/SavedLogSearchModel'; -export type { SearcherModel } from './models/SearcherModel'; -export type { SearchResultModel } from './models/SearchResultModel'; -export type { ServerStatusModel } from './models/ServerStatusModel'; +export type { SavedLogSearchPresenationBaseModel } from './models/SavedLogSearchPresenationBaseModel'; +export type { SavedLogSearchRequestModel } from './models/SavedLogSearchRequestModel'; +export type { SavedLogSearchResponseModel } from './models/SavedLogSearchResponseModel'; +export type { SaveUserGroupRequestModel } from './models/SaveUserGroupRequestModel'; +export type { ScriptItemResponseModel } from './models/ScriptItemResponseModel'; +export type { SearcherResponseModel } from './models/SearcherResponseModel'; +export type { SearchResultResponseModel } from './models/SearchResultResponseModel'; +export type { ServerStatusResponseModel } from './models/ServerStatusResponseModel'; +export type { SetAvatarRequestModel } from './models/SetAvatarRequestModel'; +export type { StaticFileItemResponseModel } from './models/StaticFileItemResponseModel'; export { StatusResultTypeModel } from './models/StatusResultTypeModel'; +export type { StylesheetItemResponseModel } from './models/StylesheetItemResponseModel'; export { TelemetryLevelModel } from './models/TelemetryLevelModel'; -export type { TelemetryModel } from './models/TelemetryModel'; -export type { TemplateCreateModel } from './models/TemplateCreateModel'; -export type { TemplateModel } from './models/TemplateModel'; +export type { TelemetryRepresentationBaseModel } from './models/TelemetryRepresentationBaseModel'; +export type { TelemetryRequestModel } from './models/TelemetryRequestModel'; +export type { TelemetryResponseModel } from './models/TelemetryResponseModel'; +export type { TemplateItemResponseModel } from './models/TemplateItemResponseModel'; export type { TemplateModelBaseModel } from './models/TemplateModelBaseModel'; -export type { TemplateQueryExecuteFilterModel } from './models/TemplateQueryExecuteFilterModel'; +export type { TemplateQueryExecuteFilterPresentationModel } from './models/TemplateQueryExecuteFilterPresentationModel'; export type { TemplateQueryExecuteModel } from './models/TemplateQueryExecuteModel'; export type { TemplateQueryExecuteSortModel } from './models/TemplateQueryExecuteSortModel'; export type { TemplateQueryOperatorModel } from './models/TemplateQueryOperatorModel'; -export type { TemplateQueryPropertyModel } from './models/TemplateQueryPropertyModel'; +export type { TemplateQueryPropertyPresentationModel } from './models/TemplateQueryPropertyPresentationModel'; export { TemplateQueryPropertyTypeModel } from './models/TemplateQueryPropertyTypeModel'; -export type { TemplateQueryResultItemModel } from './models/TemplateQueryResultItemModel'; -export type { TemplateQueryResultModel } from './models/TemplateQueryResultModel'; -export type { TemplateQuerySettingsModel } from './models/TemplateQuerySettingsModel'; -export type { TemplateScaffoldModel } from './models/TemplateScaffoldModel'; -export type { TemplateUpdateModel } from './models/TemplateUpdateModel'; -export type { TreeItemModel } from './models/TreeItemModel'; -export type { UpgradeSettingsModel } from './models/UpgradeSettingsModel'; +export type { TemplateQueryResultItemPresentationModel } from './models/TemplateQueryResultItemPresentationModel'; +export type { TemplateQueryResultResponseModel } from './models/TemplateQueryResultResponseModel'; +export type { TemplateQuerySettingsResponseModel } from './models/TemplateQuerySettingsResponseModel'; +export type { TemplateResponseModel } from './models/TemplateResponseModel'; +export type { TemplateScaffoldResponseModel } from './models/TemplateScaffoldResponseModel'; +export type { TemporaryFileResponseModel } from './models/TemporaryFileResponseModel'; +export type { TreeItemPresentationModel } from './models/TreeItemPresentationModel'; +export type { UnlockUsersRequestModel } from './models/UnlockUsersRequestModel'; +export type { UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel } from './models/UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel'; +export type { UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel } from './models/UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel'; +export type { UpdateDataTypeRequestModel } from './models/UpdateDataTypeRequestModel'; +export type { UpdateDictionaryItemRequestModel } from './models/UpdateDictionaryItemRequestModel'; +export type { UpdateDocumentNotificationsRequestModel } from './models/UpdateDocumentNotificationsRequestModel'; +export type { UpdateDocumentRequestModel } from './models/UpdateDocumentRequestModel'; +export type { UpdateDomainsRequestModel } from './models/UpdateDomainsRequestModel'; +export type { UpdateFolderReponseModel } from './models/UpdateFolderReponseModel'; +export type { UpdateLanguageRequestModel } from './models/UpdateLanguageRequestModel'; +export type { UpdateMediaRequestModel } from './models/UpdateMediaRequestModel'; +export type { UpdatePackageRequestModel } from './models/UpdatePackageRequestModel'; +export type { UpdateRelationTypeRequestModel } from './models/UpdateRelationTypeRequestModel'; +export type { UpdateTemplateRequestModel } from './models/UpdateTemplateRequestModel'; +export type { UpdateUserGroupRequestModel } from './models/UpdateUserGroupRequestModel'; +export type { UpdateUserGroupsOnUserRequestModel } from './models/UpdateUserGroupsOnUserRequestModel'; +export type { UpdateUserRequestModel } from './models/UpdateUserRequestModel'; +export type { UpgradeSettingsResponseModel } from './models/UpgradeSettingsResponseModel'; export type { UserGroupBaseModel } from './models/UserGroupBaseModel'; -export type { UserGroupModel } from './models/UserGroupModel'; -export type { UserGroupSaveModel } from './models/UserGroupSaveModel'; -export type { UserGroupUpdateModel } from './models/UserGroupUpdateModel'; -export type { UserInstallModel } from './models/UserInstallModel'; +export type { UserGroupPresentationModel } from './models/UserGroupPresentationModel'; +export type { UserInstallResponseModel } from './models/UserInstallResponseModel'; +export { UserOrderModel } from './models/UserOrderModel'; +export type { UserPresentationBaseModel } from './models/UserPresentationBaseModel'; +export type { UserResponseModel } from './models/UserResponseModel'; export type { UserSettingsModel } from './models/UserSettingsModel'; -export type { ValueViewModelBaseModel } from './models/ValueViewModelBaseModel'; -export type { VariantViewModelBaseModel } from './models/VariantViewModelBaseModel'; -export type { VersionModel } from './models/VersionModel'; +export { UserStateModel } from './models/UserStateModel'; +export type { ValueModelBaseModel } from './models/ValueModelBaseModel'; +export type { VariantModelBaseModel } from './models/VariantModelBaseModel'; +export type { VariantResponseModelBaseModel } from './models/VariantResponseModelBaseModel'; +export type { VersionResponseModel } from './models/VersionResponseModel'; export { AuditLogResource } from './services/AuditLogResource'; export { CultureResource } from './services/CultureResource'; @@ -188,6 +255,7 @@ export { MediaTypeResource } from './services/MediaTypeResource'; export { MemberGroupResource } from './services/MemberGroupResource'; export { MemberTypeResource } from './services/MemberTypeResource'; export { ModelsBuilderResource } from './services/ModelsBuilderResource'; +export { ObjectTypesResource } from './services/ObjectTypesResource'; export { PackageResource } from './services/PackageResource'; export { PartialViewResource } from './services/PartialViewResource'; export { ProfilingResource } from './services/ProfilingResource'; @@ -203,6 +271,9 @@ export { StaticFileResource } from './services/StaticFileResource'; export { StylesheetResource } from './services/StylesheetResource'; export { TelemetryResource } from './services/TelemetryResource'; export { TemplateResource } from './services/TemplateResource'; +export { TemporaryFileResource } from './services/TemporaryFileResource'; export { TrackedReferenceResource } from './services/TrackedReferenceResource'; export { UpgradeResource } from './services/UpgradeResource'; export { UserGroupsResource } from './services/UserGroupsResource'; +export { UsersResource } from './services/UsersResource'; +export { V1Resource } from './services/V1Resource'; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/AuditLogBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/AuditLogBaseModel.ts index 8da67f825a..92a6024151 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/AuditLogBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/AuditLogBaseModel.ts @@ -5,8 +5,8 @@ import type { AuditTypeModel } from './AuditTypeModel'; export type AuditLogBaseModel = { - userKey?: string; - entityKey?: string | null; + userId?: string; + entityId?: string | null; timestamp?: string; logType?: AuditTypeModel; entityType?: string | null; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ChangePasswordUserRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ChangePasswordUserRequestModel.ts new file mode 100644 index 0000000000..450bc06538 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ChangePasswordUserRequestModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type ChangePasswordUserRequestModel = { + newPassword?: string; + oldPassword?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ConsentLevelModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ConsentLevelPresentationModel.ts similarity index 81% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ConsentLevelModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ConsentLevelPresentationModel.ts index 713ad10919..b9a1283ad5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ConsentLevelModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ConsentLevelPresentationModel.ts @@ -4,7 +4,7 @@ import type { TelemetryLevelModel } from './TelemetryLevelModel'; -export type ConsentLevelModel = { +export type ConsentLevelPresentationModel = { level?: TelemetryLevelModel; description?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel.ts new file mode 100644 index 0000000000..7ad34d5e3e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel.ts @@ -0,0 +1,14 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DocumentValueModel } from './DocumentValueModel'; +import type { DocumentVariantResponseModel } from './DocumentVariantResponseModel'; + +export type ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel = { + values?: Array; + variants?: Array; + id?: string; + contentTypeId?: string; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTreeItemModel.ts deleted file mode 100644 index 2144bc6a1f..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTreeItemModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EntityTreeItemModel } from './EntityTreeItemModel'; - -export type ContentTreeItemModel = (EntityTreeItemModel & { - $type: string; - noAccess?: boolean; - isTrashed?: boolean; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTreeItemResponseModel.ts new file mode 100644 index 0000000000..630fb6ae84 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTreeItemResponseModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { EntityTreeItemResponseModel } from './EntityTreeItemResponseModel'; + +export type ContentTreeItemResponseModel = (EntityTreeItemResponseModel & { + $type: string; + noAccess?: boolean; + isTrashed?: boolean; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeCompositionModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeCompositionModel.ts index eefcd22a19..d704a9fcf9 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeCompositionModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeCompositionModel.ts @@ -5,7 +5,7 @@ import type { ContentTypeCompositionTypeModel } from './ContentTypeCompositionTypeModel'; export type ContentTypeCompositionModel = { - key?: string; + id?: string; compositionType?: ContentTypeCompositionTypeModel; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel.ts new file mode 100644 index 0000000000..8427bc56c6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel.ts @@ -0,0 +1,25 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContentTypeCompositionModel } from './ContentTypeCompositionModel'; +import type { ContentTypeSortModel } from './ContentTypeSortModel'; +import type { DocumentTypePropertyTypeContainerResponseModel } from './DocumentTypePropertyTypeContainerResponseModel'; +import type { DocumentTypePropertyTypeResponseModel } from './DocumentTypePropertyTypeResponseModel'; + +export type ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel = { + id?: string; + alias?: string; + name?: string; + description?: string | null; + icon?: string; + allowedAsRoot?: boolean; + variesByCulture?: boolean; + variesBySegment?: boolean; + isElement?: boolean; + properties?: Array; + containers?: Array; + allowedContentTypes?: Array; + compositions?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel.ts new file mode 100644 index 0000000000..c8285cef7b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel.ts @@ -0,0 +1,25 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContentTypeCompositionModel } from './ContentTypeCompositionModel'; +import type { ContentTypeSortModel } from './ContentTypeSortModel'; +import type { MediaTypePropertyTypeContainerResponseModel } from './MediaTypePropertyTypeContainerResponseModel'; +import type { MediaTypePropertyTypeResponseModel } from './MediaTypePropertyTypeResponseModel'; + +export type ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel = { + id?: string; + alias?: string; + name?: string; + description?: string | null; + icon?: string; + allowedAsRoot?: boolean; + variesByCulture?: boolean; + variesBySegment?: boolean; + isElement?: boolean; + properties?: Array; + containers?: Array; + allowedContentTypes?: Array; + compositions?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeSortModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeSortModel.ts index 63b6a44a11..02c537079a 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeSortModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeSortModel.ts @@ -3,7 +3,7 @@ /* eslint-disable */ export type ContentTypeSortModel = { - key?: string; + id?: string; sortOrder?: number; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel.ts deleted file mode 100644 index f4edc901a6..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ContentTypeCleanupModel } from './ContentTypeCleanupModel'; -import type { ContentTypeCompositionModel } from './ContentTypeCompositionModel'; -import type { ContentTypeSortModel } from './ContentTypeSortModel'; -import type { DocumentTypePropertyTypeContainerModel } from './DocumentTypePropertyTypeContainerModel'; -import type { DocumentTypePropertyTypeModel } from './DocumentTypePropertyTypeModel'; - -export type ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel = { - key?: string; - alias?: string; - name?: string; - description?: string | null; - icon?: string; - allowedAsRoot?: boolean; - variesByCulture?: boolean; - variesBySegment?: boolean; - isElement?: boolean; - properties?: Array; - containers?: Array; - allowedContentTypes?: Array; - compositions?: Array; - cleanup?: ContentTypeCleanupModel; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentViewModelBaseDocumentValueDocumentVariantModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentViewModelBaseDocumentValueDocumentVariantModel.ts deleted file mode 100644 index 4f95f27cbe..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ContentViewModelBaseDocumentValueDocumentVariantModel.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DocumentValueModel } from './DocumentValueModel'; -import type { DocumentVariantModel } from './DocumentVariantModel'; - -export type ContentViewModelBaseDocumentValueDocumentVariantModel = { - key?: string; - contentTypeKey?: string; - values?: Array; - variants?: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CopyDataTypeRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CopyDataTypeRequestModel.ts new file mode 100644 index 0000000000..eb76506716 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CopyDataTypeRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type CopyDataTypeRequestModel = { + targetId?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel.ts new file mode 100644 index 0000000000..bb5147ecc2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DocumentValueModel } from './DocumentValueModel'; +import type { DocumentVariantRequestModel } from './DocumentVariantRequestModel'; + +export type CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel = { + values?: Array; + variants?: Array; + parentId?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel.ts new file mode 100644 index 0000000000..3a0e270428 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { MediaValueModel } from './MediaValueModel'; +import type { MediaVariantRequestModel } from './MediaVariantRequestModel'; + +export type CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel = { + values?: Array; + variants?: Array; + parentId?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeCreateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDataTypeRequestModel.ts similarity index 54% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeCreateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDataTypeRequestModel.ts index 0c686d4136..a3b6c50157 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeCreateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDataTypeRequestModel.ts @@ -4,7 +4,8 @@ import type { DataTypeModelBaseModel } from './DataTypeModelBaseModel'; -export type DataTypeCreateModel = (DataTypeModelBaseModel & { - parentKey?: string | null; +export type CreateDataTypeRequestModel = (DataTypeModelBaseModel & { + id?: string | null; + parentId?: string | null; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemCreateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDictionaryItemRequestModel.ts similarity index 59% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemCreateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDictionaryItemRequestModel.ts index 211bed9e4f..95b723fb43 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemCreateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDictionaryItemRequestModel.ts @@ -4,7 +4,7 @@ import type { DictionaryItemModelBaseModel } from './DictionaryItemModelBaseModel'; -export type DictionaryItemCreateModel = (DictionaryItemModelBaseModel & { - parentKey?: string | null; +export type CreateDictionaryItemRequestModel = (DictionaryItemModelBaseModel & { + parentId?: string | null; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDocumentRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDocumentRequestModel.ts new file mode 100644 index 0000000000..645d204832 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateDocumentRequestModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel } from './CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel'; + +export type CreateDocumentRequestModel = (CreateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel & { + contentTypeId?: string; + templateId?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderCreateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateFolderRequestModel.ts similarity index 54% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderCreateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateFolderRequestModel.ts index 1ae49bc7fa..e4af10670e 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderCreateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateFolderRequestModel.ts @@ -4,7 +4,8 @@ import type { FolderModelBaseModel } from './FolderModelBaseModel'; -export type FolderCreateModel = (FolderModelBaseModel & { - parentKey?: string | null; +export type CreateFolderRequestModel = (FolderModelBaseModel & { + id?: string | null; + parentId?: string | null; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateLanguageRequestModel.ts similarity index 71% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateLanguageRequestModel.ts index cba035758b..16326ad62f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateLanguageRequestModel.ts @@ -4,7 +4,7 @@ import type { LanguageModelBaseModel } from './LanguageModelBaseModel'; -export type LanguageModel = (LanguageModelBaseModel & { +export type CreateLanguageRequestModel = (LanguageModelBaseModel & { isoCode?: string; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateMediaRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateMediaRequestModel.ts new file mode 100644 index 0000000000..723fe2ecfc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateMediaRequestModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel } from './CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel'; + +export type CreateMediaRequestModel = (CreateContentRequestModelBaseMediaValueModelMediaVariantRequestModel & { + contentTypeId?: string; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageCreateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreatePackageRequestModel.ts similarity index 69% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageCreateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreatePackageRequestModel.ts index 4061ed4560..a88367acca 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageCreateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreatePackageRequestModel.ts @@ -4,5 +4,5 @@ import type { PackageModelBaseModel } from './PackageModelBaseModel'; -export type PackageCreateModel = PackageModelBaseModel; +export type CreatePackageRequestModel = PackageModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateRelationTypeRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateRelationTypeRequestModel.ts new file mode 100644 index 0000000000..fb75ae7736 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateRelationTypeRequestModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RelationTypeBaseModel } from './RelationTypeBaseModel'; + +export type CreateRelationTypeRequestModel = (RelationTypeBaseModel & { + id?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateUpdateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateTemplateRequestModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateUpdateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateTemplateRequestModel.ts index 64da7cb574..e5aa227ac5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateUpdateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateTemplateRequestModel.ts @@ -4,5 +4,5 @@ import type { TemplateModelBaseModel } from './TemplateModelBaseModel'; -export type TemplateUpdateModel = TemplateModelBaseModel; +export type CreateTemplateRequestModel = TemplateModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateUserRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateUserRequestModel.ts new file mode 100644 index 0000000000..0166c949fa --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateUserRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UserPresentationBaseModel } from './UserPresentationBaseModel'; + +export type CreateUserRequestModel = UserPresentationBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateUserResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateUserResponseModel.ts new file mode 100644 index 0000000000..0d3678436e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CreateUserResponseModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type CreateUserResponseModel = { + userId?: string; + initialPassword?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CultureModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CultureReponseModel.ts similarity index 76% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CultureModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CultureReponseModel.ts index 8a6836bd00..cf18c8883e 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CultureModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/CultureReponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type CultureModel = { +export type CultureReponseModel = { name?: string; englishName?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeItemResponseModel.ts new file mode 100644 index 0000000000..e277363f47 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeItemResponseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type DataTypeItemResponseModel = (ItemResponseModelBaseModel & { + icon?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeModelBaseModel.ts index 85a98bebfb..c7fa61f661 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeModelBaseModel.ts @@ -2,12 +2,12 @@ /* tslint:disable */ /* eslint-disable */ -import type { DataTypePropertyModel } from './DataTypePropertyModel'; +import type { DataTypePropertyPresentationModel } from './DataTypePropertyPresentationModel'; export type DataTypeModelBaseModel = { name?: string; propertyEditorAlias?: string; propertyEditorUiAlias?: string | null; - data?: Array; + values?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypePropertyModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypePropertyPresentationModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypePropertyModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypePropertyPresentationModel.ts index 89e844f606..30bcddd9a3 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypePropertyModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypePropertyPresentationModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type DataTypePropertyModel = { +export type DataTypePropertyPresentationModel = { alias?: string; value?: any; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeReferenceModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeReferenceResponseModel.ts similarity index 78% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeReferenceModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeReferenceResponseModel.ts index fef54b8bec..9855622b89 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeReferenceModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeReferenceResponseModel.ts @@ -4,8 +4,8 @@ import type { DataTypePropertyReferenceModel } from './DataTypePropertyReferenceModel'; -export type DataTypeReferenceModel = { - key?: string; +export type DataTypeReferenceResponseModel = { + id?: string; type?: string; properties?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeResponseModel.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeResponseModel.ts index 18401c998f..ed9934a1b5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeResponseModel.ts @@ -4,9 +4,8 @@ import type { DataTypeModelBaseModel } from './DataTypeModelBaseModel'; -export type DataTypeModel = (DataTypeModelBaseModel & { - $type: string; - key?: string; - parentKey?: string | null; -}); - +export type DataTypeResponseModel = DataTypeModelBaseModel & { + $type: string; + id?: string; + parentId?: string | null; +}; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseInstallModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseInstallResponseModel.ts similarity index 87% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseInstallModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseInstallResponseModel.ts index fca252ff44..233df53325 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseInstallModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseInstallResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type DatabaseInstallModel = { +export type DatabaseInstallResponseModel = { id: string; providerName: string; server?: string | null; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseSettingsModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseSettingsPresentationModel.ts similarity index 89% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseSettingsModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseSettingsPresentationModel.ts index 1dd2cfcf83..8046700e30 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseSettingsModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DatabaseSettingsPresentationModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type DatabaseSettingsModel = { +export type DatabaseSettingsPresentationModel = { id?: string; sortOrder?: number; displayName?: string; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemItemResponseModel.ts new file mode 100644 index 0000000000..bcc5a02867 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemItemResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type DictionaryItemItemResponseModel = ItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemResponseModel.ts similarity index 65% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemResponseModel.ts index 22e1edb1e3..f5da8949f1 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemResponseModel.ts @@ -4,8 +4,8 @@ import type { DictionaryItemModelBaseModel } from './DictionaryItemModelBaseModel'; -export type DictionaryItemModel = (DictionaryItemModelBaseModel & { +export type DictionaryItemResponseModel = (DictionaryItemModelBaseModel & { $type: string; - key?: string; + id?: string; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryOverviewModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryOverviewResponseModel.ts similarity index 59% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryOverviewModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryOverviewResponseModel.ts index 9955664ba7..abc3190425 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryOverviewModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryOverviewResponseModel.ts @@ -2,10 +2,10 @@ /* tslint:disable */ /* eslint-disable */ -export type DictionaryOverviewModel = { +export type DictionaryOverviewResponseModel = { name?: string | null; - key?: string; - parentKey?: string | null; + id?: string; + parentId?: string | null; translatedIsoCodes?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryUploadModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryUploadModel.ts deleted file mode 100644 index b8191ffc6d..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryUploadModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DictionaryItemsImportModel } from './DictionaryItemsImportModel'; - -export type DictionaryUploadModel = { - dictionaryItems?: Array; - fileName?: string | null; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeCopyModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DisableUserRequestModel.ts similarity index 51% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeCopyModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DisableUserRequestModel.ts index 163d127437..1074d06b75 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeCopyModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DisableUserRequestModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type DataTypeCopyModel = { - targetKey?: string | null; +export type DisableUserRequestModel = { + userIds?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintResponseModel.ts new file mode 100644 index 0000000000..fd6b735c5b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type DocumentBlueprintResponseModel = ItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintTreeItemModel.ts deleted file mode 100644 index f2a937ba4e..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintTreeItemModel.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EntityTreeItemModel } from './EntityTreeItemModel'; - -export type DocumentBlueprintTreeItemModel = (EntityTreeItemModel & { - $type: string; - documentTypeKey?: string; - documentTypeAlias?: string; - documentTypeName?: string | null; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintTreeItemResponseModel.ts new file mode 100644 index 0000000000..0dc6c99953 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentBlueprintTreeItemResponseModel.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { EntityTreeItemResponseModel } from './EntityTreeItemResponseModel'; + +export type DocumentBlueprintTreeItemResponseModel = (EntityTreeItemResponseModel & { + $type: string; + documentTypeId?: string; + documentTypeAlias?: string; + documentTypeName?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentItemResponseModel.ts new file mode 100644 index 0000000000..3bf495dc8d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentItemResponseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type DocumentItemResponseModel = (ItemResponseModelBaseModel & { + icon?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentModel.ts deleted file mode 100644 index dd0c6f24d0..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ContentUrlInfoModel } from './ContentUrlInfoModel'; -import type { ContentViewModelBaseDocumentValueDocumentVariantModel } from './ContentViewModelBaseDocumentValueDocumentVariantModel'; - -export type DocumentModel = (ContentViewModelBaseDocumentValueDocumentVariantModel & { - urls?: Array; - templateKey?: string | null; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentNotificationResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentNotificationResponseModel.ts new file mode 100644 index 0000000000..e898c96eda --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentNotificationResponseModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type DocumentNotificationResponseModel = { + actionId?: string; + subscribed?: boolean; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentResponseModel.ts new file mode 100644 index 0000000000..ce053d9297 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentResponseModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel } from './ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel'; +import type { ContentUrlInfoModel } from './ContentUrlInfoModel'; + +export type DocumentResponseModel = (ContentResponseModelBaseDocumentValueModelDocumentVariantResponseModel & { + urls?: Array; + templateId?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTreeItemResponseModel.ts similarity index 51% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTreeItemModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTreeItemResponseModel.ts index 0376baedf3..d9d187c704 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTreeItemModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTreeItemResponseModel.ts @@ -2,9 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -import type { ContentTreeItemModel } from './ContentTreeItemModel'; +import type { ContentTreeItemResponseModel } from './ContentTreeItemResponseModel'; -export type DocumentTreeItemModel = (ContentTreeItemModel & { +export type DocumentTreeItemResponseModel = (ContentTreeItemResponseModel & { $type: string; isProtected?: boolean; isPublished?: boolean; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeItemResponseModel.ts new file mode 100644 index 0000000000..f085ce11bc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type DocumentTypeItemResponseModel = (ItemResponseModelBaseModel & { + isElement?: boolean; + icon?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeModel.ts deleted file mode 100644 index 6885b3e0c3..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel } from './ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel'; - -export type DocumentTypeModel = (ContentTypeViewModelBaseDocumentTypePropertyTypeDocumentTypePropertyTypeContainerModel & { - allowedTemplateKeys?: Array; - defaultTemplateKey?: string | null; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeContainerModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeContainerModel.ts deleted file mode 100644 index 69737e93e0..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeContainerModel.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { PropertyTypeContainerViewModelBaseModel } from './PropertyTypeContainerViewModelBaseModel'; - -export type DocumentTypePropertyTypeContainerModel = PropertyTypeContainerViewModelBaseModel; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeContainerResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeContainerResponseModel.ts new file mode 100644 index 0000000000..83aa9e6459 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeContainerResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { PropertyTypeContainerResponseModelBaseModel } from './PropertyTypeContainerResponseModelBaseModel'; + +export type DocumentTypePropertyTypeContainerResponseModel = PropertyTypeContainerResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeModel.ts deleted file mode 100644 index 6fa071b539..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeModel.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { PropertyTypeViewModelBaseModel } from './PropertyTypeViewModelBaseModel'; - -export type DocumentTypePropertyTypeModel = PropertyTypeViewModelBaseModel; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeResponseModel.ts new file mode 100644 index 0000000000..c74873bb1b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypePropertyTypeResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { PropertyTypeResponseModelBaseModel } from './PropertyTypeResponseModelBaseModel'; + +export type DocumentTypePropertyTypeResponseModel = PropertyTypeResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeResponseModel.ts new file mode 100644 index 0000000000..8712b46d1f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeResponseModel.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContentTypeCleanupModel } from './ContentTypeCleanupModel'; +import type { ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel } from './ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel'; + +export type DocumentTypeResponseModel = (ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel & { + allowedTemplateIds?: Array; + defaultTemplateId?: string | null; + cleanup?: ContentTypeCleanupModel; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeTreeItemModel.ts deleted file mode 100644 index 13f61975bb..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeTreeItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { FolderTreeItemModel } from './FolderTreeItemModel'; - -export type DocumentTypeTreeItemModel = (FolderTreeItemModel & { - $type: string; - isElement?: boolean; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeTreeItemResponseModel.ts new file mode 100644 index 0000000000..d211b01020 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentTypeTreeItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FolderTreeItemResponseModel } from './FolderTreeItemResponseModel'; + +export type DocumentTypeTreeItemResponseModel = (FolderTreeItemResponseModel & { + $type: string; + isElement?: boolean; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentValueModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentValueModel.ts index da3e425d98..497bb7255a 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentValueModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentValueModel.ts @@ -2,7 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -import type { ValueViewModelBaseModel } from './ValueViewModelBaseModel'; +import type { ValueModelBaseModel } from './ValueModelBaseModel'; -export type DocumentValueModel = ValueViewModelBaseModel; +export type DocumentValueModel = (ValueModelBaseModel & { + $type: string; +}); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantRequestModel.ts new file mode 100644 index 0000000000..8377863391 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantRequestModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { VariantModelBaseModel } from './VariantModelBaseModel'; + +export type DocumentVariantRequestModel = (VariantModelBaseModel & { + $type: string; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantResponseModel.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantResponseModel.ts index b2d7431caa..2c19f50dd9 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DocumentVariantResponseModel.ts @@ -3,9 +3,10 @@ /* eslint-disable */ import type { ContentStateModel } from './ContentStateModel'; -import type { VariantViewModelBaseModel } from './VariantViewModelBaseModel'; +import type { VariantResponseModelBaseModel } from './VariantResponseModelBaseModel'; -export type DocumentVariantModel = (VariantViewModelBaseModel & { +export type DocumentVariantResponseModel = (VariantResponseModelBaseModel & { + $type: string; state?: ContentStateModel; publishDate?: string | null; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainPresentationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainPresentationModel.ts new file mode 100644 index 0000000000..237c3037f4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainPresentationModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type DomainPresentationModel = { + domainName?: string; + isoCode?: string; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainsPresentationModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainsPresentationModelBaseModel.ts new file mode 100644 index 0000000000..597b473ad7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainsPresentationModelBaseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DomainPresentationModel } from './DomainPresentationModel'; + +export type DomainsPresentationModelBaseModel = { + defaultIsoCode?: string | null; + domains?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainsResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainsResponseModel.ts new file mode 100644 index 0000000000..aeec02fb3d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DomainsResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DomainsPresentationModelBaseModel } from './DomainsPresentationModelBaseModel'; + +export type DomainsResponseModel = DomainsPresentationModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryMoveModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EnableUserRequestModel.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryMoveModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EnableUserRequestModel.ts index c58b2262a1..6230b2469f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryMoveModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EnableUserRequestModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type DictionaryMoveModel = { - targetKey?: string | null; +export type EnableUserRequestModel = { + userIds?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EntityTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EntityTreeItemModel.ts deleted file mode 100644 index 9dd2539305..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EntityTreeItemModel.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { TreeItemModel } from './TreeItemModel'; - -export type EntityTreeItemModel = (TreeItemModel & { - $type: string; - key?: string; - isContainer?: boolean; - parentKey?: string | null; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EntityTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EntityTreeItemResponseModel.ts new file mode 100644 index 0000000000..6cff369186 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/EntityTreeItemResponseModel.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { TreeItemPresentationModel } from './TreeItemPresentationModel'; + +export type EntityTreeItemResponseModel = (TreeItemPresentationModel & { + $type: string; + id?: string; + isContainer?: boolean; + parentId?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FieldModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FieldPresentationModel.ts similarity index 75% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FieldModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FieldPresentationModel.ts index 0ef3d38779..73dd10d3b0 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FieldModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FieldPresentationModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type FieldModel = { +export type FieldPresentationModel = { name?: string; values?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileItemResponseModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileItemResponseModelBaseModel.ts new file mode 100644 index 0000000000..6867fcab7f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileItemResponseModelBaseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type FileItemResponseModelBaseModel = { + name?: string; + path?: string; + icon?: string; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileSystemTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileSystemTreeItemModel.ts deleted file mode 100644 index 970c0ef60f..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileSystemTreeItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { TreeItemModel } from './TreeItemModel'; - -export type FileSystemTreeItemModel = (TreeItemModel & { - path?: string; - isFolder?: boolean; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileSystemTreeItemPresentationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileSystemTreeItemPresentationModel.ts new file mode 100644 index 0000000000..9b82bc2e4a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FileSystemTreeItemPresentationModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { TreeItemPresentationModel } from './TreeItemPresentationModel'; + +export type FileSystemTreeItemPresentationModel = (TreeItemPresentationModel & { + path?: string; + isFolder?: boolean; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderReponseModel.ts similarity index 60% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderReponseModel.ts index ab789bb8eb..dede400904 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderReponseModel.ts @@ -4,9 +4,9 @@ import type { FolderModelBaseModel } from './FolderModelBaseModel'; -export type FolderModel = (FolderModelBaseModel & { +export type FolderReponseModel = (FolderModelBaseModel & { $type: string; - key?: string; - parentKey?: string | null; + id?: string; + parentId?: string | null; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderTreeItemModel.ts deleted file mode 100644 index 618a10ba2f..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderTreeItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { EntityTreeItemModel } from './EntityTreeItemModel'; - -export type FolderTreeItemModel = (EntityTreeItemModel & { - $type: string; - isFolder?: boolean; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderTreeItemResponseModel.ts new file mode 100644 index 0000000000..207186fdc1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderTreeItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { EntityTreeItemResponseModel } from './EntityTreeItemResponseModel'; + +export type FolderTreeItemResponseModel = (EntityTreeItemResponseModel & { + $type: string; + isFolder?: boolean; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckActionModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckActionRequestModel.ts similarity index 81% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckActionModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckActionRequestModel.ts index 82f2cd7448..05f50ef3c6 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckActionModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckActionRequestModel.ts @@ -2,8 +2,8 @@ /* tslint:disable */ /* eslint-disable */ -export type HealthCheckActionModel = { - healthCheckKey?: string; +export type HealthCheckActionRequestModel = { + healthCheckId?: string; alias?: string | null; name?: string | null; description?: string | null; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupModel.ts deleted file mode 100644 index 7f452c35ed..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HealthCheckGroupModelBaseModel } from './HealthCheckGroupModelBaseModel'; -import type { HealthCheckModel } from './HealthCheckModel'; - -export type HealthCheckGroupModel = (HealthCheckGroupModelBaseModel & { - checks?: Array; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupPresentationBaseModel.ts similarity index 63% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupModelBaseModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupPresentationBaseModel.ts index e024867963..22073b3a22 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupPresentationBaseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type HealthCheckGroupModelBaseModel = { +export type HealthCheckGroupPresentationBaseModel = { name?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupPresentationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupPresentationModel.ts new file mode 100644 index 0000000000..8029327431 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupPresentationModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { HealthCheckGroupPresentationBaseModel } from './HealthCheckGroupPresentationBaseModel'; +import type { HealthCheckModel } from './HealthCheckModel'; + +export type HealthCheckGroupPresentationModel = (HealthCheckGroupPresentationBaseModel & { + checks?: Array; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupResponseModel.ts new file mode 100644 index 0000000000..46704d9f25 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { HealthCheckGroupPresentationBaseModel } from './HealthCheckGroupPresentationBaseModel'; + +export type HealthCheckGroupResponseModel = HealthCheckGroupPresentationBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupWithResultModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupWithResultModel.ts deleted file mode 100644 index 4fe58a6a10..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupWithResultModel.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HealthCheckWithResultModel } from './HealthCheckWithResultModel'; - -export type HealthCheckGroupWithResultModel = { - checks?: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupWithResultResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupWithResultResponseModel.ts new file mode 100644 index 0000000000..e3a7841939 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckGroupWithResultResponseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { HealthCheckWithResultPresentationModel } from './HealthCheckWithResultPresentationModel'; + +export type HealthCheckGroupWithResultResponseModel = { + checks?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckModelBaseModel.ts index 053af0b984..0cee4aca31 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckModelBaseModel.ts @@ -3,6 +3,6 @@ /* eslint-disable */ export type HealthCheckModelBaseModel = { - key?: string; + id?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckResultModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckResultResponseModel.ts similarity index 55% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckResultModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckResultResponseModel.ts index 4665a20f16..c0c237a43c 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckResultModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckResultResponseModel.ts @@ -2,13 +2,13 @@ /* tslint:disable */ /* eslint-disable */ -import type { HealthCheckActionModel } from './HealthCheckActionModel'; +import type { HealthCheckActionRequestModel } from './HealthCheckActionRequestModel'; import type { StatusResultTypeModel } from './StatusResultTypeModel'; -export type HealthCheckResultModel = { +export type HealthCheckResultResponseModel = { message?: string; resultType?: StatusResultTypeModel; - actions?: Array | null; + actions?: Array | null; readMoreLink?: string | null; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckWithResultModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckWithResultModel.ts deleted file mode 100644 index a75a4c52a8..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckWithResultModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HealthCheckModelBaseModel } from './HealthCheckModelBaseModel'; -import type { HealthCheckResultModel } from './HealthCheckResultModel'; - -export type HealthCheckWithResultModel = (HealthCheckModelBaseModel & { - results?: Array | null; -}); - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckWithResultPresentationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckWithResultPresentationModel.ts new file mode 100644 index 0000000000..5028107875 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HealthCheckWithResultPresentationModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { HealthCheckModelBaseModel } from './HealthCheckModelBaseModel'; +import type { HealthCheckResultResponseModel } from './HealthCheckResultResponseModel'; + +export type HealthCheckWithResultPresentationModel = (HealthCheckModelBaseModel & { + results?: Array | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HelpPageModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HelpPageResponseModel.ts similarity index 82% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HelpPageModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HelpPageResponseModel.ts index 7a56b0085e..a3cb83ead7 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HelpPageModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/HelpPageResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type HelpPageModel = { +export type HelpPageResponseModel = { name?: string | null; description?: string | null; url?: string | null; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ImportDictionaryRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ImportDictionaryRequestModel.ts new file mode 100644 index 0000000000..4e29abf47a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ImportDictionaryRequestModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type ImportDictionaryRequestModel = { + temporaryFileId?: string; + parentId?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/IndexModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/IndexResponseModel.ts similarity index 90% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/IndexModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/IndexResponseModel.ts index a9aec87082..68c87f9aa0 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/IndexModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/IndexResponseModel.ts @@ -4,7 +4,7 @@ import type { HealthStatusModel } from './HealthStatusModel'; -export type IndexModel = { +export type IndexResponseModel = { name: string; healthStatus?: HealthStatusModel; canRebuild: boolean; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallModel.ts deleted file mode 100644 index d1898faede..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallModel.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DatabaseInstallModel } from './DatabaseInstallModel'; -import type { TelemetryLevelModel } from './TelemetryLevelModel'; -import type { UserInstallModel } from './UserInstallModel'; - -export type InstallModel = { - user: UserInstallModel; - database: DatabaseInstallModel; - telemetryLevel?: TelemetryLevelModel; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallSettingsModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallSettingsModel.ts deleted file mode 100644 index b5b8065fdf..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallSettingsModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DatabaseSettingsModel } from './DatabaseSettingsModel'; -import type { UserSettingsModel } from './UserSettingsModel'; - -export type InstallSettingsModel = { - user?: UserSettingsModel; - databases?: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallSettingsResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallSettingsResponseModel.ts new file mode 100644 index 0000000000..100bb5b12f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallSettingsResponseModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DatabaseSettingsPresentationModel } from './DatabaseSettingsPresentationModel'; +import type { UserSettingsModel } from './UserSettingsModel'; + +export type InstallSettingsResponseModel = { + user?: UserSettingsModel; + databases?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallVResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallVResponseModel.ts new file mode 100644 index 0000000000..ada168bb74 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InstallVResponseModel.ts @@ -0,0 +1,14 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DatabaseInstallResponseModel } from './DatabaseInstallResponseModel'; +import type { TelemetryLevelModel } from './TelemetryLevelModel'; +import type { UserInstallResponseModel } from './UserInstallResponseModel'; + +export type InstallVResponseModel = { + user: UserInstallResponseModel; + database: DatabaseInstallResponseModel; + telemetryLevel?: TelemetryLevelModel; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InviteUserRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InviteUserRequestModel.ts new file mode 100644 index 0000000000..e0e7e9ad62 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/InviteUserRequestModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { CreateUserRequestModel } from './CreateUserRequestModel'; + +export type InviteUserRequestModel = (CreateUserRequestModel & { + message?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ItemResponseModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ItemResponseModelBaseModel.ts new file mode 100644 index 0000000000..486b5df6f8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ItemResponseModelBaseModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type ItemResponseModelBaseModel = { + name?: string; + id?: string; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageItemResponseModel.ts new file mode 100644 index 0000000000..f9a7e78419 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageItemResponseModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type LanguageItemResponseModel = { + name?: string; + isoCode?: string; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageCreateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageResponseModel.ts similarity index 72% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageCreateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageResponseModel.ts index 69149b0561..5d17bf3842 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageCreateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageResponseModel.ts @@ -4,7 +4,7 @@ import type { LanguageModelBaseModel } from './LanguageModelBaseModel'; -export type LanguageCreateModel = (LanguageModelBaseModel & { +export type LanguageResponseModel = (LanguageModelBaseModel & { isoCode?: string; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogLevelCountsModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogLevelCountsReponseModel.ts similarity index 80% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogLevelCountsModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogLevelCountsReponseModel.ts index 6fbb50efba..a1064cc7a4 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogLevelCountsModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogLevelCountsReponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type LogLevelCountsModel = { +export type LogLevelCountsReponseModel = { information?: number; debug?: number; warning?: number; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessagePropertyModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessagePropertyPresentationModel.ts similarity index 69% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessagePropertyModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessagePropertyPresentationModel.ts index 098e1d9228..dd9be7aa49 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessagePropertyModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessagePropertyPresentationModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type LogMessagePropertyModel = { +export type LogMessagePropertyPresentationModel = { name?: string; value?: string | null; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessageModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessageResponseModel.ts similarity index 58% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessageModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessageResponseModel.ts index 750fb168e8..ad67dd8483 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessageModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogMessageResponseModel.ts @@ -3,14 +3,14 @@ /* eslint-disable */ import type { LogLevelModel } from './LogLevelModel'; -import type { LogMessagePropertyModel } from './LogMessagePropertyModel'; +import type { LogMessagePropertyPresentationModel } from './LogMessagePropertyPresentationModel'; -export type LogMessageModel = { +export type LogMessageResponseModel = { timestamp?: string; level?: LogLevelModel; messageTemplate?: string | null; renderedMessage?: string | null; - properties?: Array; + properties?: Array; exception?: string | null; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogTemplateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogTemplateResponseModel.ts similarity index 76% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogTemplateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogTemplateResponseModel.ts index 30919c8239..1aeece3a0a 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogTemplateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LogTemplateResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type LogTemplateModel = { +export type LogTemplateResponseModel = { messageTemplate?: string | null; count?: number; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LoggerModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LoggerResponseModel.ts similarity index 82% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LoggerModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LoggerResponseModel.ts index 2eeedc8142..552470c462 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LoggerModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LoggerResponseModel.ts @@ -4,7 +4,7 @@ import type { LogLevelModel } from './LogLevelModel'; -export type LoggerModel = { +export type LoggerResponseModel = { name?: string; level?: LogLevelModel; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaItemResponseModel.ts new file mode 100644 index 0000000000..1b28cf9a1d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaItemResponseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type MediaItemResponseModel = (ItemResponseModelBaseModel & { + icon?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypeItemResponseModel.ts new file mode 100644 index 0000000000..536d0ce369 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypeItemResponseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type MediaTypeItemResponseModel = (ItemResponseModelBaseModel & { + icon?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypePropertyTypeContainerResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypePropertyTypeContainerResponseModel.ts new file mode 100644 index 0000000000..f8a0b7ba60 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypePropertyTypeContainerResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { PropertyTypeContainerResponseModelBaseModel } from './PropertyTypeContainerResponseModelBaseModel'; + +export type MediaTypePropertyTypeContainerResponseModel = PropertyTypeContainerResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypePropertyTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypePropertyTypeResponseModel.ts new file mode 100644 index 0000000000..a4d992c86a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypePropertyTypeResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { PropertyTypeResponseModelBaseModel } from './PropertyTypeResponseModelBaseModel'; + +export type MediaTypePropertyTypeResponseModel = PropertyTypeResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypeResponseModel.ts new file mode 100644 index 0000000000..71d255850e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaTypeResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel } from './ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel'; + +export type MediaTypeResponseModel = ContentTypeResponseModelBaseMediaTypePropertyTypeResponseModelMediaTypePropertyTypeContainerResponseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaValueModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaValueModel.ts new file mode 100644 index 0000000000..a8ba985e23 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaValueModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ValueModelBaseModel } from './ValueModelBaseModel'; + +export type MediaValueModel = (ValueModelBaseModel & { + $type: string; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaVariantRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaVariantRequestModel.ts new file mode 100644 index 0000000000..66baded663 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaVariantRequestModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { VariantModelBaseModel } from './VariantModelBaseModel'; + +export type MediaVariantRequestModel = (VariantModelBaseModel & { + $type: string; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaVariantResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaVariantResponseModel.ts new file mode 100644 index 0000000000..739ae9bd33 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MediaVariantResponseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { VariantResponseModelBaseModel } from './VariantResponseModelBaseModel'; + +export type MediaVariantResponseModel = (VariantResponseModelBaseModel & { + $type: string; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MemberGroupItemReponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MemberGroupItemReponseModel.ts new file mode 100644 index 0000000000..d42cc718f6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MemberGroupItemReponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type MemberGroupItemReponseModel = ItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MemberTypeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MemberTypeItemResponseModel.ts new file mode 100644 index 0000000000..8d42b882cb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MemberTypeItemResponseModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type MemberTypeItemResponseModel = (ItemResponseModelBaseModel & { + icon?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ModelsBuilderModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ModelsBuilderResponseModel.ts similarity index 89% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ModelsBuilderModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ModelsBuilderResponseModel.ts index 745bba54df..5f9962c2fa 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ModelsBuilderModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ModelsBuilderResponseModel.ts @@ -4,7 +4,7 @@ import type { ModelsModeModel } from './ModelsModeModel'; -export type ModelsBuilderModel = { +export type ModelsBuilderResponseModel = { mode?: ModelsModeModel; canGenerate?: boolean; outOfDateModels?: boolean; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MoveDataTypeRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MoveDataTypeRequestModel.ts new file mode 100644 index 0000000000..3e318c9479 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MoveDataTypeRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type MoveDataTypeRequestModel = { + targetId?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MoveDictionaryRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MoveDictionaryRequestModel.ts new file mode 100644 index 0000000000..0973241bc6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/MoveDictionaryRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type MoveDictionaryRequestModel = { + targetId?: string | null; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemsImportModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ObjectTypeResponseModel.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemsImportModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ObjectTypeResponseModel.ts index 73d0d2c31e..d160dfceb5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemsImportModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ObjectTypeResponseModel.ts @@ -2,9 +2,8 @@ /* tslint:disable */ /* eslint-disable */ -export type DictionaryItemsImportModel = { - key?: string; +export type ObjectTypeResponseModel = { name?: string | null; - parentKey?: string | null; + id?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/OutOfDateStatusModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/OutOfDateStatusResponseModel.ts similarity index 79% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/OutOfDateStatusModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/OutOfDateStatusResponseModel.ts index 7493102346..6d527b9a78 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/OutOfDateStatusModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/OutOfDateStatusResponseModel.ts @@ -4,7 +4,7 @@ import type { OutOfDateTypeModel } from './OutOfDateTypeModel'; -export type OutOfDateStatusModel = { +export type OutOfDateStatusResponseModel = { status?: OutOfDateTypeModel; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageDefinitionModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageDefinitionResponseModel.ts similarity index 65% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageDefinitionModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageDefinitionResponseModel.ts index 70f174f33d..d86f8ba651 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageDefinitionModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageDefinitionResponseModel.ts @@ -4,8 +4,8 @@ import type { PackageModelBaseModel } from './PackageModelBaseModel'; -export type PackageDefinitionModel = (PackageModelBaseModel & { - key?: string; +export type PackageDefinitionResponseModel = (PackageModelBaseModel & { + id?: string; packagePath?: string; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageManifestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageManifestResponseModel.ts similarity index 77% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageManifestModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageManifestResponseModel.ts index 0c0518f0ed..269793340b 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageManifestModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageManifestResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type PackageManifestModel = { +export type PackageManifestResponseModel = { name?: string; version?: string | null; extensions?: Array; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageMigrationStatusModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageMigrationStatusResponseModel.ts similarity index 72% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageMigrationStatusModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageMigrationStatusResponseModel.ts index a0317649c5..d003e467e2 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageMigrationStatusModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageMigrationStatusResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type PackageMigrationStatusModel = { +export type PackageMigrationStatusResponseModel = { packageName?: string; hasPendingMigrations?: boolean; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageModelBaseModel.ts index a405b0ecc2..fa68538ec2 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageModelBaseModel.ts @@ -6,7 +6,7 @@ export type PackageModelBaseModel = { name?: string; contentNodeId?: string | null; contentLoadChildNodes?: boolean; - mediaKeys?: Array; + mediaIds?: Array; mediaLoadChildNodes?: boolean; documentTypes?: Array; mediaTypes?: Array; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedContentTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedContentTreeItemModel.ts deleted file mode 100644 index 397bd30608..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedContentTreeItemModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ContentTreeItemModel } from './ContentTreeItemModel'; -import type { DocumentTreeItemModel } from './DocumentTreeItemModel'; - -export type PagedContentTreeItemModel = { - total: number; - items: Array<(ContentTreeItemModel | DocumentTreeItemModel)>; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedContentTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedContentTreeItemResponseModel.ts new file mode 100644 index 0000000000..9b01050dc0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedContentTreeItemResponseModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContentTreeItemResponseModel } from './ContentTreeItemResponseModel'; +import type { DocumentTreeItemResponseModel } from './DocumentTreeItemResponseModel'; + +export type PagedContentTreeItemResponseModel = { + total: number; + items: Array<(ContentTreeItemResponseModel | DocumentTreeItemResponseModel)>; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedCultureModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedCultureModel.ts deleted file mode 100644 index 3c15f63914..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedCultureModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { CultureModel } from './CultureModel'; - -export type PagedCultureModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedCultureReponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedCultureReponseModel.ts new file mode 100644 index 0000000000..b75368444a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedCultureReponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { CultureReponseModel } from './CultureReponseModel'; + +export type PagedCultureReponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDictionaryOverviewModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDictionaryOverviewModel.ts deleted file mode 100644 index 14418fbd87..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDictionaryOverviewModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DictionaryOverviewModel } from './DictionaryOverviewModel'; - -export type PagedDictionaryOverviewModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDictionaryOverviewResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDictionaryOverviewResponseModel.ts new file mode 100644 index 0000000000..416064523d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDictionaryOverviewResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DictionaryOverviewResponseModel } from './DictionaryOverviewResponseModel'; + +export type PagedDictionaryOverviewResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentBlueprintTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentBlueprintTreeItemModel.ts deleted file mode 100644 index 699f2e1741..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentBlueprintTreeItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DocumentBlueprintTreeItemModel } from './DocumentBlueprintTreeItemModel'; - -export type PagedDocumentBlueprintTreeItemModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentBlueprintTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentBlueprintTreeItemResponseModel.ts new file mode 100644 index 0000000000..f5fb88fbf5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentBlueprintTreeItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DocumentBlueprintTreeItemResponseModel } from './DocumentBlueprintTreeItemResponseModel'; + +export type PagedDocumentBlueprintTreeItemResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTreeItemModel.ts deleted file mode 100644 index 3a919899d1..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTreeItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DocumentTreeItemModel } from './DocumentTreeItemModel'; - -export type PagedDocumentTreeItemModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTreeItemResponseModel.ts new file mode 100644 index 0000000000..3364678fac --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTreeItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DocumentTreeItemResponseModel } from './DocumentTreeItemResponseModel'; + +export type PagedDocumentTreeItemResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTypeTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTypeTreeItemModel.ts deleted file mode 100644 index 36a53706fd..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTypeTreeItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DocumentTypeTreeItemModel } from './DocumentTypeTreeItemModel'; - -export type PagedDocumentTypeTreeItemModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTypeTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTypeTreeItemResponseModel.ts new file mode 100644 index 0000000000..cfa8e9eb1d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedDocumentTypeTreeItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DocumentTypeTreeItemResponseModel } from './DocumentTypeTreeItemResponseModel'; + +export type PagedDocumentTypeTreeItemResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedEntityTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedEntityTreeItemModel.ts deleted file mode 100644 index ba5f939425..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedEntityTreeItemModel.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { ContentTreeItemModel } from './ContentTreeItemModel'; -import type { DocumentBlueprintTreeItemModel } from './DocumentBlueprintTreeItemModel'; -import type { DocumentTreeItemModel } from './DocumentTreeItemModel'; -import type { DocumentTypeTreeItemModel } from './DocumentTypeTreeItemModel'; -import type { EntityTreeItemModel } from './EntityTreeItemModel'; -import type { FolderTreeItemModel } from './FolderTreeItemModel'; - -export type PagedEntityTreeItemModel = { - total: number; - items: Array<(EntityTreeItemModel | ContentTreeItemModel | DocumentBlueprintTreeItemModel | DocumentTreeItemModel | DocumentTypeTreeItemModel | FolderTreeItemModel)>; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedEntityTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedEntityTreeItemResponseModel.ts new file mode 100644 index 0000000000..ac8b646854 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedEntityTreeItemResponseModel.ts @@ -0,0 +1,16 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ContentTreeItemResponseModel } from './ContentTreeItemResponseModel'; +import type { DocumentBlueprintTreeItemResponseModel } from './DocumentBlueprintTreeItemResponseModel'; +import type { DocumentTreeItemResponseModel } from './DocumentTreeItemResponseModel'; +import type { DocumentTypeTreeItemResponseModel } from './DocumentTypeTreeItemResponseModel'; +import type { EntityTreeItemResponseModel } from './EntityTreeItemResponseModel'; +import type { FolderTreeItemResponseModel } from './FolderTreeItemResponseModel'; + +export type PagedEntityTreeItemResponseModel = { + total: number; + items: Array<(EntityTreeItemResponseModel | ContentTreeItemResponseModel | DocumentBlueprintTreeItemResponseModel | DocumentTreeItemResponseModel | DocumentTypeTreeItemResponseModel | FolderTreeItemResponseModel)>; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFileSystemTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFileSystemTreeItemModel.ts deleted file mode 100644 index 4b45c03949..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFileSystemTreeItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { FileSystemTreeItemModel } from './FileSystemTreeItemModel'; - -export type PagedFileSystemTreeItemModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFileSystemTreeItemPresentationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFileSystemTreeItemPresentationModel.ts new file mode 100644 index 0000000000..3297c3ab40 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFileSystemTreeItemPresentationModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FileSystemTreeItemPresentationModel } from './FileSystemTreeItemPresentationModel'; + +export type PagedFileSystemTreeItemPresentationModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFolderTreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFolderTreeItemModel.ts deleted file mode 100644 index 25377aa29c..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFolderTreeItemModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { DocumentTypeTreeItemModel } from './DocumentTypeTreeItemModel'; -import type { FolderTreeItemModel } from './FolderTreeItemModel'; - -export type PagedFolderTreeItemModel = { - total: number; - items: Array<(FolderTreeItemModel | DocumentTypeTreeItemModel)>; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFolderTreeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFolderTreeItemResponseModel.ts new file mode 100644 index 0000000000..deafb5c398 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedFolderTreeItemResponseModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DocumentTypeTreeItemResponseModel } from './DocumentTypeTreeItemResponseModel'; +import type { FolderTreeItemResponseModel } from './FolderTreeItemResponseModel'; + +export type PagedFolderTreeItemResponseModel = { + total: number; + items: Array<(FolderTreeItemResponseModel | DocumentTypeTreeItemResponseModel)>; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHealthCheckGroupModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHealthCheckGroupModelBaseModel.ts deleted file mode 100644 index 8a2687142d..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHealthCheckGroupModelBaseModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HealthCheckGroupModel } from './HealthCheckGroupModel'; -import type { HealthCheckGroupModelBaseModel } from './HealthCheckGroupModelBaseModel'; - -export type PagedHealthCheckGroupModelBaseModel = { - total: number; - items: Array<(HealthCheckGroupModelBaseModel | HealthCheckGroupModel)>; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHealthCheckGroupResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHealthCheckGroupResponseModel.ts new file mode 100644 index 0000000000..bcd0a47ba7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHealthCheckGroupResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { HealthCheckGroupResponseModel } from './HealthCheckGroupResponseModel'; + +export type PagedHealthCheckGroupResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHelpPageModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHelpPageModel.ts deleted file mode 100644 index a5fe785cea..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHelpPageModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { HelpPageModel } from './HelpPageModel'; - -export type PagedHelpPageModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHelpPageResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHelpPageResponseModel.ts new file mode 100644 index 0000000000..963dcbbc72 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedHelpPageResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { HelpPageResponseModel } from './HelpPageResponseModel'; + +export type PagedHelpPageResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedIndexModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedIndexModel.ts deleted file mode 100644 index ffb2a4a1ca..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedIndexModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { IndexModel } from './IndexModel'; - -export type PagedIndexModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedIndexResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedIndexResponseModel.ts new file mode 100644 index 0000000000..7798b6b5a2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedIndexResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { IndexResponseModel } from './IndexResponseModel'; + +export type PagedIndexResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLanguageModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLanguageModel.ts deleted file mode 100644 index 700a00b67c..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLanguageModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { LanguageModel } from './LanguageModel'; - -export type PagedLanguageModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLanguageResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLanguageResponseModel.ts new file mode 100644 index 0000000000..0fba24b689 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLanguageResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { LanguageResponseModel } from './LanguageResponseModel'; + +export type PagedLanguageResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogMessageModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogMessageModel.ts deleted file mode 100644 index 2e0370b852..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogMessageModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { LogMessageModel } from './LogMessageModel'; - -export type PagedLogMessageModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogMessageResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogMessageResponseModel.ts new file mode 100644 index 0000000000..0a9e2324f3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogMessageResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { LogMessageResponseModel } from './LogMessageResponseModel'; + +export type PagedLogMessageResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogTemplateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogTemplateModel.ts deleted file mode 100644 index eefc94d7d1..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogTemplateModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { LogTemplateModel } from './LogTemplateModel'; - -export type PagedLogTemplateModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogTemplateResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogTemplateResponseModel.ts new file mode 100644 index 0000000000..0118ef7d9b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLogTemplateResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { LogTemplateResponseModel } from './LogTemplateResponseModel'; + +export type PagedLogTemplateResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLoggerModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLoggerModel.ts deleted file mode 100644 index 7f2e381960..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLoggerModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { LoggerModel } from './LoggerModel'; - -export type PagedLoggerModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLoggerResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLoggerResponseModel.ts new file mode 100644 index 0000000000..18d7c7d708 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedLoggerResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { LoggerResponseModel } from './LoggerResponseModel'; + +export type PagedLoggerResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedObjectTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedObjectTypeResponseModel.ts new file mode 100644 index 0000000000..c8eaf672f7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedObjectTypeResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ObjectTypeResponseModel } from './ObjectTypeResponseModel'; + +export type PagedObjectTypeResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageDefinitionModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageDefinitionModel.ts deleted file mode 100644 index 3a596e659a..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageDefinitionModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { PackageDefinitionModel } from './PackageDefinitionModel'; - -export type PagedPackageDefinitionModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageDefinitionResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageDefinitionResponseModel.ts new file mode 100644 index 0000000000..af37046ae9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageDefinitionResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { PackageDefinitionResponseModel } from './PackageDefinitionResponseModel'; + +export type PagedPackageDefinitionResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageMigrationStatusModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageMigrationStatusModel.ts deleted file mode 100644 index b9a95529d8..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageMigrationStatusModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { PackageMigrationStatusModel } from './PackageMigrationStatusModel'; - -export type PagedPackageMigrationStatusModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageMigrationStatusResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageMigrationStatusResponseModel.ts new file mode 100644 index 0000000000..759633f03b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedPackageMigrationStatusResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { PackageMigrationStatusResponseModel } from './PackageMigrationStatusResponseModel'; + +export type PagedPackageMigrationStatusResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRecycleBinItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRecycleBinItemModel.ts deleted file mode 100644 index 530f70a624..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRecycleBinItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { RecycleBinItemModel } from './RecycleBinItemModel'; - -export type PagedRecycleBinItemModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRecycleBinItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRecycleBinItemResponseModel.ts new file mode 100644 index 0000000000..de0221c66d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRecycleBinItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RecycleBinItemResponseModel } from './RecycleBinItemResponseModel'; + +export type PagedRecycleBinItemResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRedirectUrlModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRedirectUrlModel.ts deleted file mode 100644 index 6bd46c9a32..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRedirectUrlModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { RedirectUrlModel } from './RedirectUrlModel'; - -export type PagedRedirectUrlModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRedirectUrlResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRedirectUrlResponseModel.ts new file mode 100644 index 0000000000..efa56add27 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRedirectUrlResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RedirectUrlResponseModel } from './RedirectUrlResponseModel'; + +export type PagedRedirectUrlResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationItemModel.ts deleted file mode 100644 index fc7f3bc0db..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationItemModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { RelationItemModel } from './RelationItemModel'; - -export type PagedRelationItemModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationItemResponseModel.ts new file mode 100644 index 0000000000..2340e59dbc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationItemResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RelationItemResponseModel } from './RelationItemResponseModel'; + +export type PagedRelationItemResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationModel.ts deleted file mode 100644 index 155680334e..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { RelationModel } from './RelationModel'; - -export type PagedRelationModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationResponseModel.ts new file mode 100644 index 0000000000..a93d16ea07 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedRelationResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RelationResponseModel } from './RelationResponseModel'; + +export type PagedRelationResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSavedLogSearchModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSavedLogSearchModel.ts deleted file mode 100644 index 069463afc4..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSavedLogSearchModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { SavedLogSearchModel } from './SavedLogSearchModel'; - -export type PagedSavedLogSearchModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSavedLogSearchResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSavedLogSearchResponseModel.ts new file mode 100644 index 0000000000..994d6a2f99 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSavedLogSearchResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { SavedLogSearchResponseModel } from './SavedLogSearchResponseModel'; + +export type PagedSavedLogSearchResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearchResultModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearchResultModel.ts deleted file mode 100644 index 849f5368a8..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearchResultModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { SearchResultModel } from './SearchResultModel'; - -export type PagedSearchResultModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearchResultResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearchResultResponseModel.ts new file mode 100644 index 0000000000..faaad892f6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearchResultResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { SearchResultResponseModel } from './SearchResultResponseModel'; + +export type PagedSearchResultResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearcherModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearcherModel.ts deleted file mode 100644 index 83c716fe93..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearcherModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { SearcherModel } from './SearcherModel'; - -export type PagedSearcherModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearcherResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearcherResponseModel.ts new file mode 100644 index 0000000000..f59af076ae --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedSearcherResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { SearcherResponseModel } from './SearcherResponseModel'; + +export type PagedSearcherResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedTelemetryModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedTelemetryModel.ts deleted file mode 100644 index a447d38f2e..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedTelemetryModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { TelemetryModel } from './TelemetryModel'; - -export type PagedTelemetryModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedTelemetryResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedTelemetryResponseModel.ts new file mode 100644 index 0000000000..dfff74e1ff --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedTelemetryResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { TelemetryResponseModel } from './TelemetryResponseModel'; + +export type PagedTelemetryResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserGroupModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserGroupModel.ts deleted file mode 100644 index c4d0191652..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserGroupModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { UserGroupModel } from './UserGroupModel'; - -export type PagedUserGroupModel = { - total: number; - items: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserGroupPresentationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserGroupPresentationModel.ts new file mode 100644 index 0000000000..7000915e7e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserGroupPresentationModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UserGroupPresentationModel } from './UserGroupPresentationModel'; + +export type PagedUserGroupPresentationModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserResponseModel.ts new file mode 100644 index 0000000000..0b658bd8df --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PagedUserResponseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UserResponseModel } from './UserResponseModel'; + +export type PagedUserResponseModel = { + total: number; + items: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PartialViewItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PartialViewItemResponseModel.ts new file mode 100644 index 0000000000..545b2ebdd8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PartialViewItemResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FileItemResponseModelBaseModel } from './FileItemResponseModelBaseModel'; + +export type PartialViewItemResponseModel = FileItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusRequestModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusRequestModel.ts index b2a7cc321c..c1998e149e 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusRequestModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type ProfilingStatusModel = { +export type ProfilingStatusRequestModel = { enabled?: boolean; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeMoveModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusResponseModel.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeMoveModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusResponseModel.ts index 2c8513a405..b78df9baf7 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeMoveModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ProfilingStatusResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type DataTypeMoveModel = { - targetKey?: string | null; +export type ProfilingStatusResponseModel = { + enabled?: boolean; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeContainerViewModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeContainerResponseModelBaseModel.ts similarity index 57% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeContainerViewModelBaseModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeContainerResponseModelBaseModel.ts index 7c8e755156..e57942bc53 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeContainerViewModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeContainerResponseModelBaseModel.ts @@ -2,9 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -export type PropertyTypeContainerViewModelBaseModel = { - key?: string; - parentKey?: string | null; +export type PropertyTypeContainerResponseModelBaseModel = { + id?: string; + parentId?: string | null; name?: string | null; type?: string; sortOrder?: number; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeViewModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeResponseModelBaseModel.ts similarity index 78% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeViewModelBaseModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeResponseModelBaseModel.ts index 11fe857a2c..ad3a59bbbf 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeViewModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PropertyTypeResponseModelBaseModel.ts @@ -5,13 +5,13 @@ import type { PropertyTypeAppearanceModel } from './PropertyTypeAppearanceModel'; import type { PropertyTypeValidationModel } from './PropertyTypeValidationModel'; -export type PropertyTypeViewModelBaseModel = { - key?: string; - containerKey?: string | null; +export type PropertyTypeResponseModelBaseModel = { + id?: string; + containerId?: string | null; alias?: string; name?: string; description?: string | null; - dataTypeKey?: string; + dataTypeId?: string; variesByCulture?: boolean; variesBySegment?: boolean; validation?: PropertyTypeValidationModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RecycleBinItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RecycleBinItemResponseModel.ts similarity index 69% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RecycleBinItemModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RecycleBinItemResponseModel.ts index 17bef97f12..baa8488713 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RecycleBinItemModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RecycleBinItemResponseModel.ts @@ -2,14 +2,14 @@ /* tslint:disable */ /* eslint-disable */ -export type RecycleBinItemModel = { +export type RecycleBinItemResponseModel = { $type: string; - key?: string; + id?: string; name?: string; type?: string; icon?: string; hasChildren?: boolean; isContainer?: boolean; - parentKey?: string | null; + parentId?: string | null; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlResponseModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlResponseModel.ts index fe39dcab56..7e50854125 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlResponseModel.ts @@ -2,12 +2,12 @@ /* tslint:disable */ /* eslint-disable */ -export type RedirectUrlModel = { - key?: string; +export type RedirectUrlResponseModel = { + id?: string; originalUrl?: string; destinationUrl?: string; created?: string; - contentKey?: string; + contentId?: string; culture?: string | null; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlStatusModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlStatusResponseModel.ts similarity index 81% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlStatusModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlStatusResponseModel.ts index c97804bab7..3c24019ae5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlStatusModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RedirectUrlStatusResponseModel.ts @@ -4,7 +4,7 @@ import type { RedirectStatusModel } from './RedirectStatusModel'; -export type RedirectUrlStatusModel = { +export type RedirectUrlStatusResponseModel = { status?: RedirectStatusModel; userIsAdmin?: boolean; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationItemResponseModel.ts similarity index 86% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationItemModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationItemResponseModel.ts index d99d9050a5..544ea5831d 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationItemModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationItemResponseModel.ts @@ -2,8 +2,8 @@ /* tslint:disable */ /* eslint-disable */ -export type RelationItemModel = { - nodeKey?: string; +export type RelationItemResponseModel = { + nodeId?: string; nodeName?: string | null; nodeType?: string | null; nodePublished?: boolean | null; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationResponseModel.ts similarity index 86% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationResponseModel.ts index 47de4a65d7..7e6546465f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type RelationModel = { +export type RelationResponseModel = { parentId?: number; parentName?: string | null; childId?: number; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeBaseModel.ts new file mode 100644 index 0000000000..0213197525 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeBaseModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type RelationTypeBaseModel = { + name?: string; + isBidirectional?: boolean; + parentObjectType?: string | null; + childObjectType?: string | null; + isDependency?: boolean; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeItemResponseModel.ts new file mode 100644 index 0000000000..8458385428 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeItemResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type RelationTypeItemResponseModel = ItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeResponseModel.ts new file mode 100644 index 0000000000..cc2461d0ce --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/RelationTypeResponseModel.ts @@ -0,0 +1,15 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RelationTypeBaseModel } from './RelationTypeBaseModel'; + +export type RelationTypeResponseModel = (RelationTypeBaseModel & { + id?: string; + alias?: string | null; + path?: string; + isSystemRelationType?: boolean; + parentObjectTypeName?: string | null; + childObjectTypeName?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupUpdateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SaveUserGroupRequestModel.ts similarity index 69% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupUpdateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SaveUserGroupRequestModel.ts index 9d329770d4..33d58dc4aa 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupUpdateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SaveUserGroupRequestModel.ts @@ -4,5 +4,5 @@ import type { UserGroupBaseModel } from './UserGroupBaseModel'; -export type UserGroupUpdateModel = UserGroupBaseModel; +export type SaveUserGroupRequestModel = UserGroupBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchPresenationBaseModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchPresenationBaseModel.ts index f75781f02a..c187d78876 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchPresenationBaseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type SavedLogSearchModel = { +export type SavedLogSearchPresenationBaseModel = { name?: string; query?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchRequestModel.ts new file mode 100644 index 0000000000..3ef1732e4e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { SavedLogSearchPresenationBaseModel } from './SavedLogSearchPresenationBaseModel'; + +export type SavedLogSearchRequestModel = SavedLogSearchPresenationBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchResponseModel.ts new file mode 100644 index 0000000000..54f039e1b9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SavedLogSearchResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { SavedLogSearchPresenationBaseModel } from './SavedLogSearchPresenationBaseModel'; + +export type SavedLogSearchResponseModel = SavedLogSearchPresenationBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ScriptItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ScriptItemResponseModel.ts new file mode 100644 index 0000000000..1092e37cb1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ScriptItemResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FileItemResponseModelBaseModel } from './FileItemResponseModelBaseModel'; + +export type ScriptItemResponseModel = FileItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearchResultModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearchResultModel.ts deleted file mode 100644 index 82f9cf64de..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearchResultModel.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { FieldModel } from './FieldModel'; - -export type SearchResultModel = { - id?: string; - score?: number; - readonly fieldCount?: number; - fields?: Array; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearchResultResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearchResultResponseModel.ts new file mode 100644 index 0000000000..3d84badc22 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearchResultResponseModel.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FieldPresentationModel } from './FieldPresentationModel'; + +export type SearchResultResponseModel = { + id?: string; + score?: number; + readonly fieldCount?: number; + fields?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearcherModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearcherResponseModel.ts similarity index 70% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearcherModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearcherResponseModel.ts index e20520f4d6..bf0ec4ed22 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearcherModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SearcherResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type SearcherModel = { +export type SearcherResponseModel = { name?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ServerStatusModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ServerStatusResponseModel.ts similarity index 80% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ServerStatusModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ServerStatusResponseModel.ts index 8c338954f5..a93b8e36ac 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ServerStatusModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ServerStatusResponseModel.ts @@ -4,7 +4,7 @@ import type { RuntimeLevelModel } from './RuntimeLevelModel'; -export type ServerStatusModel = { +export type ServerStatusResponseModel = { serverStatus?: RuntimeLevelModel; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SetAvatarRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SetAvatarRequestModel.ts new file mode 100644 index 0000000000..ccf61568d0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/SetAvatarRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type SetAvatarRequestModel = { + fileId?: string; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/StaticFileItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/StaticFileItemResponseModel.ts new file mode 100644 index 0000000000..793190a8b7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/StaticFileItemResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FileItemResponseModelBaseModel } from './FileItemResponseModelBaseModel'; + +export type StaticFileItemResponseModel = FileItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/StylesheetItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/StylesheetItemResponseModel.ts new file mode 100644 index 0000000000..6b09804191 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/StylesheetItemResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { FileItemResponseModelBaseModel } from './FileItemResponseModelBaseModel'; + +export type StylesheetItemResponseModel = FileItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryRepresentationBaseModel.ts similarity index 78% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryRepresentationBaseModel.ts index 9cf2ab4b30..e1040f19bb 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryRepresentationBaseModel.ts @@ -4,7 +4,7 @@ import type { TelemetryLevelModel } from './TelemetryLevelModel'; -export type TelemetryModel = { +export type TelemetryRepresentationBaseModel = { telemetryLevel?: TelemetryLevelModel; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryRequestModel.ts new file mode 100644 index 0000000000..ed7ed14981 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { TelemetryRepresentationBaseModel } from './TelemetryRepresentationBaseModel'; + +export type TelemetryRequestModel = TelemetryRepresentationBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryResponseModel.ts new file mode 100644 index 0000000000..2ab7ab6087 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TelemetryResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { TelemetryRepresentationBaseModel } from './TelemetryRepresentationBaseModel'; + +export type TelemetryResponseModel = TelemetryRepresentationBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateItemResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateItemResponseModel.ts new file mode 100644 index 0000000000..023262e3b2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateItemResponseModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ItemResponseModelBaseModel } from './ItemResponseModelBaseModel'; + +export type TemplateItemResponseModel = ItemResponseModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteFilterModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteFilterPresentationModel.ts similarity index 78% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteFilterModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteFilterPresentationModel.ts index 1befb86885..336c8dcc51 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteFilterModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteFilterPresentationModel.ts @@ -4,7 +4,7 @@ import type { OperatorModel } from './OperatorModel'; -export type TemplateQueryExecuteFilterModel = { +export type TemplateQueryExecuteFilterPresentationModel = { propertyAlias?: string; constraintValue?: string; operator?: OperatorModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteModel.ts index 029409b196..a1711fce8f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryExecuteModel.ts @@ -2,13 +2,13 @@ /* tslint:disable */ /* eslint-disable */ -import type { TemplateQueryExecuteFilterModel } from './TemplateQueryExecuteFilterModel'; +import type { TemplateQueryExecuteFilterPresentationModel } from './TemplateQueryExecuteFilterPresentationModel'; import type { TemplateQueryExecuteSortModel } from './TemplateQueryExecuteSortModel'; export type TemplateQueryExecuteModel = { - rootContentKey?: string | null; + rootContentId?: string | null; contentTypeAlias?: string | null; - filters?: Array | null; + filters?: Array | null; sort?: TemplateQueryExecuteSortModel | null; take?: number; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryPropertyModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryPropertyPresentationModel.ts similarity index 80% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryPropertyModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryPropertyPresentationModel.ts index 545d021964..63f89b6fbd 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryPropertyModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryPropertyPresentationModel.ts @@ -4,7 +4,7 @@ import type { TemplateQueryPropertyTypeModel } from './TemplateQueryPropertyTypeModel'; -export type TemplateQueryPropertyModel = { +export type TemplateQueryPropertyPresentationModel = { alias?: string; type?: TemplateQueryPropertyTypeModel; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultItemPresentationModel.ts similarity index 66% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultItemModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultItemPresentationModel.ts index 43d24a4c62..101a71f87f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultItemModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultItemPresentationModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type TemplateQueryResultItemModel = { +export type TemplateQueryResultItemPresentationModel = { icon?: string; name?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultModel.ts deleted file mode 100644 index 1839c4e456..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultModel.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -import type { TemplateQueryResultItemModel } from './TemplateQueryResultItemModel'; - -export type TemplateQueryResultModel = { - queryExpression?: string; - sampleResults?: Array; - resultCount?: number; - executionTime?: number; -}; - diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultResponseModel.ts new file mode 100644 index 0000000000..128ba29cd6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQueryResultResponseModel.ts @@ -0,0 +1,13 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { TemplateQueryResultItemPresentationModel } from './TemplateQueryResultItemPresentationModel'; + +export type TemplateQueryResultResponseModel = { + queryExpression?: string; + sampleResults?: Array; + resultCount?: number; + executionTime?: number; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQuerySettingsModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQuerySettingsResponseModel.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQuerySettingsModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQuerySettingsResponseModel.ts index 67723966b6..724e4113eb 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQuerySettingsModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateQuerySettingsResponseModel.ts @@ -3,11 +3,11 @@ /* eslint-disable */ import type { TemplateQueryOperatorModel } from './TemplateQueryOperatorModel'; -import type { TemplateQueryPropertyModel } from './TemplateQueryPropertyModel'; +import type { TemplateQueryPropertyPresentationModel } from './TemplateQueryPropertyPresentationModel'; -export type TemplateQuerySettingsModel = { +export type TemplateQuerySettingsResponseModel = { contentTypeAliases?: Array; - properties?: Array; + properties?: Array; operators?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateResponseModel.ts similarity index 67% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateResponseModel.ts index 7f14861ddd..4163616f8f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateResponseModel.ts @@ -4,8 +4,8 @@ import type { TemplateModelBaseModel } from './TemplateModelBaseModel'; -export type TemplateModel = (TemplateModelBaseModel & { +export type TemplateResponseModel = (TemplateModelBaseModel & { $type: string; - key?: string; + id?: string; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateScaffoldModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateScaffoldResponseModel.ts similarity index 67% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateScaffoldModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateScaffoldResponseModel.ts index 47040df1dc..78ea2b296d 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateScaffoldModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateScaffoldResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type TemplateScaffoldModel = { +export type TemplateScaffoldResponseModel = { content?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryImportModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemporaryFileResponseModel.ts similarity index 50% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryImportModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemporaryFileResponseModel.ts index 3f0b6be219..117d1376ea 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryImportModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemporaryFileResponseModel.ts @@ -2,8 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -export type DictionaryImportModel = { +export type TemporaryFileResponseModel = { + id?: string; + availableUntil?: string | null; fileName?: string; - parentKey?: string | null; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TreeItemModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TreeItemPresentationModel.ts similarity index 79% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TreeItemModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TreeItemPresentationModel.ts index b16725118d..385278eba9 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TreeItemModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TreeItemPresentationModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type TreeItemModel = { +export type TreeItemPresentationModel = { name?: string; type?: string; icon?: string; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UnlockUsersRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UnlockUsersRequestModel.ts new file mode 100644 index 0000000000..78c63357bd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UnlockUsersRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type UnlockUsersRequestModel = { + userIds?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel.ts new file mode 100644 index 0000000000..be30b01b27 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DocumentValueModel } from './DocumentValueModel'; +import type { DocumentVariantRequestModel } from './DocumentVariantRequestModel'; + +export type UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel = { + values?: Array; + variants?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel.ts new file mode 100644 index 0000000000..303415adef --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { MediaValueModel } from './MediaValueModel'; +import type { MediaVariantRequestModel } from './MediaVariantRequestModel'; + +export type UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel = { + values?: Array; + variants?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeUpdateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDataTypeRequestModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeUpdateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDataTypeRequestModel.ts index 9905f91b45..b221f60b1f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DataTypeUpdateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDataTypeRequestModel.ts @@ -4,5 +4,5 @@ import type { DataTypeModelBaseModel } from './DataTypeModelBaseModel'; -export type DataTypeUpdateModel = DataTypeModelBaseModel; +export type UpdateDataTypeRequestModel = DataTypeModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemUpdateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDictionaryItemRequestModel.ts similarity index 66% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemUpdateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDictionaryItemRequestModel.ts index 7ec1024f75..e145ccd319 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/DictionaryItemUpdateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDictionaryItemRequestModel.ts @@ -4,5 +4,5 @@ import type { DictionaryItemModelBaseModel } from './DictionaryItemModelBaseModel'; -export type DictionaryItemUpdateModel = DictionaryItemModelBaseModel; +export type UpdateDictionaryItemRequestModel = DictionaryItemModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDocumentNotificationsRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDocumentNotificationsRequestModel.ts new file mode 100644 index 0000000000..37066167b2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDocumentNotificationsRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type UpdateDocumentNotificationsRequestModel = { + subscribedActionIds?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDocumentRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDocumentRequestModel.ts new file mode 100644 index 0000000000..6382ef989d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDocumentRequestModel.ts @@ -0,0 +1,10 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel } from './UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel'; + +export type UpdateDocumentRequestModel = (UpdateContentRequestModelBaseDocumentValueModelDocumentVariantRequestModel & { + templateId?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDomainsRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDomainsRequestModel.ts new file mode 100644 index 0000000000..a2cb1b6fe4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateDomainsRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { DomainsPresentationModelBaseModel } from './DomainsPresentationModelBaseModel'; + +export type UpdateDomainsRequestModel = DomainsPresentationModelBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderUpdateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateFolderReponseModel.ts similarity index 69% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderUpdateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateFolderReponseModel.ts index cadefa91e6..cc79576144 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/FolderUpdateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateFolderReponseModel.ts @@ -4,5 +4,5 @@ import type { FolderModelBaseModel } from './FolderModelBaseModel'; -export type FolderUpdateModel = FolderModelBaseModel; +export type UpdateFolderReponseModel = FolderModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageUpdateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateLanguageRequestModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageUpdateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateLanguageRequestModel.ts index 43ede0907e..dd2e81b5f5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/LanguageUpdateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateLanguageRequestModel.ts @@ -4,5 +4,5 @@ import type { LanguageModelBaseModel } from './LanguageModelBaseModel'; -export type LanguageUpdateModel = LanguageModelBaseModel; +export type UpdateLanguageRequestModel = LanguageModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateMediaRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateMediaRequestModel.ts new file mode 100644 index 0000000000..3214fd055c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateMediaRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel } from './UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel'; + +export type UpdateMediaRequestModel = UpdateContentRequestModelBaseMediaValueModelMediaVariantRequestModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageUpdateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdatePackageRequestModel.ts similarity index 71% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageUpdateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdatePackageRequestModel.ts index e8bbd052fe..95e1518519 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/PackageUpdateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdatePackageRequestModel.ts @@ -4,7 +4,7 @@ import type { PackageModelBaseModel } from './PackageModelBaseModel'; -export type PackageUpdateModel = (PackageModelBaseModel & { +export type UpdatePackageRequestModel = (PackageModelBaseModel & { packagePath?: string; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateRelationTypeRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateRelationTypeRequestModel.ts new file mode 100644 index 0000000000..d4ec475f57 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateRelationTypeRequestModel.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { RelationTypeBaseModel } from './RelationTypeBaseModel'; + +export type UpdateRelationTypeRequestModel = RelationTypeBaseModel; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateCreateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateTemplateRequestModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateCreateModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateTemplateRequestModel.ts index 7096084213..6011f0a108 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/TemplateCreateModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateTemplateRequestModel.ts @@ -4,5 +4,5 @@ import type { TemplateModelBaseModel } from './TemplateModelBaseModel'; -export type TemplateCreateModel = TemplateModelBaseModel; +export type UpdateTemplateRequestModel = TemplateModelBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupSaveModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserGroupRequestModel.ts similarity index 68% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupSaveModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserGroupRequestModel.ts index a729fbff90..f1810a85c5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupSaveModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserGroupRequestModel.ts @@ -4,5 +4,5 @@ import type { UserGroupBaseModel } from './UserGroupBaseModel'; -export type UserGroupSaveModel = UserGroupBaseModel; +export type UpdateUserGroupRequestModel = UserGroupBaseModel; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserGroupsOnUserRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserGroupsOnUserRequestModel.ts new file mode 100644 index 0000000000..0e552a780b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserGroupsOnUserRequestModel.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type UpdateUserGroupsOnUserRequestModel = { + userIds?: Array; + userGroupIds?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserRequestModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserRequestModel.ts new file mode 100644 index 0000000000..928742c00d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpdateUserRequestModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UserPresentationBaseModel } from './UserPresentationBaseModel'; + +export type UpdateUserRequestModel = (UserPresentationBaseModel & { + languageIsoCode?: string; + contentStartNodeIds?: Array; + mediaStartNodeIds?: Array; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpgradeSettingsModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpgradeSettingsResponseModel.ts similarity index 82% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpgradeSettingsModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpgradeSettingsResponseModel.ts index 0486d96ff8..c59279f453 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpgradeSettingsModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UpgradeSettingsResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type UpgradeSettingsModel = { +export type UpgradeSettingsResponseModel = { currentState?: string; newState?: string; newVersion?: string; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupBaseModel.ts index 3b22ff01eb..eaf8e83aa0 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupBaseModel.ts @@ -8,8 +8,8 @@ export type UserGroupBaseModel = { sections?: Array; languages?: Array; hasAccessToAllLanguages?: boolean; - documentStartNodeKey?: string | null; - mediaStartNodeKey?: string | null; + documentStartNodeId?: string | null; + mediaStartNodeId?: string | null; permissions?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupPresentationModel.ts similarity index 65% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupPresentationModel.ts index 0aae1e4cf7..ee3a34c477 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserGroupPresentationModel.ts @@ -4,8 +4,8 @@ import type { UserGroupBaseModel } from './UserGroupBaseModel'; -export type UserGroupModel = (UserGroupBaseModel & { +export type UserGroupPresentationModel = (UserGroupBaseModel & { $type: string; - key?: string; + id?: string; }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserInstallModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserInstallResponseModel.ts similarity index 81% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserInstallModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserInstallResponseModel.ts index 9c89afe57b..a1807e8bcd 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserInstallModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserInstallResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type UserInstallModel = { +export type UserInstallResponseModel = { name: string; email: string; password: string; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserOrderModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserOrderModel.ts new file mode 100644 index 0000000000..3c668a8c97 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserOrderModel.ts @@ -0,0 +1,16 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export enum UserOrderModel { + USER_NAME = 'UserName', + LANGUAGE = 'Language', + NAME = 'Name', + EMAIL = 'Email', + ID = 'Id', + CREATE_DATE = 'CreateDate', + UPDATE_DATE = 'UpdateDate', + IS_APPROVED = 'IsApproved', + IS_LOCKED_OUT = 'IsLockedOut', + LAST_LOGIN_DATE = 'LastLoginDate', +} diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserPresentationBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserPresentationBaseModel.ts new file mode 100644 index 0000000000..687e34bde7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserPresentationBaseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type UserPresentationBaseModel = { + email?: string; + userName?: string; + name?: string; + userGroupIds?: Array; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserResponseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserResponseModel.ts new file mode 100644 index 0000000000..69fabaf972 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserResponseModel.ts @@ -0,0 +1,23 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { UserPresentationBaseModel } from './UserPresentationBaseModel'; +import type { UserStateModel } from './UserStateModel'; + +export type UserResponseModel = (UserPresentationBaseModel & { + $type: string; + id?: string; + languageIsoCode?: string | null; + contentStartNodeIds?: Array; + mediaStartNodeIds?: Array; + avatarUrls?: Array; + state?: UserStateModel; + failedLoginAttempts?: number; + createDate?: string; + updateDate?: string; + lastLoginDate?: string | null; + lastlockoutDate?: string | null; + lastPasswordChangeDate?: string | null; +}); + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserSettingsModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserSettingsModel.ts index af052a9cc7..0179397099 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserSettingsModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserSettingsModel.ts @@ -2,11 +2,11 @@ /* tslint:disable */ /* eslint-disable */ -import type { ConsentLevelModel } from './ConsentLevelModel'; +import type { ConsentLevelPresentationModel } from './ConsentLevelPresentationModel'; export type UserSettingsModel = { minCharLength?: number; minNonAlphaNumericLength?: number; - consentLevels?: Array; + consentLevels?: Array; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserStateModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserStateModel.ts new file mode 100644 index 0000000000..7e1858868f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/UserStateModel.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export enum UserStateModel { + ACTIVE = 'Active', + DISABLED = 'Disabled', + LOCKED_OUT = 'LockedOut', + INVITED = 'Invited', + INACTIVE = 'Inactive', + ALL = 'All', +} diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ValueViewModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ValueModelBaseModel.ts similarity index 75% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ValueViewModelBaseModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ValueModelBaseModel.ts index f63bda6058..8167e5e124 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ValueViewModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/ValueModelBaseModel.ts @@ -2,7 +2,8 @@ /* tslint:disable */ /* eslint-disable */ -export type ValueViewModelBaseModel = { +export type ValueModelBaseModel = { + $type: string; culture?: string | null; segment?: string | null; alias?: string; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantModelBaseModel.ts new file mode 100644 index 0000000000..599a5fd749 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantModelBaseModel.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type VariantModelBaseModel = { + $type: string; + culture?: string | null; + segment?: string | null; + name?: string; +}; + diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantViewModelBaseModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantResponseModelBaseModel.ts similarity index 75% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantViewModelBaseModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantResponseModelBaseModel.ts index 6e2f7e0a05..8add15bf08 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantViewModelBaseModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VariantResponseModelBaseModel.ts @@ -2,7 +2,8 @@ /* tslint:disable */ /* eslint-disable */ -export type VariantViewModelBaseModel = { +export type VariantResponseModelBaseModel = { + $type: string; culture?: string | null; segment?: string | null; name?: string; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VersionModel.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VersionResponseModel.ts similarity index 72% rename from src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VersionModel.ts rename to src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VersionResponseModel.ts index a4405a253b..e545e2d0d9 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VersionModel.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/models/VersionResponseModel.ts @@ -2,7 +2,7 @@ /* tslint:disable */ /* eslint-disable */ -export type VersionModel = { +export type VersionResponseModel = { version?: string; }; diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/AuditLogResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/AuditLogResource.ts index 20a267dcb5..96065a5663 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/AuditLogResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/AuditLogResource.ts @@ -43,14 +43,14 @@ export class AuditLogResource { * @returns PagedAuditLogResponseModel Success * @throws ApiError */ - public static getAuditLogByKey({ - key, + public static getAuditLogById({ + id, orderDirection, sinceDate, skip, take = 100, }: { - key: string, + id: string, orderDirection?: DirectionModel, sinceDate?: string, skip?: number, @@ -58,9 +58,9 @@ export class AuditLogResource { }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/audit-log/{key}', + url: '/umbraco/management/api/v1/audit-log/{id}', path: { - 'key': key, + 'id': id, }, query: { 'orderDirection': orderDirection, diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/CultureResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/CultureResource.ts index 1c0efea89e..4e357c7e3f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/CultureResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/CultureResource.ts @@ -1,7 +1,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedCultureModel } from '../models/PagedCultureModel'; +import type { PagedCultureReponseModel } from '../models/PagedCultureReponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -10,7 +10,7 @@ import { request as __request } from '../core/request'; export class CultureResource { /** - * @returns PagedCultureModel Success + * @returns PagedCultureReponseModel Success * @throws ApiError */ public static getCulture({ @@ -19,7 +19,7 @@ export class CultureResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/culture', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DataTypeResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DataTypeResource.ts index 29f0ca82bd..ccf865111c 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DataTypeResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DataTypeResource.ts @@ -1,18 +1,17 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DataTypeCopyModel } from '../models/DataTypeCopyModel'; -import type { DataTypeCreateModel } from '../models/DataTypeCreateModel'; -import type { DataTypeModel } from '../models/DataTypeModel'; -import type { DataTypeMoveModel } from '../models/DataTypeMoveModel'; -import type { DataTypeReferenceModel } from '../models/DataTypeReferenceModel'; -import type { DataTypeUpdateModel } from '../models/DataTypeUpdateModel'; -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { FolderCreateModel } from '../models/FolderCreateModel'; -import type { FolderModel } from '../models/FolderModel'; -import type { FolderTreeItemModel } from '../models/FolderTreeItemModel'; -import type { FolderUpdateModel } from '../models/FolderUpdateModel'; -import type { PagedFolderTreeItemModel } from '../models/PagedFolderTreeItemModel'; +import type { CopyDataTypeRequestModel } from '../models/CopyDataTypeRequestModel'; +import type { CreateDataTypeRequestModel } from '../models/CreateDataTypeRequestModel'; +import type { CreateFolderRequestModel } from '../models/CreateFolderRequestModel'; +import type { DataTypeItemResponseModel } from '../models/DataTypeItemResponseModel'; +import type { DataTypeReferenceResponseModel } from '../models/DataTypeReferenceResponseModel'; +import type { DataTypeResponseModel } from '../models/DataTypeResponseModel'; +import type { FolderReponseModel } from '../models/FolderReponseModel'; +import type { MoveDataTypeRequestModel } from '../models/MoveDataTypeRequestModel'; +import type { PagedFolderTreeItemResponseModel } from '../models/PagedFolderTreeItemResponseModel'; +import type { UpdateDataTypeRequestModel } from '../models/UpdateDataTypeRequestModel'; +import type { UpdateFolderReponseModel } from '../models/UpdateFolderReponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -27,7 +26,7 @@ export class DataTypeResource { public static postDataType({ requestBody, }: { - requestBody?: DataTypeCreateModel, + requestBody?: CreateDataTypeRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -46,16 +45,16 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static getDataTypeByKey({ - key, + public static getDataTypeById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/data-type/{key}', + url: '/umbraco/management/api/v1/data-type/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -67,16 +66,16 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static deleteDataTypeByKey({ - key, + public static deleteDataTypeById({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'DELETE', - url: '/umbraco/management/api/v1/data-type/{key}', + url: '/umbraco/management/api/v1/data-type/{id}', path: { - 'key': key, + 'id': id, }, errors: { 400: `Bad Request`, @@ -89,18 +88,18 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static putDataTypeByKey({ - key, + public static putDataTypeById({ + id, requestBody, }: { - key: string, - requestBody?: DataTypeUpdateModel, + id: string, + requestBody?: UpdateDataTypeRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', - url: '/umbraco/management/api/v1/data-type/{key}', + url: '/umbraco/management/api/v1/data-type/{id}', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -115,18 +114,18 @@ export class DataTypeResource { * @returns string Created * @throws ApiError */ - public static postDataTypeByKeyCopy({ - key, + public static postDataTypeByIdCopy({ + id, requestBody, }: { - key: string, - requestBody?: DataTypeCopyModel, + id: string, + requestBody?: CopyDataTypeRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', - url: '/umbraco/management/api/v1/data-type/{key}/copy', + url: '/umbraco/management/api/v1/data-type/{id}/copy', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -141,18 +140,18 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static postDataTypeByKeyMove({ - key, + public static postDataTypeByIdMove({ + id, requestBody, }: { - key: string, - requestBody?: DataTypeMoveModel, + id: string, + requestBody?: MoveDataTypeRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', - url: '/umbraco/management/api/v1/data-type/{key}/move', + url: '/umbraco/management/api/v1/data-type/{id}/move', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -166,16 +165,16 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static getDataTypeByKeyReferences({ - key, + public static getDataTypeByIdReferences({ + id, }: { - key: string, - }): CancelablePromise> { + id: string, + }): CancelablePromise> { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/data-type/{key}/references', + url: '/umbraco/management/api/v1/data-type/{id}/references', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -190,7 +189,7 @@ export class DataTypeResource { public static postDataTypeFolder({ requestBody, }: { - requestBody?: FolderCreateModel, + requestBody?: CreateFolderRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -205,16 +204,16 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static getDataTypeFolderByKey({ - key, + public static getDataTypeFolderById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/data-type/folder/{key}', + url: '/umbraco/management/api/v1/data-type/folder/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -226,16 +225,16 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static deleteDataTypeFolderByKey({ - key, + public static deleteDataTypeFolderById({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'DELETE', - url: '/umbraco/management/api/v1/data-type/folder/{key}', + url: '/umbraco/management/api/v1/data-type/folder/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -247,18 +246,18 @@ export class DataTypeResource { * @returns any Success * @throws ApiError */ - public static putDataTypeFolderByKey({ - key, + public static putDataTypeFolderById({ + id, requestBody, }: { - key: string, - requestBody?: FolderUpdateModel, + id: string, + requestBody?: UpdateFolderReponseModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', - url: '/umbraco/management/api/v1/data-type/folder/{key}', + url: '/umbraco/management/api/v1/data-type/folder/{id}', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -269,25 +268,43 @@ export class DataTypeResource { } /** - * @returns PagedFolderTreeItemModel Success + * @returns any Success + * @throws ApiError + */ + public static getDataTypeItem({ + id, + }: { + id?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/data-type/item', + query: { + 'id': id, + }, + }); + } + + /** + * @returns PagedFolderTreeItemResponseModel Success * @throws ApiError */ public static getTreeDataTypeChildren({ - parentKey, + parentId, skip, take = 100, foldersOnly = false, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, foldersOnly?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/data-type/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, 'foldersOnly': foldersOnly, @@ -296,25 +313,7 @@ export class DataTypeResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeDataTypeItem({ - key, - }: { - key?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/data-type/item', - query: { - 'key': key, - }, - }); - } - - /** - * @returns PagedFolderTreeItemModel Success + * @returns PagedFolderTreeItemResponseModel Success * @throws ApiError */ public static getTreeDataTypeRoot({ @@ -325,7 +324,7 @@ export class DataTypeResource { skip?: number, take?: number, foldersOnly?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/data-type/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DictionaryResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DictionaryResource.ts index 3b4d8125e7..bbc8823aa0 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DictionaryResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DictionaryResource.ts @@ -1,16 +1,14 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DictionaryImportModel } from '../models/DictionaryImportModel'; -import type { DictionaryItemCreateModel } from '../models/DictionaryItemCreateModel'; -import type { DictionaryItemModel } from '../models/DictionaryItemModel'; -import type { DictionaryItemUpdateModel } from '../models/DictionaryItemUpdateModel'; -import type { DictionaryMoveModel } from '../models/DictionaryMoveModel'; -import type { DictionaryUploadModel } from '../models/DictionaryUploadModel'; -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { FolderTreeItemModel } from '../models/FolderTreeItemModel'; -import type { PagedDictionaryOverviewModel } from '../models/PagedDictionaryOverviewModel'; -import type { PagedEntityTreeItemModel } from '../models/PagedEntityTreeItemModel'; +import type { CreateDictionaryItemRequestModel } from '../models/CreateDictionaryItemRequestModel'; +import type { DictionaryItemItemResponseModel } from '../models/DictionaryItemItemResponseModel'; +import type { DictionaryItemResponseModel } from '../models/DictionaryItemResponseModel'; +import type { ImportDictionaryRequestModel } from '../models/ImportDictionaryRequestModel'; +import type { MoveDictionaryRequestModel } from '../models/MoveDictionaryRequestModel'; +import type { PagedDictionaryOverviewResponseModel } from '../models/PagedDictionaryOverviewResponseModel'; +import type { PagedEntityTreeItemResponseModel } from '../models/PagedEntityTreeItemResponseModel'; +import type { UpdateDictionaryItemRequestModel } from '../models/UpdateDictionaryItemRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -19,7 +17,7 @@ import { request as __request } from '../core/request'; export class DictionaryResource { /** - * @returns PagedDictionaryOverviewModel Success + * @returns PagedDictionaryOverviewResponseModel Success * @throws ApiError */ public static getDictionary({ @@ -28,7 +26,7 @@ export class DictionaryResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/dictionary', @@ -46,7 +44,7 @@ export class DictionaryResource { public static postDictionary({ requestBody, }: { - requestBody?: DictionaryItemCreateModel, + requestBody?: CreateDictionaryItemRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -66,16 +64,16 @@ export class DictionaryResource { * @returns any Success * @throws ApiError */ - public static getDictionaryByKey({ - key, + public static getDictionaryById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/dictionary/{key}', + url: '/umbraco/management/api/v1/dictionary/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -87,16 +85,16 @@ export class DictionaryResource { * @returns any Success * @throws ApiError */ - public static deleteDictionaryByKey({ - key, + public static deleteDictionaryById({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'DELETE', - url: '/umbraco/management/api/v1/dictionary/{key}', + url: '/umbraco/management/api/v1/dictionary/{id}', path: { - 'key': key, + 'id': id, }, errors: { 400: `Bad Request`, @@ -109,18 +107,18 @@ export class DictionaryResource { * @returns any Success * @throws ApiError */ - public static putDictionaryByKey({ - key, + public static putDictionaryById({ + id, requestBody, }: { - key: string, - requestBody?: DictionaryItemUpdateModel, + id: string, + requestBody?: UpdateDictionaryItemRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', - url: '/umbraco/management/api/v1/dictionary/{key}', + url: '/umbraco/management/api/v1/dictionary/{id}', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -135,18 +133,18 @@ export class DictionaryResource { * @returns binary Success * @throws ApiError */ - public static getDictionaryByKeyExport({ - key, + public static getDictionaryByIdExport({ + id, includeChildren = false, }: { - key: string, + id: string, includeChildren?: boolean, }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/dictionary/{key}/export', + url: '/umbraco/management/api/v1/dictionary/{id}/export', path: { - 'key': key, + 'id': id, }, query: { 'includeChildren': includeChildren, @@ -161,18 +159,18 @@ export class DictionaryResource { * @returns any Success * @throws ApiError */ - public static postDictionaryByKeyMove({ - key, + public static postDictionaryByIdMove({ + id, requestBody, }: { - key: string, - requestBody?: DictionaryMoveModel, + id: string, + requestBody?: MoveDictionaryRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', - url: '/umbraco/management/api/v1/dictionary/{key}/move', + url: '/umbraco/management/api/v1/dictionary/{id}/move', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -190,7 +188,7 @@ export class DictionaryResource { public static postDictionaryImport({ requestBody, }: { - requestBody?: DictionaryImportModel, + requestBody?: ImportDictionaryRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -209,39 +207,38 @@ export class DictionaryResource { * @returns any Success * @throws ApiError */ - public static postDictionaryUpload({ - requestBody, + public static getDictionaryItem({ + id, }: { - requestBody?: any, - }): CancelablePromise { + id?: Array, + }): CancelablePromise> { return __request(OpenAPI, { - method: 'POST', - url: '/umbraco/management/api/v1/dictionary/upload', - body: requestBody, - errors: { - 400: `Bad Request`, + method: 'GET', + url: '/umbraco/management/api/v1/dictionary/item', + query: { + 'id': id, }, }); } /** - * @returns PagedEntityTreeItemModel Success + * @returns PagedEntityTreeItemResponseModel Success * @throws ApiError */ public static getTreeDictionaryChildren({ - parentKey, + parentId, skip, take = 100, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/dictionary/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, }, @@ -249,25 +246,7 @@ export class DictionaryResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeDictionaryItem({ - key, - }: { - key?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/dictionary/item', - query: { - 'key': key, - }, - }); - } - - /** - * @returns PagedEntityTreeItemModel Success + * @returns PagedEntityTreeItemResponseModel Success * @throws ApiError */ public static getTreeDictionaryRoot({ @@ -276,7 +255,7 @@ export class DictionaryResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/dictionary/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentBlueprintResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentBlueprintResource.ts index 3513d34d4e..1708739c36 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentBlueprintResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentBlueprintResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DocumentBlueprintTreeItemModel } from '../models/DocumentBlueprintTreeItemModel'; -import type { PagedDocumentBlueprintTreeItemModel } from '../models/PagedDocumentBlueprintTreeItemModel'; +import type { DocumentBlueprintResponseModel } from '../models/DocumentBlueprintResponseModel'; +import type { PagedDocumentBlueprintTreeItemResponseModel } from '../models/PagedDocumentBlueprintTreeItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -14,22 +14,22 @@ export class DocumentBlueprintResource { * @returns any Success * @throws ApiError */ - public static getTreeDocumentBlueprintItem({ - key, + public static getDocumentBlueprintItem({ + id, }: { - key?: Array, - }): CancelablePromise> { + id?: Array, + }): CancelablePromise> { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/tree/document-blueprint/item', + url: '/umbraco/management/api/v1/document-blueprint/item', query: { - 'key': key, + 'id': id, }, }); } /** - * @returns PagedDocumentBlueprintTreeItemModel Success + * @returns PagedDocumentBlueprintTreeItemResponseModel Success * @throws ApiError */ public static getTreeDocumentBlueprintRoot({ @@ -38,7 +38,7 @@ export class DocumentBlueprintResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/document-blueprint/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentResource.ts index 470fa0033c..5758389b26 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentResource.ts @@ -1,10 +1,15 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DocumentModel } from '../models/DocumentModel'; -import type { DocumentTreeItemModel } from '../models/DocumentTreeItemModel'; -import type { PagedDocumentTreeItemModel } from '../models/PagedDocumentTreeItemModel'; -import type { PagedRecycleBinItemModel } from '../models/PagedRecycleBinItemModel'; +import type { CreateDocumentRequestModel } from '../models/CreateDocumentRequestModel'; +import type { DocumentItemResponseModel } from '../models/DocumentItemResponseModel'; +import type { DocumentNotificationResponseModel } from '../models/DocumentNotificationResponseModel'; +import type { DocumentResponseModel } from '../models/DocumentResponseModel'; +import type { PagedDocumentTreeItemResponseModel } from '../models/PagedDocumentTreeItemResponseModel'; +import type { PagedRecycleBinItemResponseModel } from '../models/PagedRecycleBinItemResponseModel'; +import type { UpdateDocumentNotificationsRequestModel } from '../models/UpdateDocumentNotificationsRequestModel'; +import type { UpdateDocumentRequestModel } from '../models/UpdateDocumentRequestModel'; +import type { UpdateDomainsRequestModel } from '../models/UpdateDomainsRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -12,20 +17,42 @@ import { request as __request } from '../core/request'; export class DocumentResource { + /** + * @returns string Created + * @throws ApiError + */ + public static postDocument({ + requestBody, + }: { + requestBody?: CreateDocumentRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/document', + body: requestBody, + mediaType: 'application/json', + responseHeader: 'Location', + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + /** * @returns any Success * @throws ApiError */ - public static getDocumentByKey({ - key, + public static getDocumentById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/document/{key}', + url: '/umbraco/management/api/v1/document/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -34,23 +61,181 @@ export class DocumentResource { } /** - * @returns PagedRecycleBinItemModel Success + * @returns any Success + * @throws ApiError + */ + public static deleteDocumentById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/umbraco/management/api/v1/document/{id}', + path: { + 'id': id, + }, + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putDocumentById({ + id, + requestBody, + }: { + id: string, + requestBody?: UpdateDocumentRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/document/{id}', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getDocumentByIdDomains({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/document/{id}/domains', + path: { + 'id': id, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putDocumentByIdDomains({ + id, + requestBody, + }: { + id: string, + requestBody?: UpdateDomainsRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/document/{id}/domains', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getDocumentByIdNotifications({ + id, + }: { + id: string, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/document/{id}/notifications', + path: { + 'id': id, + }, + errors: { + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putDocumentByIdNotifications({ + id, + requestBody, + }: { + id: string, + requestBody?: UpdateDocumentNotificationsRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/document/{id}/notifications', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getDocumentItem({ + id, + dataTypeId, + culture, + }: { + id?: Array, + dataTypeId?: string, + culture?: string, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/document/item', + query: { + 'id': id, + 'dataTypeId': dataTypeId, + 'culture': culture, + }, + }); + } + + /** + * @returns PagedRecycleBinItemResponseModel Success * @throws ApiError */ public static getRecycleBinDocumentChildren({ - parentKey, + parentId, skip, take = 100, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/recycle-bin/document/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, }, @@ -61,7 +246,7 @@ export class DocumentResource { } /** - * @returns PagedRecycleBinItemModel Success + * @returns PagedRecycleBinItemResponseModel Success * @throws ApiError */ public static getRecycleBinDocumentRoot({ @@ -70,7 +255,7 @@ export class DocumentResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/recycle-bin/document/root', @@ -85,81 +270,57 @@ export class DocumentResource { } /** - * @returns PagedDocumentTreeItemModel Success + * @returns PagedDocumentTreeItemResponseModel Success * @throws ApiError */ public static getTreeDocumentChildren({ - parentKey, + parentId, skip, take = 100, - dataTypeKey, + dataTypeId, culture, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, - dataTypeKey?: string, + dataTypeId?: string, culture?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/document/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, - 'dataTypeKey': dataTypeKey, + 'dataTypeId': dataTypeId, 'culture': culture, }, }); } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeDocumentItem({ - key, - dataTypeKey, - culture, - }: { - key?: Array, - dataTypeKey?: string, - culture?: string, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/document/item', - query: { - 'key': key, - 'dataTypeKey': dataTypeKey, - 'culture': culture, - }, - }); - } - - /** - * @returns PagedDocumentTreeItemModel Success + * @returns PagedDocumentTreeItemResponseModel Success * @throws ApiError */ public static getTreeDocumentRoot({ skip, take = 100, - dataTypeKey, + dataTypeId, culture, }: { skip?: number, take?: number, - dataTypeKey?: string, + dataTypeId?: string, culture?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/document/root', query: { 'skip': skip, 'take': take, - 'dataTypeKey': dataTypeKey, + 'dataTypeId': dataTypeId, 'culture': culture, }, }); diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentTypeResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentTypeResource.ts index a36a6081cc..430d840e9d 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentTypeResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/DocumentTypeResource.ts @@ -1,9 +1,9 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DocumentTypeModel } from '../models/DocumentTypeModel'; -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { PagedDocumentTypeTreeItemModel } from '../models/PagedDocumentTypeTreeItemModel'; +import type { DocumentTypeItemResponseModel } from '../models/DocumentTypeItemResponseModel'; +import type { DocumentTypeResponseModel } from '../models/DocumentTypeResponseModel'; +import type { PagedDocumentTypeTreeItemResponseModel } from '../models/PagedDocumentTypeTreeItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -15,16 +15,16 @@ export class DocumentTypeResource { * @returns any Success * @throws ApiError */ - public static getDocumentTypeByKey({ - key, + public static getDocumentTypeById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/document-type/{key}', + url: '/umbraco/management/api/v1/document-type/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -33,25 +33,43 @@ export class DocumentTypeResource { } /** - * @returns PagedDocumentTypeTreeItemModel Success + * @returns any Success + * @throws ApiError + */ + public static getDocumentTypeItem({ + id, + }: { + id?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/document-type/item', + query: { + 'id': id, + }, + }); + } + + /** + * @returns PagedDocumentTypeTreeItemResponseModel Success * @throws ApiError */ public static getTreeDocumentTypeChildren({ - parentKey, + parentId, skip, take = 100, foldersOnly = false, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, foldersOnly?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/document-type/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, 'foldersOnly': foldersOnly, @@ -60,25 +78,7 @@ export class DocumentTypeResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeDocumentTypeItem({ - key, - }: { - key?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/document-type/item', - query: { - 'key': key, - }, - }); - } - - /** - * @returns PagedDocumentTypeTreeItemModel Success + * @returns PagedDocumentTypeTreeItemResponseModel Success * @throws ApiError */ public static getTreeDocumentTypeRoot({ @@ -89,7 +89,7 @@ export class DocumentTypeResource { skip?: number, take?: number, foldersOnly?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/document-type/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HealthCheckResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HealthCheckResource.ts index 1497c8ac6f..6ec8cf2917 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HealthCheckResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HealthCheckResource.ts @@ -1,11 +1,11 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { HealthCheckActionModel } from '../models/HealthCheckActionModel'; -import type { HealthCheckGroupModel } from '../models/HealthCheckGroupModel'; -import type { HealthCheckGroupWithResultModel } from '../models/HealthCheckGroupWithResultModel'; -import type { HealthCheckResultModel } from '../models/HealthCheckResultModel'; -import type { PagedHealthCheckGroupModelBaseModel } from '../models/PagedHealthCheckGroupModelBaseModel'; +import type { HealthCheckActionRequestModel } from '../models/HealthCheckActionRequestModel'; +import type { HealthCheckGroupPresentationModel } from '../models/HealthCheckGroupPresentationModel'; +import type { HealthCheckGroupWithResultResponseModel } from '../models/HealthCheckGroupWithResultResponseModel'; +import type { HealthCheckResultResponseModel } from '../models/HealthCheckResultResponseModel'; +import type { PagedHealthCheckGroupResponseModel } from '../models/PagedHealthCheckGroupResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -14,7 +14,7 @@ import { request as __request } from '../core/request'; export class HealthCheckResource { /** - * @returns PagedHealthCheckGroupModelBaseModel Success + * @returns PagedHealthCheckGroupResponseModel Success * @throws ApiError */ public static getHealthCheckGroup({ @@ -23,7 +23,7 @@ export class HealthCheckResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/health-check-group', @@ -42,7 +42,7 @@ export class HealthCheckResource { name, }: { name: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/health-check-group/{name}', @@ -63,7 +63,7 @@ export class HealthCheckResource { name, }: { name: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'POST', url: '/umbraco/management/api/v1/health-check-group/{name}/check', @@ -83,8 +83,8 @@ export class HealthCheckResource { public static postHealthCheckExecuteAction({ requestBody, }: { - requestBody?: HealthCheckActionModel, - }): CancelablePromise { + requestBody?: HealthCheckActionRequestModel, + }): CancelablePromise { return __request(OpenAPI, { method: 'POST', url: '/umbraco/management/api/v1/health-check/execute-action', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HelpResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HelpResource.ts index 86bf5f9a4f..e3a76d04ae 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HelpResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/HelpResource.ts @@ -1,7 +1,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedHelpPageModel } from '../models/PagedHelpPageModel'; +import type { PagedHelpPageResponseModel } from '../models/PagedHelpPageResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -10,7 +10,7 @@ import { request as __request } from '../core/request'; export class HelpResource { /** - * @returns PagedHelpPageModel Success + * @returns PagedHelpPageResponseModel Success * @throws ApiError */ public static getHelp({ @@ -25,7 +25,7 @@ export class HelpResource { skip?: number, take?: number, baseUrl?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/help', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/IndexerResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/IndexerResource.ts index e59bb94642..3b8485e122 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/IndexerResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/IndexerResource.ts @@ -1,9 +1,9 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { IndexModel } from '../models/IndexModel'; +import type { IndexResponseModel } from '../models/IndexResponseModel'; import type { OkResultModel } from '../models/OkResultModel'; -import type { PagedIndexModel } from '../models/PagedIndexModel'; +import type { PagedIndexResponseModel } from '../models/PagedIndexResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -12,7 +12,7 @@ import { request as __request } from '../core/request'; export class IndexerResource { /** - * @returns PagedIndexModel Success + * @returns PagedIndexResponseModel Success * @throws ApiError */ public static getIndexer({ @@ -21,7 +21,7 @@ export class IndexerResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/indexer', @@ -40,7 +40,7 @@ export class IndexerResource { indexName, }: { indexName: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/indexer/{indexName}', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/InstallResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/InstallResource.ts index d5e8ae2949..927209fa7d 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/InstallResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/InstallResource.ts @@ -1,9 +1,9 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DatabaseInstallModel } from '../models/DatabaseInstallModel'; -import type { InstallModel } from '../models/InstallModel'; -import type { InstallSettingsModel } from '../models/InstallSettingsModel'; +import type { DatabaseInstallResponseModel } from '../models/DatabaseInstallResponseModel'; +import type { InstallSettingsResponseModel } from '../models/InstallSettingsResponseModel'; +import type { InstallVResponseModel } from '../models/InstallVResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -15,7 +15,7 @@ export class InstallResource { * @returns any Success * @throws ApiError */ - public static getInstallSettings(): CancelablePromise { + public static getInstallSettings(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/install/settings', @@ -33,7 +33,7 @@ export class InstallResource { public static postInstallSetup({ requestBody, }: { - requestBody?: InstallModel, + requestBody?: InstallVResponseModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -54,7 +54,7 @@ export class InstallResource { public static postInstallValidateDatabase({ requestBody, }: { - requestBody?: DatabaseInstallModel, + requestBody?: DatabaseInstallResponseModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LanguageResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LanguageResource.ts index b724860487..cc77a2ee60 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LanguageResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LanguageResource.ts @@ -1,10 +1,11 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { LanguageCreateModel } from '../models/LanguageCreateModel'; -import type { LanguageModel } from '../models/LanguageModel'; -import type { LanguageUpdateModel } from '../models/LanguageUpdateModel'; -import type { PagedLanguageModel } from '../models/PagedLanguageModel'; +import type { CreateLanguageRequestModel } from '../models/CreateLanguageRequestModel'; +import type { LanguageItemResponseModel } from '../models/LanguageItemResponseModel'; +import type { LanguageResponseModel } from '../models/LanguageResponseModel'; +import type { PagedLanguageResponseModel } from '../models/PagedLanguageResponseModel'; +import type { UpdateLanguageRequestModel } from '../models/UpdateLanguageRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -13,7 +14,7 @@ import { request as __request } from '../core/request'; export class LanguageResource { /** - * @returns PagedLanguageModel Success + * @returns PagedLanguageResponseModel Success * @throws ApiError */ public static getLanguage({ @@ -22,7 +23,7 @@ export class LanguageResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/language', @@ -40,7 +41,7 @@ export class LanguageResource { public static postLanguage({ requestBody, }: { - requestBody?: LanguageCreateModel, + requestBody?: CreateLanguageRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -63,7 +64,7 @@ export class LanguageResource { isoCode, }: { isoCode: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/language/{isoCode}', @@ -107,7 +108,7 @@ export class LanguageResource { requestBody, }: { isoCode: string, - requestBody?: LanguageUpdateModel, + requestBody?: UpdateLanguageRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', @@ -124,4 +125,22 @@ export class LanguageResource { }); } + /** + * @returns any Success + * @throws ApiError + */ + public static getLanguageItem({ + isoCode, + }: { + isoCode?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/language/item', + query: { + 'isoCode': isoCode, + }, + }); + } + } diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LogViewerResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LogViewerResource.ts index b768fba3a1..dc8cf7baa1 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LogViewerResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/LogViewerResource.ts @@ -2,13 +2,14 @@ /* tslint:disable */ /* eslint-disable */ import type { DirectionModel } from '../models/DirectionModel'; -import type { LogLevelCountsModel } from '../models/LogLevelCountsModel'; +import type { LogLevelCountsReponseModel } from '../models/LogLevelCountsReponseModel'; import type { LogLevelModel } from '../models/LogLevelModel'; -import type { PagedLoggerModel } from '../models/PagedLoggerModel'; -import type { PagedLogMessageModel } from '../models/PagedLogMessageModel'; -import type { PagedLogTemplateModel } from '../models/PagedLogTemplateModel'; -import type { PagedSavedLogSearchModel } from '../models/PagedSavedLogSearchModel'; -import type { SavedLogSearchModel } from '../models/SavedLogSearchModel'; +import type { PagedLoggerResponseModel } from '../models/PagedLoggerResponseModel'; +import type { PagedLogMessageResponseModel } from '../models/PagedLogMessageResponseModel'; +import type { PagedLogTemplateResponseModel } from '../models/PagedLogTemplateResponseModel'; +import type { PagedSavedLogSearchResponseModel } from '../models/PagedSavedLogSearchResponseModel'; +import type { SavedLogSearchRequestModel } from '../models/SavedLogSearchRequestModel'; +import type { SavedLogSearchResponseModel } from '../models/SavedLogSearchResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -17,7 +18,7 @@ import { request as __request } from '../core/request'; export class LogViewerResource { /** - * @returns PagedLoggerModel Success + * @returns PagedLoggerResponseModel Success * @throws ApiError */ public static getLogViewerLevel({ @@ -26,7 +27,7 @@ export class LogViewerResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/log-viewer/level', @@ -47,7 +48,7 @@ export class LogViewerResource { }: { startDate?: string, endDate?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/log-viewer/level-count', @@ -62,7 +63,7 @@ export class LogViewerResource { } /** - * @returns PagedLogMessageModel Success + * @returns PagedLogMessageResponseModel Success * @throws ApiError */ public static getLogViewerLog({ @@ -81,7 +82,7 @@ export class LogViewerResource { logLevel?: Array, startDate?: string, endDate?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/log-viewer/log', @@ -98,7 +99,7 @@ export class LogViewerResource { } /** - * @returns PagedLogTemplateModel Success + * @returns PagedLogTemplateResponseModel Success * @throws ApiError */ public static getLogViewerMessageTemplate({ @@ -111,7 +112,7 @@ export class LogViewerResource { take?: number, startDate?: string, endDate?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/log-viewer/message-template', @@ -128,7 +129,7 @@ export class LogViewerResource { } /** - * @returns PagedSavedLogSearchModel Success + * @returns PagedSavedLogSearchResponseModel Success * @throws ApiError */ public static getLogViewerSavedSearch({ @@ -137,7 +138,7 @@ export class LogViewerResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/log-viewer/saved-search', @@ -155,7 +156,7 @@ export class LogViewerResource { public static postLogViewerSavedSearch({ requestBody, }: { - requestBody?: SavedLogSearchModel, + requestBody?: SavedLogSearchRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -177,7 +178,7 @@ export class LogViewerResource { name, }: { name: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/log-viewer/saved-search/{name}', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaResource.ts index 074a7704cb..4e0385a534 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaResource.ts @@ -1,10 +1,14 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ContentTreeItemModel } from '../models/ContentTreeItemModel'; -import type { DocumentTreeItemModel } from '../models/DocumentTreeItemModel'; -import type { PagedContentTreeItemModel } from '../models/PagedContentTreeItemModel'; -import type { PagedRecycleBinItemModel } from '../models/PagedRecycleBinItemModel'; +import type { ContentTreeItemResponseModel } from '../models/ContentTreeItemResponseModel'; +import type { CreateMediaRequestModel } from '../models/CreateMediaRequestModel'; +import type { DocumentResponseModel } from '../models/DocumentResponseModel'; +import type { DocumentTreeItemResponseModel } from '../models/DocumentTreeItemResponseModel'; +import type { MediaItemResponseModel } from '../models/MediaItemResponseModel'; +import type { PagedContentTreeItemResponseModel } from '../models/PagedContentTreeItemResponseModel'; +import type { PagedRecycleBinItemResponseModel } from '../models/PagedRecycleBinItemResponseModel'; +import type { UpdateMediaRequestModel } from '../models/UpdateMediaRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -13,23 +17,135 @@ import { request as __request } from '../core/request'; export class MediaResource { /** - * @returns PagedRecycleBinItemModel Success + * @returns string Created + * @throws ApiError + */ + public static postMedia({ + requestBody, + }: { + requestBody?: CreateMediaRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/media', + body: requestBody, + mediaType: 'application/json', + responseHeader: 'Location', + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getMediaById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/media/{id}', + path: { + 'id': id, + }, + errors: { + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static deleteMediaById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/umbraco/management/api/v1/media/{id}', + path: { + 'id': id, + }, + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putMediaById({ + id, + requestBody, + }: { + id: string, + requestBody?: UpdateMediaRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/media/{id}', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getMediaItem({ + id, + dataTypeId, + }: { + id?: Array, + dataTypeId?: string, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/media/item', + query: { + 'id': id, + 'dataTypeId': dataTypeId, + }, + }); + } + + /** + * @returns PagedRecycleBinItemResponseModel Success * @throws ApiError */ public static getRecycleBinMediaChildren({ - parentKey, + parentId, skip, take = 100, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/recycle-bin/media/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, }, @@ -40,7 +156,7 @@ export class MediaResource { } /** - * @returns PagedRecycleBinItemModel Success + * @returns PagedRecycleBinItemResponseModel Success * @throws ApiError */ public static getRecycleBinMediaRoot({ @@ -49,7 +165,7 @@ export class MediaResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/recycle-bin/media/root', @@ -64,28 +180,28 @@ export class MediaResource { } /** - * @returns PagedContentTreeItemModel Success + * @returns PagedContentTreeItemResponseModel Success * @throws ApiError */ public static getTreeMediaChildren({ - parentKey, + parentId, skip, take = 100, - dataTypeKey, + dataTypeId, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, - dataTypeKey?: string, - }): CancelablePromise { + dataTypeId?: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/media/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, - 'dataTypeKey': dataTypeKey, + 'dataTypeId': dataTypeId, }, }); } @@ -95,42 +211,42 @@ export class MediaResource { * @throws ApiError */ public static getTreeMediaItem({ - key, - dataTypeKey, + id, + dataTypeId, }: { - key?: Array, - dataTypeKey?: string, - }): CancelablePromise> { + id?: Array, + dataTypeId?: string, + }): CancelablePromise> { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/media/item', query: { - 'key': key, - 'dataTypeKey': dataTypeKey, + 'id': id, + 'dataTypeId': dataTypeId, }, }); } /** - * @returns PagedContentTreeItemModel Success + * @returns PagedContentTreeItemResponseModel Success * @throws ApiError */ public static getTreeMediaRoot({ skip, take = 100, - dataTypeKey, + dataTypeId, }: { skip?: number, take?: number, - dataTypeKey?: string, - }): CancelablePromise { + dataTypeId?: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/media/root', query: { 'skip': skip, 'take': take, - 'dataTypeKey': dataTypeKey, + 'dataTypeId': dataTypeId, }, }); } diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaTypeResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaTypeResource.ts index 3f4b9b1eed..c86145f403 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaTypeResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MediaTypeResource.ts @@ -1,9 +1,9 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { FolderTreeItemModel } from '../models/FolderTreeItemModel'; -import type { PagedFolderTreeItemModel } from '../models/PagedFolderTreeItemModel'; +import type { MediaTypeItemResponseModel } from '../models/MediaTypeItemResponseModel'; +import type { MediaTypeResponseModel } from '../models/MediaTypeResponseModel'; +import type { PagedFolderTreeItemResponseModel } from '../models/PagedFolderTreeItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -12,28 +12,22 @@ import { request as __request } from '../core/request'; export class MediaTypeResource { /** - * @returns PagedFolderTreeItemModel Success + * @returns any Success * @throws ApiError */ - public static getTreeMediaTypeChildren({ - parentKey, - skip, - take = 100, - foldersOnly = false, + public static getMediaTypeById({ + id, }: { - parentKey?: string, - skip?: number, - take?: number, - foldersOnly?: boolean, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/tree/media-type/children', - query: { - 'parentKey': parentKey, - 'skip': skip, - 'take': take, - 'foldersOnly': foldersOnly, + url: '/umbraco/management/api/v1/media-type/{id}', + path: { + 'id': id, + }, + errors: { + 404: `Not Found`, }, }); } @@ -42,22 +36,49 @@ export class MediaTypeResource { * @returns any Success * @throws ApiError */ - public static getTreeMediaTypeItem({ - key, + public static getMediaTypeItem({ + id, }: { - key?: Array, - }): CancelablePromise> { + id?: Array, + }): CancelablePromise> { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/tree/media-type/item', + url: '/umbraco/management/api/v1/media-type/item', query: { - 'key': key, + 'id': id, }, }); } /** - * @returns PagedFolderTreeItemModel Success + * @returns PagedFolderTreeItemResponseModel Success + * @throws ApiError + */ + public static getTreeMediaTypeChildren({ + parentId, + skip, + take = 100, + foldersOnly = false, + }: { + parentId?: string, + skip?: number, + take?: number, + foldersOnly?: boolean, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/tree/media-type/children', + query: { + 'parentId': parentId, + 'skip': skip, + 'take': take, + 'foldersOnly': foldersOnly, + }, + }); + } + + /** + * @returns PagedFolderTreeItemResponseModel Success * @throws ApiError */ public static getTreeMediaTypeRoot({ @@ -68,7 +89,7 @@ export class MediaTypeResource { skip?: number, take?: number, foldersOnly?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/media-type/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberGroupResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberGroupResource.ts index 0229bafb93..3ef4601fe2 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberGroupResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberGroupResource.ts @@ -1,13 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ContentTreeItemModel } from '../models/ContentTreeItemModel'; -import type { DocumentBlueprintTreeItemModel } from '../models/DocumentBlueprintTreeItemModel'; -import type { DocumentTreeItemModel } from '../models/DocumentTreeItemModel'; -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { EntityTreeItemModel } from '../models/EntityTreeItemModel'; -import type { FolderTreeItemModel } from '../models/FolderTreeItemModel'; -import type { PagedEntityTreeItemModel } from '../models/PagedEntityTreeItemModel'; +import type { MemberGroupItemReponseModel } from '../models/MemberGroupItemReponseModel'; +import type { PagedEntityTreeItemResponseModel } from '../models/PagedEntityTreeItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -19,22 +14,22 @@ export class MemberGroupResource { * @returns any Success * @throws ApiError */ - public static getTreeMemberGroupItem({ - key, + public static getMemberGroupItem({ + id, }: { - key?: Array, - }): CancelablePromise> { + id?: Array, + }): CancelablePromise> { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/tree/member-group/item', + url: '/umbraco/management/api/v1/member-group/item', query: { - 'key': key, + 'id': id, }, }); } /** - * @returns PagedEntityTreeItemModel Success + * @returns PagedEntityTreeItemResponseModel Success * @throws ApiError */ public static getTreeMemberGroupRoot({ @@ -43,7 +38,7 @@ export class MemberGroupResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/member-group/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberTypeResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberTypeResource.ts index c0bda15f8a..3545cb4bca 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberTypeResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/MemberTypeResource.ts @@ -1,13 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ContentTreeItemModel } from '../models/ContentTreeItemModel'; -import type { DocumentBlueprintTreeItemModel } from '../models/DocumentBlueprintTreeItemModel'; -import type { DocumentTreeItemModel } from '../models/DocumentTreeItemModel'; -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { EntityTreeItemModel } from '../models/EntityTreeItemModel'; -import type { FolderTreeItemModel } from '../models/FolderTreeItemModel'; -import type { PagedEntityTreeItemModel } from '../models/PagedEntityTreeItemModel'; +import type { MemberTypeItemResponseModel } from '../models/MemberTypeItemResponseModel'; +import type { PagedEntityTreeItemResponseModel } from '../models/PagedEntityTreeItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -19,22 +14,22 @@ export class MemberTypeResource { * @returns any Success * @throws ApiError */ - public static getTreeMemberTypeItem({ - key, + public static getMemberTypeItem({ + id, }: { - key?: Array, - }): CancelablePromise> { + id?: Array, + }): CancelablePromise> { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/tree/member-type/item', + url: '/umbraco/management/api/v1/member-type/item', query: { - 'key': key, + 'id': id, }, }); } /** - * @returns PagedEntityTreeItemModel Success + * @returns PagedEntityTreeItemResponseModel Success * @throws ApiError */ public static getTreeMemberTypeRoot({ @@ -43,7 +38,7 @@ export class MemberTypeResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/member-type/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ModelsBuilderResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ModelsBuilderResource.ts index 2d078b6c4c..de6f0498bc 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ModelsBuilderResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ModelsBuilderResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ModelsBuilderModel } from '../models/ModelsBuilderModel'; -import type { OutOfDateStatusModel } from '../models/OutOfDateStatusModel'; +import type { ModelsBuilderResponseModel } from '../models/ModelsBuilderResponseModel'; +import type { OutOfDateStatusResponseModel } from '../models/OutOfDateStatusResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -28,7 +28,7 @@ export class ModelsBuilderResource { * @returns any Success * @throws ApiError */ - public static getModelsBuilderDashboard(): CancelablePromise { + public static getModelsBuilderDashboard(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/models-builder/dashboard', @@ -39,7 +39,7 @@ export class ModelsBuilderResource { * @returns any Success * @throws ApiError */ - public static getModelsBuilderStatus(): CancelablePromise { + public static getModelsBuilderStatus(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/models-builder/status', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ObjectTypesResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ObjectTypesResource.ts new file mode 100644 index 0000000000..b25a8644ce --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ObjectTypesResource.ts @@ -0,0 +1,33 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { PagedObjectTypeResponseModel } from '../models/PagedObjectTypeResponseModel'; + +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; + +export class ObjectTypesResource { + + /** + * @returns PagedObjectTypeResponseModel Success + * @throws ApiError + */ + public static getObjectTypes({ + skip, + take = 100, + }: { + skip?: number, + take?: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/object-types', + query: { + 'skip': skip, + 'take': take, + }, + }); + } + +} diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PackageResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PackageResource.ts index 4af66aa239..0d64af3fd7 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PackageResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PackageResource.ts @@ -1,12 +1,12 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PackageCreateModel } from '../models/PackageCreateModel'; -import type { PackageDefinitionModel } from '../models/PackageDefinitionModel'; -import type { PackageManifestModel } from '../models/PackageManifestModel'; -import type { PackageUpdateModel } from '../models/PackageUpdateModel'; -import type { PagedPackageDefinitionModel } from '../models/PagedPackageDefinitionModel'; -import type { PagedPackageMigrationStatusModel } from '../models/PagedPackageMigrationStatusModel'; +import type { CreatePackageRequestModel } from '../models/CreatePackageRequestModel'; +import type { PackageDefinitionResponseModel } from '../models/PackageDefinitionResponseModel'; +import type { PackageManifestResponseModel } from '../models/PackageManifestResponseModel'; +import type { PagedPackageDefinitionResponseModel } from '../models/PagedPackageDefinitionResponseModel'; +import type { PagedPackageMigrationStatusResponseModel } from '../models/PagedPackageMigrationStatusResponseModel'; +import type { UpdatePackageRequestModel } from '../models/UpdatePackageRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -37,7 +37,7 @@ export class PackageResource { } /** - * @returns PagedPackageDefinitionModel Success + * @returns PagedPackageDefinitionResponseModel Success * @throws ApiError */ public static getPackageCreated({ @@ -46,7 +46,7 @@ export class PackageResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/package/created', @@ -64,7 +64,7 @@ export class PackageResource { public static postPackageCreated({ requestBody, }: { - requestBody?: PackageCreateModel, + requestBody?: CreatePackageRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -83,16 +83,16 @@ export class PackageResource { * @returns any Success * @throws ApiError */ - public static getPackageCreatedByKey({ - key, + public static getPackageCreatedById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/package/created/{key}', + url: '/umbraco/management/api/v1/package/created/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -104,16 +104,16 @@ export class PackageResource { * @returns any Success * @throws ApiError */ - public static deletePackageCreatedByKey({ - key, + public static deletePackageCreatedById({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'DELETE', - url: '/umbraco/management/api/v1/package/created/{key}', + url: '/umbraco/management/api/v1/package/created/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -125,18 +125,18 @@ export class PackageResource { * @returns any Success * @throws ApiError */ - public static putPackageCreatedByKey({ - key, + public static putPackageCreatedById({ + id, requestBody, }: { - key: string, - requestBody?: PackageUpdateModel, + id: string, + requestBody?: UpdatePackageRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', - url: '/umbraco/management/api/v1/package/created/{key}', + url: '/umbraco/management/api/v1/package/created/{id}', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -150,16 +150,16 @@ export class PackageResource { * @returns binary Success * @throws ApiError */ - public static getPackageCreatedByKeyDownload({ - key, + public static getPackageCreatedByIdDownload({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/package/created/{key}/download', + url: '/umbraco/management/api/v1/package/created/{id}/download', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -171,7 +171,7 @@ export class PackageResource { * @returns any Success * @throws ApiError */ - public static getPackageManifest(): CancelablePromise> { + public static getPackageManifest(): CancelablePromise> { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/package/manifest', @@ -179,7 +179,7 @@ export class PackageResource { } /** - * @returns PagedPackageMigrationStatusModel Success + * @returns PagedPackageMigrationStatusResponseModel Success * @throws ApiError */ public static getPackageMigrationStatus({ @@ -188,7 +188,7 @@ export class PackageResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/package/migration-status', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PartialViewResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PartialViewResource.ts index 4ec4cce563..3bceafadbc 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PartialViewResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/PartialViewResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { FileSystemTreeItemModel } from '../models/FileSystemTreeItemModel'; -import type { PagedFileSystemTreeItemModel } from '../models/PagedFileSystemTreeItemModel'; +import type { PagedFileSystemTreeItemPresentationModel } from '../models/PagedFileSystemTreeItemPresentationModel'; +import type { PartialViewItemResponseModel } from '../models/PartialViewItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -11,7 +11,25 @@ import { request as __request } from '../core/request'; export class PartialViewResource { /** - * @returns PagedFileSystemTreeItemModel Success + * @returns any Success + * @throws ApiError + */ + public static getPartialViewItem({ + id, + }: { + id?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/partial-view/item', + query: { + 'id': id, + }, + }); + } + + /** + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreePartialViewChildren({ @@ -22,7 +40,7 @@ export class PartialViewResource { path?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/partial-view/children', @@ -35,25 +53,7 @@ export class PartialViewResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreePartialViewItem({ - path, - }: { - path?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/partial-view/item', - query: { - 'path': path, - }, - }); - } - - /** - * @returns PagedFileSystemTreeItemModel Success + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreePartialViewRoot({ @@ -62,7 +62,7 @@ export class PartialViewResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/partial-view/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ProfilingResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ProfilingResource.ts index c5d65d6bdc..81422ff13b 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ProfilingResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ProfilingResource.ts @@ -1,7 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ProfilingStatusModel } from '../models/ProfilingStatusModel'; +import type { ProfilingStatusRequestModel } from '../models/ProfilingStatusRequestModel'; +import type { ProfilingStatusResponseModel } from '../models/ProfilingStatusResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -13,7 +14,7 @@ export class ProfilingResource { * @returns any Success * @throws ApiError */ - public static getProfilingStatus(): CancelablePromise { + public static getProfilingStatus(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/profiling/status', @@ -27,7 +28,7 @@ export class ProfilingResource { public static putProfilingStatus({ requestBody, }: { - requestBody?: ProfilingStatusModel, + requestBody?: ProfilingStatusRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RedirectManagementResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RedirectManagementResource.ts index aa15ce40ac..2d12b27858 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RedirectManagementResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RedirectManagementResource.ts @@ -1,9 +1,9 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedRedirectUrlModel } from '../models/PagedRedirectUrlModel'; +import type { PagedRedirectUrlResponseModel } from '../models/PagedRedirectUrlResponseModel'; import type { RedirectStatusModel } from '../models/RedirectStatusModel'; -import type { RedirectUrlStatusModel } from '../models/RedirectUrlStatusModel'; +import type { RedirectUrlStatusResponseModel } from '../models/RedirectUrlStatusResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -12,7 +12,7 @@ import { request as __request } from '../core/request'; export class RedirectManagementResource { /** - * @returns PagedRedirectUrlModel Success + * @returns PagedRedirectUrlResponseModel Success * @throws ApiError */ public static getRedirectManagement({ @@ -23,7 +23,7 @@ export class RedirectManagementResource { filter?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/redirect-management', @@ -39,23 +39,23 @@ export class RedirectManagementResource { } /** - * @returns PagedRedirectUrlModel Success + * @returns PagedRedirectUrlResponseModel Success * @throws ApiError */ - public static getRedirectManagementByKey({ - key, + public static getRedirectManagementById({ + id, skip, take, }: { - key: string, + id: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/redirect-management/{key}', + url: '/umbraco/management/api/v1/redirect-management/{id}', path: { - 'key': key, + 'id': id, }, query: { 'skip': skip, @@ -68,16 +68,16 @@ export class RedirectManagementResource { * @returns any Success * @throws ApiError */ - public static deleteRedirectManagementByKey({ - key, + public static deleteRedirectManagementById({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'DELETE', - url: '/umbraco/management/api/v1/redirect-management/{key}', + url: '/umbraco/management/api/v1/redirect-management/{id}', path: { - 'key': key, + 'id': id, }, }); } @@ -86,7 +86,7 @@ export class RedirectManagementResource { * @returns any Success * @throws ApiError */ - public static getRedirectManagementStatus(): CancelablePromise { + public static getRedirectManagementStatus(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/redirect-management/status', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationResource.ts index df5460a1e4..3c5ef6f3c7 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedRelationModel } from '../models/PagedRelationModel'; -import type { RelationModel } from '../models/RelationModel'; +import type { PagedRelationResponseModel } from '../models/PagedRelationResponseModel'; +import type { RelationResponseModel } from '../models/RelationResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -18,7 +18,7 @@ export class RelationResource { id, }: { id: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/relation/{id}', @@ -32,7 +32,7 @@ export class RelationResource { } /** - * @returns PagedRelationModel Success + * @returns PagedRelationResponseModel Success * @throws ApiError */ public static getRelationChildRelationByChildId({ @@ -45,7 +45,7 @@ export class RelationResource { skip?: number, take?: number, relationTypeAlias?: string, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/relation/child-relation/{childId}', @@ -60,4 +60,30 @@ export class RelationResource { }); } + /** + * @returns PagedRelationResponseModel Success + * @throws ApiError + */ + public static getRelationTypeById({ + id, + skip, + take = 100, + }: { + id: string, + skip?: number, + take?: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/relation/type/{id}', + path: { + 'id': id, + }, + query: { + 'skip': skip, + 'take': take, + }, + }); + } + } diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationTypeResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationTypeResource.ts index 9d36d51255..76f60d04a6 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationTypeResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/RelationTypeResource.ts @@ -1,9 +1,11 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { FolderTreeItemModel } from '../models/FolderTreeItemModel'; -import type { PagedEntityTreeItemModel } from '../models/PagedEntityTreeItemModel'; +import type { CreateRelationTypeRequestModel } from '../models/CreateRelationTypeRequestModel'; +import type { PagedEntityTreeItemResponseModel } from '../models/PagedEntityTreeItemResponseModel'; +import type { RelationTypeItemResponseModel } from '../models/RelationTypeItemResponseModel'; +import type { RelationTypeResponseModel } from '../models/RelationTypeResponseModel'; +import type { UpdateRelationTypeRequestModel } from '../models/UpdateRelationTypeRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -12,25 +14,114 @@ import { request as __request } from '../core/request'; export class RelationTypeResource { /** - * @returns any Success + * @returns string Created * @throws ApiError */ - public static getTreeRelationTypeItem({ - key, + public static postRelationType({ + requestBody, }: { - key?: Array, - }): CancelablePromise> { + requestBody?: CreateRelationTypeRequestModel, + }): CancelablePromise { return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/relation-type/item', - query: { - 'key': key, + method: 'POST', + url: '/umbraco/management/api/v1/relation-type', + body: requestBody, + mediaType: 'application/json', + responseHeader: 'Location', + errors: { + 400: `Bad Request`, }, }); } /** - * @returns PagedEntityTreeItemModel Success + * @returns any Success + * @throws ApiError + */ + public static getRelationTypeById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/relation-type/{id}', + path: { + 'id': id, + }, + errors: { + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static deleteRelationTypeById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/umbraco/management/api/v1/relation-type/{id}', + path: { + 'id': id, + }, + errors: { + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putRelationTypeById({ + id, + requestBody, + }: { + id: string, + requestBody?: UpdateRelationTypeRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/relation-type/{id}', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getRelationTypeItem({ + id, + }: { + id?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/relation-type/item', + query: { + 'id': id, + }, + }); + } + + /** + * @returns PagedEntityTreeItemResponseModel Success * @throws ApiError */ public static getTreeRelationTypeRoot({ @@ -39,7 +130,7 @@ export class RelationTypeResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/relation-type/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ScriptResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ScriptResource.ts index 0b36985d82..7804889dd5 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ScriptResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ScriptResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { FileSystemTreeItemModel } from '../models/FileSystemTreeItemModel'; -import type { PagedFileSystemTreeItemModel } from '../models/PagedFileSystemTreeItemModel'; +import type { PagedFileSystemTreeItemPresentationModel } from '../models/PagedFileSystemTreeItemPresentationModel'; +import type { ScriptItemResponseModel } from '../models/ScriptItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -11,7 +11,25 @@ import { request as __request } from '../core/request'; export class ScriptResource { /** - * @returns PagedFileSystemTreeItemModel Success + * @returns any Success + * @throws ApiError + */ + public static getScriptItem({ + path, + }: { + path?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/script/item', + query: { + 'path': path, + }, + }); + } + + /** + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreeScriptChildren({ @@ -22,7 +40,7 @@ export class ScriptResource { path?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/script/children', @@ -35,25 +53,7 @@ export class ScriptResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeScriptItem({ - path, - }: { - path?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/script/item', - query: { - 'path': path, - }, - }); - } - - /** - * @returns PagedFileSystemTreeItemModel Success + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreeScriptRoot({ @@ -62,7 +62,7 @@ export class ScriptResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/script/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/SearcherResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/SearcherResource.ts index 7792b73095..68b20fe3ee 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/SearcherResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/SearcherResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedSearcherModel } from '../models/PagedSearcherModel'; -import type { PagedSearchResultModel } from '../models/PagedSearchResultModel'; +import type { PagedSearcherResponseModel } from '../models/PagedSearcherResponseModel'; +import type { PagedSearchResultResponseModel } from '../models/PagedSearchResultResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -11,7 +11,7 @@ import { request as __request } from '../core/request'; export class SearcherResource { /** - * @returns PagedSearcherModel Success + * @returns PagedSearcherResponseModel Success * @throws ApiError */ public static getSearcher({ @@ -20,7 +20,7 @@ export class SearcherResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/searcher', @@ -32,7 +32,7 @@ export class SearcherResource { } /** - * @returns PagedSearchResultModel Success + * @returns PagedSearchResultResponseModel Success * @throws ApiError */ public static getSearcherBySearcherNameQuery({ @@ -45,7 +45,7 @@ export class SearcherResource { term?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/searcher/{searcherName}/query', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ServerResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ServerResource.ts index a2351ca654..364c15ac2a 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ServerResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/ServerResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ServerStatusModel } from '../models/ServerStatusModel'; -import type { VersionModel } from '../models/VersionModel'; +import type { ServerStatusResponseModel } from '../models/ServerStatusResponseModel'; +import type { VersionResponseModel } from '../models/VersionResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -14,7 +14,7 @@ export class ServerResource { * @returns any Success * @throws ApiError */ - public static getServerStatus(): CancelablePromise { + public static getServerStatus(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/server/status', @@ -28,7 +28,7 @@ export class ServerResource { * @returns any Success * @throws ApiError */ - public static getServerVersion(): CancelablePromise { + public static getServerVersion(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/server/version', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StaticFileResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StaticFileResource.ts index 2ed706ee95..83645d7d1f 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StaticFileResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StaticFileResource.ts @@ -1,8 +1,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { FileSystemTreeItemModel } from '../models/FileSystemTreeItemModel'; -import type { PagedFileSystemTreeItemModel } from '../models/PagedFileSystemTreeItemModel'; +import type { PagedFileSystemTreeItemPresentationModel } from '../models/PagedFileSystemTreeItemPresentationModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -11,7 +10,7 @@ import { request as __request } from '../core/request'; export class StaticFileResource { /** - * @returns PagedFileSystemTreeItemModel Success + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreeStaticFileChildren({ @@ -22,7 +21,7 @@ export class StaticFileResource { path?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/static-file/children', @@ -35,25 +34,7 @@ export class StaticFileResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeStaticFileItem({ - path, - }: { - path?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/static-file/item', - query: { - 'path': path, - }, - }); - } - - /** - * @returns PagedFileSystemTreeItemModel Success + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreeStaticFileRoot({ @@ -62,7 +43,7 @@ export class StaticFileResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/static-file/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StylesheetResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StylesheetResource.ts index 1e48b59a58..f219e34cfd 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StylesheetResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/StylesheetResource.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { FileSystemTreeItemModel } from '../models/FileSystemTreeItemModel'; -import type { PagedFileSystemTreeItemModel } from '../models/PagedFileSystemTreeItemModel'; +import type { PagedFileSystemTreeItemPresentationModel } from '../models/PagedFileSystemTreeItemPresentationModel'; +import type { ScriptItemResponseModel } from '../models/ScriptItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -11,7 +11,25 @@ import { request as __request } from '../core/request'; export class StylesheetResource { /** - * @returns PagedFileSystemTreeItemModel Success + * @returns any Success + * @throws ApiError + */ + public static getStylesheetItem({ + path, + }: { + path?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/stylesheet/item', + query: { + 'path': path, + }, + }); + } + + /** + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreeStylesheetChildren({ @@ -22,7 +40,7 @@ export class StylesheetResource { path?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/stylesheet/children', @@ -35,25 +53,7 @@ export class StylesheetResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeStylesheetItem({ - path, - }: { - path?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/stylesheet/item', - query: { - 'path': path, - }, - }); - } - - /** - * @returns PagedFileSystemTreeItemModel Success + * @returns PagedFileSystemTreeItemPresentationModel Success * @throws ApiError */ public static getTreeStylesheetRoot({ @@ -62,7 +62,7 @@ export class StylesheetResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/stylesheet/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TelemetryResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TelemetryResource.ts index 2c27fcfa93..19975410d0 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TelemetryResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TelemetryResource.ts @@ -1,8 +1,9 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedTelemetryModel } from '../models/PagedTelemetryModel'; -import type { TelemetryModel } from '../models/TelemetryModel'; +import type { PagedTelemetryResponseModel } from '../models/PagedTelemetryResponseModel'; +import type { TelemetryRequestModel } from '../models/TelemetryRequestModel'; +import type { TelemetryResponseModel } from '../models/TelemetryResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -11,7 +12,7 @@ import { request as __request } from '../core/request'; export class TelemetryResource { /** - * @returns PagedTelemetryModel Success + * @returns PagedTelemetryResponseModel Success * @throws ApiError */ public static getTelemetry({ @@ -20,7 +21,7 @@ export class TelemetryResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/telemetry', @@ -35,7 +36,7 @@ export class TelemetryResource { * @returns any Success * @throws ApiError */ - public static getTelemetryLevel(): CancelablePromise { + public static getTelemetryLevel(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/telemetry/level', @@ -49,7 +50,7 @@ export class TelemetryResource { public static postTelemetryLevel({ requestBody, }: { - requestBody?: TelemetryModel, + requestBody?: TelemetryRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TemplateResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TemplateResource.ts index 32a9e49aae..b7568d4a24 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TemplateResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TemplateResource.ts @@ -1,20 +1,15 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ContentTreeItemModel } from '../models/ContentTreeItemModel'; -import type { DocumentBlueprintTreeItemModel } from '../models/DocumentBlueprintTreeItemModel'; -import type { DocumentTreeItemModel } from '../models/DocumentTreeItemModel'; -import type { DocumentTypeTreeItemModel } from '../models/DocumentTypeTreeItemModel'; -import type { EntityTreeItemModel } from '../models/EntityTreeItemModel'; -import type { FolderTreeItemModel } from '../models/FolderTreeItemModel'; -import type { PagedEntityTreeItemModel } from '../models/PagedEntityTreeItemModel'; -import type { TemplateCreateModel } from '../models/TemplateCreateModel'; -import type { TemplateModel } from '../models/TemplateModel'; +import type { CreateTemplateRequestModel } from '../models/CreateTemplateRequestModel'; +import type { PagedEntityTreeItemResponseModel } from '../models/PagedEntityTreeItemResponseModel'; +import type { TemplateItemResponseModel } from '../models/TemplateItemResponseModel'; import type { TemplateQueryExecuteModel } from '../models/TemplateQueryExecuteModel'; -import type { TemplateQueryResultModel } from '../models/TemplateQueryResultModel'; -import type { TemplateQuerySettingsModel } from '../models/TemplateQuerySettingsModel'; -import type { TemplateScaffoldModel } from '../models/TemplateScaffoldModel'; -import type { TemplateUpdateModel } from '../models/TemplateUpdateModel'; +import type { TemplateQueryResultResponseModel } from '../models/TemplateQueryResultResponseModel'; +import type { TemplateQuerySettingsResponseModel } from '../models/TemplateQuerySettingsResponseModel'; +import type { TemplateResponseModel } from '../models/TemplateResponseModel'; +import type { TemplateScaffoldResponseModel } from '../models/TemplateScaffoldResponseModel'; +import type { UpdateTemplateRequestModel } from '../models/UpdateTemplateRequestModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -29,7 +24,7 @@ export class TemplateResource { public static postTemplate({ requestBody, }: { - requestBody?: TemplateCreateModel, + requestBody?: CreateTemplateRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -48,16 +43,16 @@ export class TemplateResource { * @returns any Success * @throws ApiError */ - public static getTemplateByKey({ - key, + public static getTemplateById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/template/{key}', + url: '/umbraco/management/api/v1/template/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -69,16 +64,16 @@ export class TemplateResource { * @returns any Success * @throws ApiError */ - public static deleteTemplateByKey({ - key, + public static deleteTemplateById({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'DELETE', - url: '/umbraco/management/api/v1/template/{key}', + url: '/umbraco/management/api/v1/template/{id}', path: { - 'key': key, + 'id': id, }, errors: { 400: `Bad Request`, @@ -91,18 +86,18 @@ export class TemplateResource { * @returns any Success * @throws ApiError */ - public static putTemplateByKey({ - key, + public static putTemplateById({ + id, requestBody, }: { - key: string, - requestBody?: TemplateUpdateModel, + id: string, + requestBody?: UpdateTemplateRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', - url: '/umbraco/management/api/v1/template/{key}', + url: '/umbraco/management/api/v1/template/{id}', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', @@ -113,6 +108,24 @@ export class TemplateResource { }); } + /** + * @returns any Success + * @throws ApiError + */ + public static getTemplateItem({ + id, + }: { + id?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/template/item', + query: { + 'id': id, + }, + }); + } + /** * @returns any Success * @throws ApiError @@ -121,7 +134,7 @@ export class TemplateResource { requestBody, }: { requestBody?: TemplateQueryExecuteModel, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'POST', url: '/umbraco/management/api/v1/template/query/execute', @@ -134,7 +147,7 @@ export class TemplateResource { * @returns any Success * @throws ApiError */ - public static getTemplateQuerySettings(): CancelablePromise { + public static getTemplateQuerySettings(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/template/query/settings', @@ -145,7 +158,7 @@ export class TemplateResource { * @returns any Success * @throws ApiError */ - public static getTemplateScaffold(): CancelablePromise { + public static getTemplateScaffold(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/template/scaffold', @@ -156,23 +169,23 @@ export class TemplateResource { } /** - * @returns PagedEntityTreeItemModel Success + * @returns PagedEntityTreeItemResponseModel Success * @throws ApiError */ public static getTreeTemplateChildren({ - parentKey, + parentId, skip, take = 100, }: { - parentKey?: string, + parentId?: string, skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/template/children', query: { - 'parentKey': parentKey, + 'parentId': parentId, 'skip': skip, 'take': take, }, @@ -180,25 +193,7 @@ export class TemplateResource { } /** - * @returns any Success - * @throws ApiError - */ - public static getTreeTemplateItem({ - key, - }: { - key?: Array, - }): CancelablePromise> { - return __request(OpenAPI, { - method: 'GET', - url: '/umbraco/management/api/v1/tree/template/item', - query: { - 'key': key, - }, - }); - } - - /** - * @returns PagedEntityTreeItemModel Success + * @returns PagedEntityTreeItemResponseModel Success * @throws ApiError */ public static getTreeTemplateRoot({ @@ -207,7 +202,7 @@ export class TemplateResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tree/template/root', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TemporaryFileResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TemporaryFileResource.ts new file mode 100644 index 0000000000..44dc7b5f19 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TemporaryFileResource.ts @@ -0,0 +1,80 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { TemporaryFileResponseModel } from '../models/TemporaryFileResponseModel'; + +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; + +export class TemporaryFileResource { + + /** + * @returns string Created + * @throws ApiError + */ + public static postTemporaryfile({ + formData, + }: { + formData?: { + Id?: string; + File?: Blob; + }, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/temporaryfile', + formData: formData, + mediaType: 'multipart/form-data', + responseHeader: 'Location', + errors: { + 400: `Bad Request`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getTemporaryfileById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/temporaryfile/{id}', + path: { + 'id': id, + }, + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static deleteTemporaryfileById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/umbraco/management/api/v1/temporaryfile/{id}', + path: { + 'id': id, + }, + errors: { + 400: `Bad Request`, + 404: `Not Found`, + }, + }); + } + +} diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TrackedReferenceResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TrackedReferenceResource.ts index e5637971a9..2ba114f3a2 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TrackedReferenceResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/TrackedReferenceResource.ts @@ -1,7 +1,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedRelationItemModel } from '../models/PagedRelationItemModel'; +import type { PagedRelationItemResponseModel } from '../models/PagedRelationItemResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -10,25 +10,25 @@ import { request as __request } from '../core/request'; export class TrackedReferenceResource { /** - * @returns PagedRelationItemModel Success + * @returns PagedRelationItemResponseModel Success * @throws ApiError */ - public static getTrackedReferenceByKey({ - key, + public static getTrackedReferenceById({ + id, skip, take = 20, filterMustBeIsDependency = false, }: { - key: string, + id: string, skip?: number, take?: number, filterMustBeIsDependency?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/tracked-reference/{key}', + url: '/umbraco/management/api/v1/tracked-reference/{id}', path: { - 'key': key, + 'id': id, }, query: { 'skip': skip, @@ -39,25 +39,25 @@ export class TrackedReferenceResource { } /** - * @returns PagedRelationItemModel Success + * @returns PagedRelationItemResponseModel Success * @throws ApiError */ - public static getTrackedReferenceDescendantsByParentKey({ - parentKey, + public static getTrackedReferenceDescendantsByParentId({ + parentId, skip, take, filterMustBeIsDependency = true, }: { - parentKey: string, + parentId: string, skip?: number, take?: number, filterMustBeIsDependency?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/tracked-reference/descendants/{parentKey}', + url: '/umbraco/management/api/v1/tracked-reference/descendants/{parentId}', path: { - 'parentKey': parentKey, + 'parentId': parentId, }, query: { 'skip': skip, @@ -68,25 +68,25 @@ export class TrackedReferenceResource { } /** - * @returns PagedRelationItemModel Success + * @returns PagedRelationItemResponseModel Success * @throws ApiError */ public static getTrackedReferenceItem({ - key, + id, skip, take = 20, filterMustBeIsDependency = true, }: { - key?: Array, + id?: Array, skip?: number, take?: number, filterMustBeIsDependency?: boolean, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/tracked-reference/item', query: { - 'key': key, + 'id': id, 'skip': skip, 'take': take, 'filterMustBeIsDependency': filterMustBeIsDependency, diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UpgradeResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UpgradeResource.ts index 472f46ea16..9ea941f41d 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UpgradeResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UpgradeResource.ts @@ -1,7 +1,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { UpgradeSettingsModel } from '../models/UpgradeSettingsModel'; +import type { UpgradeSettingsResponseModel } from '../models/UpgradeSettingsResponseModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -28,7 +28,7 @@ export class UpgradeResource { * @returns any Success * @throws ApiError */ - public static getUpgradeSettings(): CancelablePromise { + public static getUpgradeSettings(): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/upgrade/settings', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UserGroupsResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UserGroupsResource.ts index eefa1fcb91..c161c4e304 100644 --- a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UserGroupsResource.ts +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UserGroupsResource.ts @@ -1,10 +1,10 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { PagedUserGroupModel } from '../models/PagedUserGroupModel'; -import type { UserGroupModel } from '../models/UserGroupModel'; -import type { UserGroupSaveModel } from '../models/UserGroupSaveModel'; -import type { UserGroupUpdateModel } from '../models/UserGroupUpdateModel'; +import type { PagedUserGroupPresentationModel } from '../models/PagedUserGroupPresentationModel'; +import type { SaveUserGroupRequestModel } from '../models/SaveUserGroupRequestModel'; +import type { UpdateUserGroupRequestModel } from '../models/UpdateUserGroupRequestModel'; +import type { UserGroupPresentationModel } from '../models/UserGroupPresentationModel'; import type { CancelablePromise } from '../core/CancelablePromise'; import { OpenAPI } from '../core/OpenAPI'; @@ -19,7 +19,7 @@ export class UserGroupsResource { public static postUserGroups({ requestBody, }: { - requestBody?: UserGroupSaveModel, + requestBody?: SaveUserGroupRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'POST', @@ -34,7 +34,7 @@ export class UserGroupsResource { } /** - * @returns PagedUserGroupModel Success + * @returns PagedUserGroupPresentationModel Success * @throws ApiError */ public static getUserGroups({ @@ -43,7 +43,7 @@ export class UserGroupsResource { }: { skip?: number, take?: number, - }): CancelablePromise { + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', url: '/umbraco/management/api/v1/user-groups', @@ -58,16 +58,16 @@ export class UserGroupsResource { * @returns any Success * @throws ApiError */ - public static getUserGroupsByKey({ - key, + public static getUserGroupsById({ + id, }: { - key: string, - }): CancelablePromise { + id: string, + }): CancelablePromise { return __request(OpenAPI, { method: 'GET', - url: '/umbraco/management/api/v1/user-groups/{key}', + url: '/umbraco/management/api/v1/user-groups/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -79,16 +79,16 @@ export class UserGroupsResource { * @returns any Success * @throws ApiError */ - public static deleteUserGroupsByKey({ - key, + public static deleteUserGroupsById({ + id, }: { - key: string, + id: string, }): CancelablePromise { return __request(OpenAPI, { method: 'DELETE', - url: '/umbraco/management/api/v1/user-groups/{key}', + url: '/umbraco/management/api/v1/user-groups/{id}', path: { - 'key': key, + 'id': id, }, errors: { 404: `Not Found`, @@ -100,18 +100,18 @@ export class UserGroupsResource { * @returns any Success * @throws ApiError */ - public static putUserGroupsByKey({ - key, + public static putUserGroupsById({ + id, requestBody, }: { - key: string, - requestBody?: UserGroupUpdateModel, + id: string, + requestBody?: UpdateUserGroupRequestModel, }): CancelablePromise { return __request(OpenAPI, { method: 'PUT', - url: '/umbraco/management/api/v1/user-groups/{key}', + url: '/umbraco/management/api/v1/user-groups/{id}', path: { - 'key': key, + 'id': id, }, body: requestBody, mediaType: 'application/json', diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UsersResource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UsersResource.ts new file mode 100644 index 0000000000..e2b78bae8a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/UsersResource.ts @@ -0,0 +1,323 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ChangePasswordUserRequestModel } from '../models/ChangePasswordUserRequestModel'; +import type { CreateUserRequestModel } from '../models/CreateUserRequestModel'; +import type { CreateUserResponseModel } from '../models/CreateUserResponseModel'; +import type { DirectionModel } from '../models/DirectionModel'; +import type { DisableUserRequestModel } from '../models/DisableUserRequestModel'; +import type { EnableUserRequestModel } from '../models/EnableUserRequestModel'; +import type { InviteUserRequestModel } from '../models/InviteUserRequestModel'; +import type { PagedUserResponseModel } from '../models/PagedUserResponseModel'; +import type { SetAvatarRequestModel } from '../models/SetAvatarRequestModel'; +import type { UnlockUsersRequestModel } from '../models/UnlockUsersRequestModel'; +import type { UpdateUserGroupsOnUserRequestModel } from '../models/UpdateUserGroupsOnUserRequestModel'; +import type { UpdateUserRequestModel } from '../models/UpdateUserRequestModel'; +import type { UserOrderModel } from '../models/UserOrderModel'; +import type { UserResponseModel } from '../models/UserResponseModel'; +import type { UserStateModel } from '../models/UserStateModel'; + +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; + +export class UsersResource { + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsers({ + requestBody, + }: { + requestBody?: (CreateUserRequestModel | InviteUserRequestModel), + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + }, + }); + } + + /** + * @returns PagedUserResponseModel Success + * @throws ApiError + */ + public static getUsers({ + skip, + take = 100, + }: { + skip?: number, + take?: number, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/users', + query: { + 'skip': skip, + 'take': take, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getUsersById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/users/{id}', + path: { + 'id': id, + }, + errors: { + 404: `Not Found`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static deleteUsersById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/umbraco/management/api/v1/users/{id}', + path: { + 'id': id, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static putUsersById({ + id, + requestBody, + }: { + id: string, + requestBody?: UpdateUserRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/umbraco/management/api/v1/users/{id}', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static deleteUsersAvatarById({ + id, + }: { + id: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'DELETE', + url: '/umbraco/management/api/v1/users/avatar/{id}', + path: { + 'id': id, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsersAvatarById({ + id, + requestBody, + }: { + id: string, + requestBody?: SetAvatarRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users/avatar/{id}', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsersChangePasswordById({ + id, + requestBody, + }: { + id: string, + requestBody?: ChangePasswordUserRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users/change-password/{id}', + path: { + 'id': id, + }, + body: requestBody, + mediaType: 'application/json', + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsersDisable({ + requestBody, + }: { + requestBody?: DisableUserRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users/disable', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsersEnable({ + requestBody, + }: { + requestBody?: EnableUserRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users/enable', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static getUsersFilter({ + skip, + take = 100, + orderBy, + orderDirection, + userGroupIds, + userStates, + filter = '', + }: { + skip?: number, + take?: number, + orderBy?: UserOrderModel, + orderDirection?: DirectionModel, + userGroupIds?: Array, + userStates?: Array, + filter?: string, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/umbraco/management/api/v1/users/filter', + query: { + 'skip': skip, + 'take': take, + 'orderBy': orderBy, + 'orderDirection': orderDirection, + 'userGroupIds': userGroupIds, + 'userStates': userStates, + 'filter': filter, + }, + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsersInvite({ + requestBody, + }: { + requestBody?: InviteUserRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users/invite', + body: requestBody, + mediaType: 'application/json', + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsersSetUserGroups({ + requestBody, + }: { + requestBody?: UpdateUserGroupsOnUserRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users/set-user-groups', + body: requestBody, + mediaType: 'application/json', + }); + } + + /** + * @returns any Success + * @throws ApiError + */ + public static postUsersUnlock({ + requestBody, + }: { + requestBody?: UnlockUsersRequestModel, + }): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/umbraco/management/api/v1/users/unlock', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Bad Request`, + }, + }); + } + +} diff --git a/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/V1Resource.ts b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/V1Resource.ts new file mode 100644 index 0000000000..d63c01efe2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/backend-api/src/services/V1Resource.ts @@ -0,0 +1,30 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { StaticFileItemResponseModel } from '../models/StaticFileItemResponseModel'; + +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; + +export class V1Resource { + + /** + * @returns any Success + * @throws ApiError + */ + public static getItem({ + path, + }: { + path?: Array, + }): CancelablePromise> { + return __request(OpenAPI, { + method: 'GET', + url: '/item', + query: { + 'path': path, + }, + }); + } + +} diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.controller.ts b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.controller.ts index fe96b6e817..ed5bd3eeb2 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.controller.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.controller.ts @@ -1,10 +1,10 @@ -import { UmbContextToken } from '../context-token'; +import { UmbContextToken } from '../token/context-token'; import { UmbContextConsumer } from './context-consumer'; import { UmbContextCallback } from './context-request.event'; -import type { UmbControllerHostInterface, UmbControllerInterface } from '@umbraco-cms/controller'; +import type { UmbControllerHostElement, UmbControllerInterface } from '@umbraco-cms/backoffice/controller'; export class UmbContextConsumerController - extends UmbContextConsumer + extends UmbContextConsumer implements UmbControllerInterface { public get unique() { @@ -12,7 +12,7 @@ export class UmbContextConsumerController } constructor( - host: UmbControllerHostInterface, + host: UmbControllerHostElement, contextAlias: string | UmbContextToken, callback: UmbContextCallback ) { diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.ts b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.ts index 0fe4fc33d8..32bc1781a8 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-consumer.ts @@ -1,4 +1,4 @@ -import { UmbContextToken } from '../context-token'; +import { UmbContextToken } from '../token/context-token'; import { isUmbContextProvideEventType, umbContextProvideEventType } from '../provide/context-provide.event'; import { UmbContextRequestEventImplementation, UmbContextCallback } from './context-request.event'; @@ -7,10 +7,8 @@ import { UmbContextRequestEventImplementation, UmbContextCallback } from './cont * @class UmbContextConsumer */ export class UmbContextConsumer { - - _promise?: Promise; - _promiseResolver?: (instance:T) => void; + _promiseResolver?: (instance: T) => void; private _instance?: T; get instance() { @@ -38,15 +36,22 @@ export class UmbContextConsumer { + // TODO: check that this check is not giving us any problems: + if (this._instance === instance) { + return; + } this._instance = instance; this._callback?.(instance); this._promiseResolver?.(instance); }; public asPromise() { - return this._promise || (this._promise = new Promise((resolve) => { - this._instance ? resolve(this._instance) : (this._promiseResolver = resolve); - })); + return ( + this._promise || + (this._promise = new Promise((resolve) => { + this._instance ? resolve(this._instance) : (this._promiseResolver = resolve); + })) + ); } /** diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts index ab96c5bd51..d1b630be4b 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/consume/context-request.event.ts @@ -1,4 +1,4 @@ -import { UmbContextToken } from '../context-token'; +import { UmbContextToken } from '../token/context-token'; export const umbContextRequestEventType = 'umb:context-request'; export const umbDebugContextEventType = 'umb:debug-contexts'; @@ -33,9 +33,8 @@ export const isUmbContextRequestEvent = (event: Event): event is UmbContextReque return event.type === umbContextRequestEventType; }; - export class UmbContextDebugRequest extends Event { - public constructor(public readonly callback:any) { + public constructor(public readonly callback: any) { super(umbDebugContextEventType, { bubbles: true, composed: true, cancelable: false }); } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/debug/context-data.function.ts b/src/Umbraco.Web.UI.Client/libs/context-api/debug/context-data.function.ts new file mode 100644 index 0000000000..1834d95002 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/context-api/debug/context-data.function.ts @@ -0,0 +1,140 @@ +/** + * Change the collection of Contexts into a simplified array of data + * + * @param contexts This is a map of the collected contexts from umb-debug + * @returns An array of simplified context data + */ +export function contextData(contexts:Map): Array { + const contextData = new Array; + for (const [alias, instance] of contexts) { + + const data:DebugContextItemData = contextItemData(instance); + contextData.push({ alias: alias, type: typeof instance, data }); + } + return contextData; +} + +/** + * Used to find the methods and properties of a context + * + * @param contextInstance The instance of the context + * @returns A simplied object contain the properties and methods of the context + */ +function contextItemData(contextInstance:any):DebugContextItemData { + let contextItemData:DebugContextItemData = { type: 'unknown' }; + + if (typeof contextInstance === 'function') { + contextItemData = { ...contextItemData, type: 'function'}; + } else if (typeof contextInstance === 'object') { + contextItemData = { ...contextItemData, type: 'object' }; + + const methodNames = getClassMethodNames(contextInstance); + if (methodNames.length) { + contextItemData = { ...contextItemData, methods: methodNames }; + + const props = []; + for (const key in contextInstance) { + if (key.startsWith('_')) { + continue; + } + + const value = contextInstance[key]; + if (typeof value === 'string' || typeof value === 'boolean') { + props.push({ key: key, value: value, type: typeof value }); + } else { + props.push({ key: key, type: typeof value }); + } + } + + contextItemData = { ...contextItemData, properties: props }; + } + } + else{ + contextItemData = {...contextItemData, type: 'primitive', value: contextInstance }; + } + + return contextItemData; +}; + +/** + * Gets a list of methods from a class + * + * @param klass The class to get the methods from + * @returns An array of method names as strings + */ +function getClassMethodNames(klass: any) { + const isGetter = (x: any, name: string): boolean => !!(Object.getOwnPropertyDescriptor(x, name) || {}).get; + const isFunction = (x: any, name: string): boolean => typeof x[name] === 'function'; + const deepFunctions = (x: any): any => + x !== Object.prototype && + Object.getOwnPropertyNames(x) + .filter((name) => isGetter(x, name) || isFunction(x, name)) + .concat(deepFunctions(Object.getPrototypeOf(x)) || []); + const distinctDeepFunctions = (klass: any) => Array.from(new Set(deepFunctions(klass))); + + const allMethods = + typeof klass.prototype === 'undefined' + ? distinctDeepFunctions(klass) + : Object.getOwnPropertyNames(klass.prototype); + return allMethods.filter((name: any) => name !== 'constructor' && !name.startsWith('_')); +} + + +export interface DebugContextData { + /** + * The alias of the context + * + * @type {string} + * @memberof DebugContextData + */ + alias: string; + + /** + * The type of the context such as object or string + * + * @type {("string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function")} + * @memberof DebugContextData + */ + type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"; + + /** + * Data about the context that includes method and property names + * + * @type {DebugContextItemData} + * @memberof DebugContextData + */ + data: DebugContextItemData; +} + +export interface DebugContextItemData { + type: string; + methods?: Array; + properties?: Array; + value?: unknown; +} + +export interface DebugContextItemPropertyData { + /** + * The name of the property + * + * @type {string} + * @memberof DebugContextItemPropertyData + */ + key: string; + + /** + * The type of the property's value such as string or number + * + * @type {("string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function")} + * @memberof DebugContextItemPropertyData + */ + type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"; + + /** + * Simple types such as string or number can have their value displayed stored inside the property + * + * @type {("string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function")} + * @memberof DebugContextItemPropertyData + */ + value?: unknown; +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/index.ts b/src/Umbraco.Web.UI.Client/libs/context-api/index.ts index 67aaa8edcf..8fbfe3303c 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/index.ts @@ -4,4 +4,5 @@ export * from './consume/context-request.event'; export * from './provide/context-provider.controller'; export * from './provide/context-provider'; export * from './provide/context-provide.event'; -export * from './context-token'; +export * from './token/'; +export * from './debug/context-data.function'; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provide.event.ts b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provide.event.ts index 37b88cea24..9388743921 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provide.event.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provide.event.ts @@ -1,4 +1,4 @@ -import { UmbContextToken } from '../context-token'; +import { UmbContextToken } from '../token/context-token'; export const umbContextProvideEventType = 'umb:context-provide'; diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.test.ts b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.test.ts index 621ae25a1a..7946d8b30b 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, defineCE } from '@open-wc/testing'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UmbContextConsumer } from '../consume/context-consumer'; import { UmbContextProviderController } from './context-provider.controller'; -import { UmbLitElement } from '@umbraco-cms/element'; class MyClass { prop = 'value from provider'; diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.ts b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.ts index 9a54497be8..46d4c9c1b5 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.controller.ts @@ -1,16 +1,16 @@ -import { UmbContextToken } from '../context-token'; +import { UmbContextToken } from '../token/context-token'; import { UmbContextProvider } from './context-provider'; -import type { UmbControllerHostInterface, UmbControllerInterface } from '@umbraco-cms/controller'; +import type { UmbControllerHostElement, UmbControllerInterface } from '@umbraco-cms/backoffice/controller'; export class UmbContextProviderController - extends UmbContextProvider + extends UmbContextProvider implements UmbControllerInterface { public get unique() { return this._contextAlias.toString(); } - constructor(host: UmbControllerHostInterface, contextAlias: string | UmbContextToken, instance: T) { + constructor(host: UmbControllerHostElement, contextAlias: string | UmbContextToken, instance: T) { super(host, contextAlias, instance); // If this API is already provided with this alias? Then we do not want to register this controller: diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts index c9ce3ab9c3..efed204d3a 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/provide/context-provider.ts @@ -1,5 +1,9 @@ -import { umbContextRequestEventType, isUmbContextRequestEvent, umbDebugContextEventType } from '../consume/context-request.event'; -import { UmbContextToken } from '../context-token'; +import { + umbContextRequestEventType, + isUmbContextRequestEvent, + umbDebugContextEventType, +} from '../consume/context-request.event'; +import { UmbContextToken } from '../token/context-token'; import { UmbContextProvideEventImplementation } from './context-provide.event'; /** @@ -68,14 +72,14 @@ export class UmbContextProvider { private _handleDebugContextRequest = (event: any) => { // If the event doesn't have an instances property, create it. - if(!event.instances){ + if (!event.instances) { event.instances = new Map(); } // If the event doesn't have an instance for this context, add it. // Nearest to the DOM element of will be added first // as contexts can change/override deeper in the DOM - if(!event.instances.has(this._contextAlias)){ + if (!event.instances.has(this._contextAlias)) { event.instances.set(this._contextAlias, this.#instance); } }; diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/context-api/rollup.config.js deleted file mode 100644 index 44c6c08405..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/context-api/rollup.config.js +++ /dev/null @@ -1,4 +0,0 @@ -import config from '../../utils/rollup.config.js'; -export default [ - ...config, -]; diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/context-token.test.ts b/src/Umbraco.Web.UI.Client/libs/context-api/token/context-token.test.ts similarity index 91% rename from src/Umbraco.Web.UI.Client/libs/context-api/context-token.test.ts rename to src/Umbraco.Web.UI.Client/libs/context-api/token/context-token.test.ts index 66531d06f0..f8b0a2046d 100644 --- a/src/Umbraco.Web.UI.Client/libs/context-api/context-token.test.ts +++ b/src/Umbraco.Web.UI.Client/libs/context-api/token/context-token.test.ts @@ -1,7 +1,7 @@ import { expect } from '@open-wc/testing'; -import { UmbContextConsumer } from './consume/context-consumer'; +import { UmbContextConsumer } from '../consume/context-consumer'; +import { UmbContextProvider } from '../provide/context-provider'; import { UmbContextToken } from './context-token'; -import { UmbContextProvider } from './provide/context-provider'; const testContextAlias = 'my-test-context'; diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/context-token.ts b/src/Umbraco.Web.UI.Client/libs/context-api/token/context-token.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/context-api/context-token.ts rename to src/Umbraco.Web.UI.Client/libs/context-api/token/context-token.ts diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/token/entity-workspace-context.token.ts b/src/Umbraco.Web.UI.Client/libs/context-api/token/entity-workspace-context.token.ts new file mode 100644 index 0000000000..52a66be29b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/context-api/token/entity-workspace-context.token.ts @@ -0,0 +1,7 @@ +import { UmbEntityWorkspaceContextInterface } from '../../workspace/context/workspace-entity-context.interface'; +import { UmbContextToken } from './context-token'; +import type { BaseEntity } from '@umbraco-cms/backoffice/models'; + +export const UMB_ENTITY_WORKSPACE_CONTEXT = new UmbContextToken>( + 'UmbEntityWorkspaceContext' +); diff --git a/src/Umbraco.Web.UI.Client/libs/context-api/token/index.ts b/src/Umbraco.Web.UI.Client/libs/context-api/token/index.ts new file mode 100644 index 0000000000..6ca732ea3b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/context-api/token/index.ts @@ -0,0 +1,2 @@ +export * from './entity-workspace-context.token'; +export * from './context-token'; diff --git a/src/Umbraco.Web.UI.Client/libs/controller/controller-host.mixin.ts b/src/Umbraco.Web.UI.Client/libs/controller/controller-host.mixin.ts index 6c0342846b..221da8d54b 100644 --- a/src/Umbraco.Web.UI.Client/libs/controller/controller-host.mixin.ts +++ b/src/Umbraco.Web.UI.Client/libs/controller/controller-host.mixin.ts @@ -1,9 +1,7 @@ import { UmbControllerInterface } from './controller.interface'; -import type { HTMLElementConstructor } from '@umbraco-cms/models'; +import type { HTMLElementConstructor } from '@umbraco-cms/backoffice/models'; -export declare class UmbControllerHostInterface extends HTMLElement { - //#controllers:UmbController[]; - //#attached:boolean; +export declare class UmbControllerHostElement extends HTMLElement { hasController(controller: UmbControllerInterface): boolean; getControllers(filterMethod: (ctrl: UmbControllerInterface) => boolean): UmbControllerInterface[]; addController(controller: UmbControllerInterface): void; @@ -101,7 +99,7 @@ export const UmbControllerHostMixin = (superCl } } - return UmbContextConsumerClass as unknown as HTMLElementConstructor & T; + return UmbContextConsumerClass as unknown as HTMLElementConstructor & T; }; declare global { diff --git a/src/Umbraco.Web.UI.Client/libs/controller/controller.class.ts b/src/Umbraco.Web.UI.Client/libs/controller/controller.class.ts index c34be538a7..f461faf6fc 100644 --- a/src/Umbraco.Web.UI.Client/libs/controller/controller.class.ts +++ b/src/Umbraco.Web.UI.Client/libs/controller/controller.class.ts @@ -1,15 +1,15 @@ -import { UmbControllerHostInterface } from './controller-host.mixin'; +import { UmbControllerHostElement } from './controller-host.mixin'; import { UmbControllerInterface } from './controller.interface'; export abstract class UmbController implements UmbControllerInterface { - protected host?: UmbControllerHostInterface; + protected host?: UmbControllerHostElement; private _alias?: string; public get unique() { return this._alias; } - constructor(host: UmbControllerHostInterface, alias?: string) { + constructor(host: UmbControllerHostElement, alias?: string) { this.host = host; this._alias = alias; this.host.addController(this); diff --git a/src/Umbraco.Web.UI.Client/libs/controller/controller.test.ts b/src/Umbraco.Web.UI.Client/libs/controller/controller.test.ts index 3d16f3a207..993bc546ca 100644 --- a/src/Umbraco.Web.UI.Client/libs/controller/controller.test.ts +++ b/src/Umbraco.Web.UI.Client/libs/controller/controller.test.ts @@ -1,7 +1,7 @@ import { expect } from '@open-wc/testing'; import { customElement } from 'lit/decorators.js'; -import { UmbControllerHostInterface, UmbControllerHostMixin } from './controller-host.mixin'; -import { UmbContextProviderController } from '@umbraco-cms/context-api'; +import { UmbControllerHostElement, UmbControllerHostMixin } from './controller-host.mixin'; +import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; class MyClass { prop = 'value from provider'; @@ -11,13 +11,13 @@ class MyClass { export class MyHostElement extends UmbControllerHostMixin(HTMLElement) {} describe('UmbContextProvider', () => { - type NewType = UmbControllerHostInterface; + type NewType = UmbControllerHostElement; let hostElement: NewType; const contextInstance = new MyClass(); beforeEach(() => { - hostElement = document.createElement('test-my-controller-host') as UmbControllerHostInterface; + hostElement = document.createElement('test-my-controller-host') as UmbControllerHostElement; }); describe('Destroyed controllers is gone from host', () => { diff --git a/src/Umbraco.Web.UI.Client/libs/controller/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/controller/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/controller/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/css/custom-properties.css b/src/Umbraco.Web.UI.Client/libs/css/custom-properties.css deleted file mode 100644 index 4f728ed1fd..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/css/custom-properties.css +++ /dev/null @@ -1,3 +0,0 @@ -:root { - --uui-color-positive: #1c874c; -} diff --git a/src/Umbraco.Web.UI.Client/libs/element/element.mixin.ts b/src/Umbraco.Web.UI.Client/libs/element/element.mixin.ts index 39748f9f26..a53c101822 100644 --- a/src/Umbraco.Web.UI.Client/libs/element/element.mixin.ts +++ b/src/Umbraco.Web.UI.Client/libs/element/element.mixin.ts @@ -1,22 +1,22 @@ import { Observable } from 'rxjs'; -import type { HTMLElementConstructor } from '@umbraco-cms/models'; +import type { HTMLElementConstructor } from '@umbraco-cms/backoffice/models'; -import { UmbControllerHostInterface, UmbControllerHostMixin } from '@umbraco-cms/controller'; +import { UmbControllerHostElement, UmbControllerHostMixin } from '@umbraco-cms/backoffice/controller'; import { UmbContextToken, UmbContextCallback, UmbContextConsumerController, UmbContextProviderController, -} from '@umbraco-cms/context-api'; -import { UmbObserverController } from '@umbraco-cms/observable-api'; +} from '@umbraco-cms/backoffice/context-api'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; // TODO: can we use this aliases to generate the key of this type interface ResolvedContexts { [key: string]: any; } -export declare class UmbElementMixinInterface extends UmbControllerHostInterface { +export declare class UmbElementMixinInterface extends UmbControllerHostElement { observe(source: Observable, callback: (_value: T) => void, unique?: string): UmbObserverController; provideContext(alias: string | UmbContextToken, instance: R): UmbContextProviderController; consumeContext( diff --git a/src/Umbraco.Web.UI.Client/libs/element/index.module.ts b/src/Umbraco.Web.UI.Client/libs/element/index.module.ts deleted file mode 100644 index 18d6126ccc..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/element/index.module.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './element.mixin'; diff --git a/src/Umbraco.Web.UI.Client/libs/element/index.ts b/src/Umbraco.Web.UI.Client/libs/element/index.ts index 4048b79c02..18d6126ccc 100644 --- a/src/Umbraco.Web.UI.Client/libs/element/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/element/index.ts @@ -1,2 +1 @@ export * from './element.mixin'; -export * from './lit-element.element'; diff --git a/src/Umbraco.Web.UI.Client/libs/element/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/element/rollup.config.js deleted file mode 100644 index d3af596f5f..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/element/rollup.config.js +++ /dev/null @@ -1,6 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -config[0].input = 'index.module.ts'; -config[1].input = 'index.module.ts'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/action.ts index 70c4a25985..536c4df85d 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/action.ts @@ -1,18 +1,18 @@ -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { umbExtensionsRegistry, createExtensionClass } from '@umbraco-cms/extensions-api'; -import { UmbObserverController } from '@umbraco-cms/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { umbExtensionsRegistry, createExtensionClass } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; export interface UmbAction { - host: UmbControllerHostInterface; + host: UmbControllerHostElement; repository: RepositoryType; execute(): Promise; } export class UmbActionBase { - host: UmbControllerHostInterface; + host: UmbControllerHostElement; repository?: RepositoryType; - constructor(host: UmbControllerHostInterface, repositoryAlias: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string) { this.host = host; // TODO: unsure a method can't be called before everything is initialized diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/copy/copy.action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/copy/copy.action.ts index ac5995ea1f..f647d7f092 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/copy/copy.action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/copy/copy.action.ts @@ -1,8 +1,8 @@ -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbCopyEntityAction }> extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/delete-folder/delete-folder.action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/delete-folder/delete-folder.action.ts new file mode 100644 index 0000000000..9a2adadb0b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/delete-folder/delete-folder.action.ts @@ -0,0 +1,39 @@ +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; + +export class UmbDeleteFolderEntityAction< + T extends { deleteFolder(unique: string): Promise; requestTreeItems(uniques: Array): any } +> extends UmbEntityActionBase { + #modalContext?: UmbModalContext; + + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { + super(host, repositoryAlias, unique); + + new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.#modalContext = instance; + }); + } + + async execute() { + if (!this.repository || !this.#modalContext) return; + + const { data } = await this.repository.requestTreeItems([this.unique]); + + if (data) { + const item = data[0]; + + // TODO: maybe we can show something about how many items are part of the folder? + const modalHandler = this.#modalContext.open(UMB_CONFIRM_MODAL, { + headline: `Delete folder ${item.name}`, + content: 'Are you sure you want to delete this folder?', + color: 'danger', + confirmLabel: 'Delete', + }); + + await modalHandler.onSubmit(); + await this.repository?.deleteFolder(this.unique); + } + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/delete/delete.action.ts index e6d9deb818..d290a1f912 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/delete/delete.action.ts @@ -1,15 +1,14 @@ -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../../src/backoffice/shared/modals/confirm'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; export class UmbDeleteEntityAction< - T extends { delete(unique: string): Promise; requestItems(uniques: Array): any } + T extends { delete(unique: string): Promise; requestTreeItems(uniques: Array): any } > extends UmbEntityActionBase { #modalContext?: UmbModalContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -20,12 +19,12 @@ export class UmbDeleteEntityAction< async execute() { if (!this.repository || !this.#modalContext) return; - const { data } = await this.repository.requestItems([this.unique]); + const { data } = await this.repository.requestTreeItems([this.unique]); if (data) { const item = data[0]; - const modalHandler = this.#modalContext.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this.#modalContext.open(UMB_CONFIRM_MODAL, { headline: `Delete ${item.name}`, content: 'Are you sure you want to delete this item?', color: 'danger', diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/folder-update/folder-update.action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/folder-update/folder-update.action.ts new file mode 100644 index 0000000000..2a1fc97ece --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/folder-update/folder-update.action.ts @@ -0,0 +1,30 @@ +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbModalContext, UMB_FOLDER_MODAL, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbFolderRepository } from '@umbraco-cms/backoffice/repository'; + +export class UmbFolderUpdateEntityAction< + T extends UmbFolderRepository = UmbFolderRepository +> extends UmbEntityActionBase { + #modalContext?: UmbModalContext; + + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { + super(host, repositoryAlias, unique); + + new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.#modalContext = instance; + }); + } + + async execute() { + if (!this.repository || !this.#modalContext) return; + + const modalHandler = this.#modalContext.open(UMB_FOLDER_MODAL, { + repositoryAlias: this.repositoryAlias, + unique: this.unique, + }); + + await modalHandler.onSubmit(); + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/index.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/index.ts index b8fa3d3206..8551f08139 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/index.ts @@ -1,5 +1,7 @@ export * from './copy/copy.action'; export * from './delete/delete.action'; +export * from './delete-folder/delete-folder.action'; +export * from './folder-update/folder-update.action'; export * from './move/move.action'; export * from './sort-children-of/sort-children-of.action'; export * from './trash/trash.action'; diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/move/move.action.ts index 79c9a20dd1..2744029e82 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/move/move.action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/move/move.action.ts @@ -1,8 +1,8 @@ -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbMoveEntityAction }> extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/sort-children-of/sort-children-of.action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/sort-children-of/sort-children-of.action.ts index 002e0b6613..4816e9d1ff 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/sort-children-of/sort-children-of.action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/sort-children-of/sort-children-of.action.ts @@ -1,10 +1,10 @@ -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbSortChildrenOfEntityAction< T extends { sortChildrenOf(): Promise } > extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/trash/trash.action.ts index 36ade2fef0..2b86b4d56c 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/actions/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/actions/trash/trash.action.ts @@ -1,15 +1,14 @@ -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../../src/backoffice/shared/modals/confirm'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; export class UmbTrashEntityAction< T extends { trash(unique: Array): Promise; requestTreeItems(uniques: Array): any } > extends UmbEntityActionBase { #modalContext?: UmbModalContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -25,7 +24,7 @@ export class UmbTrashEntityAction< if (data) { const item = data[0]; - const modalHandler = this.#modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this.#modalContext?.open(UMB_CONFIRM_MODAL, { headline: `Trash ${item.name}`, content: 'Are you sure you want to move this item to the recycle bin?', color: 'danger', diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/entity-action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/entity-action.ts index 17b010128b..5c2d816deb 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/entity-action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/entity-action.ts @@ -1,5 +1,5 @@ import { UmbAction, UmbActionBase } from './action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export interface UmbEntityAction extends UmbAction { unique: string; @@ -7,9 +7,11 @@ export interface UmbEntityAction extends UmbAction extends UmbActionBase { unique: string; + repositoryAlias: string; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias); this.unique = unique; + this.repositoryAlias = repositoryAlias; } } diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/entity-bulk-action.ts b/src/Umbraco.Web.UI.Client/libs/entity-action/entity-bulk-action.ts index a75ae2e498..22f7d58dbe 100644 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/entity-bulk-action.ts +++ b/src/Umbraco.Web.UI.Client/libs/entity-action/entity-bulk-action.ts @@ -1,5 +1,5 @@ import { UmbAction, UmbActionBase } from './action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export interface UmbEntityBulkAction extends UmbAction { selection: Array; @@ -9,7 +9,7 @@ export interface UmbEntityBulkAction extends UmbAction export class UmbEntityBulkActionBase extends UmbActionBase { selection: Array; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias); this.selection = selection; } diff --git a/src/Umbraco.Web.UI.Client/libs/entity-action/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/entity-action/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/entity-action/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/events/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/events/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/events/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-class.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-class.function.ts index 8057ab4b62..be6781fe16 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-class.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-class.function.ts @@ -1,11 +1,14 @@ -import type { ClassConstructor, ManifestClass } from '../models'; import { hasDefaultExport } from './has-default-export.function'; import { isManifestClassConstructorType } from './is-manifest-class-instance-type.function'; import { loadExtension } from './load-extension.function'; +import type { ClassConstructor } from '@umbraco-cms/backoffice/models'; +import type { ManifestClass } from '@umbraco-cms/backoffice/extensions-registry'; //TODO: Write tests for this method: -export async function createExtensionClass(manifest: ManifestClass, constructorArguments: unknown[]): Promise { - +export async function createExtensionClass( + manifest: ManifestClass, + constructorArguments: unknown[] +): Promise { const js = await loadExtension(manifest); if (isManifestClassConstructorType(manifest)) { @@ -17,11 +20,17 @@ export async function createExtensionClass(manifest: ManifestClass, return new js.default(...constructorArguments); } - console.error('-- Extension did not succeed creating an class instance, missing a default export of the served JavaScript file', manifest); + console.error( + '-- Extension did not succeed creating an class instance, missing a default export of the served JavaScript file', + manifest + ); return undefined; } - console.error('-- Extension did not succeed creating an class instance, missing a default export or `class` in the manifest.', manifest); + console.error( + '-- Extension did not succeed creating an class instance, missing a default export or `class` in the manifest.', + manifest + ); return undefined; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-element.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-element.function.ts index f6e1966c0d..ccb92df877 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-element.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/create-extension-element.function.ts @@ -1,10 +1,11 @@ -import type { HTMLElementConstructor, ManifestElement } from '../models'; import { hasDefaultExport } from './has-default-export.function'; import { isManifestElementNameType } from './is-manifest-element-name-type.function'; import { loadExtension } from './load-extension.function'; +import type { HTMLElementConstructor } from '@umbraco-cms/backoffice/models'; +import type { ManifestElement } from '@umbraco-cms/backoffice/extensions-registry'; +import type { PageComponent } from '@umbraco-cms/backoffice/router'; -export async function createExtensionElement(manifest: ManifestElement): Promise { - +export async function createExtensionElement(manifest: ManifestElement): Promise { //TODO: Write tests for these extension options: const js = await loadExtension(manifest); @@ -20,12 +21,18 @@ export async function createExtensionElement(manifest: ManifestElement): Promise return new js.default(); } - console.error('-- Extension did not succeed creating an element, missing a default export of the served JavaScript file', manifest); + console.error( + '-- Extension did not succeed creating an element, missing a default export of the served JavaScript file', + manifest + ); // If some JS was loaded and it did not at least contain a default export, then we are safe to assume that it executed its side effects and does not need to be returned return undefined; } - console.error('-- Extension did not succeed creating an element, missing a default export or `elementName` in the manifest.', manifest); + console.error( + '-- Extension did not succeed creating an element, missing a default export or `elementName` in the manifest.', + manifest + ); return undefined; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/has-init-export.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/has-init-export.function.ts index a7f957c7e9..4aca8929f2 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/has-init-export.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/has-init-export.function.ts @@ -1,4 +1,4 @@ -import type { UmbEntrypointModule } from "./umb-lifecycle.interface"; +import type { UmbEntrypointModule } from './umb-lifecycle.interface'; /** * Validate if an ESModule exports a known init function called 'onInit' diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-class-instance-type.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-class-instance-type.function.ts index a66cd5de85..1683d083a2 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-class-instance-type.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-class-instance-type.function.ts @@ -1,7 +1,5 @@ -import type { ManifestClass, ManifestClassWithClassConstructor } from '../models'; +import type { ManifestClass, ManifestClassWithClassConstructor } from '@umbraco-cms/backoffice/extensions-registry'; export function isManifestClassConstructorType(manifest: unknown): manifest is ManifestClassWithClassConstructor { - return ( - typeof manifest === 'object' && manifest !== null && (manifest as ManifestClass).class !== undefined - ); + return typeof manifest === 'object' && manifest !== null && (manifest as ManifestClass).class !== undefined; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-classable-type.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-classable-type.function.ts index e6f247b3f4..1b80efcbc7 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-classable-type.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-classable-type.function.ts @@ -1,7 +1,7 @@ import { isManifestJSType } from './is-manifest-js-type.function'; import { isManifestLoaderType } from './is-manifest-loader-type.function'; import { isManifestClassConstructorType } from './is-manifest-class-instance-type.function'; -import type { ManifestBase, ManifestClass } from '@umbraco-cms/extensions-registry'; +import type { ManifestBase, ManifestClass } from '@umbraco-cms/backoffice/extensions-registry'; export function isManifestClassableType(manifest: ManifestBase): manifest is ManifestClass { return isManifestClassConstructorType(manifest) || isManifestLoaderType(manifest) || isManifestJSType(manifest); diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-element-name-type.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-element-name-type.function.ts index a5176b90c8..0a1ec48892 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-element-name-type.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-element-name-type.function.ts @@ -1,7 +1,5 @@ -import type { ManifestElement, ManifestElementWithElementName } from '../models'; +import type { ManifestElement, ManifestElementWithElementName } from '@umbraco-cms/backoffice/extensions-registry'; export function isManifestElementNameType(manifest: unknown): manifest is ManifestElementWithElementName { - return ( - typeof manifest === 'object' && manifest !== null && (manifest as ManifestElement).elementName !== undefined - ); + return typeof manifest === 'object' && manifest !== null && (manifest as ManifestElement).elementName !== undefined; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-elementable-type.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-elementable-type.function.ts index 25d9c8f478..c794099245 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-elementable-type.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-elementable-type.function.ts @@ -1,7 +1,7 @@ import { isManifestElementNameType } from './is-manifest-element-name-type.function'; import { isManifestJSType } from './is-manifest-js-type.function'; import { isManifestLoaderType } from './is-manifest-loader-type.function'; -import type { ManifestElement, ManifestBase } from '@umbraco-cms/extensions-registry'; +import type { ManifestElement, ManifestBase } from '@umbraco-cms/backoffice/extensions-registry'; export function isManifestElementableType(manifest: ManifestBase): manifest is ManifestElement { return isManifestElementNameType(manifest) || isManifestLoaderType(manifest) || isManifestJSType(manifest); diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-js-type.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-js-type.function.ts index 24962b7ec0..9d4cfbf7b8 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-js-type.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-js-type.function.ts @@ -1,5 +1,5 @@ import { ManifestJSType } from './load-extension.function'; -import type { ManifestBase } from '@umbraco-cms/extensions-registry'; +import type { ManifestBase } from '@umbraco-cms/backoffice/extensions-registry'; export function isManifestJSType(manifest: ManifestBase | unknown): manifest is ManifestJSType { return (manifest as ManifestJSType).js !== undefined; diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-loader-type.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-loader-type.function.ts index b2a3ba7dbf..1f018b2d6f 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-loader-type.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/is-manifest-loader-type.function.ts @@ -1,5 +1,5 @@ import { ManifestLoaderType } from './load-extension.function'; -import type { ManifestBase } from '@umbraco-cms/extensions-registry'; +import type { ManifestBase } from '@umbraco-cms/backoffice/extensions-registry'; export function isManifestLoaderType(manifest: ManifestBase): manifest is ManifestLoaderType { return typeof (manifest as ManifestLoaderType).loader === 'function'; diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/load-extension.function.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/load-extension.function.ts index 516a5d6d68..7e0c0ebda3 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/load-extension.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/load-extension.function.ts @@ -1,6 +1,6 @@ -import type { ManifestElement } from '../models'; import { isManifestJSType } from './is-manifest-js-type.function'; import { isManifestLoaderType } from './is-manifest-loader-type.function'; +import type { ManifestElement } from '@umbraco-cms/backoffice/extensions-registry'; export type ManifestLoaderType = ManifestElement & { loader: () => Promise }; export type ManifestJSType = ManifestElement & { js: string }; diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.test.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.test.ts index 960bdfea4a..a7cf61027a 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.test.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.test.ts @@ -1,8 +1,8 @@ import { expect } from '@open-wc/testing'; -import type { ManifestTypes } from '../../models'; import { UmbExtensionRegistry } from './extension.registry'; +import type { ManifestKind, ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -describe('UmbContextRequestEvent', () => { +describe('UmbExtensionRegistry', () => { let extensionRegistry: UmbExtensionRegistry; let manifests: Array; @@ -60,31 +60,175 @@ describe('UmbContextRequestEvent', () => { it('should get an extension by alias', (done) => { const alias = 'Umb.Test.Section.1'; - extensionRegistry.getByAlias(alias).subscribe((extension) => { - expect(extension?.alias).to.eq(alias); - done(); - }); + extensionRegistry + .getByTypeAndAlias('section', alias) + .subscribe((extension) => { + expect(extension?.alias).to.eq(alias); + done(); + }) + .unsubscribe(); }); describe('getByType', () => { const type = 'section'; it('should get all extensions by type', (done) => { - extensionRegistry.extensionsOfType(type).subscribe((extensions) => { - expect(extensions).to.have.lengthOf(3); - expect(extensions?.[0]?.type).to.eq(type); - expect(extensions?.[1]?.type).to.eq(type); - done(); - }); + extensionRegistry + .extensionsOfType(type) + .subscribe((extensions) => { + expect(extensions).to.have.lengthOf(3); + expect(extensions?.[0]?.type).to.eq(type); + expect(extensions?.[1]?.type).to.eq(type); + done(); + }) + .unsubscribe(); }); it('should return extensions ordered by weight', (done) => { - extensionRegistry.extensionsOfType(type).subscribe((extensions) => { - expect(extensions?.[0]?.weight).to.eq(200); - expect(extensions?.[1]?.weight).to.eq(25); - expect(extensions?.[2]?.weight).to.eq(1); - done(); - }); + extensionRegistry + .extensionsOfType(type) + .subscribe((extensions) => { + expect(extensions?.[0]?.weight).to.eq(200); + expect(extensions?.[1]?.weight).to.eq(25); + expect(extensions?.[2]?.weight).to.eq(1); + done(); + }) + .unsubscribe(); + }); + + it('Observable only trigged when changes made to the scope of it', (done) => { + let amountOfTimesTriggered = -1; + let lastAmount = 0; + + extensionRegistry + .extensionsOfType('section') + .subscribe((extensions) => { + amountOfTimesTriggered++; + const newAmount = extensions?.length ?? 0; + if (amountOfTimesTriggered === 0) { + expect(newAmount).to.eq(3); + } + if (amountOfTimesTriggered === 1) { + expect(newAmount).to.eq(4); + } + if (lastAmount === newAmount) { + expect(null).to.eq('Update was triggered without a change, this test should fail.'); + } else { + lastAmount = newAmount; + + if (lastAmount === 3) { + // We registerer a extension that should not affect this observable. + extensionRegistry.register({ + type: 'workspace', + name: 'test-editor-2', + alias: 'Umb.Test.Editor.2', + meta: { + entityType: 'testEntity', + }, + }); + // And then register a extension that triggers this observable. + extensionRegistry.register({ + type: 'section', + name: 'test-section-4', + alias: 'Umb.Test.Section.4', + weight: 9999, + meta: { + label: 'Test Section 4', + pathname: 'test-section-4', + }, + }); + } + + if (newAmount === 4) { + expect(amountOfTimesTriggered).to.eq(1); + expect(extensions?.[0]?.alias).to.eq('Umb.Test.Section.4'); + done(); + } + } + }) + .unsubscribe(); }); }); }); + +describe('UmbExtensionRegistry with kinds', () => { + let extensionRegistry: UmbExtensionRegistry; + let manifests: Array; + + beforeEach(() => { + extensionRegistry = new UmbExtensionRegistry(); + manifests = [ + { + type: 'kind', + alias: 'Umb.Test.Kind', + matchType: 'section', + matchKind: 'test-kind', + manifest: { + type: 'section', + elementName: 'my-kind-element', + meta: { + label: 'my-kind-meta-label', + }, + }, + }, + { + type: 'section', + kind: 'test-kind' as unknown as undefined, // We do not know about this one, so it makes good sense that its not a valid option. + name: 'test-section-1', + alias: 'Umb.Test.Section.1', + weight: 1, + meta: { + //label: 'Test Section 1',// should come from the kind. + pathname: 'test-section-1', + }, + }, + { + type: 'section', + name: 'test-section-2', + alias: 'Umb.Test.Section.2', + weight: 200, + meta: { + label: 'Test Section 2', + pathname: 'test-section-2', + }, + }, + { + type: 'section', + kind: 'test-kind' as unknown as undefined, // We do not know about this one, so it makes good sense that its not a valid option. + name: 'test-section-3', + alias: 'Umb.Test.Section.3', + weight: 25, + meta: { + label: 'Test Section 3', + pathname: 'test-section-3', + }, + }, + { + type: 'workspace', + name: 'test-editor-1', + alias: 'Umb.Test.Editor.1', + meta: { + entityType: 'testEntity', + }, + }, + ]; + + manifests.forEach((manifest) => extensionRegistry.register(manifest)); + }); + + it('should merge with kinds', (done) => { + extensionRegistry + .extensionsOfType('section') + .subscribe((extensions) => { + expect(extensions).to.have.lengthOf(3); + expect(extensions?.[0]?.elementName).to.not.eq('my-kind-element'); + expect(extensions?.[1]?.alias).to.eq('Umb.Test.Section.3'); + expect(extensions?.[1]?.elementName).to.eq('my-kind-element'); + expect(extensions?.[2]?.alias).to.eq('Umb.Test.Section.1'); + expect(extensions?.[2]?.elementName).to.eq('my-kind-element'); + expect(extensions?.[2]?.meta.label).to.eq('my-kind-meta-label'); + done(); + }) + .unsubscribe(); + }); +}); diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.ts index 14dfe2cc9e..c1279b91f7 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/registry/extension.registry.ts @@ -1,40 +1,73 @@ -import { BehaviorSubject, map, Observable } from 'rxjs'; -import type { ManifestTypes, ManifestTypeMap, ManifestBase, ManifestEntrypoint } from '../../models'; -import { loadExtension } from '../load-extension.function'; -import { hasInitExport } from "../has-init-export.function"; -import type { UmbControllerHostInterface } from "@umbraco-cms/controller"; -import { UmbContextToken } from "@umbraco-cms/context-api"; +import { BehaviorSubject, map, Observable, distinctUntilChanged, combineLatest } from 'rxjs'; +import type { + ManifestTypes, + ManifestTypeMap, + ManifestBase, + SpecificManifestTypeOrManifestBase, + ManifestKind, +} from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; -type SpecificManifestTypeOrManifestBase = T extends keyof ManifestTypeMap - ? ManifestTypeMap[T] - : ManifestBase; +function extensionArrayMemoization( + previousValue: Array, + currentValue: Array +): boolean { + // If length is different, data is different: + if (previousValue.length !== currentValue.length) { + return false; + } + // previousValue has an alias that is not present in currentValue: + if (previousValue.find((p) => !currentValue.find((c) => c.alias === p.alias))) { + return false; + } + return true; +} + +function extensionSingleMemoization( + previousValue: T | undefined, + currentValue: T | undefined +): boolean { + if (previousValue && currentValue) { + return previousValue.alias === currentValue.alias; + } + return previousValue === currentValue; +} + +const sortExtensions = (a: ManifestBase, b: ManifestBase) => (b.weight || 0) - (a.weight || 0); export class UmbExtensionRegistry { - // TODO: Use UniqueBehaviorSubject, as we don't want someone to edit data of extensions. - private _extensions = new BehaviorSubject>([]); + private _extensions = new BehaviorSubject>([]); public readonly extensions = this._extensions.asObservable(); - register(manifest: ManifestTypes, rootHost?: UmbControllerHostInterface): void { - const extensionsValues = this._extensions.getValue(); - const extension = extensionsValues.find((extension) => extension.alias === manifest.alias); + private _kinds = new BehaviorSubject>([]); + public readonly kinds = this._kinds.asObservable(); - if (extension) { - console.error(`Extension with alias ${manifest.alias} is already registered`); + defineKind(kind: ManifestKind) { + const nextData = this._kinds + .getValue() + .filter( + (k) => !(k.matchType === (kind as ManifestKind).matchType && k.matchKind === (kind as ManifestKind).matchKind) + ); + nextData.push(kind as ManifestKind); + this._kinds.next(nextData); + } + + register(manifest: ManifestTypes | ManifestKind): void { + if (manifest.type === 'kind') { + this.defineKind(manifest as ManifestKind); return; } - this._extensions.next([...extensionsValues, manifest]); + const extensionsValues = this._extensions.getValue(); + const extension = extensionsValues.find((extension) => extension.alias === (manifest as ManifestTypes).alias); - // If entrypoint extension, we should load and run it immediately - if (manifest.type === 'entrypoint') { - loadExtension(manifest as ManifestEntrypoint).then((js) => { - // If the extension has an onInit export, be sure to run that or else let the module handle itself - if (hasInitExport(js)) { - js.onInit(rootHost!, this); - } - }); + if (extension) { + console.error(`Extension with alias ${(manifest as ManifestTypes).alias} is already registered`); + return; } + + this._extensions.next([...extensionsValues, manifest as ManifestTypes]); } unregister(alias: string): void { @@ -55,44 +88,117 @@ export class UmbExtensionRegistry { return values.some((ext) => ext.alias === alias); } + /* getByAlias(alias: string) { // TODO: make pipes prettier/simpler/reuseable - return this.extensions.pipe(map((dataTypes) => dataTypes.find((extension) => extension.alias === alias) || null)); + return this.extensions.pipe(map((extensions) => extensions.find((extension) => extension.alias === alias) || null)); } + */ - getByTypeAndAlias(type: Key, alias: string) { - return this.extensionsOfType(type).pipe( - map((extensions) => extensions.find((extension) => extension.alias === alias) || null) + private _kindsOfType(type: Key) { + return this.kinds.pipe( + map((kinds) => kinds.filter((kind) => kind.matchType === type)), + distinctUntilChanged(extensionArrayMemoization) ); } - - extensionsOfType>(type: Key) { + private _extensionsOfType(type: Key) { return this.extensions.pipe( - map((exts) => exts.filter((ext) => ext.type === type).sort((a, b) => (b.weight || 0) - (a.weight || 0))) + map((exts) => exts.filter((ext) => ext.type === type)), + distinctUntilChanged(extensionArrayMemoization) + ); + } + private _kindsOfTypes(types: string[]) { + return this.kinds.pipe( + map((kinds) => kinds.filter((kind) => types.indexOf(kind.matchType) !== -1)), + distinctUntilChanged(extensionArrayMemoization) + ); + } + private _extensionsOfTypes(types: string[]): Observable> { + return this.extensions.pipe( + map((exts) => exts.filter((ext) => types.indexOf(ext.type) !== -1)), + distinctUntilChanged(extensionArrayMemoization) + ) as Observable>; + } + + getByTypeAndAlias< + Key extends keyof ManifestTypeMap | string, + T extends ManifestBase = SpecificManifestTypeOrManifestBase + >(type: Key, alias: string) { + return combineLatest([ + this.extensions.pipe( + map((exts) => exts.find((ext) => ext.type === type && ext.alias === alias)), + distinctUntilChanged(extensionSingleMemoization) + ), + this._kindsOfType(type), + ]).pipe( + map(([ext, kinds]) => { + // TODO: share one merge function between the different methods of this class: + // Specific Extension Meta merge (does not merge conditions) + if (ext) { + const baseManifest = kinds.find((kind) => kind.matchKind === ext.kind)?.manifest; + if (baseManifest) { + const merged = { ...baseManifest, ...ext } as any; + if ((baseManifest as any).meta) { + merged.meta = { ...(baseManifest as any).meta, ...(ext as any).meta }; + } + return merged; + } + } + return ext; + }), + distinctUntilChanged(extensionSingleMemoization) + ) as Observable; + } + + extensionsOfType< + Key extends keyof ManifestTypeMap | string, + T extends ManifestBase = SpecificManifestTypeOrManifestBase + >(type: Key) { + return combineLatest([this._extensionsOfType(type), this._kindsOfType(type)]).pipe( + map(([exts, kinds]) => + exts + .map((ext) => { + // Specific Extension Meta merge (does not merge conditions) + const baseManifest = kinds.find((kind) => kind.matchKind === ext.kind)?.manifest; + if (baseManifest) { + const merged = { ...baseManifest, ...ext } as any; + if ((baseManifest as any).meta) { + merged.meta = { ...(baseManifest as any).meta, ...(ext as any).meta }; + } + return merged; + } + return ext; + }) + .sort(sortExtensions) + ), + distinctUntilChanged(extensionArrayMemoization) ) as Observable>; } - extensionsOfTypes(types: string[]): Observable> { - return this.extensions.pipe( - map((exts) => - exts.filter((ext) => types.indexOf(ext.type) !== -1).sort((a, b) => (b.weight || 0) - (a.weight || 0)) - ) - ) as Observable>; - } - - extensionsSortedByTypeAndWeight(): Observable> { - return this.extensions.pipe( - map((exts) => exts - .sort((a, b) => { - // If type is the same, sort by weight - if (a.type === b.type) { - return (a.weight || 0) - (b.weight || 0); - } - - // Otherwise sort by type - return a.type.localeCompare(b.type); - })) - ) as Observable>; + extensionsOfTypes( + types: string[] + ): Observable> { + return combineLatest([this._extensionsOfTypes(types), this._kindsOfTypes(types)]).pipe( + map(([exts, kinds]) => + exts + .map((ext) => { + // Specific Extension Meta merge (does not merge conditions) + if (ext) { + const baseManifest = kinds.find((kind) => kind.matchKind === ext.kind)?.manifest; + if (baseManifest) { + const merged = { ...baseManifest, ...ext } as any; + if ((baseManifest as any).meta) { + merged.meta = { ...(baseManifest as any).meta, ...(ext as any).meta }; + } + return merged; + } + } + return ext; + }) + .sort(sortExtensions) + ), + distinctUntilChanged(extensionArrayMemoization) + ) as Observable>; } } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-api/umb-lifecycle.interface.ts b/src/Umbraco.Web.UI.Client/libs/extensions-api/umb-lifecycle.interface.ts index c90a871320..e2ec64bcc5 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-api/umb-lifecycle.interface.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-api/umb-lifecycle.interface.ts @@ -1,9 +1,11 @@ -import type { UmbExtensionRegistry } from "./registry/extension.registry"; -import type { UmbControllerHostInterface } from "@umbraco-cms/controller"; +import type { UmbExtensionRegistry } from './registry/extension.registry'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +export type UmbEntrypointOnInit = (host: UmbControllerHostElement, extensionRegistry: UmbExtensionRegistry) => void; /** * Interface containing supported life-cycle functions for ESModule entrypoints */ export interface UmbEntrypointModule { - onInit: (host: UmbControllerHostInterface, extensionRegistry: UmbExtensionRegistry) => void + onInit: UmbEntrypointOnInit; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/collection-view.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/collection-view.models.ts index 0f99af2f99..4f7104b913 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/collection-view.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/collection-view.models.ts @@ -1,10 +1,6 @@ -import type { ManifestElement } from './models'; +import type { ManifestElement, ManifestWithConditions } from './models'; -/** - * A collection view is a view that can be used to display a collection of entities. - * For example you may wish to display a collection of nodes as a table or grid of cards - */ -export interface ManifestCollectionView extends ManifestElement { +export interface ManifestCollectionView extends ManifestElement, ManifestWithConditions { type: 'collectionView'; meta: MetaCollectionView; } @@ -23,13 +19,11 @@ export interface MetaCollectionView { icon: string; /** - * The entity type that this collection view is for - * @example 'media' - */ - entityType: string; - - /** - * The URL pathname for this collection view that can be deep linked to by sharing the url - */ + * The URL pathname for this collection view that can be deep linked to by sharing the url + */ pathName: string; } + +export interface ConditionsCollectionView { + entityType: string; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard-collection.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard-collection.models.ts index b41add8d85..3255547b42 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard-collection.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard-collection.models.ts @@ -3,12 +3,16 @@ import type { ManifestBase } from './models'; export interface ManifestDashboardCollection extends ManifestBase { type: 'dashboardCollection'; meta: MetaDashboardCollection; + conditions: ConditionsDashboardCollection; } export interface MetaDashboardCollection { - sections: string[]; pathname: string; label?: string; - entityType: string; repositoryAlias: string; } + +export interface ConditionsDashboardCollection { + sections: string[]; + entityType: string; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard.models.ts index 8cef6c0fff..40aa2d570a 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/dashboard.models.ts @@ -1,25 +1,15 @@ -import type { ManifestElement } from './models'; +import type { ManifestElement, ManifestWithConditions } from './models'; -export interface ManifestDashboard extends ManifestElement { +export interface ManifestDashboard extends ManifestElement, ManifestWithConditions { type: 'dashboard'; meta: MetaDashboard; } export interface MetaDashboard { - - /** - * A string array of section aliases to which this dashboard will appear such as - * 'Umb.Section.Content', 'Umb.Section.Settings', 'Umb.Section.Translation' - * - * @minItems 1 - * @uniqueItems true - */ - sections: string[]; - /** * This is the URL path for the dashboard which is used for navigating or deep linking directly to the dashboard * https://yoursite.com/section/settings/dashboard/my-dashboard-path - * + * * @example 'my-dashboard-path' */ pathname: string; @@ -29,3 +19,7 @@ export interface MetaDashboard { */ label?: string; } + +export interface ConditionsDashboard { + sections: string[]; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-action.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-action.models.ts index 55843a4114..a9cd1b27a8 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-action.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-action.models.ts @@ -7,6 +7,7 @@ import type { ManifestElement } from './models'; export interface ManifestEntityAction extends ManifestElement { type: 'entityAction'; meta: MetaEntityAction; + conditions: ConditionsEntityAction; } export interface MetaEntityAction { @@ -23,15 +24,9 @@ export interface MetaEntityAction { * @example 'Create Content Template' */ label: string; - - /** - * The type of entity this action is for such as 'document' - * @example 'media' - * @example 'document' - */ - entityType: string; - api: any; // TODO: create interface + api: any; // create interface + /** * The alias for the repsoitory of the entity type this action is for @@ -40,3 +35,7 @@ export interface MetaEntityAction { */ repositoryAlias: string; } + +export interface ConditionsEntityAction { + entityType: string; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-bulk-action.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-bulk-action.models.ts index 0c7bbd2fc1..afe32fa3f8 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-bulk-action.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/entity-bulk-action.models.ts @@ -1,27 +1,20 @@ -import type { ManifestElement } from './models'; +import type { ManifestElement, ManifestWithConditions } from './models'; /** * An action to perform on multiple entities * For example for content you may wish to move one or more documents in bulk */ -export interface ManifestEntityBulkAction extends ManifestElement { +export interface ManifestEntityBulkAction extends ManifestElement, ManifestWithConditions { type: 'entityBulkAction'; meta: MetaEntityBulkAction; } export interface MetaEntityBulkAction { /** - * + * */ label: string; - - /** - * The friendly name of the action to perform - * @example 'Move' - */ - entityType: string; - - api: any; // TODO create interface + api: any; // create interface /** * The alias for the repsoitory of the entity type this action is for @@ -30,3 +23,7 @@ export interface MetaEntityBulkAction { */ repositoryAlias: string; } + +export interface ConditionsEntityBulkAction { + entityType: string; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/entry-point-extension-initializer.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/entry-point-extension-initializer.ts new file mode 100644 index 0000000000..1ab0d19abe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/entry-point-extension-initializer.ts @@ -0,0 +1,28 @@ +import type { ManifestEntrypoint } from './models'; +import { hasInitExport, loadExtension, UmbExtensionRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +export class UmbEntryPointExtensionInitializer { + #rootHost; + #extensionRegistry; + + constructor(rootHost: UmbControllerHostElement, extensionRegistry: UmbExtensionRegistry) { + this.#rootHost = rootHost; + this.#extensionRegistry = extensionRegistry; + // TODO: change entrypoint extension to be entryPoint: + extensionRegistry.extensionsOfType('entrypoint').subscribe((entryPoints) => { + entryPoints.forEach((entryPoint) => { + this.instantiateEntryPoint(entryPoint); + }); + }); + } + + instantiateEntryPoint(manifest: ManifestEntrypoint) { + loadExtension(manifest).then((js) => { + // If the extension has an onInit export, be sure to run that or else let the module handle itself + if (hasInitExport(js)) { + js.onInit(this.#rootHost, this.#extensionRegistry); + } + }); + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/header-app.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/header-app.models.ts index 25c34b8907..e6e990c591 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/header-app.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/header-app.models.ts @@ -6,7 +6,7 @@ import type { ManifestElement } from './models'; */ export interface ManifestHeaderApp extends ManifestElement { type: 'headerApp'; - meta: MetaHeaderApp; + //meta: MetaHeaderApp; } // TODO: Warren these don't seem to be used anywhere @@ -15,3 +15,15 @@ export interface MetaHeaderApp { label: string; icon: string; } + +export interface ManifestHeaderAppButtonKind extends ManifestHeaderApp { + type: 'headerApp'; + kind: 'button'; + meta: MetaHeaderAppButtonKind; +} + +export interface MetaHeaderAppButtonKind { + href: string; + label: string; + icon: string; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/index.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/index.ts index e9644dae47..3ea5cea392 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/index.ts @@ -1 +1,2 @@ export * from './models'; +export * from './entry-point-extension-initializer'; diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/menu-item.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/menu-item.models.ts index 783713e834..e27223bbf8 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/menu-item.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/menu-item.models.ts @@ -3,11 +3,28 @@ import type { ManifestElement } from './models'; export interface ManifestMenuItem extends ManifestElement { type: 'menuItem'; meta: MetaMenuItem; + conditions: ConditionsMenuItem; } export interface MetaMenuItem { label: string; icon: string; - menus: Array; + entityType?: string; +} + +export interface ConditionsMenuItem { + menus: Array; +} + +export interface ManifestMenuItemTreeKind extends ManifestMenuItem { + type: 'menuItem'; + kind: 'tree'; + meta: MetaMenuItemTreeKind; +} + +export interface MetaMenuItemTreeKind { + treeAlias: string; + label: string; + icon: string; entityType?: string; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/models.ts index 1543773122..8619fdd9ba 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/models.ts @@ -4,19 +4,20 @@ import type { ManifestDashboardCollection } from './dashboard-collection.models' import type { ManifestEntityAction } from './entity-action.models'; import type { ManifestEntityBulkAction } from './entity-bulk-action.models'; import type { ManifestExternalLoginProvider } from './external-login-provider.models'; -import type { ManifestHeaderApp } from './header-app.models'; +import type { ManifestHeaderApp, ManifestHeaderAppButtonKind } from './header-app.models'; import type { ManifestHealthCheck } from './health-check.models'; import type { ManifestPackageView } from './package-view.models'; import type { ManifestPropertyAction } from './property-action.models'; import type { ManifestPropertyEditorUI, ManifestPropertyEditorModel } from './property-editor.models'; import type { ManifestSection } from './section.models'; import type { ManifestSectionView } from './section-view.models'; -import type { ManifestSectionSidebarApp, ManifestMenuSectionSidebarApp } from './section-sidebar-app.models'; +import type { ManifestSectionSidebarApp, ManifestSectionSidebarAppMenuKind } from './section-sidebar-app.models'; import type { ManifestMenu } from './menu.models'; -import type { ManifestMenuItem } from './menu-item.models'; +import type { ManifestMenuItem, ManifestMenuItemTreeKind } from './menu-item.models'; import type { ManifestTheme } from './theme.models'; import type { ManifestTree } from './tree.models'; -import type { ManifestUserDashboard } from './user-dashboard.models'; +import type { ManifestTreeItem } from './tree-item.models'; +import type { ManifestUserProfileApp } from './user-profile-app.models'; import type { ManifestWorkspace } from './workspace.models'; import type { ManifestWorkspaceAction } from './workspace-action.models'; import type { ManifestWorkspaceView } from './workspace-view.models'; @@ -24,6 +25,7 @@ import type { ManifestWorkspaceViewCollection } from './workspace-view-collectio import type { ManifestRepository } from './repository.models'; import type { ManifestModal } from './modal.models'; import type { ManifestStore, ManifestTreeStore } from './store.models'; +import type { ClassConstructor } from '@umbraco-cms/backoffice/models'; export * from './collection-view.models'; export * from './dashboard-collection.models'; @@ -43,7 +45,8 @@ export * from './menu.models'; export * from './menu-item.models'; export * from './theme.models'; export * from './tree.models'; -export * from './user-dashboard.models'; +export * from './tree-item.models'; +export * from './user-profile-app.models'; export * from './workspace-action.models'; export * from './workspace-view-collection.models'; export * from './workspace-view.models'; @@ -54,7 +57,6 @@ export * from './modal.models'; export type ManifestTypes = | ManifestCollectionView - | ManifestCustom | ManifestDashboard | ManifestDashboardCollection | ManifestEntityAction @@ -62,6 +64,7 @@ export type ManifestTypes = | ManifestEntrypoint | ManifestExternalLoginProvider | ManifestHeaderApp + | ManifestHeaderAppButtonKind | ManifestHealthCheck | ManifestPackageView | ManifestPropertyAction @@ -70,13 +73,15 @@ export type ManifestTypes = | ManifestRepository | ManifestSection | ManifestSectionSidebarApp + | ManifestSectionSidebarAppMenuKind | ManifestSectionView - | ManifestMenuSectionSidebarApp | ManifestMenu | ManifestMenuItem + | ManifestMenuItemTreeKind | ManifestTheme | ManifestTree - | ManifestUserDashboard + | ManifestTreeItem + | ManifestUserProfileApp | ManifestWorkspace | ManifestWorkspaceAction | ManifestWorkspaceView @@ -92,6 +97,9 @@ export type ManifestTypeMap = { [Manifest in ManifestTypes as Manifest['type']]: Manifest; }; +export type SpecificManifestTypeOrManifestBase = + T extends keyof ManifestTypeMap ? ManifestTypeMap[T] : ManifestBase; + export interface ManifestBase { /** * The type of extension such as dashboard etc... @@ -103,6 +111,12 @@ export interface ManifestBase { */ alias: string; + /** + * The kind of the extension, used to group extensions together + * @example "button" + */ + kind?: any; // I had to add the optional kind property set to undefined. To make the ManifestTypes recognize the Manifest Kind types. Notice that Kinds has to Omit the kind property when extending. + /** * The friendly name of the extension */ @@ -114,6 +128,18 @@ export interface ManifestBase { weight?: number; } +export interface ManifestKind { + type: 'kind'; + alias: string; + matchType: string; + matchKind: string; + manifest: Partial; +} + +export interface ManifestWithConditions { + conditions: ConditionsType; +} + export interface ManifestWithLoader extends ManifestBase { /** * Ignore this property when serializing to JSON Schema @@ -127,14 +153,22 @@ export interface ManifestWithLoader extends ManifestBase { * The type of extension such as dashboard etc... */ export interface ManifestClass extends ManifestWithLoader { - type: ManifestStandardTypes; + //type: ManifestStandardTypes; /** * The file location of the javascript file to load + * @required */ js?: string; + /** + * @ignore + */ className?: string; + + /** + * @ignore + */ class?: ClassConstructor; //loader?: () => Promise; } @@ -144,13 +178,11 @@ export interface ManifestClassWithClassConstructor extends ManifestClass { } export interface ManifestElement extends ManifestWithLoader { - /** - * The type of extension such as dashboard etc... - */ - type: ManifestStandardTypes; + //type: ManifestStandardTypes; /** * The file location of the javascript file to load + * @required */ js?: string; @@ -159,11 +191,12 @@ export interface ManifestElement extends ManifestWithLoader but just the name */ elementName?: string; + //loader?: () => Promise; /** * This contains properties specific to the type of extension */ - meta?: unknown; + meta?: any; } export interface ManifestWithView extends ManifestElement { @@ -184,15 +217,6 @@ export interface ManifestElementWithElementName extends ManifestElement { elementName: string; } -export interface ManifestCustom extends ManifestBase { - type: 'custom'; - - /** - * This contains properties specific to the type of extension - */ - meta?: unknown; -} - export interface ManifestWithMeta extends ManifestBase { /** * This contains properties specific to the type of extension @@ -200,8 +224,6 @@ export interface ManifestWithMeta extends ManifestBase { meta: unknown; } -export type ClassConstructor = new (...args: any[]) => T; - /** * This type of extension gives full control and will simply load the specified JS file * You could have custom logic to decide which extensions to load/register by using extensionRegistry diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/property-action.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/property-action.models.ts index 640849b9d7..8c98a0da0d 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/property-action.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/property-action.models.ts @@ -1,10 +1,9 @@ -import type { ManifestElement } from './models'; +import type { ManifestElement, ManifestWithConditions } from './models'; -export interface ManifestPropertyAction extends ManifestElement { +export interface ManifestPropertyAction extends ManifestElement, ManifestWithConditions { type: 'propertyAction'; - meta: MetaPropertyAction; } -export interface MetaPropertyAction { +export interface ConditionsPropertyAction { propertyEditors: string[]; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/extensions-registry/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-sidebar-app.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-sidebar-app.models.ts index 544e64021e..c769ded62b 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-sidebar-app.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-sidebar-app.models.ts @@ -2,20 +2,20 @@ import type { ManifestElement } from './models'; export interface ManifestSectionSidebarApp extends ManifestElement { type: 'sectionSidebarApp'; - meta: MetaSectionSidebarApp; + conditions: ConditionsSectionSidebarApp; } -export interface MetaSectionSidebarApp { +export interface ConditionsSectionSidebarApp { sections: Array; } -// TODO: this is a temp solution until we implement kinds -export interface ManifestMenuSectionSidebarApp extends ManifestElement { - type: 'menuSectionSidebarApp'; - meta: MetaMenuSectionSidebarApp; +export interface ManifestSectionSidebarAppMenuKind extends ManifestSectionSidebarApp { + type: 'sectionSidebarApp'; + kind: 'menu'; + meta: MetaSectionSidebarAppMenuKind; } -export interface MetaMenuSectionSidebarApp extends MetaSectionSidebarApp { +export interface MetaSectionSidebarAppMenuKind { label: string; menu: string; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-view.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-view.models.ts index 37c59c90ba..5bd892e818 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-view.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/section-view.models.ts @@ -1,14 +1,16 @@ -import type { ManifestElement } from './models'; +import type { ManifestElement, ManifestWithConditions } from './models'; -export interface ManifestSectionView extends ManifestElement { +export interface ManifestSectionView extends ManifestElement, ManifestWithConditions { type: 'sectionView'; meta: MetaSectionView; } export interface MetaSectionView { - sections: Array; label: string; pathname: string; - weight: number; icon: string; } + +export interface ConditionsSectionView { + sections: Array; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/store.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/store.models.ts index 35a156c466..18e8c10c17 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/store.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/store.models.ts @@ -1,10 +1,10 @@ import type { ManifestClass } from './models'; -import { UmbStoreBase, UmbTreeStoreBase } from '@umbraco-cms/store'; +import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store'; export interface ManifestStore extends ManifestClass { type: 'store'; } -export interface ManifestTreeStore extends ManifestClass { +export interface ManifestTreeStore extends ManifestClass { type: 'treeStore'; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/theme.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/theme.models.ts index 7618a21a31..51704abc53 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/theme.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/theme.models.ts @@ -1,4 +1,4 @@ -import type { ManifestWithLoader } from "./models"; +import type { ManifestWithLoader } from './models'; // TODO: make or find type for JS Module with default export: Would be nice to support css file directly. diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/tree-item.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/tree-item.models.ts new file mode 100644 index 0000000000..9231a8ae68 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/tree-item.models.ts @@ -0,0 +1,10 @@ +import type { ManifestElement } from './models'; + +export interface ManifestTreeItem extends ManifestElement { + type: 'treeItem'; + conditions: ConditionsTreeItem; +} + +export interface ConditionsTreeItem { + entityType: string; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/tree.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/tree.models.ts index a4576d7298..49e8387bb4 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/tree.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/tree.models.ts @@ -1,4 +1,4 @@ -import type { ClassConstructor, ManifestBase } from './models'; +import type { ManifestBase } from './models'; export interface ManifestTree extends ManifestBase { type: 'tree'; @@ -6,6 +6,5 @@ export interface ManifestTree extends ManifestBase { } export interface MetaTree { - storeAlias?: string; - repository?: ClassConstructor; + repositoryAlias: string; } diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/umbraco-package.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/umbraco-package.ts index 88d5d29604..766226d672 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/umbraco-package.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/umbraco-package.ts @@ -9,7 +9,6 @@ import type { ManifestHealthCheck, ManifestMenu, ManifestMenuItem, - ManifestMenuSectionSidebarApp, ManifestPackageView, ManifestPropertyAction, ManifestPropertyEditorModel, @@ -19,7 +18,6 @@ import type { ManifestSectionSidebarApp, ManifestSectionView, ManifestTheme, - ManifestUserDashboard, ManifestWorkspace, ManifestWorkspaceView, ManifestWorkspaceViewCollection, @@ -42,11 +40,9 @@ export type ManifestJSONTypes = | ManifestSection | ManifestSectionSidebarApp | ManifestSectionView - | ManifestMenuSectionSidebarApp | ManifestMenu | ManifestMenuItem | ManifestTheme - | ManifestUserDashboard | ManifestWorkspace | ManifestWorkspaceView | ManifestWorkspaceViewCollection; diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/user-dashboard.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/user-dashboard.models.ts deleted file mode 100644 index 23f6acf325..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/user-dashboard.models.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { ManifestElement } from './models'; - -/** - * A user dashboard extension is shown in the dialog that opens when the user clicks on the user avatar in the top right corner - */ -export interface ManifestUserDashboard extends ManifestElement { - type: 'userDashboard'; -} - diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/user-profile-app.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/user-profile-app.models.ts new file mode 100644 index 0000000000..456f6e32d0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/user-profile-app.models.ts @@ -0,0 +1,11 @@ +import type { ManifestElement } from './models'; + +export interface ManifestUserProfileApp extends ManifestElement { + type: 'userProfileApp'; + meta: MetaUserProfileApp; +} + +export interface MetaUserProfileApp { + label: string; + pathname: string; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-action.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-action.models.ts index 209e982f1d..2cb7595388 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-action.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-action.models.ts @@ -1,15 +1,20 @@ import type { InterfaceColor, InterfaceLook } from '@umbraco-ui/uui-base/lib/types/index'; -import type { ClassConstructor, ManifestElement } from './models'; +import type { ManifestElement } from './models'; +import type { ClassConstructor } from '@umbraco-cms/backoffice/models'; export interface ManifestWorkspaceAction extends ManifestElement { type: 'workspaceAction'; meta: MetaWorkspaceAction; + conditions: ConditionsWorkspaceAction; } export interface MetaWorkspaceAction { - workspaces: Array; label?: string; //TODO: Use or implement additional label-key look?: InterfaceLook; color?: InterfaceColor; api: ClassConstructor; } + +export interface ConditionsWorkspaceAction { + workspaces: Array; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view-collection.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view-collection.models.ts index 366dd3cdbe..309a2af11b 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view-collection.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view-collection.models.ts @@ -1,13 +1,14 @@ -import type { ManifestBase } from './models'; +import type { ManifestBase, ManifestWithConditions } from './models'; -export interface ManifestWorkspaceViewCollection extends ManifestBase { +export interface ManifestWorkspaceViewCollection + extends ManifestBase, + ManifestWithConditions { type: 'workspaceViewCollection'; meta: MetaEditorViewCollection; } // TODO: Get rid of store alias, when we are done migrating to repositories(remember to enforce repositoryAlias): export interface MetaEditorViewCollection { - workspaces: string[]; pathname: string; label: string; icon: string; @@ -15,3 +16,7 @@ export interface MetaEditorViewCollection { storeAlias?: string; repositoryAlias?: string; } + +export interface ConditionsEditorViewCollection { + workspaces: string[]; +} diff --git a/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view.models.ts b/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view.models.ts index acfc5e9062..6f2898de75 100644 --- a/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view.models.ts +++ b/src/Umbraco.Web.UI.Client/libs/extensions-registry/workspace-view.models.ts @@ -2,12 +2,16 @@ import type { ManifestWithView } from './models'; export interface ManifestWorkspaceView extends ManifestWithView { type: 'workspaceView'; - meta: MetaEditorView; + meta: MetaWorkspaceView; + conditions: ConditionsWorkspaceView; } -export interface MetaEditorView { - workspaces: string[]; +export interface MetaWorkspaceView { pathname: string; label: string; icon: string; } + +export interface ConditionsWorkspaceView { + workspaces: string[]; +} diff --git a/src/Umbraco.Web.UI.Client/libs/modal/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/index.ts index 5882bda117..3e2caa5f16 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/index.ts @@ -1,5 +1,6 @@ export * from './modal.context'; export * from './modal-handler'; -export * from './elements/modal-element.element'; -export * from './elements/modal-element-picker-base'; -export * from './token/modal-token'; +export * from './modal-route-registration'; +export * from './modal-route-registration.controller'; +export * from './token'; +export * from './modal.interfaces'; diff --git a/src/Umbraco.Web.UI.Client/libs/modal/modal-handler.ts b/src/Umbraco.Web.UI.Client/libs/modal/modal-handler.ts index bf46856f13..43f10f9e14 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/modal-handler.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/modal-handler.ts @@ -1,19 +1,22 @@ -import type { UUIDialogElement } from '@umbraco-ui/uui'; -import type { UUIModalDialogElement } from '@umbraco-ui/uui-modal-dialog'; -import { UUIModalSidebarElement, UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; +import type { + UUIDialogElement, + UUIModalDialogElement, + UUIModalSidebarElement, + UUIModalSidebarSize, +} from '@umbraco-ui/uui'; import { v4 as uuidv4 } from 'uuid'; import { BehaviorSubject } from 'rxjs'; import { UmbModalConfig, UmbModalType } from './modal.context'; import { UmbModalToken } from './token/modal-token'; -import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbObserverController } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ManifestModal } from '@umbraco-cms/extensions-registry'; +import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; /** * Type which omits the real submit method, and replaces it with a submit method which accepts an optional argument depending on the generic type. */ -export type UmbModalHandler = Omit< +export type UmbModalHandler = Omit< UmbModalHandlerClass, 'submit' > & @@ -35,15 +38,15 @@ type OptionalSubmitArgumentIfUndefined = T extends undefined }; //TODO consider splitting this into two separate handlers -export class UmbModalHandlerClass { +export class UmbModalHandlerClass { private _submitPromise: Promise; private _submitResolver?: (value: ModalResult) => void; private _submitRejecter?: () => void; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; public modalElement: UUIModalDialogElement | UUIModalSidebarElement; - #innerElement = new BehaviorSubject(undefined); + #innerElement = new BehaviorSubject(undefined); public readonly innerElement = this.#innerElement.asObservable(); #modalElement?: UUIModalSidebarElement | UUIDialogElement; @@ -53,7 +56,7 @@ export class UmbModalHandlerClass { public size: UUIModalSidebarSize = 'small'; constructor( - host: UmbControllerHostInterface, + host: UmbControllerHostElement, modalAlias: string | UmbModalToken, data?: ModalData, config?: UmbModalConfig @@ -103,7 +106,7 @@ export class UmbModalHandlerClass { const innerElement = (await createExtensionElement(manifest)) as any; if (innerElement) { - innerElement.data = data; // + innerElement.data = data; //innerElement.observable = this.#dataObservable; innerElement.modalHandler = this; } @@ -111,7 +114,7 @@ export class UmbModalHandlerClass { return innerElement; } - // note, this methods argument is not defined correctly here, but requires to be fix by appending the OptionalSubmitArgumentIfUndefined type when newing up this class. + // note, this methods is private argument is not defined correctly here, but requires to be fix by appending the OptionalSubmitArgumentIfUndefined type when newing up this class. private submit(result?: ModalResult) { this._submitResolver?.(result as ModalResult); this.modalElement.close(); @@ -137,22 +140,25 @@ export class UmbModalHandlerClass { async (manifest) => { if (manifest) { const innerElement = await this.#createInnerElement(manifest, data); - this.#appendInnerElement(innerElement); - } else { - this.#removeInnerElement(); + if (innerElement) { + this.#appendInnerElement(innerElement); + return; + } } + this.#removeInnerElement(); } ); } - #appendInnerElement(element: any) { + #appendInnerElement(element: HTMLElement) { this.#modalElement?.appendChild(element); this.#innerElement.next(element); } #removeInnerElement() { - if (this.#innerElement.getValue()) { - this.#modalElement?.removeChild(this.#innerElement.getValue()); + const innerElement = this.#innerElement.getValue(); + if (innerElement) { + this.#modalElement?.removeChild(innerElement); this.#innerElement.next(undefined); } } diff --git a/src/Umbraco.Web.UI.Client/libs/modal/modal-route-registration.controller.ts b/src/Umbraco.Web.UI.Client/libs/modal/modal-route-registration.controller.ts new file mode 100644 index 0000000000..213debd539 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/modal-route-registration.controller.ts @@ -0,0 +1,88 @@ +// TODO: Be aware here we import a class from src! +import { UMB_ROUTE_CONTEXT_TOKEN } from '../router/route.context'; +import { UmbModalRouteRegistration } from './modal-route-registration'; +import type { UmbControllerHostElement, UmbControllerInterface } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbModalConfig, UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export class UmbModalRouteRegistrationController + extends UmbModalRouteRegistration + implements UmbControllerInterface +{ + //#host: UmbControllerHostInterface; + + #configuredPath: string; + #uniqueParts: Map; + + #routeContext?: typeof UMB_ROUTE_CONTEXT_TOKEN.TYPE; + #modalRegistration?: UmbModalRouteRegistration; + + public get unique() { + return undefined; + } + + constructor( + host: UmbControllerHostElement, + alias: UmbModalToken | string, + path: string, + uniqueParts?: Map | null, + modalConfig?: UmbModalConfig + ) { + super(alias, path, modalConfig); + //this.#host = host; + this.#configuredPath = path; + this.#uniqueParts = uniqueParts || new Map(); + + new UmbContextConsumerController(host, UMB_ROUTE_CONTEXT_TOKEN, (_routeContext) => { + this.#routeContext = _routeContext; + this._registererModal(); + }); + } + + setUniqueIdentifier(identifier: string, value: string | undefined) { + if (!this.#uniqueParts.has(identifier)) { + throw new Error( + `Identifier ${identifier} was not registered at the construction of the modal registration controller, it has to be.` + ); + } + this.#uniqueParts.set(identifier, value); + this._registererModal(); + } + + private _registererModal() { + if (!this.#routeContext) return; + if (this.#modalRegistration) { + this.#routeContext.unregisterModal(this.#modalRegistration); + this.#modalRegistration = undefined; + } + + const pathParts = Array.from(this.#uniqueParts.values()); + + // Check if there is any undefined values of unique map: + if (pathParts.some((value) => value === undefined)) return; + + // Add the configured part of the path: + pathParts.push(this.#configuredPath); + + // Make this the path of the modal registration: + this._setPath(pathParts.join('/')); + + this.#modalRegistration = this.#routeContext.registerModal(this); + } + + hostConnected() { + if (!this.#modalRegistration) { + this._registererModal(); + } + } + hostDisconnected(): void { + if (this.#modalRegistration) { + this.#routeContext?.unregisterModal(this.#modalRegistration); + this.#modalRegistration = undefined; + } + } + + public destroy(): void { + this.hostDisconnected(); + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/modal/modal-route-registration.ts b/src/Umbraco.Web.UI.Client/libs/modal/modal-route-registration.ts new file mode 100644 index 0000000000..3c7f7e7557 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/modal-route-registration.ts @@ -0,0 +1,115 @@ +import { v4 as uuidv4 } from 'uuid'; +import { UmbModalHandler } from './modal-handler'; +import { UmbModalConfig, UmbModalContext } from './modal.context'; +import { UmbModalToken } from './token/modal-token'; +import type { Params } from '@umbraco-cms/backoffice/router'; + +export type UmbModalRouteBuilder = (params: { [key: string]: string | number }) => string; + +export class UmbModalRouteRegistration { + #key: string; + #path: string; + #modalAlias: UmbModalToken | string; + #modalConfig?: UmbModalConfig; + + #onSetupCallback?: (routingInfo: Params) => UmbModalTokenData | false; + #onSubmitCallback?: (data: UmbModalTokenResult) => void; + #onRejectCallback?: () => void; + + #modalHandler: UmbModalHandler | undefined; + #routeBuilder?: UmbModalRouteBuilder; + #urlBuilderCallback: ((urlBuilder: UmbModalRouteBuilder) => void) | undefined; + + // Notice i removed the key in the transferring to this class. + constructor( + modalAlias: UmbModalToken | string, + path: string, + modalConfig?: UmbModalConfig + ) { + this.#key = modalConfig?.key || uuidv4(); + this.#modalAlias = modalAlias; + this.#path = path; + this.#modalConfig = { ...modalConfig, key: this.#key }; + } + + public get key() { + return this.#key; + } + + public get alias() { + return this.#modalAlias; + } + + public get path() { + return this.#path; + } + + protected _setPath(path: string) { + this.#path = path; + } + + public get modalConfig() { + return this.#modalConfig; + } + + /** + * Returns true if the modal is currently active. + */ + public get active() { + return !!this.#modalHandler; + } + + public open(params: { [key: string]: string | number }) { + if (this.active) return; + + window.history.pushState({}, '', this.#routeBuilder?.(params)); + } + + /** + * Returns the modal handler if the modal is currently active. Otherwise its undefined. + */ + public get modalHandler() { + return this.#modalHandler; + } + + public observeRouteBuilder(callback: (urlBuilder: UmbModalRouteBuilder) => void) { + this.#urlBuilderCallback = callback; + return this; + } + public _internal_setRouteBuilder(urlBuilder: UmbModalRouteBuilder) { + this.#routeBuilder = urlBuilder; + this.#urlBuilderCallback?.(urlBuilder); + } + + public onSetup(callback: (routingInfo: Params) => UmbModalTokenData | false) { + this.#onSetupCallback = callback; + return this; + } + public onSubmit(callback: (data: UmbModalTokenResult) => void) { + this.#onSubmitCallback = callback; + return this; + } + public onReject(callback: () => void) { + this.#onRejectCallback = callback; + return this; + } + + #onSubmit = (data: UmbModalTokenResult) => { + this.#onSubmitCallback?.(data); + this.#modalHandler = undefined; + }; + #onReject = () => { + this.#onRejectCallback?.(); + this.#modalHandler = undefined; + }; + + routeSetup(modalContext: UmbModalContext, params: Params) { + const modalData = this.#onSetupCallback ? this.#onSetupCallback(params) : undefined; + if (modalData !== false) { + this.#modalHandler = modalContext.open(this.#modalAlias, modalData, this.modalConfig); + this.#modalHandler.onSubmit().then(this.#onSubmit, this.#onReject); + return this.#modalHandler; + } + return null; + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/modal/modal.context.ts b/src/Umbraco.Web.UI.Client/libs/modal/modal.context.ts index aacb0f1646..1d58c827df 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/modal.context.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/modal.context.ts @@ -1,13 +1,12 @@ // TODO: remove this import when the search hack is removed import '../../src/backoffice/search/modals/search/search-modal.element'; -import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; +import type { UUIModalDialogElement, UUIModalSidebarSize } from '@umbraco-ui/uui'; import { BehaviorSubject } from 'rxjs'; -import type { UUIModalDialogElement } from '@umbraco-ui/uui-modal-dialog'; import { UmbModalHandler, UmbModalHandlerClass } from './modal-handler'; import type { UmbModalToken } from './token/modal-token'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export type UmbModalType = 'dialog' | 'sidebar'; @@ -20,12 +19,12 @@ export interface UmbModalConfig { // TODO: we should find a way to easily open a modal without adding custom methods to this context. It would result in a better separation of concerns. // TODO: move all layouts into their correct "silo" folders. User picker should live with users etc. export class UmbModalContext { - host: UmbControllerHostInterface; + host: UmbControllerHostElement; // TODO: Investigate if we can get rid of HTML elements in our store, so we can use one of our states. - #modals = new BehaviorSubject(>>[]); + #modals = new BehaviorSubject(>[]); public readonly modals = this.#modals.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.host = host; } @@ -76,7 +75,7 @@ export class UmbModalContext { * @return {*} {UmbModalHandler} * @memberof UmbModalContext */ - public open( + public open( modalAlias: string | UmbModalToken, data?: ModalData, config?: UmbModalConfig diff --git a/src/Umbraco.Web.UI.Client/libs/modal/modal.interfaces.ts b/src/Umbraco.Web.UI.Client/libs/modal/modal.interfaces.ts new file mode 100644 index 0000000000..86ad653a1b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/modal.interfaces.ts @@ -0,0 +1,9 @@ +export interface UmbPickerModalData { + multiple: boolean; + selection: Array; + filter?: (language: T) => boolean; +} + +export interface UmbPickerModalResult { + selection: Array; +} diff --git a/src/Umbraco.Web.UI.Client/libs/modal/stories/modal.mdx b/src/Umbraco.Web.UI.Client/libs/modal/stories/modal.mdx deleted file mode 100644 index 9cb19bc473..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/modal/stories/modal.mdx +++ /dev/null @@ -1,145 +0,0 @@ -import { Meta } from '@storybook/blocks'; - - - -# Modals - -A modal is a popup that darkens the background and has focus lock. There are two types of modals: "dialog" and "sidebar". - -**Dialog modals** appears in the middle of the screen. -| option | values | -|:------:|:--------------------------:| -| No options yet | | - -**Sidebar modals** slides in from the right. -| option | values | -|:------:|:--------------------------:| -| size | small, medium, large, full | - -## Basic Usage - -### Consume UmbModalContext from an element - -The UmbModal context can be used to open modals. - -```ts -import { LitElement } from 'lit'; -import { UmbElementMixin } from '@umbraco-cms/element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_ALIAS } from '@umbraco-cms/modal'; - -class MyElement extends UmbElementMixin(LitElement) { - #modalContext?: UmbModalContext; - - constructor() { - super(); - this.consumeContext(UMB_MODAL_CONTEXT_ALIAS, (instance) => { - this.#modalContext = instance; - // modalContext is now ready to be used. - }); - } -} -``` - -### Open a modal - -A modal is opened by calling the open method on the UmbModalContext. The methods will accept a modal token (or extension alias), an optional dataset, and optional modal options .It returns an instance of UmbModalHandler. - -```ts -import { html, LitElement } from 'lit'; -import { UmbElementMixin } from '@umbraco-cms/element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_ALIAS } from '@umbraco-cms/modal'; -class MyElement extends UmbElementMixin(LitElement) { - #modalContext?: UmbModalContext; - - constructor() { - super(); - this.consumeContext(UMB_MODAL_CONTEXT_ALIAS, (instance) => { - this.#modalContext = instance; - // modalContext is now ready to be used - }); - } - - #onClick() { - const data = {'data goes here'}; - const options {'options go here'}; - const modalHandler = this.#modalContext?.open(SOME_MODAL_TOKEN), data, options); - - modalHandler?.onSubmit().then((data) => { - // if modal submitted, then data is supplied here. - }); - } - - render() { - return html``; - } -} -``` - -## Create a custom modal - -### Register in the extension registry - -The manifest - -```json -{ - "type": "modal", - "alias": "My.Modal", - "name": "My Modal", - "js": "../path/to/my-modal.element.js" -} -``` - -### Create a modal token - -A modal token is a string that identifies a modal. It should be the modal extension alias. It is used to open a modal and is also to set default options for the modal. - -```ts -interface MyModalData = { - headline: string; - content: string; -} - -interface MyModalResult = { - myReturnData: string; -} - -const MY_MODAL_TOKEN = new ModalToken('My.Modal', { - type: 'sidebar', - size: 'small' -}); -``` - -The Modal element - -```ts -import { html, LitElement } from 'lit'; -import { UmbElementMixin } from '@umbraco-cms/element'; -import type { UmbModalHandler } from '@umbraco-cms/modal'; - -class MyDialog extends UmbElementMixin(LitElement) { - // the modal handler will be injected into the element when the modal is opened. - @property({ attribute: false }) - modalHandler?: UmbModalHandler; - - private _handleCancel() { - this._modalHandler?.close(); - } - - private _handleSubmit() { - /* Optional data of any type can be applied to the submit method to pass it - to the modal parent through the onSubmit promise. */ - this._modalHandler?.submit({ myReturnData: 'hello world' }); - } - - render() { - return html` -
-

My Modal

- - -
- `; - } -} -``` diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/allowed-document-types-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/allowed-document-types-modal.token.ts new file mode 100644 index 0000000000..c4f7631758 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/allowed-document-types-modal.token.ts @@ -0,0 +1,17 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbAllowedDocumentTypesModalData { + id: string | null; +} + +export interface UmbAllowedDocumentTypesModalResult { + documentTypeKey: string; +} + +export const UMB_ALLOWED_DOCUMENT_TYPES_MODAL = new UmbModalToken< + UmbAllowedDocumentTypesModalData, + UmbAllowedDocumentTypesModalResult +>('Umb.Modal.AllowedDocumentTypes', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/change-password-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/change-password-modal.token.ts new file mode 100644 index 0000000000..b2db240cd6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/change-password-modal.token.ts @@ -0,0 +1,9 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbChangePasswordModalData { + requireOldPassword: boolean; +} + +export const UMB_CHANGE_PASSWORD_MODAL = new UmbModalToken('Umb.Modal.ChangePassword', { + type: 'dialog', +}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/confirm-modal.token.ts similarity index 54% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/confirm-modal.token.ts index eb7a773cc3..612881bc26 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/confirm-modal.token.ts @@ -1,5 +1,5 @@ import type { TemplateResult } from 'lit'; -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbConfirmModalData { headline: string; @@ -10,9 +10,6 @@ export interface UmbConfirmModalData { export type UmbConfirmModalResult = undefined; -export const UMB_CONFIRM_MODAL_TOKEN = new UmbModalToken( - 'Umb.Modal.Confirm', - { - type: 'dialog', - } -); +export const UMB_CONFIRM_MODAL = new UmbModalToken('Umb.Modal.Confirm', { + type: 'dialog', +}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/create-dictionary-modal.token.ts similarity index 77% rename from src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/create-dictionary-modal.token.ts index 32139c6bd6..3e635f2cc4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/create-dictionary-modal.token.ts @@ -1,5 +1,5 @@ import { Observable } from 'rxjs'; -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; // TODO: add interface for data // PropertyTypeViewModelBaseModel @@ -12,7 +12,7 @@ export interface UmbCreateDictionaryModalResult { name?: string; } -export const UMB_CREATE_DICTIONARY_MODAL_TOKEN = new UmbModalToken< +export const UMB_CREATE_DICTIONARY_MODAL = new UmbModalToken< UmbCreateDictionaryModalData, UmbCreateDictionaryModalResult >('Umb.Modal.CreateDictionary', { diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/create-user-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/create-user-modal.token.ts new file mode 100644 index 0000000000..5ac7a0a780 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/create-user-modal.token.ts @@ -0,0 +1,6 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export const UMB_CREATE_USER_MODAL = new UmbModalToken('Umb.Modal.CreateUser', { + type: 'dialog', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/current-user-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/current-user-modal.token.ts new file mode 100644 index 0000000000..5a78080a7a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/current-user-modal.token.ts @@ -0,0 +1,6 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export const UMB_CURRENT_USER_MODAL = new UmbModalToken('Umb.Modal.CurrentUser', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/debug-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/debug-modal.token.ts new file mode 100644 index 0000000000..7e3f797a38 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/debug-modal.token.ts @@ -0,0 +1,11 @@ +import { TemplateResult } from 'lit'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbContextDebuggerModalData { + content: TemplateResult | string; +} + +export const UMB_CONTEXT_DEBUGGER_MODAL = new UmbModalToken('Umb.Modal.ContextDebugger', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/document-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/document-picker-modal.token.ts new file mode 100644 index 0000000000..133318c692 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/document-picker-modal.token.ts @@ -0,0 +1,18 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbDocumentPickerModalData { + multiple?: boolean; + selection?: Array; +} + +export interface UmbDocumentPickerModalResult { + selection: Array; +} + +export const UMB_DOCUMENT_PICKER_MODAL = new UmbModalToken( + 'Umb.Modal.DocumentPicker', + { + type: 'sidebar', + size: 'small', + } +); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/document-type-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/document-type-picker-modal.token.ts new file mode 100644 index 0000000000..d0c16dfc68 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/document-type-picker-modal.token.ts @@ -0,0 +1,18 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbDocumentTypePickerModalData { + multiple?: boolean; + selection?: Array; +} + +export interface UmbDocumentTypePickerModalResult { + selection: Array; +} + +export const UMB_DOCUMENT_TYPE_PICKER_MODAL = new UmbModalToken< + UmbDocumentTypePickerModalData, + UmbDocumentTypePickerModalResult +>('Umb.Modal.DocumentTypePicker', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/embedded-media-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/embedded-media-modal.token.ts new file mode 100644 index 0000000000..610b935d80 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/embedded-media-modal.token.ts @@ -0,0 +1,35 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export enum OEmbedStatus { + NotSupported, + Error, + Success, +} + +interface UmbEmbeddedMediaDimensions { + width?: number; + height?: number; + constrain?: boolean; +} + +export interface UmbEmbeddedMediaModalData extends UmbEmbeddedMediaDimensions { + url?: string; +} + +export interface OEmbedResult extends UmbEmbeddedMediaDimensions { + oEmbedStatus: OEmbedStatus; + supportsDimensions: boolean; + markup?: string; +} + +export type UmbEmbeddedMediaModalResult = { + selection: OEmbedResult; +}; + +export const UMB_EMBEDDED_MEDIA_MODAL = new UmbModalToken( + 'Umb.Modal.EmbeddedMedia', + { + type: 'sidebar', + size: 'small', + } +); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/examine-fields-settings-modal.token.ts similarity index 72% rename from src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/examine-fields-settings-modal.token.ts index 3ff332b969..d6f6aec2d7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/examine-fields-settings-modal.token.ts @@ -1,4 +1,4 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export type UmbExamineFieldsSettingsModalData = Array<{ name: string; @@ -9,7 +9,7 @@ export interface UmbCreateDocumentModalResultData { fields?: UmbExamineFieldsSettingsModalData; } -export const UMB_EXAMINE_FIELDS_SETTINGS_MODAL_TOKEN = new UmbModalToken< +export const UMB_EXAMINE_FIELDS_SETTINGS_MODAL = new UmbModalToken< UmbExamineFieldsSettingsModalData, UmbCreateDocumentModalResultData >('Umb.Modal.ExamineFieldsSettings', { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/export-dictionary-modal.token.ts similarity index 70% rename from src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/export-dictionary-modal.token.ts index 891165f3c0..4ae285e25f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/export-dictionary-modal.token.ts @@ -1,4 +1,4 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbExportDictionaryModalData { unique: string | null; @@ -8,7 +8,7 @@ export interface UmbExportDictionaryModalResult { includeChildren?: boolean; } -export const UMB_EXPORT_DICTIONARY_MODAL_TOKEN = new UmbModalToken< +export const UMB_EXPORT_DICTIONARY_MODAL = new UmbModalToken< UmbExportDictionaryModalData, UmbExportDictionaryModalResult >('Umb.Modal.ExportDictionary', { diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/folder-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/folder-modal.token.ts new file mode 100644 index 0000000000..f842409751 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/folder-modal.token.ts @@ -0,0 +1,16 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; +import { FolderReponseModel } from '@umbraco-cms/backoffice/backend-api'; + +export interface UmbFolderModalData { + repositoryAlias: string; + unique?: string; +} + +export interface UmbFolderModalResult { + folder: FolderReponseModel; +} + +export const UMB_FOLDER_MODAL = new UmbModalToken('Umb.Modal.Folder', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/icon-picker-modal.token.ts similarity index 60% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/icon-picker-modal.token.ts index 158a3a6a19..0ae41a9fbb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/icon-picker-modal.token.ts @@ -1,4 +1,4 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbIconPickerModalData { multiple: boolean; @@ -10,7 +10,7 @@ export interface UmbIconPickerModalResult { icon: string | undefined; } -export const UMB_ICON_PICKER_MODAL_TOKEN = new UmbModalToken( +export const UMB_ICON_PICKER_MODAL = new UmbModalToken( 'Umb.Modal.IconPicker', { type: 'sidebar', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/import-dictionary-modal.token.ts similarity index 65% rename from src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/import-dictionary-modal.token.ts index 41f2b60917..c420afa120 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/import-dictionary-modal.token.ts @@ -1,4 +1,4 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; // TODO: add interface for data // PropertyTypeViewModelBaseModel @@ -7,11 +7,11 @@ export interface UmbImportDictionaryModalData { } export interface UmbImportDictionaryModalResult { - fileName?: string; - parentKey?: string; + temporaryFileId?: string; + parentId?: string; } -export const UMB_IMPORT_DICTIONARY_MODAL_TOKEN = new UmbModalToken< +export const UMB_IMPORT_DICTIONARY_MODAL = new UmbModalToken< UmbImportDictionaryModalData, UmbImportDictionaryModalResult >('Umb.Modal.ImportDictionary', { diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/index.ts new file mode 100644 index 0000000000..7fd02d418b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/index.ts @@ -0,0 +1,28 @@ +export * from './modal-token'; +export * from './allowed-document-types-modal.token'; +export * from './change-password-modal.token'; +export * from './confirm-modal.token'; +export * from './create-dictionary-modal.token'; +export * from './create-user-modal.token'; +export * from './current-user-modal.token'; +export * from './debug-modal.token'; +export * from './document-picker-modal.token'; +export * from './document-type-picker-modal.token'; +export * from './embedded-media-modal.token'; +export * from './examine-fields-settings-modal.token'; +export * from './export-dictionary-modal.token'; +export * from './icon-picker-modal.token'; +export * from './import-dictionary-modal.token'; +export * from './invite-user-modal.token'; +export * from './language-picker-modal.token'; +export * from './link-picker-modal.token'; +export * from './media-picker-modal.token'; +export * from './property-editor-ui-picker-modal.token'; +export * from './property-settings-modal.token'; +export * from './search-modal.token'; +export * from './section-picker-modal.token'; +export * from './template-modal.token'; +export * from './template-picker-modal.token'; +export * from './user-group-picker-modal.token'; +export * from './user-picker-modal.token'; +export * from './folder-modal.token'; diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/invite-user-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/invite-user-modal.token.ts new file mode 100644 index 0000000000..20bb006c54 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/invite-user-modal.token.ts @@ -0,0 +1,6 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export const UMB_INVITE_USER_MODAL = new UmbModalToken('Umb.Modal.InviteUser', { + type: 'dialog', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/language-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/language-picker-modal.token.ts new file mode 100644 index 0000000000..fb47287bd9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/language-picker-modal.token.ts @@ -0,0 +1,20 @@ +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbLanguagePickerModalData { + multiple?: boolean; + selection?: Array; + filter?: (language: LanguageResponseModel) => boolean; +} + +export interface UmbLanguagePickerModalResult { + selection: Array; +} + +export const UMB_LANGUAGE_PICKER_MODAL = new UmbModalToken( + 'Umb.Modal.LanguagePicker', + { + type: 'sidebar', + size: 'small', + } +); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/link-picker/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/link-picker-modal.token.ts similarity index 65% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/link-picker/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/link-picker-modal.token.ts index ecbd202e43..025b5582cb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/link-picker/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/link-picker-modal.token.ts @@ -1,12 +1,13 @@ -import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; -import { UmbModalToken } from '@umbraco-cms/modal'; +import type { UUIModalSidebarSize } from '@umbraco-ui/uui'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbLinkPickerModalData { + index: number | null; link: UmbLinkPickerLink; config: UmbLinkPickerConfig; } -export type UmbLinkPickerModalResult = UmbLinkPickerLink; +export type UmbLinkPickerModalResult = { index: number | null; link: UmbLinkPickerLink }; export interface UmbLinkPickerLink { icon?: string | null; @@ -26,7 +27,7 @@ export interface UmbLinkPickerConfig { overlaySize?: UUIModalSidebarSize; } -export const UMB_LINK_PICKER_MODAL_TOKEN = new UmbModalToken( +export const UMB_LINK_PICKER_MODAL = new UmbModalToken( 'Umb.Modal.LinkPicker', { type: 'sidebar', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/media-picker/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/media-picker-modal.token.ts similarity index 58% rename from src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/media-picker/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/media-picker-modal.token.ts index 7075158e15..94607575c4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/media-picker/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/media-picker-modal.token.ts @@ -1,4 +1,4 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbMediaPickerModalData { multiple?: boolean; @@ -9,7 +9,7 @@ export interface UmbMediaPickerModalResult { selection: Array; } -export const UMB_MEDIA_PICKER_MODAL_TOKEN = new UmbModalToken( +export const UMB_MEDIA_PICKER_MODAL = new UmbModalToken( 'Umb.Modal.MediaPicker', { type: 'sidebar', diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/modal-token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/modal-token.ts index ab466d34d7..99510c47a8 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/token/modal-token.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/modal-token.ts @@ -1,6 +1,6 @@ import { UmbModalConfig } from '../modal.context'; -export class UmbModalToken { +export class UmbModalToken { /** * Get the data type of the token's data. * diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/property-editor-ui-picker-modal.token.ts similarity index 72% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/property-editor-ui-picker-modal.token.ts index 74d4587f2e..9bff24f2fe 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/property-editor-ui-picker-modal.token.ts @@ -1,4 +1,4 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export interface UmbPropertyEditorUIPickerModalData { selection?: Array; @@ -9,7 +9,7 @@ export type UmbPropertyEditorUIPickerModalResult = { selection: Array; }; -export const UMB_PROPERTY_EDITOR_UI_PICKER_MODAL_TOKEN = new UmbModalToken< +export const UMB_PROPERTY_EDITOR_UI_PICKER_MODAL = new UmbModalToken< UmbPropertyEditorUIPickerModalData, UmbPropertyEditorUIPickerModalResult >('Umb.Modal.PropertyEditorUIPicker', { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/property-settings/index.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/property-settings-modal.token.ts similarity index 71% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/property-settings/index.ts rename to src/Umbraco.Web.UI.Client/libs/modal/token/property-settings-modal.token.ts index c3719e1789..80d28d4578 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/property-settings/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/property-settings-modal.token.ts @@ -1,4 +1,4 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; // TODO: add interface for data // PropertyTypeViewModelBaseModel @@ -17,7 +17,7 @@ export interface UmbPropertySettingsModalResult { }; } -export const UMB_PROPERTY_SETTINGS_MODAL_TOKEN = new UmbModalToken( +export const UMB_PROPERTY_SETTINGS_MODAL = new UmbModalToken( 'Umb.Modal.PropertySettings', { type: 'sidebar', diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/search-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/search-modal.token.ts new file mode 100644 index 0000000000..e3a99aab38 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/search-modal.token.ts @@ -0,0 +1,3 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export const UMB_SEARCH_MODAL = new UmbModalToken('Umb.Modal.Search'); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/section-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/section-picker-modal.token.ts new file mode 100644 index 0000000000..c74346cc70 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/section-picker-modal.token.ts @@ -0,0 +1,11 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbSectionPickerModalData { + multiple: boolean; + selection: string[]; +} + +export const UMB_SECTION_PICKER_MODAL = new UmbModalToken('Umb.Modal.SectionPicker', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/template-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/template-modal.token.ts new file mode 100644 index 0000000000..55901ab786 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/template-modal.token.ts @@ -0,0 +1,18 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbTemplateModalData { + id: string; + language?: 'razor' | 'typescript' | 'javascript' | 'css' | 'markdown' | 'json' | 'html'; +} + +export interface UmbTemplateModalResult { + id: string; +} + +export const UMB_TEMPLATE_MODAL = new UmbModalToken( + 'Umb.Modal.Template', + { + type: 'sidebar', + size: 'full', + } +); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/template-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/template-picker-modal.token.ts new file mode 100644 index 0000000000..a4660816e9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/template-picker-modal.token.ts @@ -0,0 +1,18 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbTemplatePickerModalData { + multiple: boolean; + selection: string[]; +} + +export interface UmbTemplatePickerModalResult { + selection: string[] | undefined; +} + +export const UMB_TEMPLATE_PICKER_MODAL = new UmbModalToken( + 'Umb.Modal.TemplatePicker', + { + type: 'sidebar', + size: 'small', + } +); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/user-group-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/user-group-picker-modal.token.ts new file mode 100644 index 0000000000..4264345e24 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/user-group-picker-modal.token.ts @@ -0,0 +1,10 @@ +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbModalToken, UmbPickerModalData } from '@umbraco-cms/backoffice/modal'; + +export const UMB_USER_GROUP_PICKER_MODAL = new UmbModalToken>( + 'Umb.Modal.UserGroupPicker', + { + type: 'sidebar', + size: 'small', + } +); diff --git a/src/Umbraco.Web.UI.Client/libs/modal/token/user-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/libs/modal/token/user-picker-modal.token.ts new file mode 100644 index 0000000000..c1bf2c975a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/modal/token/user-picker-modal.token.ts @@ -0,0 +1,7 @@ +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbModalToken, UmbPickerModalData } from '@umbraco-cms/backoffice/modal'; + +export const UMB_USER_PICKER_MODAL = new UmbModalToken>('Umb.Modal.UserPicker', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/libs/models/index.ts b/src/Umbraco.Web.UI.Client/libs/models/index.ts index 54fc943724..0d96ea3bff 100644 --- a/src/Umbraco.Web.UI.Client/libs/models/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/models/index.ts @@ -1,35 +1,34 @@ -import { - ContentTreeItemModel, - DictionaryItemTranslationModel, - EntityTreeItemModel, - FolderTreeItemModel, - PackageManifestModel, - ProblemDetailsModel, -} from '@umbraco-cms/backend-api'; - -// Extension Manifests -export * from '@umbraco-cms/extensions-registry'; +import type { + EntityTreeItemResponseModel, + FolderTreeItemResponseModel, + PackageManifestResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type HTMLElementConstructor = new (...args: any[]) => T; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type ClassConstructor = new (...args: any[]) => T; + // Users -// TODO: would the right name be Node? as entity is just something with a Key. But node is something in a content structure, aka. with hasChildren and parentKey. +// TODO: would the right name be Node? as entity is just something with a Key. But node is something in a content structure, aka. with hasChildren and parentId. export interface Entity { - key: string; + id: string; name: string; icon: string; type: string; hasChildren: boolean; - parentKey: string | null; + parentId: string | null; } -export interface ContentDetails extends ContentTreeItemModel { - isTrashed: boolean; // TODO: remove only temp part of refactor - properties: Array; - //data: Array; - //layout?: any; // TODO: define layout type - make it non-optional -} +/** Tried to find a common base of our entities — used by Entity Workspace Context */ +export type BaseEntity = { + id?: string; + //alias?: string; + name?: string; + //icon?: string; + //properties?: Array; +}; export interface UserEntity extends Entity { type: 'user'; @@ -62,77 +61,33 @@ export interface UserGroupDetails extends UserGroupEntity { permissions: Array; } -/* -// Data Types -export interface DataTypeDetails extends FolderTreeItemModel { - key: string; // TODO: Remove this when the backend is fixed - propertyEditorAlias: string | null; - propertyEditorUiAlias: string | null; - data: Array; -} - -export interface DataTypeProperty { - alias: string; - value: any; -} -*/ - // TODO: Make sure Entity Type/interface. -export interface MemberTypeDetails extends EntityTreeItemModel { - key: string; // TODO: Remove this when the backend is fixed +export interface MemberTypeDetails extends EntityTreeItemResponseModel { + id: string; // TODO: Remove this when the backend is fixed alias: string; properties: []; } -// Content -export interface ContentProperty { - alias: string; - label: string; - description: string; - dataTypeKey: string; -} - -export interface ContentPropertyData { - alias: string; - value: any; -} - -// Media -export interface MediaDetails extends ContentTreeItemModel { - key: string; // TODO: Remove this when the backend is fixed - isTrashed: boolean; // TODO: remove only temp part of refactor - properties: Array; - data: Array; - variants: Array; // TODO: define variant data - //layout?: any; // TODO: define layout type - make it non-optional -} - // Media Types -export interface MediaTypeDetails extends FolderTreeItemModel { - key: string; // TODO: Remove this when the backend is fixed +export interface MediaTypeDetails extends FolderTreeItemResponseModel { + id: string; // TODO: Remove this when the backend is fixed alias: string; properties: []; } // Member Groups -export interface MemberGroupDetails extends EntityTreeItemModel { - key: string; // TODO: Remove this when the backend is fixed +export interface MemberGroupDetails extends EntityTreeItemResponseModel { + id: string; // TODO: Remove this when the backend is fixed } -export interface MemberDetails extends EntityTreeItemModel { - key: string; // TODO: Remove this when the backend is fixed -} - -// Dictionary -export interface DictionaryDetails extends EntityTreeItemModel { - key: string; // TODO: Remove this when the backend is fixed - translations: DictionaryItemTranslationModel[]; +export interface MemberDetails extends EntityTreeItemResponseModel { + id: string; // TODO: Remove this when the backend is fixed } // Document Blueprint export interface DocumentBlueprintDetails { - key: string; + id: string; name: string; type: 'document-blueprint'; properties: Array; @@ -141,17 +96,12 @@ export interface DocumentBlueprintDetails { documentTypeKey: string; } -export interface DataSourceResponse { - data?: T; - error?: ProblemDetailsModel; -} - export interface SwatchDetails { label: string; value: string; } -export type UmbPackage = PackageManifestModel; +export type UmbPackage = PackageManifestResponseModel; export type PackageManifestResponse = UmbPackage[]; diff --git a/src/Umbraco.Web.UI.Client/libs/models/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/models/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/models/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/notification/notification.context.ts b/src/Umbraco.Web.UI.Client/libs/notification/notification.context.ts index e3aad5ccd4..1cf55a0525 100644 --- a/src/Umbraco.Web.UI.Client/libs/notification/notification.context.ts +++ b/src/Umbraco.Web.UI.Client/libs/notification/notification.context.ts @@ -1,6 +1,6 @@ import { BehaviorSubject } from 'rxjs'; import { UmbNotificationHandler } from './notification-handler'; -import { UmbContextToken } from '@umbraco-cms/context-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; /** * The default data of notifications diff --git a/src/Umbraco.Web.UI.Client/libs/notification/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/notification/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/notification/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/append-to-frozen-array.function.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/append-to-frozen-array.function.ts index 1e5c060f00..97ff56848c 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/append-to-frozen-array.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/append-to-frozen-array.function.ts @@ -6,8 +6,8 @@ * @param {(previousResult: R, currentResult: R) => boolean} [memoizationFunction] - Method to Compare if the data has changed. Should return true when data is different. * @description - Creates a RxJS Observable from RxJS Subject. * @example Example append new entry for a ArrayState or a part of DeepState/ObjectState it which is an array. Where the key is unique and the item will be updated if matched with existing. - * const entry = {key: 'myKey', value: 'myValue'}; - * const newDataSet = appendToFrozenArray(mySubject.getValue(), entry, x => x.key === key); + * const entry = {id: 'myKey', value: 'myValue'}; + * const newDataSet = appendToFrozenArray(mySubject.getValue(), entry, x => x.id === id); * mySubject.next(newDataSet); */ export function appendToFrozenArray(data: T[], entry: T, getUniqueMethod?: (entry: T) => unknown): T[] { diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.test.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.test.ts index 3ff159c362..854ec3ee92 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.test.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.test.ts @@ -2,8 +2,7 @@ import { expect } from '@open-wc/testing'; import { ArrayState } from './array-state'; describe('ArrayState', () => { - - type ObjectType = {key: string, another: string}; + type ObjectType = { key: string; another: string }; type ArrayType = ObjectType[]; let subject: ArrayState; @@ -11,29 +10,30 @@ describe('ArrayState', () => { beforeEach(() => { initialData = [ - {key: '1', another: 'myValue1'}, - {key: '2', another: 'myValue2'}, - {key: '3', another: 'myValue3'} + { key: '1', another: 'myValue1' }, + { key: '2', another: 'myValue2' }, + { key: '3', another: 'myValue3' }, ]; - subject = new ArrayState(initialData, x => x.key); + subject = new ArrayState(initialData, (x) => x.key); }); - it('replays latests, no matter the amount of subscriptions.', (done) => { - + let amountOfCallbacks = 0; const observer = subject.asObservable(); observer.subscribe((value) => { + amountOfCallbacks++; expect(value).to.be.equal(initialData); }); observer.subscribe((value) => { + amountOfCallbacks++; expect(value).to.be.equal(initialData); - done(); + if (amountOfCallbacks === 2) { + done(); + } }); - }); it('remove method, removes the one with the key', (done) => { - const expectedData = [initialData[0], initialData[2]]; subject.remove(['2']); @@ -42,25 +42,21 @@ describe('ArrayState', () => { expect(JSON.stringify(value)).to.be.equal(JSON.stringify(expectedData)); done(); }); - }); it('filter method, removes anything that is not true of the given predicate method', (done) => { - const expectedData = [initialData[0], initialData[2]]; - subject.filter(x => x.key !== '2'); + subject.filter((x) => x.key !== '2'); const observer = subject.asObservable(); observer.subscribe((value) => { expect(JSON.stringify(value)).to.be.equal(JSON.stringify(expectedData)); done(); }); - }); it('add new item via appendOne method.', (done) => { - - const newItem = {key: '4', another: 'myValue4'}; + const newItem = { key: '4', another: 'myValue4' }; subject.appendOne(newItem); const expectedData = [...initialData, newItem]; @@ -71,37 +67,44 @@ describe('ArrayState', () => { expect(value[3].another).to.be.equal(expectedData[3].another); done(); }); - }); + it('partially update an existing item via updateOne method.', (done) => { + const newItem = { another: 'myValue2.2' }; + subject.updateOne('2', newItem); + + const observer = subject.asObservable(); + observer.subscribe((value) => { + expect(value.length).to.be.equal(initialData.length); + expect(value[0].another).to.be.equal('myValue1'); + expect(value[1].another).to.be.equal('myValue2.2'); + done(); + }); + }); it('getObservablePart for a specific entry of array', (done) => { - - const subObserver = subject.getObservablePart(data => data.find(x => x.key === '2')); + const subObserver = subject.getObservablePart((data) => data.find((x) => x.key === '2')); subObserver.subscribe((entry) => { - if(entry) { + if (entry) { expect(entry.another).to.be.equal(initialData[1].another); done(); } }); - }); - it('getObservablePart returns undefined if item does not exist', (done) => { - let amountOfCallbacks = 0; - const newItem = {key: '4', another: 'myValue4'}; + const newItem = { key: '4', another: 'myValue4' }; - const subObserver = subject.getObservablePart(data => data.find(x => x.key === newItem.key)); + const subObserver = subject.getObservablePart((data) => data.find((x) => x.key === newItem.key)); subObserver.subscribe((entry) => { amountOfCallbacks++; - if(amountOfCallbacks === 1) { - expect(entry).to.be.equal(undefined);// First callback should give null, cause we didn't have this entry when the subscription was made. + if (amountOfCallbacks === 1) { + expect(entry).to.be.equal(undefined); // First callback should give null, cause we didn't have this entry when the subscription was made. } - if(amountOfCallbacks === 2) { - expect(entry).to.be.equal(newItem);// Second callback should give us the right data: - if(entry) { + if (amountOfCallbacks === 2) { + expect(entry).to.be.equal(newItem); // Second callback should give us the right data: + if (entry) { expect(entry.another).to.be.equal(newItem.another); done(); } @@ -109,13 +112,10 @@ describe('ArrayState', () => { }); subject.appendOne(newItem); - }); - it('asObservable returns the replaced item', (done) => { - - const newItem = {key: '2', another: 'myValue4'}; + const newItem = { key: '2', another: 'myValue4' }; subject.appendOne(newItem); const expectedData = [initialData[0], newItem, initialData[2]]; @@ -126,24 +126,61 @@ describe('ArrayState', () => { expect(value[1].another).to.be.equal(newItem.another); done(); }); - }); it('getObservablePart returns the replaced item', (done) => { - - const newItem = {key: '2', another: 'myValue4'}; + const newItem = { key: '2', another: 'myValue4' }; subject.appendOne(newItem); - const subObserver = subject.getObservablePart(data => data.find(x => x.key === newItem.key)); + const subObserver = subject.getObservablePart((data) => data.find((x) => x.key === newItem.key)); subObserver.subscribe((entry) => { - expect(entry).to.be.equal(newItem);// Second callback should give us the right data: - if(entry) { + expect(entry).to.be.equal(newItem); // Second callback should give us the right data: + if (entry) { expect(entry.another).to.be.equal(newItem.another); done(); } }); - }); + it('getObservablePart replays existing data to any amount of subscribers.', (done) => { + let amountOfCallbacks = 0; + const subObserver = subject.getObservablePart((data) => data.find((x) => x.key === '2')); + subObserver.subscribe((entry) => { + if (entry) { + amountOfCallbacks++; + expect(entry.another).to.be.equal(initialData[1].another); + } + }); + subObserver.subscribe((entry) => { + if (entry) { + amountOfCallbacks++; + expect(entry.another).to.be.equal(initialData[1].another); + if (amountOfCallbacks === 2) { + done(); + } + } + }); + }); + + it('getObservablePart replays existing data to any amount of subscribers.', (done) => { + let amountOfCallbacks = 0; + + const subObserver = subject.getObservablePart((data) => data.find((x) => x.key === '2')); + subObserver.subscribe((entry) => { + if (entry) { + amountOfCallbacks++; + expect(entry.another).to.be.equal(initialData[1].another); + } + }); + subObserver.subscribe((entry) => { + if (entry) { + amountOfCallbacks++; + expect(entry.another).to.be.equal(initialData[1].another); + if (amountOfCallbacks === 2) { + done(); + } + } + }); + }); }); diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts index d421e4d6b5..7572f89d8b 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/array-state.ts @@ -1,4 +1,5 @@ import { DeepState } from './deep-state'; +import { partialUpdateFrozenArray } from './partial-update-frozen-array.function'; import { pushToUniqueArray } from './push-to-unique-array.function'; /** @@ -11,8 +12,37 @@ import { pushToUniqueArray } from './push-to-unique-array.function'; * The ArrayState provides methods to append data when the data is an Object. */ export class ArrayState extends DeepState { - constructor(initialData: T[], private _getUnique?: (entry: T) => unknown) { + #getUnique?: (entry: T) => unknown; + #sortMethod?: (a: T, b: T) => number; + + constructor(initialData: T[], getUniqueMethod?: (entry: T) => unknown) { super(initialData); + this.#getUnique = getUniqueMethod; + } + + /** + * @method sortBy + * @param {(a: T, b: T) => number} sortMethod - A method to be used for sorting everytime data is set. + * @description - A sort method to this Subject. + * @example Example add sort method + * const data = [ + * { key: 1, value: 'foo'}, + * { key: 2, value: 'bar'} + * ]; + * const myState = new ArrayState(data, (x) => x.key); + * myState.sortBy((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); + */ + sortBy(sortMethod?: (a: T, b: T) => number) { + this.#sortMethod = sortMethod; + return this; + } + + next(value: T[]) { + if (this.#sortMethod) { + super.next(value.sort(this.#sortMethod)); + } else { + super.next(value); + } } /** @@ -20,22 +50,22 @@ export class ArrayState extends DeepState { * @param {unknown[]} uniques - The unique values to remove. * @return {ArrayState} Reference to it self. * @description - Remove some new data of this Subject. - * @example Example remove entry with key '1' and '2' + * @example Example remove entry with id '1' and '2' * const data = [ - * { key: 1, value: 'foo'}, - * { key: 2, value: 'bar'} + * { id: 1, value: 'foo'}, + * { id: 2, value: 'bar'} * ]; - * const myState = new ArrayState(data, (x) => x.key); + * const myState = new ArrayState(data, (x) => x.id); * myState.remove([1, 2]); */ remove(uniques: unknown[]) { let next = this.getValue(); - if (this._getUnique) { + if (this.#getUnique) { uniques.forEach((unique) => { next = next.filter((x) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - return this._getUnique(x) !== unique; + return this.#getUnique(x) !== unique; }); }); @@ -49,21 +79,21 @@ export class ArrayState extends DeepState { * @param {unknown} unique - The unique value to remove. * @return {ArrayState} Reference to it self. * @description - Remove some new data of this Subject. - * @example Example remove entry with key '1' + * @example Example remove entry with id '1' * const data = [ - * { key: 1, value: 'foo'}, - * { key: 2, value: 'bar'} + * { id: 1, value: 'foo'}, + * { id: 2, value: 'bar'} * ]; - * const myState = new ArrayState(data, (x) => x.key); + * const myState = new ArrayState(data, (x) => x.id); * myState.removeOne(1); */ removeOne(unique: unknown) { let next = this.getValue(); - if (this._getUnique) { + if (this.#getUnique) { next = next.filter((x) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - return this._getUnique(x) !== unique; + return this.#getUnique(x) !== unique; }); this.next(next); @@ -112,8 +142,8 @@ export class ArrayState extends DeepState { */ appendOne(entry: T) { const next = [...this.getValue()]; - if (this._getUnique) { - pushToUniqueArray(next, entry, this._getUnique); + if (this.#getUnique) { + pushToUniqueArray(next, entry, this.#getUnique); } else { next.push(entry); } @@ -138,10 +168,10 @@ export class ArrayState extends DeepState { * ]); */ append(entries: T[]) { - if (this._getUnique) { + if (this.#getUnique) { const next = [...this.getValue()]; entries.forEach((entry) => { - pushToUniqueArray(next, entry, this._getUnique!); + pushToUniqueArray(next, entry, this.#getUnique!); }); this.next(next); } else { @@ -149,4 +179,26 @@ export class ArrayState extends DeepState { } return this; } + + /** + * @method updateOne + * @param {unknown} unique - Unique value to find entry to update. + * @param {Partial} entry - new data to be added in this Subject. + * @return {ArrayState} Reference to it self. + * @description - Update a item with some new data, requires the ArrayState to be constructed with a getUnique method. + * @example Example append some data. + * const data = [ + * { key: 1, value: 'foo'}, + * { key: 2, value: 'bar'} + * ]; + * const myState = new ArrayState(data, (x) => x.key); + * myState.updateOne(2, {value: 'updated-bar'}); + */ + updateOne(unique: unknown, entry: Partial) { + if (!this.#getUnique) { + throw new Error("Can't partial update an ArrayState without a getUnique method provided when constructed."); + } + this.next(partialUpdateFrozenArray(this.getValue(), entry, (x) => unique === this.#getUnique!(x))); + return this; + } } diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/basic-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/basic-state.ts index 3512c0508c..57d7f8581b 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/basic-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/basic-state.ts @@ -1,4 +1,4 @@ -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject } from 'rxjs'; /** * @export @@ -12,7 +12,7 @@ export class BasicState extends BehaviorSubject { } next(newData: T): void { - if(newData !== this.getValue()) { + if (newData !== this.getValue()) { super.next(newData); } } diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/class-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/class-state.ts index 138d51b055..11c38dc6b9 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/class-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/class-state.ts @@ -6,10 +6,9 @@ interface ClassStateData { /** * @export - * @class DeepState + * @class ClassState * @extends {BehaviorSubject} - * @description - A RxJS BehaviorSubject which deepFreezes the data to ensure its not manipulated from any implementations. - * Additionally the Subject ensures the data is unique, not updating any Observes unless there is an actual change of the content. + * @description - A RxJS BehaviorSubject which can hold class instance which has a equal method to compare in coming instances for changes. */ export class ClassState extends BehaviorSubject { constructor(initialData: T) { diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/create-observable-part.function.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/create-observable-part.function.ts index 5dd2e2f085..c795965a84 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/create-observable-part.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/create-observable-part.function.ts @@ -1,5 +1,7 @@ import { distinctUntilChanged, map, Observable, shareReplay } from 'rxjs'; -import { MappingFunction, MemoizationFunction, defaultMemoization } from './deep-state'; +import { MemoizationFunction } from './memoization-function'; +import { MappingFunction } from './mapping-function'; +import { defaultMemoization } from './default-memoization'; /** * @export diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/deep-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/deep-state.ts index ad3bf66ca0..201ab479c8 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/deep-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/deep-state.ts @@ -1,20 +1,9 @@ import { BehaviorSubject } from 'rxjs'; import { createObservablePart } from './create-observable-part.function'; import { deepFreeze } from './deep-freeze.function'; - -export function naiveObjectComparison(objOne: any, objTwo: any): boolean { - return JSON.stringify(objOne) === JSON.stringify(objTwo); -} - -export type MappingFunction = (mappable: T) => R; -export type MemoizationFunction = (previousResult: R, currentResult: R) => boolean; - -export function defaultMemoization(previousValue: any, currentValue: any): boolean { - if (typeof previousValue === 'object' && typeof currentValue === 'object') { - return naiveObjectComparison(previousValue, currentValue); - } - return previousValue === currentValue; -} +import type { MappingFunction } from './mapping-function'; +import type { MemoizationFunction } from './memoization-function'; +import { naiveObjectComparison } from './naive-object-comparison'; /** * @export diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/default-memoization.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/default-memoization.ts new file mode 100644 index 0000000000..f8811febad --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/default-memoization.ts @@ -0,0 +1,8 @@ +import { naiveObjectComparison } from './naive-object-comparison'; + +export function defaultMemoization(previousValue: any, currentValue: any): boolean { + if (typeof previousValue === 'object' && typeof currentValue === 'object') { + return naiveObjectComparison(previousValue, currentValue); + } + return previousValue === currentValue; +} diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/index.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/index.ts index dbfa7cf4b5..c18d4495b7 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/index.ts @@ -1,5 +1,6 @@ export * from './observer.controller'; export * from './observer'; +export * from './basic-state'; export * from './boolean-state'; export * from './number-state'; export * from './string-state'; @@ -10,3 +11,4 @@ export * from './object-state'; export * from './create-observable-part.function'; export * from './append-to-frozen-array.function'; export * from './partial-update-frozen-array.function'; +export * from './mapping-function'; diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/mapping-function.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/mapping-function.ts new file mode 100644 index 0000000000..1b843ecff4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/mapping-function.ts @@ -0,0 +1 @@ +export type MappingFunction = (mappable: T) => R; diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/memoization-function.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/memoization-function.ts new file mode 100644 index 0000000000..1d43da86ea --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/memoization-function.ts @@ -0,0 +1 @@ +export type MemoizationFunction = (previousResult: R, currentResult: R) => boolean; diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/naive-object-comparison.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/naive-object-comparison.ts new file mode 100644 index 0000000000..4afbe928cb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/naive-object-comparison.ts @@ -0,0 +1,3 @@ +export function naiveObjectComparison(objOne: any, objTwo: any): boolean { + return JSON.stringify(objOne) === JSON.stringify(objTwo); +} diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/number-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/number-state.ts index 9d1cfd5c21..ded3defeb9 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/number-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/number-state.ts @@ -1,4 +1,4 @@ -import { BasicState } from "./basic-state"; +import { BasicState } from './basic-state'; /** * @export @@ -10,5 +10,4 @@ export class NumberState extends BasicState { constructor(initialData: T | number) { super(initialData); } - } diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/object-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/object-state.ts index e726a075bb..04c72dd9b3 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/object-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/object-state.ts @@ -1,4 +1,4 @@ -import { DeepState } from "./deep-state"; +import { DeepState } from './deep-state'; /** * @export @@ -10,7 +10,6 @@ import { DeepState } from "./deep-state"; * The ObjectState provides methods to append data when the data is an Object. */ export class ObjectState extends DeepState { - /** * @method update * @param {Partial} partialData - A object containing some of the data to update in this Subject. diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/observer.controller.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/observer.controller.ts index 38f51421cc..f4d1f9bf49 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/observer.controller.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/observer.controller.ts @@ -1,6 +1,6 @@ import { Observable } from 'rxjs'; import { UmbObserver } from './observer'; -import { UmbControllerInterface, UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerInterface, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbObserverController extends UmbObserver implements UmbControllerInterface { _alias?: string; @@ -8,11 +8,12 @@ export class UmbObserverController extends UmbObserver implement return this._alias; } - constructor(host: UmbControllerHostInterface, source: Observable, callback: (_value: T) => void, alias?: string) { + constructor(host: UmbControllerHostElement, source: Observable, callback: (_value: T) => void, alias?: string) { super(source, callback); this._alias = alias; // Lets check if controller is already here: + // No we don't want this, as multiple different controllers might be looking at the same source. /* if (this._subscriptions.has(source)) { const subscription = this._subscriptions.get(source); @@ -22,8 +23,4 @@ export class UmbObserverController extends UmbObserver implement host.addController(this); } - - hostConnected() { - return; - } } diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/observer.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/observer.ts index bf7210c284..20eb7a0a34 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/observer.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/observer.ts @@ -1,18 +1,24 @@ import { Observable, Subscription } from 'rxjs'; export class UmbObserver { + #source!: Observable; + #callback!: (_value: T) => void; #subscription!: Subscription; constructor(source: Observable, callback: (_value: T) => void) { - this.#subscription = source.subscribe((value) => { - callback(value); - }); + this.#source = source; + this.#subscription = source.subscribe(callback); } - // Notice controller class implements empty hostConnected(). + hostConnected() { + if (this.#subscription.closed) { + this.#subscription = this.#source.subscribe(this.#callback); + } + } hostDisconnected() { - this.#subscription.unsubscribe(); + // No cause then it cant re-connect, if the same element just was moved in DOM. + //this.#subscription.unsubscribe(); } destroy(): void { diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/observable-api/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/observable-api/string-state.ts b/src/Umbraco.Web.UI.Client/libs/observable-api/string-state.ts index 7a92238a6a..d3e9689a7b 100644 --- a/src/Umbraco.Web.UI.Client/libs/observable-api/string-state.ts +++ b/src/Umbraco.Web.UI.Client/libs/observable-api/string-state.ts @@ -1,4 +1,4 @@ -import { BasicState } from "./basic-state"; +import { BasicState } from './basic-state'; /** * @export diff --git a/src/Umbraco.Web.UI.Client/libs/package.json b/src/Umbraco.Web.UI.Client/libs/package.json new file mode 100644 index 0000000000..e5f1036d7d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/package.json @@ -0,0 +1,33 @@ +{ + "name": "@umbraco-cms/backoffice", + "version": "13.0.0-alpha.0", + "license": "MIT", + "keywords": [ + "umbraco", + "backoffice" + ], + "repository": { + "url": "https://github.com/umbraco/Umbraco.CMS.Backoffice", + "type": "git" + }, + "bugs": { + "url": "https://github.com/umbraco/Umbraco.CMS.Backoffice/issues" + }, + "author": { + "name": "Umbraco A/S", + "email": "backoffice@umbraco.com", + "url": "https://umbraco.com" + }, + "type": "module", + "files": [ + "*.d.ts", + "*.json", + "*.md" + ], + "peerDependencies": { + "@types/uuid": "^9.0.1", + "@umbraco-ui/uui": "^1.2.0-rc.0", + "rxjs": "^7.8.0" + }, + "customElements": "custom-elements.json" +} diff --git a/src/Umbraco.Web.UI.Client/libs/property-editor/index.ts b/src/Umbraco.Web.UI.Client/libs/property-editor/index.ts index e2a222e019..afa798d5e8 100644 --- a/src/Umbraco.Web.UI.Client/libs/property-editor/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/property-editor/index.ts @@ -1,6 +1,6 @@ -import { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; export interface UmbPropertyEditorElement extends HTMLElement { value: unknown; - config: DataTypePropertyModel[]; + config: DataTypePropertyPresentationModel[]; } diff --git a/src/Umbraco.Web.UI.Client/libs/property-editor/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/property-editor/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/property-editor/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/repository/data-source/data-source-response.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/data-source/data-source-response.interface.ts new file mode 100644 index 0000000000..a3ee6e90f0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/repository/data-source/data-source-response.interface.ts @@ -0,0 +1,6 @@ +import type { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; + +export interface DataSourceResponse { + data?: T; + error?: ProblemDetailsModel; +} diff --git a/src/Umbraco.Web.UI.Client/libs/repository/data-source/data-source.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/data-source/data-source.interface.ts new file mode 100644 index 0000000000..1721ce3e47 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/repository/data-source/data-source.interface.ts @@ -0,0 +1,9 @@ +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; + +export interface UmbDataSource { + createScaffold(parentId: string | null): Promise>; + get(unique: string): Promise>; + insert(data: CreateRequestType): Promise; + update(unique: string, data: UpdateRequestType): Promise>; + delete(unique: string): Promise; +} diff --git a/src/Umbraco.Web.UI.Client/libs/repository/data-source/folder-data-source.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/data-source/folder-data-source.interface.ts new file mode 100644 index 0000000000..0998583c9f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/repository/data-source/folder-data-source.interface.ts @@ -0,0 +1,14 @@ +import { DataSourceResponse } from './data-source-response.interface'; +import { + CreateFolderRequestModel, + FolderReponseModel, + UpdateFolderReponseModel, +} from '@umbraco-cms/backoffice/backend-api'; + +export interface UmbFolderDataSource { + createScaffold(parentId: string | null): Promise>; + get(unique: string): Promise>; + insert(data: CreateFolderRequestModel): Promise>; + update(unique: string, data: CreateFolderRequestModel): Promise>; + delete(unique: string): Promise; +} diff --git a/src/Umbraco.Web.UI.Client/libs/repository/data-source/index.ts b/src/Umbraco.Web.UI.Client/libs/repository/data-source/index.ts new file mode 100644 index 0000000000..905a6849fe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/repository/data-source/index.ts @@ -0,0 +1,4 @@ +export * from './data-source-response.interface'; +export * from './data-source.interface'; +export * from './folder-data-source.interface'; +export * from './tree-data-source.interface'; diff --git a/src/Umbraco.Web.UI.Client/libs/repository/data-source/tree-data-source.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/data-source/tree-data-source.interface.ts new file mode 100644 index 0000000000..ae57ef57af --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/repository/data-source/tree-data-source.interface.ts @@ -0,0 +1,7 @@ +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; + +export interface UmbTreeDataSource { + getRootItems(): Promise>; + getChildrenOf(parentUnique: string): Promise>; + getItems(unique: Array): Promise>>; +} diff --git a/src/Umbraco.Web.UI.Client/libs/repository/detail-repository.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/detail-repository.interface.ts index ea842ef36f..cb70ab8dd2 100644 --- a/src/Umbraco.Web.UI.Client/libs/repository/detail-repository.interface.ts +++ b/src/Umbraco.Web.UI.Client/libs/repository/detail-repository.interface.ts @@ -1,25 +1,16 @@ -import type { ProblemDetailsModel } from '@umbraco-cms/backend-api'; +import type { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; -export interface UmbDetailRepository { - createScaffold(parentKey: string | null): Promise<{ - data?: DetailType; - error?: ProblemDetailsModel; - }>; - - requestByKey(key: string): Promise<{ - data?: DetailType; - error?: ProblemDetailsModel; - }>; - - create(data: DetailType): Promise<{ - error?: ProblemDetailsModel; - }>; - - save(data: DetailType): Promise<{ - error?: ProblemDetailsModel; - }>; - - delete(key: string): Promise<{ - error?: ProblemDetailsModel; - }>; +export interface UmbRepositoryErrorResponse { + error?: ProblemDetailsModel; +} +export interface UmbRepositoryResponse extends UmbRepositoryErrorResponse { + data?: T; +} + +export interface UmbDetailRepository { + createScaffold(parentId: string | null): Promise>; + requestById(id: string): Promise>; + create(data: CreateRequestType): Promise; + save(id: string, data: UpdateRequestType): Promise; + delete(id: string): Promise; } diff --git a/src/Umbraco.Web.UI.Client/libs/repository/folder-repository.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/folder-repository.interface.ts new file mode 100644 index 0000000000..3d9559bb2b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/repository/folder-repository.interface.ts @@ -0,0 +1,35 @@ +import type { + CreateFolderRequestModel, + FolderModelBaseModel, + FolderReponseModel, + ProblemDetailsModel, + UpdateFolderReponseModel, +} from '@umbraco-cms/backoffice/backend-api'; + +export interface UmbFolderRepository { + createFolderScaffold(parentId: string | null): Promise<{ + data?: FolderReponseModel; + error?: ProblemDetailsModel; + }>; + createFolder(folderRequest: CreateFolderRequestModel): Promise<{ + data?: string; + error?: ProblemDetailsModel; + }>; + + requestFolder(unique: string): Promise<{ + data?: FolderReponseModel; + error?: ProblemDetailsModel; + }>; + + updateFolder( + unique: string, + folder: FolderModelBaseModel + ): Promise<{ + data?: UpdateFolderReponseModel; + error?: ProblemDetailsModel; + }>; + + deleteFolder(id: string): Promise<{ + error?: ProblemDetailsModel; + }>; +} diff --git a/src/Umbraco.Web.UI.Client/libs/repository/index.ts b/src/Umbraco.Web.UI.Client/libs/repository/index.ts index c90aed53e7..9dcba782ba 100644 --- a/src/Umbraco.Web.UI.Client/libs/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/repository/index.ts @@ -1,4 +1,4 @@ +export * from './data-source'; export * from './detail-repository.interface'; export * from './tree-repository.interface'; -export * from './repository-tree-data-source.interface'; -export * from './repository-detail-data-source.interface'; +export * from './folder-repository.interface'; diff --git a/src/Umbraco.Web.UI.Client/libs/repository/repository-detail-data-source.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/repository-detail-data-source.interface.ts deleted file mode 100644 index 7715d5a61e..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/repository/repository-detail-data-source.interface.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { DataSourceResponse } from '@umbraco-cms/models'; - -export interface RepositoryDetailDataSource { - createScaffold(parentKey: string | null): Promise>; - get(key: string): Promise>; - insert(data: DetailType): Promise>; - update(data: DetailType): Promise>; - delete(key: string): Promise>; -} diff --git a/src/Umbraco.Web.UI.Client/libs/repository/repository-tree-data-source.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/repository-tree-data-source.interface.ts deleted file mode 100644 index aff4ec4451..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/repository/repository-tree-data-source.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { EntityTreeItemModel, PagedEntityTreeItemModel } from '@umbraco-cms/backend-api'; -import type { DataSourceResponse } from '@umbraco-cms/models'; - -export interface RepositoryTreeDataSource { - getRootItems(): Promise>; - getChildrenOf(parentKey: string): Promise>; - getItems(key: Array): Promise>; -} diff --git a/src/Umbraco.Web.UI.Client/libs/repository/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/repository/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/repository/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/repository/tree-repository.interface.ts b/src/Umbraco.Web.UI.Client/libs/repository/tree-repository.interface.ts index 2ef082005f..4ef19c3920 100644 --- a/src/Umbraco.Web.UI.Client/libs/repository/tree-repository.interface.ts +++ b/src/Umbraco.Web.UI.Client/libs/repository/tree-repository.interface.ts @@ -1,24 +1,29 @@ import type { Observable } from 'rxjs'; -import { EntityTreeItemModel, PagedEntityTreeItemModel, ProblemDetailsModel } from '@umbraco-cms/backend-api'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; -export interface UmbTreeRepository { - requestRootTreeItems: () => Promise<{ - data: PagedEntityTreeItemModel | undefined; - error: ProblemDetailsModel | undefined; - asObservable?: () => Observable; - }>; - requestTreeItemsOf: (parentKey: string | null) => Promise<{ - data: PagedEntityTreeItemModel | undefined; - error: ProblemDetailsModel | undefined; - asObservable?: () => Observable; - }>; - requestTreeItems: (keys: string[]) => Promise<{ - data: Array | undefined; - error: ProblemDetailsModel | undefined; - asObservable?: () => Observable; - }>; - - rootTreeItems: () => Promise>; - treeItemsOf: (parentKey: string | null) => Promise>; - treeItems: (keys: string[]) => Promise>; +export interface UmbPagedData { + total: number; + items: Array; +} + +export interface UmbTreeRepository> { + requestRootTreeItems: () => Promise<{ + data: PagedItemType | undefined; + error: ProblemDetailsModel | undefined; + asObservable?: () => Observable; + }>; + requestTreeItemsOf: (parentUnique: string | null) => Promise<{ + data: PagedItemType | undefined; + error: ProblemDetailsModel | undefined; + asObservable?: () => Observable; + }>; + requestTreeItems: (uniques: string[]) => Promise<{ + data: Array | undefined; + error: ProblemDetailsModel | undefined; + asObservable?: () => Observable; + }>; + + rootTreeItems: () => Promise>; + treeItemsOf: (parentUnique: string | null) => Promise>; + treeItems: (uniques: string[]) => Promise>; } diff --git a/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts b/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts index 26c8a481a2..2432b6fe96 100644 --- a/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts +++ b/src/Umbraco.Web.UI.Client/libs/resources/resource.controller.ts @@ -3,18 +3,18 @@ import { UmbNotificationOptions, UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN, -} from '@umbraco-cms/notification'; -import { ApiError, CancelablePromise, ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbController, UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import type { DataSourceResponse } from '@umbraco-cms/models'; +} from '@umbraco-cms/backoffice/notification'; +import { ApiError, CancelablePromise, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; export class UmbResourceController extends UmbController { #promise: Promise; #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface, promise: Promise, alias?: string) { + constructor(host: UmbControllerHostElement, promise: Promise, alias?: string) { super(host, alias); this.#promise = promise; @@ -39,8 +39,17 @@ export class UmbResourceController extends UmbController { */ static toProblemDetailsModel(error: unknown): ProblemDetailsModel | undefined { if (error instanceof ApiError) { - const errorDetails = error.body as ProblemDetailsModel; - return errorDetails; + try { + const errorDetails = ( + typeof error.body === 'string' ? JSON.parse(error.body) : error.body + ) as ProblemDetailsModel; + return errorDetails; + } catch { + return { + title: error.name, + detail: error.message, + }; + } } else if (error instanceof Error) { return { title: error.name, @@ -56,9 +65,9 @@ export class UmbResourceController extends UmbController { */ static async tryExecute(promise: Promise): Promise> { try { - return {data: await promise}; + return { data: await promise }; } catch (e) { - return {error: UmbResourceController.toProblemDetailsModel(e)}; + return { error: UmbResourceController.toProblemDetailsModel(e) }; } } @@ -67,15 +76,16 @@ export class UmbResourceController extends UmbController { * If the executor function throws an error, then show the details in a notification. */ async tryExecuteAndNotify(options?: UmbNotificationOptions): Promise> { - const {data, error} = await UmbResourceController.tryExecute(this.#promise); + const { data, error } = await UmbResourceController.tryExecute(this.#promise); if (error) { if (this.#notificationContext) { this.#notificationContext?.peek('danger', { data: { headline: error.title ?? 'Server Error', - message: error.detail ?? 'Something went wrong' - }, ...options + message: error.detail ?? 'Something went wrong', + }, + ...options, }); } else { console.group('UmbResourceController'); @@ -84,7 +94,7 @@ export class UmbResourceController extends UmbController { } } - return {data, error}; + return { data, error }; } /** diff --git a/src/Umbraco.Web.UI.Client/libs/resources/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/resources/rollup.config.js deleted file mode 100644 index 44c6c08405..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/resources/rollup.config.js +++ /dev/null @@ -1,4 +0,0 @@ -import config from '../../utils/rollup.config.js'; -export default [ - ...config, -]; diff --git a/src/Umbraco.Web.UI.Client/libs/resources/tryExecuteAndNotify.function.ts b/src/Umbraco.Web.UI.Client/libs/resources/tryExecuteAndNotify.function.ts index 8a280ec876..d34b90fb02 100644 --- a/src/Umbraco.Web.UI.Client/libs/resources/tryExecuteAndNotify.function.ts +++ b/src/Umbraco.Web.UI.Client/libs/resources/tryExecuteAndNotify.function.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { UmbResourceController } from './resource.controller'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import type { UmbNotificationOptions } from '@umbraco-cms/notification'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import type { UmbNotificationOptions } from '@umbraco-cms/backoffice/notification'; export function tryExecuteAndNotify( - host: UmbControllerHostInterface, + host: UmbControllerHostElement, resource: Promise, options?: UmbNotificationOptions ) { diff --git a/src/Umbraco.Web.UI.Client/libs/router/index.ts b/src/Umbraco.Web.UI.Client/libs/router/index.ts new file mode 100644 index 0000000000..537b3d396d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/router/index.ts @@ -0,0 +1,5 @@ +export type * from 'router-slot/model'; +export * from 'router-slot/util'; +export * from './route-location.interface'; +export * from './route.context'; +export * from './route.interface'; diff --git a/src/Umbraco.Web.UI.Client/libs/router/route-location.interface.ts b/src/Umbraco.Web.UI.Client/libs/router/route-location.interface.ts new file mode 100644 index 0000000000..ef5f56188f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/router/route-location.interface.ts @@ -0,0 +1,6 @@ +export interface UmbRouteLocation { + name?: string; + params: { + [key: string]: string; + }; +} diff --git a/src/Umbraco.Web.UI.Client/libs/router/route.context.ts b/src/Umbraco.Web.UI.Client/libs/router/route.context.ts new file mode 100644 index 0000000000..ee3ffed616 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/router/route.context.ts @@ -0,0 +1,144 @@ +// eslint-disable-next-line local-rules/no-external-imports +import type { IRoutingInfo, ISlashOptions } from 'router-slot/model'; +import type { UmbRoute } from './route.interface'; +import { + UmbContextConsumerController, + UmbContextProviderController, + UmbContextToken, +} from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UMB_MODAL_CONTEXT_TOKEN, UmbModalRouteRegistration } from '@umbraco-cms/backoffice/modal'; + +const EmptyDiv = document.createElement('div'); + +const PARAM_IDENTIFIER = /:([^\\/]+)/g; + +function stripSlash(path: string): string { + return slashify(path, { start: false, end: false }); +} + +function slashify(path: string, { start = true, end = true }: Partial = {}): string { + path = start && !path.startsWith('/') ? `/${path}` : !start && path.startsWith('/') ? path.slice(1) : path; + return end && !path.endsWith('/') ? `${path}/` : !end && path.endsWith('/') ? path.slice(0, path.length - 1) : path; +} + +export class UmbRouteContext { + #modalRegistrations: UmbModalRouteRegistration[] = []; + #modalContext?: typeof UMB_MODAL_CONTEXT_TOKEN.TYPE; + #contextRoutes: UmbRoute[] = []; + #routerBasePath?: string; + #activeModalPath?: string; + + constructor(host: UmbControllerHostElement, private _onGotModals: (contextRoutes: any) => void) { + new UmbContextProviderController(host, UMB_ROUTE_CONTEXT_TOKEN, this); + new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (context) => { + this.#modalContext = context; + this.#generateContextRoutes(); + }); + } + + public registerModal(registration: UmbModalRouteRegistration) { + this.#modalRegistrations.push(registration); + this.#generateNewUrlBuilder(registration); + this.#generateContextRoutes(); + return registration; + } + + public unregisterModal(registrationToken: ReturnType) { + const index = this.#modalRegistrations.indexOf(registrationToken); + if (index === -1) return; + this.#modalRegistrations.splice(index, 1); + this.#generateContextRoutes(); + } + + #getModalRoutePath(modalRegistration: UmbModalRouteRegistration) { + return `/modal/${modalRegistration.alias.toString()}/${modalRegistration.path}`; + } + + #generateRoute(modalRegistration: UmbModalRouteRegistration): UmbRoute { + return { + path: this.#getModalRoutePath(modalRegistration), + component: EmptyDiv, + setup: (component, info) => { + if (!this.#modalContext) return; + const modalHandler = modalRegistration.routeSetup(this.#modalContext, info.match.params); + if (modalHandler) { + modalHandler.onSubmit().then( + () => { + this.#removeModalPath(info); + }, + () => { + this.#removeModalPath(info); + } + ); + } + }, + }; + } + + #removeModalPath(info: IRoutingInfo) { + if (window.location.href.includes(info.match.fragments.consumed)) { + window.history.pushState({}, '', window.location.href.split(info.match.fragments.consumed)[0]); + } + } + + #generateContextRoutes() { + this.#contextRoutes = this.#modalRegistrations.map((modalRegistration) => { + return this.#generateRoute(modalRegistration); + }); + + // Add an empty route, so there is a route for the router to react on when no modals are open. + this.#contextRoutes.push({ + path: '', + component: EmptyDiv, + }); + + // TODO: Should we await one frame, to ensure we don't call back too much?. + this._onGotModals(this.#contextRoutes); + } + + public _internal_routerGotBasePath(routerBasePath: string) { + if (this.#routerBasePath === routerBasePath) return; + this.#routerBasePath = routerBasePath; + this.#generateNewUrlBuilders(); + } + + // Also notice each registration should now hold its handler when its active. + public _internal_modalRouterChanged(activeModalPath: string | undefined) { + if (this.#activeModalPath === activeModalPath) return; + if (this.#activeModalPath) { + // If if there is a modal using the old path. + const activeModal = this.#modalRegistrations.find( + (registration) => this.#getModalRoutePath(registration) === this.#activeModalPath + ); + if (activeModal) { + this.#modalContext?.close(activeModal.key); + } + } + this.#activeModalPath = activeModalPath; + } + + #generateNewUrlBuilders() { + this.#modalRegistrations.forEach(this.#generateNewUrlBuilder); + } + + #generateNewUrlBuilder = (modalRegistration: UmbModalRouteRegistration) => { + if (!this.#routerBasePath) return; + + const routeBasePath = this.#routerBasePath.endsWith('/') ? this.#routerBasePath : this.#routerBasePath + '/'; + const localPath = `modal/${modalRegistration.alias.toString()}/${modalRegistration.path}`; + + const urlBuilder = (params: { [key: string]: string | number }) => { + const localRoutePath = stripSlash( + localPath.replace(PARAM_IDENTIFIER, (substring: string, ...args: string[]) => { + return params[args[0]].toString(); + }) + ); + return routeBasePath + localRoutePath; + }; + + modalRegistration._internal_setRouteBuilder(urlBuilder); + }; +} + +export const UMB_ROUTE_CONTEXT_TOKEN = new UmbContextToken('UmbRouterContext'); diff --git a/src/Umbraco.Web.UI.Client/libs/router/route.interface.ts b/src/Umbraco.Web.UI.Client/libs/router/route.interface.ts new file mode 100644 index 0000000000..8c7f94ac63 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/router/route.interface.ts @@ -0,0 +1 @@ +export type { IRoute as UmbRoute } from 'router-slot/model'; diff --git a/src/Umbraco.Web.UI.Client/libs/store/entity-tree-store.ts b/src/Umbraco.Web.UI.Client/libs/store/entity-tree-store.ts new file mode 100644 index 0000000000..ea94db043a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/store/entity-tree-store.ts @@ -0,0 +1,67 @@ +import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store'; + +/** + * @export + * @class UmbEntityTreeStore + * @extends {UmbStoreBase} + * @description - General Tree Data Store + */ +export class UmbEntityTreeStore extends UmbStoreBase implements UmbTreeStore { + #data = new ArrayState([], (x) => x.id); + + /** + * Appends items to the store + * @param {Array} items + * @memberof UmbEntityTreeStore + */ + appendItems(items: Array) { + this.#data.append(items); + } + + /** + * Updates an item in the store + * @param {string} id + * @param {Partial} data + * @memberof UmbEntityTreeStore + */ + updateItem(id: string, data: Partial) { + this.#data.next(partialUpdateFrozenArray(this.#data.getValue(), data, (entry) => entry.id === id)); + } + + /** + * Removes an item from the store + * @param {string} id + * @memberof UmbEntityTreeStore + */ + removeItem(id: string) { + this.#data.removeOne(id); + } + + /** + * An observable to observe the root items + * @memberof UmbEntityTreeStore + */ + rootItems = this.#data.getObservablePart((items) => items.filter((item) => item.parentId === null)); + + /** + * Returns an observable to observe the children of a given parent + * @param {(string | null)} parentId + * @return {*} + * @memberof UmbEntityTreeStore + */ + childrenOf(parentId: string | null) { + return this.#data.getObservablePart((items) => items.filter((item) => item.parentId === parentId)); + } + + /** + * Returns an observable to observe the items with the given ids + * @param {Array} ids + * @return {*} + * @memberof UmbEntityTreeStore + */ + items(ids: Array) { + return this.#data.getObservablePart((items) => items.filter((item) => ids.includes(item.id ?? ''))); + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/store/file-system-tree.store.ts b/src/Umbraco.Web.UI.Client/libs/store/file-system-tree.store.ts new file mode 100644 index 0000000000..8afa8ca62e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/store/file-system-tree.store.ts @@ -0,0 +1,67 @@ +import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; +import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store'; + +/** + * @export + * @class UmbFileSystemTreeStore + * @extends {UmbStoreBase} + * @description - General Tree Data Store + */ +export class UmbFileSystemTreeStore extends UmbStoreBase implements UmbTreeStore { + #data = new ArrayState([], (x) => x.path); + + /** + * Appends items to the store + * @param {Array} items + * @memberof UmbFileSystemTreeStore + */ + appendItems(items: Array) { + this.#data.append(items); + } + + /** + * Updates an item in the store + * @param {string} path + * @param {Partial} data + * @memberof UmbFileSystemTreeStore + */ + updateItem(path: string, data: Partial) { + this.#data.appendOne(data); + } + + /** + * Removes an item from the store + * @param {string} path + * @memberof UmbFileSystemTreeStore + */ + removeItem(path: string) { + this.#data.removeOne(path); + } + + /** + * An observable to observe the root items + * @memberof UmbFileSystemTreeStore + */ + rootItems = this.#data.getObservablePart((items) => items.filter((item) => item.path?.includes('/') === false)); + + /** + * Returns an observable to observe the children of a given parent + * @param {(string | null)} parentPath + * @return {*} + * @memberof UmbFileSystemTreeStore + */ + childrenOf(parentPath: string | null) { + return this.#data.getObservablePart((items) => items.filter((item) => item.path?.startsWith(parentPath + '/'))); + } + + /** + * Returns an observable to observe the items with the given ids + * @param {Array} paths + * @return {*} + * @memberof UmbFileSystemTreeStore + */ + items(paths: Array) { + return this.#data.getObservablePart((items) => items.filter((item) => paths.includes(item.path ?? ''))); + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/store/index.ts b/src/Umbraco.Web.UI.Client/libs/store/index.ts index fbda429a4b..f9152d3ebd 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/index.ts @@ -1,4 +1,5 @@ -export * from './icon/icon.store'; export * from './store'; export * from './store-base'; -export * from './tree-store-base'; +export * from './entity-tree-store'; +export * from './file-system-tree.store'; +export * from './tree-store.interface'; diff --git a/src/Umbraco.Web.UI.Client/libs/store/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/store/rollup.config.js deleted file mode 100644 index 35421e5ce7..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/store/rollup.config.js +++ /dev/null @@ -1,3 +0,0 @@ -import config from '../../utils/rollup.config.js'; - -export default config; diff --git a/src/Umbraco.Web.UI.Client/libs/store/store-base.ts b/src/Umbraco.Web.UI.Client/libs/store/store-base.ts index 0c640fe58e..4021307cd6 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/store-base.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/store-base.ts @@ -1,8 +1,9 @@ -import { UmbContextProviderController } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +// TODO: Make a Store interface? export class UmbStoreBase { - constructor(protected _host: UmbControllerHostInterface, public readonly storeAlias: string) { + constructor(protected _host: UmbControllerHostElement, public readonly storeAlias: string) { new UmbContextProviderController(_host, storeAlias, this); } } diff --git a/src/Umbraco.Web.UI.Client/libs/store/store.ts b/src/Umbraco.Web.UI.Client/libs/store/store.ts index 083cc9fc2f..4961162767 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/store.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/store.ts @@ -9,40 +9,14 @@ export interface UmbDataStore { readonly storeAlias: string; } -export interface UmbTreeStore extends UmbDataStore { - - getTreeRoot(): Observable>; - - getTreeItemChildren(key: string): Observable>; - - // Notice: this might not be right to put here as only some content items has ability to be trashed. - /** - * @description - Trash data. - * @param {string[]} keys - * @return {*} {(Promise)} - * @memberof UmbTreeStore - */ - trash(keys: string[]): Promise; - - // Notice: this might not be right to put here as only some content items has ability to be moved. - /** - * @description - Move data. - * @param {string[]} keys - * @return {*} {(Promise)} - * @memberof UmbTreeStore - */ - move(keys: string[], destination: string): Promise; -} - export interface UmbEntityDetailStore extends UmbDataStore { - /** * @description - Request scaffold data by entityType and . The data is added to the store and is returned as an Observable. * @param {string} key * @return {*} {T} * @memberof UmbEntityDetailStore */ - getScaffold: (entityType: string, parentKey: string | null) => T; + getScaffold: (entityType: string, parentId: string | null) => T; /** * @description - Request data by key. The data is added to the store and is returned as an Observable. @@ -61,10 +35,7 @@ export interface UmbEntityDetailStore extends UmbDataStore { save(data: T[]): Promise; } - export interface UmbContentStore extends UmbEntityDetailStore { - // TODO: make something that is specific for UmbContentStore, or then we should get rid of it. But for now i kept it as we might want this for rollback or other things specific to Content types. save(data: T[]): Promise; - } diff --git a/src/Umbraco.Web.UI.Client/libs/store/tree-store-base.ts b/src/Umbraco.Web.UI.Client/libs/store/tree-store-base.ts deleted file mode 100644 index feab80cb01..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/store/tree-store-base.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { EntityTreeItemModel } from '@umbraco-cms/backend-api'; -import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/observable-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; - -/** - * @export - * @class UmbTreeStoreBase - * @extends {UmbStoreBase} - * @description - General Tree Data Store - */ -// TODO: consider if tree store could be turned into a general EntityTreeStore class? -export class UmbTreeStoreBase extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); - - /** - * Appends items to the store - * @param {Array} items - * @memberof UmbTreeStoreBase - */ - appendItems(items: Array) { - this.#data.append(items); - } - - /** - * Updates an item in the store - * @param {string} key - * @param {Partial} data - * @memberof UmbTreeStoreBase - */ - updateItem(key: string, data: Partial) { - this.#data.next(partialUpdateFrozenArray(this.#data.getValue(), data, (entry) => entry.key === key)); - } - - /** - * Removes an item from the store - * @param {string} key - * @memberof UmbTreeStoreBase - */ - removeItem(key: string) { - this.#data.removeOne(key); - } - - /** - * An observable to observe the root items - * @memberof UmbTreeStoreBase - */ - rootItems = this.#data.getObservablePart((items) => items.filter((item) => item.parentKey === null)); - - /** - * Returns an observable to observe the children of a given parent - * @param {(string | null)} parentKey - * @return {*} - * @memberof UmbTreeStoreBase - */ - childrenOf(parentKey: string | null) { - return this.#data.getObservablePart((items) => items.filter((item) => item.parentKey === parentKey)); - } - - /** - * Returns an observable to observe the items with the given keys - * @param {Array} keys - * @return {*} - * @memberof UmbTreeStoreBase - */ - items(keys: Array) { - return this.#data.getObservablePart((items) => items.filter((item) => keys.includes(item.key ?? ''))); - } -} diff --git a/src/Umbraco.Web.UI.Client/libs/store/tree-store.interface.ts b/src/Umbraco.Web.UI.Client/libs/store/tree-store.interface.ts new file mode 100644 index 0000000000..80a366ada5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/store/tree-store.interface.ts @@ -0,0 +1,12 @@ +import type { Observable } from 'rxjs'; +import { TreeItemPresentationModel } from '../backend-api'; + +export interface UmbTreeStore { + appendItems: (items: Array) => void; + updateItem: (unique: string, item: Partial) => void; + removeItem: (unique: string) => void; + + rootItems: Observable>; + childrenOf: (parentUnique: string | null) => Observable>; + items: (uniques: Array) => Observable>; +} diff --git a/src/Umbraco.Web.UI.Client/libs/test-utils/index.ts b/src/Umbraco.Web.UI.Client/libs/test-utils/index.ts deleted file mode 100644 index 0d2296cc1c..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/test-utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './chai'; diff --git a/src/Umbraco.Web.UI.Client/libs/events/change.event.ts b/src/Umbraco.Web.UI.Client/libs/umb-events/change.event.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/events/change.event.ts rename to src/Umbraco.Web.UI.Client/libs/umb-events/change.event.ts diff --git a/src/Umbraco.Web.UI.Client/libs/events/delete.event.ts b/src/Umbraco.Web.UI.Client/libs/umb-events/delete.event.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/events/delete.event.ts rename to src/Umbraco.Web.UI.Client/libs/umb-events/delete.event.ts diff --git a/src/Umbraco.Web.UI.Client/libs/events/executed.event.ts b/src/Umbraco.Web.UI.Client/libs/umb-events/executed.event.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/events/executed.event.ts rename to src/Umbraco.Web.UI.Client/libs/umb-events/executed.event.ts diff --git a/src/Umbraco.Web.UI.Client/libs/events/index.ts b/src/Umbraco.Web.UI.Client/libs/umb-events/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/events/index.ts rename to src/Umbraco.Web.UI.Client/libs/umb-events/index.ts diff --git a/src/Umbraco.Web.UI.Client/libs/events/input.event.ts b/src/Umbraco.Web.UI.Client/libs/umb-events/input.event.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/events/input.event.ts rename to src/Umbraco.Web.UI.Client/libs/umb-events/input.event.ts diff --git a/src/Umbraco.Web.UI.Client/libs/utils/generate-guid.ts b/src/Umbraco.Web.UI.Client/libs/utils/generate-guid.ts new file mode 100644 index 0000000000..b0b7f6b981 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/utils/generate-guid.ts @@ -0,0 +1,4 @@ +import { v4 as uuid } from 'uuid'; +export function generateGuid() { + return uuid(); +} diff --git a/src/Umbraco.Web.UI.Client/libs/utils/index.ts b/src/Umbraco.Web.UI.Client/libs/utils/index.ts index b7439f0c3a..d16b3e3261 100644 --- a/src/Umbraco.Web.UI.Client/libs/utils/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/utils/index.ts @@ -1,3 +1,4 @@ export * from './utils'; export * from './umbraco-path'; export * from './udi-service'; +export * from './generate-guid'; diff --git a/src/Umbraco.Web.UI.Client/libs/utils/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/utils/rollup.config.js deleted file mode 100644 index 44c6c08405..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/utils/rollup.config.js +++ /dev/null @@ -1,4 +0,0 @@ -import config from '../../utils/rollup.config.js'; -export default [ - ...config, -]; diff --git a/src/Umbraco.Web.UI.Client/libs/utils/utils.test.ts b/src/Umbraco.Web.UI.Client/libs/utils/utils.test.ts index 47950df551..36bbe2e2a0 100644 --- a/src/Umbraco.Web.UI.Client/libs/utils/utils.test.ts +++ b/src/Umbraco.Web.UI.Client/libs/utils/utils.test.ts @@ -1,7 +1,7 @@ import { expect } from '@open-wc/testing'; import { InterfaceColor, InterfaceLook } from '@umbraco-ui/uui-base/lib/types'; import { getLookAndColorFromUserStatus } from './utils'; -import type { UserStatus } from '@umbraco-cms/models'; +import type { UserStatus } from '@umbraco-cms/backoffice/models'; describe('UmbUserExtensions', () => { it('returns correct look and color from a status string', () => { diff --git a/src/Umbraco.Web.UI.Client/libs/utils/utils.ts b/src/Umbraco.Web.UI.Client/libs/utils/utils.ts index 15c6ed72c4..76da7bba7c 100644 --- a/src/Umbraco.Web.UI.Client/libs/utils/utils.ts +++ b/src/Umbraco.Web.UI.Client/libs/utils/utils.ts @@ -1,5 +1,5 @@ import { InterfaceColor, InterfaceLook } from '@umbraco-ui/uui-base/lib/types'; -import type { UserStatus } from '@umbraco-cms/models'; +import type { UserStatus } from '@umbraco-cms/backoffice/models'; export const getLookAndColorFromUserStatus = (status: UserStatus): { look: InterfaceLook; color: InterfaceColor } => { switch ((status || '').toLowerCase()) { diff --git a/src/Umbraco.Web.UI.Client/libs/workspace/actions/save/save.action.ts b/src/Umbraco.Web.UI.Client/libs/workspace/actions/save/save.action.ts index 5429581259..08a19462a8 100644 --- a/src/Umbraco.Web.UI.Client/libs/workspace/actions/save/save.action.ts +++ b/src/Umbraco.Web.UI.Client/libs/workspace/actions/save/save.action.ts @@ -1,10 +1,10 @@ -import { UmbWorkspaceContextInterface } from '../../../../src/backoffice/shared/components/workspace/workspace-context/workspace-context.interface'; +import { UmbWorkspaceContextInterface } from '../../context/workspace-context.interface'; import { UmbWorkspaceActionBase } from '../workspace-action-base'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; // TODO: add interface for repo/partial repo/save-repo export class UmbSaveWorkspaceAction extends UmbWorkspaceActionBase { - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host); } @@ -19,7 +19,7 @@ export class UmbSaveWorkspaceAction extends UmbWorkspaceActionBase { - host: UmbControllerHostInterface; + host: UmbControllerHostElement; workspaceContext?: T; execute(): Promise; } export class UmbWorkspaceActionBase { - host: UmbControllerHostInterface; + host: UmbControllerHostElement; workspaceContext?: WorkspaceType; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.host = host; - new UmbContextConsumerController(this.host, 'umbWorkspaceContext', (instance: WorkspaceType) => { - this.workspaceContext = instance; + new UmbContextConsumerController(this.host, UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.workspaceContext = instance as WorkspaceType; }); } } diff --git a/src/Umbraco.Web.UI.Client/libs/workspace/context/index.ts b/src/Umbraco.Web.UI.Client/libs/workspace/context/index.ts new file mode 100644 index 0000000000..8bcfcfdd5c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/workspace/context/index.ts @@ -0,0 +1,2 @@ +export * from './workspace-context.interface'; +export * from './workspace-entity-context.interface'; diff --git a/src/Umbraco.Web.UI.Client/libs/workspace/context/workspace-context.interface.ts b/src/Umbraco.Web.UI.Client/libs/workspace/context/workspace-context.interface.ts new file mode 100644 index 0000000000..7ed8d16a41 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/workspace/context/workspace-context.interface.ts @@ -0,0 +1,17 @@ +import { Observable } from 'rxjs'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +export interface UmbWorkspaceContextInterface { + host: UmbControllerHostElement; + repository: any; // TODO: add type + isNew: Observable; + getIsNew(): boolean; + setIsNew(value: boolean): void; + // TODO: should we consider another name than entity type. File system files are not entities but still have this type. + getEntityType(): string; + getData(): DataType | undefined; + destroy(): void; + // TODO: temp solution to bubble validation errors to the UI + setValidationErrors?(errorMap: any): void; + save(): void; +} diff --git a/src/Umbraco.Web.UI.Client/libs/workspace/context/workspace-entity-context.interface.ts b/src/Umbraco.Web.UI.Client/libs/workspace/context/workspace-entity-context.interface.ts new file mode 100644 index 0000000000..878f050818 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/workspace/context/workspace-entity-context.interface.ts @@ -0,0 +1,9 @@ +import type { UmbWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; + +export interface UmbEntityWorkspaceContextInterface + extends UmbWorkspaceContextInterface { + getEntityId(): string | undefined; // COnsider if this should go away now that we have getUnique() + getEntityType(): string; // TODO: consider of this should be on the repository because a repo is responsible for one entity type + //getData(): EntityType | undefined; + save(): Promise; +} diff --git a/src/Umbraco.Web.UI.Client/libs/workspace/index.ts b/src/Umbraco.Web.UI.Client/libs/workspace/index.ts index 485f1b10af..de14fcfee4 100644 --- a/src/Umbraco.Web.UI.Client/libs/workspace/index.ts +++ b/src/Umbraco.Web.UI.Client/libs/workspace/index.ts @@ -1 +1,2 @@ export * from './actions'; +export * from './context'; diff --git a/src/Umbraco.Web.UI.Client/libs/workspace/rollup.config.js b/src/Umbraco.Web.UI.Client/libs/workspace/rollup.config.js deleted file mode 100644 index 44c6c08405..0000000000 --- a/src/Umbraco.Web.UI.Client/libs/workspace/rollup.config.js +++ /dev/null @@ -1,4 +0,0 @@ -import config from '../../utils/rollup.config.js'; -export default [ - ...config, -]; diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 185300282b..37edbdfc85 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -9,16 +9,13 @@ "version": "0.0.0", "license": "MIT", "dependencies": { - "@umbraco-ui/uui": "^1.2.0-rc.0", - "@umbraco-ui/uui-css": "^1.2.0-rc.0", - "@umbraco-ui/uui-modal": "file:umbraco-ui-uui-modal-0.0.0.tgz", - "@umbraco-ui/uui-modal-container": "file:umbraco-ui-uui-modal-container-0.0.0.tgz", - "@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", - "@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz", + "@umbraco-ui/uui": "^1.2.0-rc.2", + "@umbraco-ui/uui-css": "^1.2.0-rc.2", "element-internals-polyfill": "^1.1.19", - "lit": "^2.6.1", + "lit": "^2.7.0", "lodash-es": "4.17.21", - "router-slot": "file:router-slot-1.6.1.tgz", + "monaco-editor": "^0.36.1", + "router-slot": "file:router-slot-2.0.0.tgz", "rxjs": "^7.8.0", "uuid": "^9.0.0" }, @@ -28,19 +25,20 @@ "@open-wc/testing": "^3.1.7", "@playwright/test": "^1.30.0", "@rollup/plugin-json": "^6.0.0", - "@storybook/addon-a11y": "^7.0.0-rc.3", - "@storybook/addon-actions": "^7.0.0-rc.3", - "@storybook/addon-essentials": "^7.0.0-rc.3", - "@storybook/addon-links": "^7.0.0-rc.3", - "@storybook/mdx2-csf": "^1.0.0-next.5", - "@storybook/web-components": "^7.0.0-rc.3", - "@storybook/web-components-vite": "^7.0.0-rc.3", + "@rollup/plugin-node-resolve": "^15.0.1", + "@storybook/addon-a11y": "^7.0.2", + "@storybook/addon-actions": "^7.0.2", + "@storybook/addon-essentials": "^7.0.2", + "@storybook/addon-links": "^7.0.2", + "@storybook/mdx2-csf": "^1.0.0", + "@storybook/web-components": "^7.0.2", + "@storybook/web-components-vite": "^7.0.2", "@types/chai": "^4.3.4", "@types/lodash-es": "^4.17.6", "@types/mocha": "^10.0.0", "@types/uuid": "^9.0.0", "@typescript-eslint/eslint-plugin": "^5.50.0", - "@typescript-eslint/parser": "^5.54.0", + "@typescript-eslint/parser": "^5.57.0", "@web/dev-server-esbuild": "^0.3.3", "@web/dev-server-import-maps": "^0.0.7", "@web/dev-server-rollup": "^0.3.21", @@ -48,7 +46,7 @@ "@web/test-runner-playwright": "^0.9.0", "babel-loader": "^9.1.2", "eslint": "^8.32.0", - "eslint-config-prettier": "^8.6.0", + "eslint-config-prettier": "^8.8.0", "eslint-import-resolver-typescript": "^3.5.3", "eslint-plugin-import": "^2.27.4", "eslint-plugin-lit": "^1.8.2", @@ -56,9 +54,8 @@ "eslint-plugin-local-rules": "^1.3.2", "eslint-plugin-storybook": "^0.6.11", "eslint-plugin-wc": "^1.4.0", - "lit-html": "^2.6.1", "msw": "^1.1.0", - "msw-storybook-addon": "^1.7.0", + "msw-storybook-addon": "^1.8.0", "openapi-typescript-codegen": "^0.23.0", "playwright-msw": "^2.1.0", "plop": "^3.1.1", @@ -69,11 +66,11 @@ "rollup-plugin-dts": "^5.2.0", "rollup-plugin-esbuild": "^5.0.0", "rollup-plugin-url": "^3.0.1", - "storybook": "^7.0.0-rc.3", + "storybook": "^7.0.2", "tiny-glob": "^0.2.9", - "typescript": "^4.9.5", + "typescript": "^5.0.3", "typescript-json-schema": "^0.55.0", - "vite": "^4.1.4", + "vite": "^4.2.1", "vite-plugin-static-copy": "^0.13.0", "vite-tsconfig-paths": "^4.0.5", "web-component-analyzer": "^2.0.0-next.4" @@ -151,9 +148,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", - "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", + "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", "dev": true, "engines": { "node": ">=6.9.0" @@ -244,13 +241,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", + "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", "semver": "^6.3.0" @@ -263,9 +260,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz", - "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", + "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", @@ -285,9 +282,9 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz", - "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz", + "integrity": "sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", @@ -925,12 +922,12 @@ } }, "node_modules/@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz", + "integrity": "sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -967,12 +964,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1084,12 +1081,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1200,9 +1197,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", - "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", + "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" @@ -1454,9 +1451,9 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", - "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", + "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" @@ -1610,11 +1607,12 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz", - "integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz", + "integrity": "sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==", "dev": true, "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" @@ -1658,31 +1656,31 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", + "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", + "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", + "@babel/plugin-proposal-async-generator-functions": "^7.20.7", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.21.0", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.0", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1699,40 +1697,40 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.20.7", + "@babel/plugin-transform-async-to-generator": "^7.20.7", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-block-scoping": "^7.21.0", + "@babel/plugin-transform-classes": "^7.21.0", + "@babel/plugin-transform-computed-properties": "^7.20.7", + "@babel/plugin-transform-destructuring": "^7.21.3", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-for-of": "^7.21.0", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-amd": "^7.20.11", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-modules-systemjs": "^7.20.11", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-parameters": "^7.21.3", "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.20.5", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-spread": "^7.20.7", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", + "@babel/types": "^7.21.4", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1747,14 +1745,14 @@ } }, "node_modules/@babel/preset-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz", - "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.21.4.tgz", + "integrity": "sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-flow-strip-types": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-transform-flow-strip-types": "^7.21.0" }, "engines": { "node": ">=6.9.0" @@ -1780,14 +1778,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz", - "integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.4.tgz", + "integrity": "sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-transform-typescript": "^7.21.0" + "@babel/plugin-syntax-jsx": "^7.21.4", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-typescript": "^7.21.3" }, "engines": { "node": ">=6.9.0" @@ -1978,9 +1978,9 @@ } }, "node_modules/@babel/types": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", - "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.19.4", @@ -2041,10 +2041,74 @@ "react": ">=16.8.0" } }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz", + "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz", + "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz", + "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz", + "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz", + "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==", "cpu": [ "x64" ], @@ -2057,6 +2121,278 @@ "node": ">=12" } }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz", + "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz", + "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz", + "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz", + "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz", + "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz", + "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz", + "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz", + "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz", + "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz", + "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz", + "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz", + "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz", + "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz", + "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz", + "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz", + "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz", + "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", @@ -2499,9 +2835,9 @@ "dev": true }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.0.0.tgz", - "integrity": "sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.0.tgz", + "integrity": "sha512-92uQ5ARf7UXYrzaFcAX3T2rTvaS9Z1//ukV+DqjACM4c8s0ZBQd7ayJU5Dh2AFLD/Ayuyz4uMmxQec8q3U4Ong==" }, "node_modules/@lit/reactive-element": { "version": "1.6.1", @@ -2755,7 +3091,32 @@ } } }, - "node_modules/@rollup/plugin-json/node_modules/@rollup/pluginutils": { + "node_modules/@rollup/plugin-node-resolve": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz", + "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.0", + "is-module": "^1.0.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.78.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", @@ -2777,55 +3138,6 @@ } } }, - "node_modules/@rollup/plugin-json/node_modules/@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", - "dev": true - }, - "node_modules/@rollup/plugin-json/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", - "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "rollup": "^2.42.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, "node_modules/@sinclair/typebox": { "version": "0.25.24", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", @@ -2833,21 +3145,21 @@ "dev": true }, "node_modules/@storybook/addon-a11y": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-7.0.0-rc.3.tgz", - "integrity": "sha512-V/wl19IzsOA0OkUofKKbL09Qj93ywRHW3Pjq3pOLRE178zCumWuBKxpr+dS4C1lNwecIU1ffp8408RSzZ4K5sA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-7.0.2.tgz", + "integrity": "sha512-PCJaLdp/3MypMYQufLIaKL4gzZjDgU8fTW45O7feXwiUZzFUVZamBwBw5BHcHAPsDOr5CmebGvJ9+l2gByWL/g==", "dev": true, "dependencies": { - "@storybook/addon-highlight": "7.0.0-rc.3", - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/addon-highlight": "7.0.2", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "axe-core": "^4.2.0", "lodash": "^4.17.21", "react-resize-detector": "^7.1.2" @@ -2870,19 +3182,19 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.0-rc.3.tgz", - "integrity": "sha512-kyPuSN/PzBnW3w9D/KBEmMqfeGpBeY6Ha2VVPz3BBqcWSHfw0AbHFqvnqluubaHZl1VokE88QT6RxkdyBg33uw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.2.tgz", + "integrity": "sha512-rcj39u9MrmzsrDWYt1zsoVxrogZ1Amrv9xkEofEY/QKUr2R3xpHhTALveY9BKIlG1GoE8zLlLoP2k4nz3sNNwQ==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "dequal": "^2.0.2", "lodash": "^4.17.21", "polished": "^4.2.2", @@ -2910,19 +3222,19 @@ } }, "node_modules/@storybook/addon-backgrounds": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.0-rc.3.tgz", - "integrity": "sha512-6qIwuNwzLFdsLCjj5rO6TCaBvAGUYbrLpw2EQyKg5J/5GxqhMU/HsinCViok2VEn/z45vji9FI1W6bmo7t4LNQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.2.tgz", + "integrity": "sha512-yRNHQ4PPRJ+HIORQPhDGxn5xolw1xW0ByQZoNRpMD+AMEyfUNFdWbCsRQAOWjNhawxVMHM7EeA2Exrb41zhEjA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "memoizerific": "^1.11.3", "ts-dedent": "^2.0.0" }, @@ -2944,20 +3256,20 @@ } }, "node_modules/@storybook/addon-controls": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.0-rc.3.tgz", - "integrity": "sha512-16E0AJ1+psFDbL6abOfLFg0zWhUQeJjcM3RKEzJjYZEBuKKL86LAvKhnlkyCUW3VlLN23V0akY6Gev81DR/BfA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.2.tgz", + "integrity": "sha512-dMpRtj5cmfC9vEMve5ncvbWCEC+WD9YuzJ+grdc48E/Hd//p+O2FE6klSkrz5FAjrc+rHINixdyssekpEL6nYQ==", "dev": true, "dependencies": { - "@storybook/blocks": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/blocks": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/manager-api": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" }, @@ -2979,28 +3291,28 @@ } }, "node_modules/@storybook/addon-docs": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.0-rc.3.tgz", - "integrity": "sha512-UPy+o7IBly2TgCQ7hviaExq++KQSPS7/+/8iLUdv81mtRm3hMBMARmom+wjXfciGHp1re1bazQQYoDsOcorDhA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.2.tgz", + "integrity": "sha512-q3rDWoZEym6Lkmhqc/HBNfLDAmTY8l0WINGUZo/nF98eP5iu4B7Nk7V6BRGYGQt6Y6ZyIQ8WKH0e/eJww2zIog==", "dev": true, "dependencies": { "@babel/core": "^7.20.2", "@babel/plugin-transform-react-jsx": "^7.19.0", "@jest/transform": "^29.3.1", "@mdx-js/react": "^2.1.5", - "@storybook/blocks": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/csf-plugin": "7.0.0-rc.3", - "@storybook/csf-tools": "7.0.0-rc.3", + "@storybook/blocks": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/csf-plugin": "7.0.2", + "@storybook/csf-tools": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/mdx2-csf": "next", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/postinstall": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/react-dom-shim": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/mdx2-csf": "^1.0.0", + "@storybook/node-logger": "7.0.2", + "@storybook/postinstall": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/react-dom-shim": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "fs-extra": "^11.1.0", "remark-external-links": "^8.0.0", "remark-slug": "^6.0.0", @@ -3022,24 +3334,24 @@ } }, "node_modules/@storybook/addon-essentials": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.0-rc.3.tgz", - "integrity": "sha512-RLA1RgjwuDsRKp2QjBAx2XsgTZ+Dura2k8xCTyBLf0yxnleC8hiAxLwTJSSdDEUuiXxWsBbu0vhHzYnCCVTDnw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.2.tgz", + "integrity": "sha512-LAsWsXa/Pp2B4Ve2WVgc990FtsiHpFDRsq7S3V7xRrZP8DYRbtJIVdszPMDS5uKC+yzbswFEXz08lqbGvq8zgQ==", "dev": true, "dependencies": { - "@storybook/addon-actions": "7.0.0-rc.3", - "@storybook/addon-backgrounds": "7.0.0-rc.3", - "@storybook/addon-controls": "7.0.0-rc.3", - "@storybook/addon-docs": "7.0.0-rc.3", - "@storybook/addon-highlight": "7.0.0-rc.3", - "@storybook/addon-measure": "7.0.0-rc.3", - "@storybook/addon-outline": "7.0.0-rc.3", - "@storybook/addon-toolbars": "7.0.0-rc.3", - "@storybook/addon-viewport": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", + "@storybook/addon-actions": "7.0.2", + "@storybook/addon-backgrounds": "7.0.2", + "@storybook/addon-controls": "7.0.2", + "@storybook/addon-docs": "7.0.2", + "@storybook/addon-highlight": "7.0.2", + "@storybook/addon-measure": "7.0.2", + "@storybook/addon-outline": "7.0.2", + "@storybook/addon-toolbars": "7.0.2", + "@storybook/addon-viewport": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/manager-api": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/preview-api": "7.0.2", "ts-dedent": "^2.0.0" }, "funding": { @@ -3052,14 +3364,14 @@ } }, "node_modules/@storybook/addon-highlight": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.0-rc.3.tgz", - "integrity": "sha512-MeFIKfDpFrF33TPdl2ko2rie485AhfG2n0MFXA73L8Yzj5JPV+LVNa5eIKUUFyOMUGSkVjfFS6n63F08eqHbCw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.2.tgz", + "integrity": "sha512-9BkL1OOanguuy73S6nLK0isUb045tOkFONd/PQldOJ0PV3agCvKxKHyzlBz7Hsba8KZhY5jQs+nVW2NiREyGYg==", "dev": true, "dependencies": { - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.0-rc.3" + "@storybook/preview-api": "7.0.2" }, "funding": { "type": "opencollective", @@ -3067,19 +3379,19 @@ } }, "node_modules/@storybook/addon-links": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.0-rc.3.tgz", - "integrity": "sha512-K2PMxVooGAgb8hCEU2oGUMzKjPLEPACH8NcRLs/fz9PKadepmijY0hBDC50SGkZd2HWSxXxyt6d5WaXTxhP8aw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.2.tgz", + "integrity": "sha512-lPtfy2MqrcI9YjupBM2eRKGPdFKVPCz7WgO/JQQakGugORJTEGCyJrNJNtWY9jDenv8ynLZ40OxtPBZi54Sr6Q==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/router": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/router": "7.0.2", + "@storybook/types": "7.0.2", "prop-types": "^15.7.2", "ts-dedent": "^2.0.0" }, @@ -3101,18 +3413,18 @@ } }, "node_modules/@storybook/addon-measure": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.0-rc.3.tgz", - "integrity": "sha512-N0HjObHjktlgWvOQcOqyC6/vFXERHzH7aP8L1RRrSnz+mP0XDO+62eBZunlnDGu4uAECH+AV/7LO+bmTMohulg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.2.tgz", + "integrity": "sha512-cf/d5MXpHAjyUiDIVfc8pLn79CPHgnryDmNNlSiP2zEFKcivrRWiu8Rmrad8pGqLkuAh+PXLKCGn9uiqDvg7QQ==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3" + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2" }, "funding": { "type": "opencollective", @@ -3132,18 +3444,18 @@ } }, "node_modules/@storybook/addon-outline": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.0-rc.3.tgz", - "integrity": "sha512-SocPRmzzu2wR3SiqMsPskfFumOd0Ph8MUTeJ2cwnaonqqHjjqxaEaFYio8AGmGaHLpY8PKtW0s75jU0oDh9Ezg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.2.tgz", + "integrity": "sha512-thVISO4NM22xlETisBvAPvz2yFD3qLGOjgzBmj8l8r9Rv0IEdwdPrwm5j0WTv8OtbhC4A8lPpvMsn5FhY5mDXg==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "ts-dedent": "^2.0.0" }, "funding": { @@ -3164,16 +3476,16 @@ } }, "node_modules/@storybook/addon-toolbars": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.0-rc.3.tgz", - "integrity": "sha512-qnvMWZAa3ELRNiVjj1sy0dJb2GzE5fga9SbsbVQQT2zBvou2e8XbiPRw0WHdwUU2Zj9t9/PVjz2+av7P8B+Cqg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.2.tgz", + "integrity": "sha512-tAxZ2+nUYsJdT1sx3BrmoMAZFM19+OzWJY6qSnbEq5zoRgvGZaXGR6tLMKydDoHQBU9Ta9YHGo7N7u7h1C23yg==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3" + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2" }, "funding": { "type": "opencollective", @@ -3193,18 +3505,18 @@ } }, "node_modules/@storybook/addon-viewport": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.0-rc.3.tgz", - "integrity": "sha512-GXBi7f4WNeM4yvKXKYNAMLDHauTOcLpimzf1wtyVapBLpwzcJHBaJTCHQ02yIcm6mU2TFbKXMmzC1uBZcCa+5w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.2.tgz", + "integrity": "sha512-TaHJWIIazPM/TerRbka9RqjMPNpwaRsGRdVRBtVoVosy1FzsEjAdQSO7RBMe4G03m5CacSqdsDiJCblI2AXaew==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", "memoizerific": "^1.11.3", "prop-types": "^15.7.2" }, @@ -3225,292 +3537,23 @@ } } }, - "node_modules/@storybook/addons": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.16.tgz", - "integrity": "sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ==", - "dev": true, - "dependencies": { - "@storybook/api": "6.5.16", - "@storybook/channels": "6.5.16", - "@storybook/client-logger": "6.5.16", - "@storybook/core-events": "6.5.16", - "@storybook/csf": "0.0.2--canary.4566f4d.1", - "@storybook/router": "6.5.16", - "@storybook/theming": "6.5.16", - "@types/webpack-env": "^1.16.0", - "core-js": "^3.8.2", - "global": "^4.4.0", - "regenerator-runtime": "^0.13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/addons/node_modules/@storybook/channels": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.16.tgz", - "integrity": "sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg==", - "dev": true, - "dependencies": { - "core-js": "^3.8.2", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addons/node_modules/@storybook/client-logger": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.16.tgz", - "integrity": "sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q==", - "dev": true, - "dependencies": { - "core-js": "^3.8.2", - "global": "^4.4.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addons/node_modules/@storybook/core-events": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.16.tgz", - "integrity": "sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==", - "dev": true, - "dependencies": { - "core-js": "^3.8.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/addons/node_modules/@storybook/csf": { - "version": "0.0.2--canary.4566f4d.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", - "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/@storybook/addons/node_modules/@storybook/router": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.16.tgz", - "integrity": "sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "regenerator-runtime": "^0.13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/addons/node_modules/@storybook/theming": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.16.tgz", - "integrity": "sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "regenerator-runtime": "^0.13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/api": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.5.16.tgz", - "integrity": "sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA==", - "dev": true, - "dependencies": { - "@storybook/channels": "6.5.16", - "@storybook/client-logger": "6.5.16", - "@storybook/core-events": "6.5.16", - "@storybook/csf": "0.0.2--canary.4566f4d.1", - "@storybook/router": "6.5.16", - "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.5.16", - "core-js": "^3.8.2", - "fast-deep-equal": "^3.1.3", - "global": "^4.4.0", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "regenerator-runtime": "^0.13.7", - "store2": "^2.12.0", - "telejson": "^6.0.8", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/channels": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.16.tgz", - "integrity": "sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg==", - "dev": true, - "dependencies": { - "core-js": "^3.8.2", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/client-logger": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.16.tgz", - "integrity": "sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q==", - "dev": true, - "dependencies": { - "core-js": "^3.8.2", - "global": "^4.4.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/core-events": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.16.tgz", - "integrity": "sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==", - "dev": true, - "dependencies": { - "core-js": "^3.8.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/csf": { - "version": "0.0.2--canary.4566f4d.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", - "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/router": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.16.tgz", - "integrity": "sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "regenerator-runtime": "^0.13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/api/node_modules/@storybook/theming": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.16.tgz", - "integrity": "sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ==", - "dev": true, - "dependencies": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "regenerator-runtime": "^0.13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@storybook/api/node_modules/isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@storybook/api/node_modules/telejson": { - "version": "6.0.8", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-6.0.8.tgz", - "integrity": "sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==", - "dev": true, - "dependencies": { - "@types/is-function": "^1.0.0", - "global": "^4.4.0", - "is-function": "^1.0.2", - "is-regex": "^1.1.2", - "is-symbol": "^1.0.3", - "isobject": "^4.0.0", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3" - } - }, "node_modules/@storybook/blocks": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.0-rc.3.tgz", - "integrity": "sha512-mh4LQk2f/Q9n7Sqo6t02CspHubXmSgDY4S5vF3dTgVBM/sD0OxkAY3Pv+HTsXH36lQHYYUft7U7OfhZapgS4ng==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.2.tgz", + "integrity": "sha512-JzHmU8jZLzeQ6bunzci8j/2Ji18GBTyhrPFLk5RjEbMNGWpGjvER/yR127tZOdbPguVNr4iVbRfGzd1wGHlrzA==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", - "@storybook/docs-tools": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", + "@storybook/docs-tools": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "@types/lodash": "^4.14.167", "color-convert": "^2.0.1", "dequal": "^2.0.2", @@ -3533,27 +3576,26 @@ } }, "node_modules/@storybook/builder-manager": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.0-rc.3.tgz", - "integrity": "sha512-aScwYA9MWtqgiD39SkcwUlrR9RFbngv7jPoOaVMdXuMgNabMNz9417L9bCwSPwgO4XZ5a/nSEbGNLfOHfBemsw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.2.tgz", + "integrity": "sha512-Oej/n8D7eaWgmWF7nN2hXLRM53lcYOdh6umSN8Mh/LcYUfxB+dvUBFzUjoLE0xjhW6xRinrKrENT5LcP/f/HBQ==", "dev": true, "dependencies": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/manager": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", + "@storybook/core-common": "7.0.2", + "@storybook/manager": "7.0.2", + "@storybook/node-logger": "7.0.2", "@types/ejs": "^3.1.1", "@types/find-cache-dir": "^3.2.1", "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", "browser-assert": "^1.2.1", "ejs": "^3.1.8", - "esbuild": "^0.16.4", + "esbuild": "^0.17.0", "esbuild-plugin-alias": "^0.2.1", "express": "^4.17.3", "find-cache-dir": "^3.0.0", "fs-extra": "^11.1.0", "process": "^0.11.10", - "slash": "^3.0.0", "util": "^0.12.4" }, "funding": { @@ -3562,21 +3604,21 @@ } }, "node_modules/@storybook/builder-vite": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-7.0.0-rc.3.tgz", - "integrity": "sha512-v2d04PWfcITD7zI68d7XbCbOd+5vl3gIMEX5Xdsmuw3WcaqYxvDSE8GhL6zsBhrUyygV/8xhSaaxyfv8ImM0+w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-7.0.2.tgz", + "integrity": "sha512-G6CD2Gf2zwzRslvNvqgz4FeADVEA9XA4Mw6+NM6Twc+Wy/Ah482dvHS9ApSgirtGyBKjOfdHn1xQT4Z+kzbJnw==", "dev": true, "dependencies": { - "@storybook/channel-postmessage": "7.0.0-rc.3", - "@storybook/channel-websocket": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/csf-plugin": "7.0.0-rc.3", - "@storybook/mdx2-csf": "next", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/channel-postmessage": "7.0.2", + "@storybook/channel-websocket": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/csf-plugin": "7.0.2", + "@storybook/mdx2-csf": "^1.0.0", + "@storybook/node-logger": "7.0.2", + "@storybook/preview": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "browser-assert": "^1.2.1", "es-module-lexer": "^0.9.3", "express": "^4.17.3", @@ -3584,8 +3626,9 @@ "glob": "^8.1.0", "glob-promise": "^6.0.2", "magic-string": "^0.27.0", - "rollup": "^2.25.0 || ^3.3.0", - "slash": "^3.0.0" + "remark-external-links": "^8.0.0", + "remark-slug": "^6.0.0", + "rollup": "^2.25.0 || ^3.3.0" }, "funding": { "type": "opencollective", @@ -3614,14 +3657,14 @@ } }, "node_modules/@storybook/channel-postmessage": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.0-rc.3.tgz", - "integrity": "sha512-1uptuCjA4vAvvoxNoIJPTIpSARzJnLU7eahRhTPwELBnCH0ObqvgInge0cvbYsaTRDNV90oBbEKlxLf1Zb1BhQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.2.tgz", + "integrity": "sha512-SZ/KqnZcx10W9hJbrzBKcP9dmgaeTaXugUhcgw1IkmjKWdsKazqFZCPwQWZZKAmhO4wYbyYOhkz3wfSIeB4mFw==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.0.3" @@ -3632,13 +3675,13 @@ } }, "node_modules/@storybook/channel-websocket": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.0-rc.3.tgz", - "integrity": "sha512-706jopde+OZZkqsmrRuwd9utusqiKianiF8cvjAxrxogSx8LwHk8jxrEKHxHiZUEWDS3JxJoIYSV8gxH9hcjsA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.2.tgz", + "integrity": "sha512-YU3lFId6Nsi75ddA+3qfbnLfNUPswboYyx+SALhaLuXqz7zqfzX4ezMgxeS/h0gRlUJ7nf2/yJ5qie/kZaizjw==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", "@storybook/global": "^5.0.0", "telejson": "^7.0.3" }, @@ -3648,9 +3691,9 @@ } }, "node_modules/@storybook/channels": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.0-rc.3.tgz", - "integrity": "sha512-jaODIck+um16Fn2k1vwHK9RNk2J8hLVyzLSkoGM40TsMF5nichwI3rA6225pLk015itJbhCAi/RhaMFBI+ZtsA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.2.tgz", + "integrity": "sha512-qkI8mFy9c8mxN2f01etayKhCaauL6RAsxRzbX1/pKj6UqhHWqqUbtHwymrv4hG5qDYjV1e9pd7ae5eNF8Kui0g==", "dev": true, "funding": { "type": "opencollective", @@ -3658,21 +3701,21 @@ } }, "node_modules/@storybook/cli": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.0-rc.3.tgz", - "integrity": "sha512-g1nWHLI1fiDK2dnLpmbhbrm6ZaAwuZkUgEGtlEQCPTHWVRZj2fJT0y5zjgBIhFpdkB/X8MZzgVxqhTJF0uX39Q==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.2.tgz", + "integrity": "sha512-xMM2QdXNGg09wuXzAGroKrbsnaHSFPmtmefX1XGALhHuKVwxOoC2apWMpek6gY/9vh5EIRTog2Dvfd2BzNrT6Q==", "dev": true, "dependencies": { "@babel/core": "^7.20.2", "@babel/preset-env": "^7.20.2", "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/core-server": "7.0.0-rc.3", - "@storybook/csf-tools": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/telemetry": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/codemod": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/core-server": "7.0.2", + "@storybook/csf-tools": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/telemetry": "7.0.2", + "@storybook/types": "7.0.2", "@types/semver": "^7.3.4", "boxen": "^5.1.2", "chalk": "^4.1.0", @@ -3784,26 +3827,6 @@ "ms": "2.0.0" } }, - "node_modules/@storybook/cli/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@storybook/cli/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3877,6 +3900,15 @@ "node": ">=8.16.0" } }, + "node_modules/@storybook/cli/node_modules/puppeteer-core/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, "node_modules/@storybook/cli/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -3889,6 +3921,26 @@ "rimraf": "bin.js" } }, + "node_modules/@storybook/cli/node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@storybook/cli/node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -3916,15 +3968,6 @@ "node": ">=8" } }, - "node_modules/@storybook/cli/node_modules/ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, - "dependencies": { - "async-limiter": "~1.0.0" - } - }, "node_modules/@storybook/cli/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -3932,9 +3975,9 @@ "dev": true }, "node_modules/@storybook/client-logger": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.0-rc.3.tgz", - "integrity": "sha512-cC7lq+S4n5fFooDCyefgTAOfipadiZskNuzsQF7drE9nQLZ8GflLdmTKK//5NQUHKPzF7r+4Q5DAK4I3nqIkxA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.2.tgz", + "integrity": "sha512-rv7W2BhzIQHbFpUM5/CP/acS6T5lTmaxT0MbZ9n+9h++9QQU/cFOdkZgSUbLVAb1AeUGoLsk0HYzcqPpV35Xsw==", "dev": true, "dependencies": { "@storybook/global": "^5.0.0" @@ -3945,18 +3988,18 @@ } }, "node_modules/@storybook/codemod": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.0-rc.3.tgz", - "integrity": "sha512-P965X5g4WIBfrYMLYPQIvwp9wfIf5bnUIVgwjeGUDLDLIst6RXmHGik9MHLy2Ic/MXTsf/kwK5qY9pj95t8DZg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.2.tgz", + "integrity": "sha512-D9PdByxJlFiaDJcLkM+RN1DHCj4VfQIlSZkADOcNtI4o9H064oiMloWDGZiR1i1FCYMSXuWmW6tMsuCVebA+Nw==", "dev": true, "dependencies": { "@babel/core": "~7.21.0", - "@babel/preset-env": "~7.20.2", + "@babel/preset-env": "~7.21.0", "@babel/types": "~7.21.2", - "@storybook/csf": "next", - "@storybook/csf-tools": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/csf": "^0.1.0", + "@storybook/csf-tools": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/types": "7.0.2", "cross-spawn": "^7.0.3", "globby": "^11.0.2", "jscodeshift": "^0.14.0", @@ -3970,16 +4013,16 @@ } }, "node_modules/@storybook/components": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.0-rc.3.tgz", - "integrity": "sha512-PeQFr2hZvLnxLswKihw1Ro5wCqmNZeSE4q+tFdifhLVIqP/OwHG+ShiLCHQ1aEa0Z3Ub+80m7uPzg69+y9m+bQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.2.tgz", + "integrity": "sha512-Ee9pY6WlpricPUdYiyR0Ov8zgHkUt541yl1CZ6Ytaom2TA12cAnRjKewbLAgVPPhIE1LsMRhOPFYql0JMtnN4Q==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/client-logger": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "memoizerific": "^1.11.3", "use-resize-observer": "^9.1.0", "util-deprecate": "^1.0.2" @@ -3994,13 +4037,13 @@ } }, "node_modules/@storybook/core-client": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.0-rc.3.tgz", - "integrity": "sha512-epUiHzFQNoEr5PYq9069SliQzHl5fVQj94aWdGZWCQPGldxiFtCNB7o32NzwwIVzXOKPzU38qg2B4738jt/1XQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.2.tgz", + "integrity": "sha512-tr6Uv41YD2O0xiUrtgujiY1QxuznhbyUI0BRsSh49e8cx3QoW7FgPy7IVZHgb17DXKZ/wY/hgdyTTB87H6IbLA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3" + "@storybook/client-logger": "7.0.2", + "@storybook/preview-api": "7.0.2" }, "funding": { "type": "opencollective", @@ -4008,18 +4051,18 @@ } }, "node_modules/@storybook/core-common": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.0-rc.3.tgz", - "integrity": "sha512-uUIs14+35ubRcpYwuX0OHW05tSDC5jeNEY8gv2EjcexBLeNozfGV4Tf5/ncG8glVbp8jGUlu2S3XJZoHKHDSqQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.2.tgz", + "integrity": "sha512-DayFPTCj695tnEKLuDlogclBim8mzdrbj9U1xzFm23BUReheGSGdLl2zrb3mP1l9Zj4xJ/Ctst1KN9SFbW84vw==", "dev": true, "dependencies": { - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/node-logger": "7.0.2", + "@storybook/types": "7.0.2", "@types/node": "^16.0.0", "@types/pretty-hrtime": "^1.0.0", "chalk": "^4.1.0", - "esbuild": "^0.16.4", - "esbuild-register": "^3.3.3", + "esbuild": "^0.17.0", + "esbuild-register": "^3.4.0", "file-system-cache": "^2.0.0", "find-up": "^5.0.0", "fs-extra": "^11.1.0", @@ -4031,7 +4074,6 @@ "pkg-dir": "^5.0.0", "pretty-hrtime": "^1.0.3", "resolve-from": "^5.0.0", - "slash": "^3.0.0", "ts-dedent": "^2.0.0" }, "funding": { @@ -4040,9 +4082,9 @@ } }, "node_modules/@storybook/core-common/node_modules/@types/node": { - "version": "16.18.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.16.tgz", - "integrity": "sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA==", + "version": "16.18.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.23.tgz", + "integrity": "sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g==", "dev": true }, "node_modules/@storybook/core-common/node_modules/ansi-styles": { @@ -4098,9 +4140,9 @@ } }, "node_modules/@storybook/core-events": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.0-rc.3.tgz", - "integrity": "sha512-EBihNmxxiIJbPt6OhCTXFPl2T/9OXNVKtsy8hchBNEzp+UJGyeHx+t9K6tRvbcmt5TG/y7C7ZsYx9U28JTwNkg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.2.tgz", + "integrity": "sha512-1DCHCwHRL3+rlvnVVc/BCfReP31XaT2WYgcLeGTmkX1E43Po1MkgcM7PnJPSaa9POvSqZ+6YLZv5Bs1SXbufow==", "dev": true, "funding": { "type": "opencollective", @@ -4108,25 +4150,25 @@ } }, "node_modules/@storybook/core-server": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.0-rc.3.tgz", - "integrity": "sha512-211514C7w8hvu/bLP97KdF7TM8FpcchgDAhldODDvKFyxFTHMcQFj3ABlptsWFO6JxZsy32hG8qi6phFUtceQA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.2.tgz", + "integrity": "sha512-7ipGws8YffVaiwkc+D0+MfZc/Sy52aKenG3nDJdK4Ajmp5LPAlelb/sxIhfRvoHDbDsy2FQNz++Mb55Yh03KkA==", "dev": true, "dependencies": { "@aw-web-design/x-default-browser": "1.4.88", "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", - "@storybook/csf-tools": "7.0.0-rc.3", - "@storybook/docs-mdx": "next", + "@storybook/builder-manager": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", + "@storybook/csf-tools": "7.0.2", + "@storybook/docs-mdx": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/telemetry": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/telemetry": "7.0.2", + "@storybook/types": "7.0.2", "@types/detect-port": "^1.3.0", "@types/node": "^16.0.0", "@types/node-fetch": "^2.5.7", @@ -4150,7 +4192,6 @@ "read-pkg-up": "^7.0.1", "semver": "^7.3.7", "serve-favicon": "^2.5.0", - "slash": "^3.0.0", "telejson": "^7.0.3", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2", @@ -4163,9 +4204,9 @@ } }, "node_modules/@storybook/core-server/node_modules/@types/node": { - "version": "16.18.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.16.tgz", - "integrity": "sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA==", + "version": "16.18.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.23.tgz", + "integrity": "sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g==", "dev": true }, "node_modules/@storybook/core-server/node_modules/ansi-styles": { @@ -4254,21 +4295,21 @@ "dev": true }, "node_modules/@storybook/csf": { - "version": "0.0.2-next.10", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2-next.10.tgz", - "integrity": "sha512-m2PFgBP/xRIF85VrDhvesn9ktaD2pN3VUjvMqkAL/cINp/3qXsCyI81uw7N5VEOkQAbWrY2FcydnvEPDEdE8fA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.0.tgz", + "integrity": "sha512-uk+jMXCZ8t38jSTHk2o5btI+aV2Ksbvl6DoOv3r6VaCM1KZqeuMwtwywIQdflkA8/6q/dKT8z8L+g8hC4GC3VQ==", "dev": true, "dependencies": { "type-fest": "^2.19.0" } }, "node_modules/@storybook/csf-plugin": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.0-rc.3.tgz", - "integrity": "sha512-+r2m09o/5B846Q8ykDWjwPJSZXc3i4Z6vLc04SxIR/VJffF7K0Z/vFmTcPz8Qg5wFdfvy/HFqTLpaOJtVwWBdA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.2.tgz", + "integrity": "sha512-aGuo+G6G5IwSGkmc+OUA796sOfvJMaQj8QS/Zh5F0nL4ZlQvghHpXON8cRHHvmXHQqUo07KLiy7CZh2I2oq4iQ==", "dev": true, "dependencies": { - "@storybook/csf-tools": "7.0.0-rc.3", + "@storybook/csf-tools": "7.0.2", "unplugin": "^0.10.2" }, "funding": { @@ -4277,17 +4318,17 @@ } }, "node_modules/@storybook/csf-tools": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.0-rc.3.tgz", - "integrity": "sha512-I3QG2buAswIYVbYlstmZAamwLopW6daHj2+wrod+whTmeKShp0rbOrVkU0M3Hpj9CVzFM1/4YqCNOBkS2XTnsw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.2.tgz", + "integrity": "sha512-sOp355yQSpYiMqNSopmFYWZkPPRJdGgy4tpxGGLxpOZMygK3j1wQ/WQtl2Z0h61KP0S0dl6hrs0pHQz3A/eVrw==", "dev": true, "dependencies": { "@babel/generator": "~7.21.1", "@babel/parser": "~7.21.2", "@babel/traverse": "~7.21.2", "@babel/types": "~7.21.2", - "@storybook/csf": "next", - "@storybook/types": "7.0.0-rc.3", + "@storybook/csf": "^0.1.0", + "@storybook/types": "7.0.2", "fs-extra": "^11.1.0", "recast": "^0.23.1", "ts-dedent": "^2.0.0" @@ -4298,21 +4339,21 @@ } }, "node_modules/@storybook/docs-mdx": { - "version": "0.0.1-next.6", - "resolved": "https://registry.npmjs.org/@storybook/docs-mdx/-/docs-mdx-0.0.1-next.6.tgz", - "integrity": "sha512-DjoSIXADmLJtdroXAjUotFiZlcZ2usWhqrS7aeOtZs0DVR0Ws5WQjnwtpDUXt8gryTSd+OZJ0cNsDcqg4JDEvQ==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@storybook/docs-mdx/-/docs-mdx-0.1.0.tgz", + "integrity": "sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg==", "dev": true }, "node_modules/@storybook/docs-tools": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.0-rc.3.tgz", - "integrity": "sha512-1uGIMq0+t8AUJyj0jkta7Imr3vFLkX8oRXhX5zi7znjWMhgeXKskEFujvCcz7eI1NIU9x2WvFwbtSzWDpdC/0g==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.2.tgz", + "integrity": "sha512-w4D5BURrYjLbLGG9VKAaKU2dSdukszxRE3HWkJyhQU9R1JHvS3n8ntcMqYPqRfoHCOeBLBxP0edDYcAfzGNDYQ==", "dev": true, "dependencies": { "@babel/core": "^7.12.10", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/core-common": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "@types/doctrine": "^0.0.3", "doctrine": "^3.0.0", "lodash": "^4.17.21" @@ -4329,9 +4370,9 @@ "dev": true }, "node_modules/@storybook/manager": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.0-rc.3.tgz", - "integrity": "sha512-8Q/vpHkvWQ/fZHRPFOgGC4Qhgpmafe9GV2QKk3yRA/p9zcW4UzP9fbL4qw6tq+5GLM/kFKArBu28ZA7L7sKB9A==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.2.tgz", + "integrity": "sha512-jsFsFKG0rPNYfuRm/WSXGMBy8vnALyFWU330ObDmfU0JID3SeLlVqAOZT1GlwI6vupYpWodsN6qPZKRmC8onRw==", "dev": true, "funding": { "type": "opencollective", @@ -4339,19 +4380,19 @@ } }, "node_modules/@storybook/manager-api": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.0-rc.3.tgz", - "integrity": "sha512-Pa+LabGYakPd9RuS8G7tCp3hPjZwGZL95Dj+yef0bM9WmYBimNjaUsqVJOGttuE4TLXjUIU9+58YImN7QrGfbQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.2.tgz", + "integrity": "sha512-PbLj9Rc5uCMPfMdaXv1wE3koA3+d0rmZ3BJI8jeq+mfZEvpvfI4OOpRioT1q04CkkVomFOVFTyO0Q/o6Rb5N7g==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/router": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/router": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", @@ -4403,15 +4444,15 @@ "dev": true }, "node_modules/@storybook/mdx2-csf": { - "version": "1.0.0-next.5", - "resolved": "https://registry.npmjs.org/@storybook/mdx2-csf/-/mdx2-csf-1.0.0-next.5.tgz", - "integrity": "sha512-02w0sgGZaK1agT050yCVhJ+o4rLHANWvLKWjQjeAsYbjneLC5ITt+3GDB4jRiWwJboZ8dHW1fGSK1Vg5fA34aQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@storybook/mdx2-csf/-/mdx2-csf-1.0.0.tgz", + "integrity": "sha512-dBAnEL4HfxxJmv7LdEYUoZlQbWj9APZNIbOaq0tgF8XkxiIbzqvgB0jhL/9UOrysSDbQWBiCRTu2wOVxedGfmw==", "dev": true }, "node_modules/@storybook/node-logger": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.0-rc.3.tgz", - "integrity": "sha512-ViWIJUdFUTrFtcoO88T3h55ryjl73aMNyn8vPvIgejJoJfYMTB5ErI4zLquN23HNc+H9AKKm/qMFFSf9xjGORQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.2.tgz", + "integrity": "sha512-UENpXxB1yDqP7JXaODJo+pbGt5y3NFBNurBr4+pI4bMAC4ARjpgRE4wp6fxUKFPu9MAR10oCdcLEHkaVUAjYRg==", "dev": true, "dependencies": { "@types/npmlog": "^4.1.2", @@ -4477,9 +4518,9 @@ } }, "node_modules/@storybook/postinstall": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.0-rc.3.tgz", - "integrity": "sha512-kOCJjixFwdnZxR6K45XR+6Q4UBzOLdabzh3aednQ/piiqj7ZdldaF75ZfoDhKPK4cjrd5AGU6/OWbsJQ+DLVMg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.2.tgz", + "integrity": "sha512-Hhiu3+N3ZDcbrhOCBJTDJbn/mC4l0v3ziyAP3yalq/2ZR9R5kfsEHHakKmswsKKV+ey0gNGijFTy3soU5oSs+A==", "dev": true, "funding": { "type": "opencollective", @@ -4487,9 +4528,9 @@ } }, "node_modules/@storybook/preview": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.0-rc.3.tgz", - "integrity": "sha512-7FeJjOV2pNVesdNljzy1DvzhhShZ/pjQOmhFs4GXBXTJCPNQP5iZTSR6b3ehN8L96yVPT5JsdjX4MiyGw2QPnQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.2.tgz", + "integrity": "sha512-U7MZkDT9bBq7HggLAXmTO9gI4eqhYs26fZS0L6iTE/PCX4Wg2TJBJSq2X8jhDXRqJFOt8SrQ756+V5Vtwrh4Og==", "dev": true, "funding": { "type": "opencollective", @@ -4497,24 +4538,23 @@ } }, "node_modules/@storybook/preview-api": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.0-rc.3.tgz", - "integrity": "sha512-iIifbFRmrFIlLzApTZyCWmI3JNt2IxfM8Dm4rNlMJBifjtgHfpxA+DsQI8mW8UGM64a8N1wF7azkN6cnRz6v2w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.2.tgz", + "integrity": "sha512-QAlJM/r92+dQe/kB7MTTR9b/1mt9UJjxNjazGdEWipA/nw23kOF3o/hBcvKwBYkit4zGYsX70H+vuzW8hCo/lA==", "dev": true, "dependencies": { - "@storybook/channel-postmessage": "7.0.0-rc.3", - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/channel-postmessage": "7.0.2", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/types": "7.0.0-rc.3", + "@storybook/types": "7.0.2", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", "qs": "^6.10.0", - "slash": "^3.0.0", "synchronous-promise": "^2.0.15", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" @@ -4525,9 +4565,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.0-rc.3.tgz", - "integrity": "sha512-3rQsOPwNlHyV93311GaGP28BFobEaNfw+djxDBxocNrL07xvY3u/XE6bShKOJ6R28ATaGwXUxmj2Cwtd2GxASg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.2.tgz", + "integrity": "sha512-fMl0aV7mJ3wyQKvt6z+rZuiIiSd9YinS77IJ1ETHqVZ4SxWriOS0GFKP6sZflrlpShoZBh+zl1lDPG7ZZdrQGw==", "dev": true, "funding": { "type": "opencollective", @@ -4539,12 +4579,12 @@ } }, "node_modules/@storybook/router": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.0-rc.3.tgz", - "integrity": "sha512-D3Uoz1WRFWH3QUjyrDObwCVRYXdSGZGpCN2eh6gjlKC9VQ9ohaGerEdXSsYnAj2lovhfze8oXp+PS1VKJTlpgg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.2.tgz", + "integrity": "sha512-ZB2vucfayZUrMLBlXju4v6CNOQQb0YKDLw5RoojdBxOsUFtnp5UiPOE+I8PQR63EBwnRjozeibV1XSM+GlQb5w==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", "memoizerific": "^1.11.3", "qs": "^6.10.0" }, @@ -4557,82 +4597,14 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@storybook/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", - "dev": true, - "dependencies": { - "core-js": "^3.6.5", - "find-up": "^4.1.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@storybook/semver/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/semver/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@storybook/semver/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@storybook/semver/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@storybook/telemetry": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.0-rc.3.tgz", - "integrity": "sha512-0vPVA1aTWCA6jr3iSOPCu8x3zpNUsyxYN30B4b6d3o2iO6YU/CZdm8rxzInv+bKkz2fHFDzCDsfZTgQ5VEggEw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.2.tgz", + "integrity": "sha512-s2PIwI9nVYQBf3h40EFHLynYUfdqzRJMXyaCWJdVQuvdQfRkAn3CLXaubK+VdjC869z3ZfW20EMu3Mbgzcc0HA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/core-common": "7.0.2", "chalk": "^4.1.0", "detect-package-manager": "^2.0.1", "fetch-retry": "^5.0.2", @@ -4699,13 +4671,13 @@ } }, "node_modules/@storybook/theming": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.0-rc.3.tgz", - "integrity": "sha512-sVt8Egv9CmeDnTJYPsyvlvHE+GX8hAczc1SvuoLeXs/1gsEsnVn6ovCFGSV0Rc7sAr5oSv794/pFUsboU8tYqg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.2.tgz", + "integrity": "sha512-c9sE+QAZNbopPvLiJ6BMxBERfTaq1ATyIri97FBvTucuSotNXw7X5q+ip5/nrCOPZuvK2f5wF4DRyD2HnB/rIQ==", "dev": true, "dependencies": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" }, @@ -4719,12 +4691,12 @@ } }, "node_modules/@storybook/types": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.0-rc.3.tgz", - "integrity": "sha512-2xxgs4zL1QZUdut+Zt5sQdgNCUP0n/y5CRbvEpDwkcuE4KWbfJYixJNumioZ6UwK17ZE9gf4ZxVgttvexmW8eg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.2.tgz", + "integrity": "sha512-0OCt/kAexa8MCcljxA+yZxGMn0n2U2Ync0KxotItqNbKBKVkaLQUls0+IXTWSCpC/QJvNZ049jxUHHanNi/96w==", "dev": true, "dependencies": { - "@storybook/channels": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "^2.0.0" @@ -4735,18 +4707,18 @@ } }, "node_modules/@storybook/web-components": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-7.0.0-rc.3.tgz", - "integrity": "sha512-enG/VoXu7i5r39Ao4qg6a4Q/aPX5LYkkFaj955BLkUJXW1ZANwjRqo6JSquC4tW8Dm1FYN8sJBAzO6M8YRlbnA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-7.0.2.tgz", + "integrity": "sha512-qJc5EsNZci0yBOCH9YKuUoSEHvvfetFUsUWpLQa2pzHa648z0Qb8Z1OS/hYCq7PyJN/knb+00Pd8z3zNSw9SgA==", "dev": true, "dependencies": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-client": "7.0.0-rc.3", - "@storybook/docs-tools": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/core-client": "7.0.2", + "@storybook/docs-tools": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "ts-dedent": "^2.0.0" }, "engines": { @@ -4761,15 +4733,15 @@ } }, "node_modules/@storybook/web-components-vite": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-7.0.0-rc.3.tgz", - "integrity": "sha512-A/+tm879pmD9UwWDJdYimwuIaSQPYyf2FSwL/+zIJ6ZS63LFimkIkt/C7hWD6pYNzk1w36VESfRhEeP3Hu4VNA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-7.0.2.tgz", + "integrity": "sha512-9c6wt+4yvOGN3d2FV3dBbtAeswjuIOS5InCQiMHLZEywjghg3SMre5yatKnO88eEk4XBJkamc6rHzSbETrc3sg==", "dev": true, "dependencies": { - "@storybook/builder-vite": "7.0.0-rc.3", - "@storybook/core-server": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/web-components": "7.0.0-rc.3", + "@storybook/builder-vite": "7.0.2", + "@storybook/core-server": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/web-components": "7.0.2", "magic-string": "^0.27.0" }, "engines": { @@ -4978,9 +4950,9 @@ "dev": true }, "node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", "dev": true }, "node_modules/@types/express": { @@ -5059,12 +5031,6 @@ "rxjs": "^7.2.0" } }, - "node_modules/@types/is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q==", - "dev": true - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -5269,13 +5235,10 @@ } }, "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true }, "node_modules/@types/scheduler": { "version": "0.16.2", @@ -5359,12 +5322,6 @@ "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==", "dev": true }, - "node_modules/@types/webpack-env": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.0.tgz", - "integrity": "sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==", - "dev": true - }, "node_modules/@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", @@ -5375,9 +5332,9 @@ } }, "node_modules/@types/yargs": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", - "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -5467,14 +5424,14 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz", - "integrity": "sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==", + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.57.0.tgz", + "integrity": "sha512-orrduvpWYkgLCyAdNtR1QIWovcNZlEm6yL8nwH/eTxWLd8gsP+25pdLHYzL2QdkqrieaDwLpytHqycncv0woUQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.54.0", - "@typescript-eslint/types": "5.54.0", - "@typescript-eslint/typescript-estree": "5.54.0", + "@typescript-eslint/scope-manager": "5.57.0", + "@typescript-eslint/types": "5.57.0", + "@typescript-eslint/typescript-estree": "5.57.0", "debug": "^4.3.4" }, "engines": { @@ -5493,6 +5450,113 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.57.0.tgz", + "integrity": "sha512-NANBNOQvllPlizl9LatX8+MHi7bx7WGIWYjPHDmQe5Si/0YEYfxSljJpoTyTWFTgRy3X8gLYSE4xQ2U+aCozSw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.57.0", + "@typescript-eslint/visitor-keys": "5.57.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/parser/node_modules/@typescript-eslint/types": { + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.57.0.tgz", + "integrity": "sha512-mxsod+aZRSyLT+jiqHw1KK6xrANm19/+VFALVFP5qa/aiJnlP38qpyaTd0fEKhWvQk6YeNZ5LGwI1pDpBRBhtQ==", + "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/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.0.tgz", + "integrity": "sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.57.0", + "@typescript-eslint/visitor-keys": "5.57.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/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.0.tgz", + "integrity": "sha512-ery2g3k0hv5BLiKpPuwYt9KBkAp2ugT6VvyShXdLOkax895EC55sP0Tx5L0fZaQueiK3fBLvHVvEl3jFS5ia+g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.57.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/parser/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser/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/parser/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/scope-manager": { "version": "5.54.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz", @@ -5687,839 +5751,780 @@ } }, "node_modules/@umbraco-ui/uui": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.2.0-rc.0.tgz", - "integrity": "sha512-t5NjWxXivl5Em2xusuudQ8asJtayrpw2Y6G5Ge4P2CdyFF4YD5C1hD54HzkisfuQJDTSogERVtcNMts9y7sHeQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.2.0-rc.2.tgz", + "integrity": "sha512-E8CrJYKLBcCnshV+nTVkfkL9I+0sJbBjKMHOVr/jCOj6Dw9mGytq0bmq8EIT0QcqZ6teZZplkwW2JPQauuv5JA==", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-avatar": "1.2.0-rc.0", - "@umbraco-ui/uui-avatar-group": "1.2.0-rc.0", - "@umbraco-ui/uui-badge": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.2.0-rc.0", - "@umbraco-ui/uui-box": "1.2.0-rc.0", - "@umbraco-ui/uui-breadcrumbs": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-button-group": "1.2.0-rc.0", - "@umbraco-ui/uui-button-inline-create": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0", - "@umbraco-ui/uui-card-content-node": "1.2.0-rc.0", - "@umbraco-ui/uui-card-media": "1.2.0-rc.0", - "@umbraco-ui/uui-card-user": "1.2.0-rc.0", - "@umbraco-ui/uui-caret": "1.2.0-rc.0", - "@umbraco-ui/uui-checkbox": "1.2.0-rc.0", - "@umbraco-ui/uui-color-area": "1.2.0-rc.0", - "@umbraco-ui/uui-color-picker": "1.2.0-rc.0", - "@umbraco-ui/uui-color-slider": "1.2.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.2.0-rc.0", - "@umbraco-ui/uui-color-swatches": "1.2.0-rc.0", - "@umbraco-ui/uui-combobox": "1.2.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0", - "@umbraco-ui/uui-dialog": "1.2.0-rc.0", - "@umbraco-ui/uui-dialog-layout": "1.2.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.0", - "@umbraco-ui/uui-file-preview": "1.2.0-rc.0", - "@umbraco-ui/uui-form": "1.2.0-rc.0", - "@umbraco-ui/uui-form-layout-item": "1.2.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0", - "@umbraco-ui/uui-input": "1.2.0-rc.0", - "@umbraco-ui/uui-input-file": "1.2.0-rc.0", - "@umbraco-ui/uui-input-lock": "1.2.0-rc.0", - "@umbraco-ui/uui-input-password": "1.2.0-rc.0", - "@umbraco-ui/uui-keyboard-shortcut": "1.2.0-rc.0", - "@umbraco-ui/uui-label": "1.2.0-rc.0", - "@umbraco-ui/uui-loader": "1.2.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-loader-circle": "1.2.0-rc.0", - "@umbraco-ui/uui-menu-item": "1.2.0-rc.0", - "@umbraco-ui/uui-pagination": "1.2.0-rc.0", - "@umbraco-ui/uui-popover": "1.2.0-rc.0", - "@umbraco-ui/uui-progress-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-radio": "1.2.0-rc.0", - "@umbraco-ui/uui-range-slider": "1.2.0-rc.0", - "@umbraco-ui/uui-ref": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-list": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-data-type": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-document-type": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-form": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-member": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-package": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-user": "1.2.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.2.0-rc.0", - "@umbraco-ui/uui-select": "1.2.0-rc.0", - "@umbraco-ui/uui-slider": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-lock": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-more": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-sort": "1.2.0-rc.0", - "@umbraco-ui/uui-table": "1.2.0-rc.0", - "@umbraco-ui/uui-tabs": "1.2.0-rc.0", - "@umbraco-ui/uui-tag": "1.2.0-rc.0", - "@umbraco-ui/uui-textarea": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification-container": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification-layout": "1.2.0-rc.0", - "@umbraco-ui/uui-toggle": "1.2.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-avatar": "1.2.0-rc.2", + "@umbraco-ui/uui-avatar-group": "1.2.0-rc.2", + "@umbraco-ui/uui-badge": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-boolean-input": "1.2.0-rc.2", + "@umbraco-ui/uui-box": "1.2.0-rc.2", + "@umbraco-ui/uui-breadcrumbs": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-button-group": "1.2.0-rc.2", + "@umbraco-ui/uui-button-inline-create": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2", + "@umbraco-ui/uui-card-content-node": "1.2.0-rc.2", + "@umbraco-ui/uui-card-media": "1.2.0-rc.2", + "@umbraco-ui/uui-card-user": "1.2.0-rc.2", + "@umbraco-ui/uui-caret": "1.2.0-rc.2", + "@umbraco-ui/uui-checkbox": "1.2.0-rc.2", + "@umbraco-ui/uui-color-area": "1.2.0-rc.2", + "@umbraco-ui/uui-color-picker": "1.2.0-rc.2", + "@umbraco-ui/uui-color-slider": "1.2.0-rc.2", + "@umbraco-ui/uui-color-swatch": "1.2.0-rc.2", + "@umbraco-ui/uui-color-swatches": "1.2.0-rc.2", + "@umbraco-ui/uui-combobox": "1.2.0-rc.2", + "@umbraco-ui/uui-combobox-list": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2", + "@umbraco-ui/uui-dialog": "1.2.0-rc.2", + "@umbraco-ui/uui-dialog-layout": "1.2.0-rc.2", + "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.2", + "@umbraco-ui/uui-file-preview": "1.2.0-rc.2", + "@umbraco-ui/uui-form": "1.2.0-rc.2", + "@umbraco-ui/uui-form-layout-item": "1.2.0-rc.2", + "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2", + "@umbraco-ui/uui-input": "1.2.0-rc.2", + "@umbraco-ui/uui-input-file": "1.2.0-rc.2", + "@umbraco-ui/uui-input-lock": "1.2.0-rc.2", + "@umbraco-ui/uui-input-password": "1.2.0-rc.2", + "@umbraco-ui/uui-keyboard-shortcut": "1.2.0-rc.2", + "@umbraco-ui/uui-label": "1.2.0-rc.2", + "@umbraco-ui/uui-loader": "1.2.0-rc.2", + "@umbraco-ui/uui-loader-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-loader-circle": "1.2.0-rc.2", + "@umbraco-ui/uui-menu-item": "1.2.0-rc.2", + "@umbraco-ui/uui-modal": "1.2.0-rc.2", + "@umbraco-ui/uui-pagination": "1.2.0-rc.2", + "@umbraco-ui/uui-popover": "1.2.0-rc.2", + "@umbraco-ui/uui-progress-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-radio": "1.2.0-rc.2", + "@umbraco-ui/uui-range-slider": "1.2.0-rc.2", + "@umbraco-ui/uui-ref": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-list": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-data-type": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-document-type": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-form": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-member": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-package": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-user": "1.2.0-rc.2", + "@umbraco-ui/uui-scroll-container": "1.2.0-rc.2", + "@umbraco-ui/uui-select": "1.2.0-rc.2", + "@umbraco-ui/uui-slider": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-lock": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-more": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-sort": "1.2.0-rc.2", + "@umbraco-ui/uui-table": "1.2.0-rc.2", + "@umbraco-ui/uui-tabs": "1.2.0-rc.2", + "@umbraco-ui/uui-tag": "1.2.0-rc.2", + "@umbraco-ui/uui-textarea": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification-container": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification-layout": "1.2.0-rc.2", + "@umbraco-ui/uui-toggle": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.2.0-rc.0.tgz", - "integrity": "sha512-CV40V9kMo5+fmTybbKc/ZKn6I/7xPWlkvPHifdu6WhwRsFeC4P8nPV6CKgxnrTIdrNbUjwK9Kn0UCs/UiKQ6FA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.2.0-rc.2.tgz", + "integrity": "sha512-JI9n1/gB6cr+7k0+v+HVAnfXCkZIN3UYbC8BhC+YinMsKIIWiLgo/FmgClgHmJ9zPD9EhAVqUa8wViM03npyDg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button-group": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button-group": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.2.0-rc.0.tgz", - "integrity": "sha512-xlz49sZAr5nVb4eX/eCssox8Wn/Qm4slIIZTahu2jKo1tL9s75iEQFjGGjVbNJV3EfEn5fXreHez2ADwA19d5A==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.2.0-rc.2.tgz", + "integrity": "sha512-WnVicYfGExAKA7gXHjVk4dcANRrWYnXLlAWiRS9SOVDFUYezbNbX82Nt2rMGxZ5K3TJr+WWxBa0b2AYhz/pWpw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.2.0-rc.0.tgz", - "integrity": "sha512-XQjl2YFGtg6vFVrlUoF/Ulbc9tmbFAbIQxSJWP/CxvQgOqFRldoeNZ9puiTOFykvCaKDc2MBkTwC2vUI/F2DCA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.2.0-rc.2.tgz", + "integrity": "sha512-bEtJzr4tC8oL4KszNxqu3ey1DPg9hZnaEND7p8RDXCknZLpi9flhpU73esvskiCRSJr5CTu0pTwJwOR+Bhwr9Q==", "dependencies": { - "@umbraco-ui/uui-avatar": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-avatar": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.2.0-rc.0.tgz", - "integrity": "sha512-QoW0puGm6yF7h77C9tq4zc8jZIDnmXsokthCVAcwks2i4BQV4SRfsEJZOQAphdNE+VOIPO5whZG5+D7smDHhCA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.2.0-rc.2.tgz", + "integrity": "sha512-Z/zxDmf5WbeXo+3CrB62TOHgg5cEcKNB4vc06NAllypzLBKdBPjRe3FtBtRL8ExwZmXoAlJmlItr6nEnfogKUQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.2.0-rc.0.tgz", - "integrity": "sha512-q/QU6MRoU/d6pepobqNjEEUu8fcUfQ2RjT4wWQA/z1CFtXF1xIQGGHemdmkb/V+RqUma8CimDscklxxR7yARRg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.2.0-rc.2.tgz", + "integrity": "sha512-rGHM+OgldohqNlq5B1BMcpVkZNMu8A0X5uN6cG74qGg+WXqXbX9XlRFxMMuoxCTgtqowGZMn7St+Tu3O8GQAiA==", "dependencies": { "lit": "^2.3.1" } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.2.0-rc.0.tgz", - "integrity": "sha512-Jno5TPnwJbOi7yvSigCBmMEqK1fY2XdKUMFpB2ZXVi4T8o69cq5m+bcboARshf1NdPmkWqQMDNroMqG73gFhiA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.2.0-rc.2.tgz", + "integrity": "sha512-W3qKtrH1c+nPe0yuz8sySf6hF7rOK9Hg3I2HZ5jRmoKnDmTLiZpXhDDyaYKy1oH5n/WdRlJx9aBaZG5TMmRqpg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.2.0-rc.0.tgz", - "integrity": "sha512-+JYJ6lwoLq7MsD51acS7ZOFrVwUiWRWywL90rGtPYXHDTkw5D/MdeFgbQjBU+vcIEEZWR5iwNX0uTpA7hO3xKw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.2.0-rc.2.tgz", + "integrity": "sha512-c3rqT0KdCnBqWv8Lbzpetj/MldQSTQ7/7uxTtHcS+Wclkvr+ktKeai45NebiKqDCb6l3scy2Va0TRoJBUNmofA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.2.0-rc.0.tgz", - "integrity": "sha512-SyjimBB0E7fpIepBxcVOIJSYvg8Yjgtel8fA7VG/sPVmP4YSZeGoRB2G/eHAvH/VG9L7/ENOUIzEYCFYXbHJsw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.2.0-rc.2.tgz", + "integrity": "sha512-xX93r/n6dKY1D0wWRx2FKDVtJ2Yja91KPheHExSPuBuwUI0C0hBI02U+AhWjr/6+hUl+Kc0CWOdoYNkuum3RZg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.2.0-rc.0.tgz", - "integrity": "sha512-VnA+1FoUpg5tMrGfpLnFCMLtDPM+ACAu1+XQcuo6o99XUYdSf+Z5lf/P4NBCDfdqdKXBSDut/Npu7DYJsYIFHA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.2.0-rc.2.tgz", + "integrity": "sha512-IVtsxvRPT8on8vomxCWWRwhJbDl8dDmeUxSFxOPm/LrDZ8Y3sVf5Z248mBVCvX87E9AsBYkd7WX4KRDf3vubFQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.2.0-rc.0.tgz", - "integrity": "sha512-ROxoZPTVDkJKhX9wcmZGOqdtWiVs13QpL/2habQTzkS2JeaTTiLhIf/KPeZpZ0JPSbJnh0yj5nCL13Ov2rS96g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.2.0-rc.2.tgz", + "integrity": "sha512-sNxAiZGCbjKE95hiCroBb5DBIiIncpojpS0ARWFHXQAbjPi99qP72cE/+D/LF61NZwDKyyP+GKrzOmzgI4BQMw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.2.0-rc.0.tgz", - "integrity": "sha512-A/FO9mRXFku+Qjg2uDNbDNRamKpP99kckwRy3hH8hzl6MpynzD+Cr7VS/bL0lmBa/G55XVrNi0BeuGbunEGvpA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.2.0-rc.2.tgz", + "integrity": "sha512-lNIFbBuiv113JyS8igqV7VhVppObRa34gpsflcmkCaCN2Khm6XVVsG4h226RNrhnQgjJ0J+r+/QTdaIUKLYX+w==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.2.0-rc.0.tgz", - "integrity": "sha512-ZnQSb8k9N6wSeD++8pL2R7jo01FW3bKQ6SzAAlq4MFppYaylgW6BcnhIcSxiXciWRgNsb+4BJhc/0gxbJh25+g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.2.0-rc.2.tgz", + "integrity": "sha512-7hlGuunANegwsC6R4N+ILxNMHwXzB6tJzO/enMnrAQA7SkuLDEJB1rHy2TOhUOjEP1hQREM+rc+srX1wT8ZkCw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.2.0-rc.0.tgz", - "integrity": "sha512-xgS1hK8OYimUhKP//DpKt2W054ciW+1DiEV0Qr1zWRDgAN3F85IwNiLVs6JPeBjY1yM4mOvC29POG35jc/yBmg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.2.0-rc.2.tgz", + "integrity": "sha512-RA4VK+XoJQpQmc3sfkw/ZnrMGCn1HDiFowanwrR8SEYOPiMbmGUhRMnnmsa8WSOlNJ4KLpgN8vyaa7cvu93ZuA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.2.0-rc.0.tgz", - "integrity": "sha512-8fH3IrLtPV9rE/dkEID5rMoTIPEg4E/9VoYHms59zNTdtyQKG8dM0vLSKTbz72zaYH+Ox5VHp4X/CVIXFDH2rw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.2.0-rc.2.tgz", + "integrity": "sha512-VDMbhevtLu0ucbhqVf17rKUrRfiNyyzttBFHX7NDUfeXGoqjTb98z6aproP5ujvqsWhECa5Q2iemTbxqVr/b7A==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.2.0-rc.0.tgz", - "integrity": "sha512-B0QmgKXWt5yU0/misn3sY8PsAjOfNzOCJ/LkC9cI2zGX/tQNbfziOFwk6bAQluQP2zJnAoab1leSghP+1PcTEA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.2.0-rc.2.tgz", + "integrity": "sha512-SVh2Rf1b/PL3WamMlSoLtm4bFLj9Ms33wS+94FVoEKikH/b/5OSHJyMnW4h6K/c2yyaMT7/y+tQhoc9oGcq5WQ==", "dependencies": { - "@umbraco-ui/uui-avatar": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0" + "@umbraco-ui/uui-avatar": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.2.0-rc.0.tgz", - "integrity": "sha512-V4nKfTYEqJvxG/jbwwPCzZuSK4qKra4aqWrtU6B6QMcYohYJVTaEvVE4No46AtbtrSfvKm050pMzb9sRxiMLcw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.2.0-rc.2.tgz", + "integrity": "sha512-/19J8MpMLkWT5u4QdGGmf7xqCZ0URB0YUq48rsn5y/efElWi1HG0ptJwGoqrW5hhKuLWEcZG4V1WVJxT4LgwZQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.2.0-rc.0.tgz", - "integrity": "sha512-7smHPIBmniccCuaA3JaFCLia5uyClFElv3WBngX2qbz6JwKXQ9nemYaFOuM4KjcukMH9iFMQQy7sbrmRar0reg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.2.0-rc.2.tgz", + "integrity": "sha512-shjQWdFjjRnbXGaZa6BkSxC2Q1jfSh5q6xVjkDrcGToOW94q6PURF6Vm1aodsBVWZGuJUzmTdT41mhG/SjsIPg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-boolean-input": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.2.0-rc.0.tgz", - "integrity": "sha512-cUJdrcNEkXNAwjeQEV0Vi/Hj4xaj7rFOMm/U9Q9JlRUX05xkBRl01AjS6Qi0QDKEPtLG9YC+AnNXpFFA1rjtaw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.2.0-rc.2.tgz", + "integrity": "sha512-LwdmkwFu+3Ms9xm86sZovTItlWlHgVfHPOMnW+nxUkVMfwv1FjK4n4G7xVJ9nmpa8W4GjMwcENjvR0Qs2/JqqQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", + "@umbraco-ui/uui-base": "1.2.0-rc.2", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.2.0-rc.0.tgz", - "integrity": "sha512-rpMBG+ZyrL10w7EX/UqtWZHhwZ3oe7MSf8cQqimK/Arn1kpBqZ4JJLpJPcZ1bwcYekHbT5LbHZBD/EuHMRP1bA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.2.0-rc.2.tgz", + "integrity": "sha512-Ibn3dRJn/N8E9mRi2EWEFxyL4BwEbraytGNq7jD+iJZ9cIaZTU/zuxYGxNFNBP3EDsdD10iLnyBA9hfyEDxRcQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", + "@umbraco-ui/uui-base": "1.2.0-rc.2", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.2.0-rc.0.tgz", - "integrity": "sha512-04qZnUlVJmk7dN+r8BJNeZHvmu5/TqIq7WVlmHmfmbULW4hJkw18qBamfhOP7nFz06b21pfLFjBy61dqqH1tUg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.2.0-rc.2.tgz", + "integrity": "sha512-aQTTizgH0oNHBFRXXr3tjhH456SRx7TVx797elcA9b0NtSFMuFwWZZI4qqppHTaVkVGZz/0coF973Xu8s5GSGg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.2.0-rc.0.tgz", - "integrity": "sha512-acTb4xOwSMU3j1xa0IRpykdw7y9wQZoNWBPA/wWilCYJcxnJ9BeDU7QZaLrkGYOhq8vfBjtxO6+DZ4gBd5/4CA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.2.0-rc.2.tgz", + "integrity": "sha512-A7G0kz/ZEOANizHNek6nsq41XrCbCBE5XTE5Y0afUEbL3RM37yZHsjNFM4H1iJs57plt4Mfb85TQqb3h5HnHJA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.2.0-rc.0.tgz", - "integrity": "sha512-mJIi+PYeQP9naFZ9CBWyKIT5C10kzavQXkfA5dp1WBwyoTbmJzDaXXkz0vf1IcYSKBjJ3y67PmVRdaR30J8GZA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.2.0-rc.2.tgz", + "integrity": "sha512-FskzxqYXCfi3gV0BOfoo5acDJEpiHF2ZIcjYxgrPNtG2phjVZ1Mk1BinfKRRibXqKGU/uhAQxbNIygxW/C9bJA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-color-swatch": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.2.0-rc.0.tgz", - "integrity": "sha512-TnijClKq4NK7tGY0VaG3bZaTz8FYoLFezl1eXKIHYpx/hiidbu+a22Kcyio5TAW7VNFGFjJ3h3JQt06pBRBphA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.2.0-rc.2.tgz", + "integrity": "sha512-8BctuzQ1hoiAkhV4XU6sOICoKWn4EMIesWiQavl44IILuldrJhBc9PJlSkBeaOs8raOXCwWb7yhDf0w68rlY/w==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-combobox-list": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-scroll-container": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.2.0-rc.0.tgz", - "integrity": "sha512-K3CcgBPXiUnV/1sZvwKtxdgmIjjYWBNDtJ8Bc2jpqcyN2C0rcFLBwJwTXzBtIxakPXj9G6vP/OyXRUnN4I+lsA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.2.0-rc.2.tgz", + "integrity": "sha512-hOnfyje4XzhPWgDlbfOlaJOIUlMvc0RmwpKmqFynZMo0wZ+zuPMQ34jjPRAkgDa7dHkkAmbhZczLHdPF6I9aFA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.2.0-rc.0.tgz", - "integrity": "sha512-eE093LnIKdr1RKggmcsVI2G7Tyr+I0lV7XH4Kuq3cPmDaOC1C1UBvRPVdVhdEtQ2LA67SAsTvXWpyEuYKZO6OQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.2.0-rc.2.tgz", + "integrity": "sha512-yEHxeUFqRPhxHblR/jjkNLabMFZXZ3aMGVGgehBvsGM01D3yQq9wvFe+qtjr4TGXs7v62DIT4bOtP0f45KfRRg==", "dependencies": { "lit": "^2.2.2" } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.2.0-rc.0.tgz", - "integrity": "sha512-j/ZrWFJPXBXvt0IrxEB6DoUOejsDClJWlfpH8bft8bjF4bw0uDWDFXW+wlE9aSYagALYXJIJmKzyzfxPJsjyFA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.2.0-rc.2.tgz", + "integrity": "sha512-Jw0YfP4WJMaSsdvUGPjOQtFUiAlno2knxt709V2IugdbnfjgSYllBzQGNHWmbBFS1kJtURAcCWJX74B9P/qRfQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.2.0-rc.0.tgz", - "integrity": "sha512-ZpLOucZTNEsm9cuLxWOzN437iI0zxVdArYBaPQ8G7Mkn3AxvOoqiETHq+rnNJRIsOIh0CfMuD5XWX6hPt2w+Ug==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.2.0-rc.2.tgz", + "integrity": "sha512-gqFpO38XtYXQszCwUqt2jUqFHgcIIqf8+evlcGTXr1arFPpLfq2FWbEnXR83BjVRhHRCHhmLrbsoAZzwaJmToQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.2.0-rc.0.tgz", - "integrity": "sha512-1dkcZ6AHsLABFDhCWwNdyu5oMrNnV25cmbUsesBSyM3zedDtYKD2MZLJ+QEBXaHBtiDxO+G8mAL6Jof952gheg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.2.0-rc.2.tgz", + "integrity": "sha512-Pm07+UkQmp+SXuvynjlKlc+/NOHBVve3k6hoPX5Z0mHWUG0XBG0WgbrTJoqgQYytbndt6AaE6vrKKyPE/VvoHw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.2.0-rc.0.tgz", - "integrity": "sha512-fqbMD+uwxvV+uFrj5akmIkq1ngASKkZunt7wgq4wFeFksAi9QCMdfvdAE0aqhy9RbzdQHfLmaxOOrL8aLh3zwA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.2.0-rc.2.tgz", + "integrity": "sha512-eG+BtfA+22KmY+UoMBp8iJDTWUoy2Iq0jLahWmHADaQ+HWUMJ/CXYFquNVfk2nQ5SmYrJV+qPC0d+ikf4UXVmQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.2.0-rc.0.tgz", - "integrity": "sha512-kAR51/hAxg8rbLgam9/te3kq7aa9+HTQ2YRRyrdy2pJVVHMDIl2lKvzVf05ya7nTapW5+SMoUqWV5WjZg3lhjA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.2.0-rc.2.tgz", + "integrity": "sha512-9iCKrLzmjpUaaL7l3C50UL3iJOYxqEY3aFLx9hRbpFzyQvwMmt/hcKiUeSEVjEtAIxpk5wUTwD7WlxeRve0POA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.2.0-rc.0.tgz", - "integrity": "sha512-fbY2B2QJtmnd+GdLwEac9+egrIADeCJiGiYgl1ohcp0TYTuQakT6yhNSdkVsBpJ4dtH1+xFbsW2j8a5oRHozoQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.2.0-rc.2.tgz", + "integrity": "sha512-jFmw83oA/ecFOItGc27oHUHa2c6gA0gpzS2qsyYs7pSYEqwUxxe5iWI4otl3Ioi/3GgJwp69qzmVaEYuBgy/Sw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.2.0-rc.0.tgz", - "integrity": "sha512-gSEqpaHVWYGs3SxpflRTxO328ITRxmRWsDj8nWXCFGKtUK7xNKdhr85P4DWxW76u4UdcCk+lReoUxmVRelMm1Q==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.2.0-rc.2.tgz", + "integrity": "sha512-rbdJIO9uvSclc+8lRNcOv3ePp9Aa7wW7pZ6S8aY1bkV03vTAp7syKILNF70NIzxSq1yOKBE8xFXspHxDftdEVw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.2.0-rc.0.tgz", - "integrity": "sha512-U98JO00fXes3Ifjq144dDKKh9ASEJ8UkBgb9aDRlVEIuku6VfhUbENLH8r3zSpgFh3lV0ObXLJMnbIQrW+tRaA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.2.0-rc.2.tgz", + "integrity": "sha512-DKKco6oTG0XpwcYhLscRo22tF1R3Y/kQHn2tDi1T8IBez/AdknQPveYOGoUVC2jENngeNahuXNpWwgNvTpn4Zg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.2.0-rc.0.tgz", - "integrity": "sha512-CQTPh/2YE6Zxa4yJMNHPDBUOibmzkNKuyavwMwQ3oFB6pOJU5agBFasS3QOaw8p6Pv9i7wwKQC7keE14fJK26g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.2.0-rc.2.tgz", + "integrity": "sha512-Tt9RiNBCsbsZo2uh1saw0V8Z0pIXOAvRr9UgBOdn0GJIYbKDtHV1yALyqcQ//qenwkkPB5a5ly0a3tJHzeej0w==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.2.0-rc.0.tgz", - "integrity": "sha512-zSILXAwVAvb52vlFgfIkqnaPm7So9s0MaPrjKjgluC2Ii7CZIyNwr9fjaboSrPngsjoGT2C4gUYYoJjp6vw5ew==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.2.0-rc.2.tgz", + "integrity": "sha512-K93QxSybUhz7Q/UWZVqib2LGxlIQkTGF0fq7yDbGAYnx1OGJ7fKR0BjWok0G5Xz+7bCmjfNqTcb364XECUKpjw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.2.0-rc.0.tgz", - "integrity": "sha512-e8CabJJMrD+D8wBXKDgHQ8T7SQ7Rf7iLPzL55duLUrO80PATiMxqppyIh567bW9s5soDX7DhQNBX+UIa57chsQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.2.0-rc.2.tgz", + "integrity": "sha512-+Spx/J0ofNL9Rozy05LdKBxDh8It32JzRjt3LCOuBPrN6Tme5HwCmcWtBK2Cn2HQ1zQJgnD+h1KItSyyYPXsnw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.2.0-rc.0.tgz", - "integrity": "sha512-kkVSCqv61AZEHd0b4p0vmoEYosDjLl/YG3a2FEuXjBn+F6lETW+RriuhKY3a0pyRA+gTI9GRR86icpSC0KpHfQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.2.0-rc.2.tgz", + "integrity": "sha512-zoFda6gYT1OSJDd9ObTzx4+xEL5/rBrzAZBniWJUQqrPPi3NfYrT+q4hY9c262F/HPbiyWYIH7xxMmr18EfNfw==", "dependencies": { - "@umbraco-ui/uui-action-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.2.0-rc.0.tgz", - "integrity": "sha512-k1azXchNXcFy0QgsIm5ecJWo5Yh95vPRfwTohiDUUg4kla+yHIVHcpkNosqhYD4FKm8cAv4cdQr7o2eI+ExL6A==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.2.0-rc.2.tgz", + "integrity": "sha512-jhWEm+qeJs4PZLEGNUs9DSTs3VAKe6IS70+i9fQQY0VQQgyDzMtAqf9A+93D6EgT6pLu7HdtfS1yZVIzAteEsg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-input": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-input": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.2.0-rc.0.tgz", - "integrity": "sha512-IWsAJCRUZFVdpUDnup60i7MS2A4DePU1YIp460veAbwIZZjZBG4x9mmD6EvjFkP5YDaqCwyg3k75p3hC9RiQzw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.2.0-rc.2.tgz", + "integrity": "sha512-MafMMXrAof7YUKQy+hwKfwOADwRQV7xKkDjagyobVsBp2ccCRndZKTOAyBBDTqu+7w/k0SbHd9BvC4xCvVUwrA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0", - "@umbraco-ui/uui-input": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2", + "@umbraco-ui/uui-input": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.2.0-rc.0.tgz", - "integrity": "sha512-y5uKat6H7G752q2svp6iFi0UlnlpZuj+qlUVp7GJjLJ2tYWS7M13KnNXrhOOZW5kusXJsXSw/+g3YE30f3rydg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.2.0-rc.2.tgz", + "integrity": "sha512-iMvqmDNwU9R0w3D4xRb9nNdoYOiXQJfE+6ojwld84XhfyfMYGIwmiIlCnIzW6g8yFPIDOkF91B+wKgyk5xBlqQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.2.0-rc.0.tgz", - "integrity": "sha512-aG/oSvVx4U36mW2XK/HF+sEj42WM/PTO4a/sDYA62gDhok1Ksl+Mk6tdTDzBh3sdGYoZDemtOcWvjd87pPgimA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.2.0-rc.2.tgz", + "integrity": "sha512-eYY9e7cPGdwkw3JvM54fPpjn28bkKi3IVkfgDgvVP71vbuoBGCOk4rMP/H2XLElwKFTEM6EDRsXqrth02Ws0SA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.2.0-rc.0.tgz", - "integrity": "sha512-hfI3wZQxrAbsq+sNca6yfZ41vUOPIlg1clZNCSh76XD5YwTgFtHDse1HBrib7NY4kkOxHhRCFW4RO7BgWJcbtA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.2.0-rc.2.tgz", + "integrity": "sha512-Vms+NrPH15BhhawaCIdTzC9vY/2oMwu4/3AdEzHznELx3OfZbrt57a+Cpaoq6ojJoynJdGHQ+Kl92cKcv2kk3A==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.2.0-rc.0.tgz", - "integrity": "sha512-DA1Tbvnri0HWbbzSe5v4wVezdHang8cmAfActLawF6LG9CV6LZLxSMMsSzbDBisGS8cscc0RgAeSLXnlNaLN8w==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.2.0-rc.2.tgz", + "integrity": "sha512-dGXjMdWzndnWdbh6bNaeR3rP36Oi91l82Hx5mlByAKYVBG/q0J1nDn4gZhfczEx0ItaCq9uB8dfa3WolZKaMTw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.2.0-rc.0.tgz", - "integrity": "sha512-GrRVkZrLSk1Pjmo0JtbGNUfYCVZ4ZWIGo78GDPRPOdccuTVNLS1HwdKfNV+ZRJe0hJYt1ALglSprujuG67ORcA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.2.0-rc.2.tgz", + "integrity": "sha512-Djp2Vikv8t7y4yw7hrAveyRe5ASN2ooRCKrN49F2Tn8fKhi5NfZ0NRKMtIU+QZNzLMRA1mjrnxB2mqcD/xGsug==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.2.0-rc.0.tgz", - "integrity": "sha512-XGytEGLb1tTnEP6eB6K/RJXYzGhhgfwrm7/OKuMvIANc2OI0toYpDSOeRclm7W4tQwZCM9OadnGXZYkzJGcj5Q==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.2.0-rc.2.tgz", + "integrity": "sha512-i2YRq6DtxhjjpvhdbG6AVSWGMfY1sxBtylMwyWPMWCY/l0ozQrS8wiE34CEopvQszfnxKABb9nZYM6de3ybbZA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-loader-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "0.0.0", - "resolved": "file:umbraco-ui-uui-modal-0.0.0.tgz", - "integrity": "sha512-BYfbO5UocZrtj8t1Baox3ivldbNyoKugZGvwKXl0XZ7FZVGvAMrVmzZSI6KtEvYl9Jey/I8VqkZh30QBflEM0Q==", - "license": "MIT", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.2.0-rc.2.tgz", + "integrity": "sha512-mWGhjqb4xk4QJsflXByYy9wvKtUdSVyIQv4064zGSBWH9VgUkSmz3hHrBpjQU2MjCpj6XW96aeEIkg7mY9J0VA==", "dependencies": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - } - }, - "node_modules/@umbraco-ui/uui-modal-container": { - "version": "0.0.0", - "resolved": "file:umbraco-ui-uui-modal-container-0.0.0.tgz", - "integrity": "sha512-nsw2fkpOnG7pU+TqDZqXF57eNw2a4zIyN1TllVNEU4tdPrF5c4vTyIzE5O6Flsu8euCVruDZepo9SyLTm6jnew==", - "license": "MIT", - "dependencies": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - } - }, - "node_modules/@umbraco-ui/uui-modal-container/node_modules/@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "dependencies": { - "lit": "^2.2.2" - } - }, - "node_modules/@umbraco-ui/uui-modal-dialog": { - "version": "0.0.0", - "resolved": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", - "integrity": "sha512-hv3LQ/kzTZQMMXDt8NM5ZJTIsEYof5zKx9VFxbUGnhJhNRLeJ4bk9suWVl8h942VsOJwR+NbXzOs4XTIqXb9MA==", - "license": "MIT", - "dependencies": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - } - }, - "node_modules/@umbraco-ui/uui-modal-dialog/node_modules/@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "dependencies": { - "lit": "^2.2.2" - } - }, - "node_modules/@umbraco-ui/uui-modal-sidebar": { - "version": "0.0.0", - "resolved": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz", - "integrity": "sha512-qQTO/YD3wzACmHf6QVW5c2smWMPougDwyKLV6Zku+QdgeZleS1ZiR/AvqHVHiRjuQ84ZhKyBl4H1IcYnAMntnw==", - "license": "MIT", - "dependencies": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - } - }, - "node_modules/@umbraco-ui/uui-modal-sidebar/node_modules/@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "dependencies": { - "lit": "^2.2.2" - } - }, - "node_modules/@umbraco-ui/uui-modal/node_modules/@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "dependencies": { - "lit": "^2.2.2" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.2.0-rc.0.tgz", - "integrity": "sha512-ut26Z5NPaQVs4u45TcdgaCaj2Qt5jNtCgyHpgMhqfbs28lAwwuvodvLClQ1TiTv+TzE+Kzq6YyC57tQJVkRrDQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.2.0-rc.2.tgz", + "integrity": "sha512-tk5aS8NyugAPl7Dh8g8Igakup2k4eNT5clGvJacRRHIPBOn0p1gV6vKL3NDiVCmHHGLtgZMVnQQN7uSfm/Xj5w==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-button-group": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-button-group": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.2.0-rc.0.tgz", - "integrity": "sha512-AVkXJsP9IuL6rGXzTvUNqvDEA80vhMOGBGLVzwumfNzV0kIjyEWtAXQWIllssUUI5pDUY1FY7hk7RIiB5QmczA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.2.0-rc.2.tgz", + "integrity": "sha512-ecxT66ZrU/xTRs0vrpPIfr7YpykVtSEh/vwwo9DSkhaaIotPorMrRXi7LixS2mllslHvsETis6STCzsBylqB3w==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.2.0-rc.0.tgz", - "integrity": "sha512-RjmEpCc3moZynCDOAM5eGKi/7y2pXPGB2ohvcjCSZVDFxX3QZAyRB5PIAAT/pNo0aPii8HxTTE3b4qJFurNxGA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.2.0-rc.2.tgz", + "integrity": "sha512-KaffpsaFfj/7w2gGziMoYLvcQLCaDFhhCvbOYZE2DyyagIcJMr59LQYbX0ma7cTtUKSaJTk4RB1SWzIEuDu9Mg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.2.0-rc.0.tgz", - "integrity": "sha512-I2j/bOLSHSqXnJx/Fh9Jfabao+a5Xx6BYRgkJCxRCfHl0FTncufmSwDFs5WjrR45eKFUuU9gOWtbddFQjCdBMg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.2.0-rc.2.tgz", + "integrity": "sha512-jfGK/wzXue9s/E026k9ZBThCodrzRbpw/xS8xX9YHq3NvJNjfPTMABuTM2VpW4sPZtkdpkjZKNreJAfpYJoPrA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.2.0-rc.0.tgz", - "integrity": "sha512-EhdQAu6POZL5a8IOjBcMraCcufa1JYesVuZ2VZwGaOojfcVGjH0rIuqngpq/Oe5GAJUMOgzqCKmYyFhFCfmLpA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.2.0-rc.2.tgz", + "integrity": "sha512-5K//peXBIAsOh9uAcY/8U+qoRxTaHGwfYl5SYjD/NnfpHXPY8xxXtMDHZcPXnSZLyVsoL2DSroFXgTLSJLsYlg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.2.0-rc.0.tgz", - "integrity": "sha512-rrpWYRjjbx+ge7baO+tRcn+Qa1nwecQ/Sl4d/0rgo3xP+pKAnT0rozt6htfc60a/9Mnbz7mbj0NGSzMOJZRtJA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.2.0-rc.2.tgz", + "integrity": "sha512-Qdat4AxQt8neF1sIWvWDGoWkTDa3BHOhc8JUw7QxmcPwvv11Hvg62tAfRN7zbiVcTmpYIPoy6GV+tgAUn7TAIQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.2.0-rc.0.tgz", - "integrity": "sha512-8h+GG1kGc3LM5ojCZxsHRjHuvopuc5ZYXtg/Upgm7G5ct32JbVnUNM8b6hjH7NHSskDTLoslO1+wnalHcPc/Bw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.2.0-rc.2.tgz", + "integrity": "sha512-t0iriFiVPLepRgB4JbCu8YNKBycHHusev3SBGtAV1NJ6uBKVcNgoKk2UCcmy4H9nq+pMAafXm/HX/Oq5F4JfZA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.2.0-rc.0.tgz", - "integrity": "sha512-v9UpY1ADCAGPaFzRBLU2OTmczBNYAUN9Y6OVG5QCHUfGIvo6lwbYWJITN1tVAiofJemaTftJI9j9wy77kDTvDw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.2.0-rc.2.tgz", + "integrity": "sha512-Ji90frchpuqcl/wro/Np4hRhQLa15pvb078UA+zOSpBLHO03Py/Bs6l3BzFYskfOntC3EFSHm6HxFntPjAKFzw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-ref": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-ref": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.2.0-rc.0.tgz", - "integrity": "sha512-TvKxerjA3vsyuLu9peVnhnOAPKzeQPsZupSKixMqm2x2oX6S1QoCPNpSbIYi6mEcDnjFMi62VFYojinbngQ3CA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.2.0-rc.2.tgz", + "integrity": "sha512-aNV5GORnxkPvu0HWKfc7xzRDGYKMzeAXPLjYpcArKKFDfI95GTTNMvR9P0M/8IBJWiGb8oXCjMe1+YsVUCBSfw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.2.0-rc.0.tgz", - "integrity": "sha512-ALhCascGg+7Gl7IDih/K2ZirWhKG9pyfH3q/m4nfmNVjutLqTT1vOkvj/9DUjJw1hPdWFdn5jFYiPr1XpfUHHw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.2.0-rc.2.tgz", + "integrity": "sha512-WC3aCJjVhDNFF0aSvMf/wZkRzQMmAvkRQzcresG0J20xzGyNh8HiDVTFp24luT7l8vYqAeAl9NlLYbCWZAEyvA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.2.0-rc.0.tgz", - "integrity": "sha512-tls/sJMu1MXg9vS16fpAXSKuntqKO6vkiI4oQHH1w5OV+QaS8+8nAsiWD3ogDN2P7JyOlfCMnqhj31E2EFqGPg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.2.0-rc.2.tgz", + "integrity": "sha512-UxK8tKD9pYuMU6rYfBcT3zyf/NM6LtnXCN/p9/3CWDhAeHJ4gdf6fFoPzgehZlxHl22BUQ0+bjZ2VF5/4KKtbQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.2.0-rc.0.tgz", - "integrity": "sha512-Z+2/Q29kJbio7hSNntRTuiw7AXL7/6Y79rmEaDtQdz51f+hkaO35f/fQTLTf5VDuWTzgG1p6jcDpdlRMq1dQhw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.2.0-rc.2.tgz", + "integrity": "sha512-I9RZAg0AZKLSlmJBu7iL9OHoNg5f+FLdDWv8cO060LRXGftjNdnjaLwlQFL5uxXvXwDI3E4i94XFThiju41fWw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.2.0-rc.0.tgz", - "integrity": "sha512-SBQgrbvEP7dXkoZ1b1t3q0EmWmaOXtWNmd6oH8aMtA/SL43Uwjgmhv9gbxzeP8fMjK4zGCu9D0CLSmFO+1s5sg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.2.0-rc.2.tgz", + "integrity": "sha512-2tNl9S+J17uRSy6eSFJJ47b/zUuemm3UALaBII1+c5rWmUvtvs9ZYljX77VAkuwELKEMgExWjGQKaLQBTbvFMQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.2.0-rc.0.tgz", - "integrity": "sha512-myEYc6NkT8y/L8n1ndeRLGN584A+r0PPxbQCaMWmVAbcAq+Eb58W3ExnZM5toHJNUWjq7o2bIeX40eckYjkE3g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.2.0-rc.2.tgz", + "integrity": "sha512-sTrz9xhHrcv9Il27NMMSKTm7A50gpRF9z3vDWiZ0Ottg37oUkGiitgk4XI3AJOSWqDzNJjwuwUk6tAlwc6D5TQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.2.0-rc.0.tgz", - "integrity": "sha512-9XBHcDyact/5tdlrgCGwoEdmvcV14D5FrVS3jj/cOCqoBg0NaE1O9AS8OeLa1t4/HlOPijWYLj4oUs0aG3cyQg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.2.0-rc.2.tgz", + "integrity": "sha512-Aj2hiU05DFZ7eXab/zAXjitP9bM/TAM7HNVPOAl08BNpkemo0DYTtdFu4VmLIkqw6WtyxIVZ/N5pSJYMYovXYA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.2.0-rc.0.tgz", - "integrity": "sha512-Kmg8pTm0Ll+t0lussikOCWpvBeVxYh0TEIlaTNyLQZNwT3jKVvdyKsY4yNU7YUBMRQaBRhl0glJOTPxUBURroA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.2.0-rc.2.tgz", + "integrity": "sha512-X17ciKmnrtEut6RTrHvsOSIfwimPc0gT6kQoQFgPcTmF14Zr6edFPd6YKhWtjQNG9rVpmW1HK5bBSyeyiw/P4w==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.2.0-rc.0.tgz", - "integrity": "sha512-CqhSI2T7Rg3EAZemZvYaSaij9sLwS0Vk86g6QCzDVUoyF7q5QpUcd3+7vMD0rvbwBISarrPprooX+GGjTNLiAw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.2.0-rc.2.tgz", + "integrity": "sha512-PRoKMCvGTejDg37dm5fGYxO7jFrHECPn20X3fv3bsVqnF5wH7RZ88dBW5oMNoYxoreph4SSQd5AsSQabuCpT4w==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.2.0-rc.0.tgz", - "integrity": "sha512-87Jxw6bYls7qs/srRXvqnadak3UDsbmYYItsIm2RS1CPxWvrSS3uEdLeCDhvMEoDCm+6B581ntmfiZ/k9OBxWQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.2.0-rc.2.tgz", + "integrity": "sha512-i42zskMlDb7tivcFkFo5pXPo6Z+A2Sgu/MTChDzIEw3AK3/V2Lf8jNZtjL9Anjn1ZWg0Mq4GBjR5iv+pkjHZjw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.2.0-rc.0.tgz", - "integrity": "sha512-iTZPVNB8kqQsqS/Kx/prTY1Hl70bQ+ZZKGm0+d0GxsoEoHKYB9jyQpMx80BWIO0sz5MgqM/8GA+ezAQh1v7sLw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.2.0-rc.2.tgz", + "integrity": "sha512-jIKSrcsmYwQJDyDOSeu49LbqaB7r9xq62cHB5dq2V1SRX9CYQqnX6E6hwcj2KBXwvp6oeAVWg+RzHth/8nR66A==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.2.0-rc.0.tgz", - "integrity": "sha512-59g/paTrCuUlZidjvQh87MSEqxcN/xJf33tEw2BhbXRFGCP/2zzqhIeZx/xh690e0/JKUxPTmhznqmdjOPt5Ig==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.2.0-rc.2.tgz", + "integrity": "sha512-yy6Ay2q3MW5ntJxmT+bgcCzwfSvsX9/0Fp/W7sX7sSO3gwraWobZuOBCiULiUkMe8No1t7x2HecW4Xr1mHUNXQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.2.0-rc.0.tgz", - "integrity": "sha512-huuJrD1v8hxmR02+KCS4RXmvNzwdEXDEVgLReAnDzhEQBQ3nhulEAJnyexw5MZ18LkB1l5rhNeHiRbFxh9u6lw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.2.0-rc.2.tgz", + "integrity": "sha512-hcpxQWHDfPDx8eqWz6O8hHR4C09BOZ/ukYpy5EOJ8I+nwgB6eR39Waml+rOmOoDdMue1B8qPxKUcBODzWomSJg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.2.0-rc.0.tgz", - "integrity": "sha512-jj5n22biZIcGqt3bpBluPxCmsBqAGf5FlzU/1rEZdt9HWsJ2Yo9led+Fm26SqPTlo2Wqixm+MQhmIWJjQZxbOQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.2.0-rc.2.tgz", + "integrity": "sha512-LdNRWeuE/If+v9N6/MH2rgTWlyBwgjynffmUw+Js29OUJFuCp3docdsB2KlVOsfoDVEyAJtlGbsdAXQvf718VQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.2.0-rc.0.tgz", - "integrity": "sha512-YmbeEYeEHAEgZo46rdubsFNTCREqzr5eOGWv4t7QGOawroKGCrLJs+xpBPqGSQkWRENVpj2etWD6pa4s3LW2Dw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.2.0-rc.2.tgz", + "integrity": "sha512-xJIf+T5VkOGEU6A62SINUlkRJjV8rAGp5bS1Buf2z8vxpe50yqLpOm4mXpJXTyvmyybGm0efrUhfX9ESXWWP2g==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.2.0-rc.0.tgz", - "integrity": "sha512-5YuXU3RsowBd6k7YbR39R4cP408apA9rVM2uYD0FhR5JE8XVJ1o/AlapEZB455zeQcYeaWNZKM3VhNY4hzpOMw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.2.0-rc.2.tgz", + "integrity": "sha512-KSJ5JoAijccGBGk233ZSN0a2sz9EDf50oWOE8x10mQvTGRUwwAgEIoxkXN39d0oBgCeY6xrkFS1JL0SC6qD4qg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.2.0-rc.0.tgz", - "integrity": "sha512-gKqd1oMS/uZTcUUCZuqo1ZOMW13QvuVbbTL420RVzjTilC9IZ4SDZU3ZbqS/fsLYPReeKkm4U9NJZdm6a9OqpQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.2.0-rc.2.tgz", + "integrity": "sha512-LcUNh/yaKiG5Mli9f95SPcKufKLFFPFz2zaD/iR80kcem2niXfgNPzuhV145XaLpKrebktrDTYKUefsDI6xqrA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.2.0-rc.0.tgz", - "integrity": "sha512-BoGN8edf4MWhh2jxLcKht843c99ePeSN3LO1f7ICUFHxLJ1l+eEZLieWFh8ZpeErfY2zXsylRALsSSdGagnwKA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.2.0-rc.2.tgz", + "integrity": "sha512-IhHnB5vr7l+8E2Ae/CCy1ZJMH7yWITTfn1zzN+5qcAvQn5M/mm0gCCVFSvHQSRmt9Bj4s9CYSN1rRVp6Nw6gow==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.2.0-rc.0.tgz", - "integrity": "sha512-0vMtMCIAyQ6aPLQiTtM+K7O7qoNCtHEjcVU8LrqGJjdCERvsrktyP6hwDlcOW52MiYcb7H5p4wxXoxi8fKdi+g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.2.0-rc.2.tgz", + "integrity": "sha512-R7kK3j8zF9Em4sB85h//hwXh2tV5h6xuJ1DawqY+am0imdZlr/7rkdv89NTJlP5y8nGGKY1P2lfy3prajxcoqQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.2.0-rc.0.tgz", - "integrity": "sha512-oZS5eaQUMo060Uh3z2yUp7ukb62j42MpE262fK7L0hmtk80Sqn9uff7RNWf3bgwIkyj+GuLm4coakSfbd56D7Q==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.2.0-rc.2.tgz", + "integrity": "sha512-8P9ejFdgy1LTwJIWAT90DDj1cKFNbnwo/6HiqmFIHL40h43oa5/xtAh8SlwF+VzzT3EyuIS2+kOQBIaUT5CGRA==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.2.0-rc.0.tgz", - "integrity": "sha512-aMtDe8C2ZuEr9NLV5onhiUx5Uw/09vnN2oXILoVKaPHhxtK/oqZS6MTnoGt3rlpfjZAjwfXY049MCn8pDPOJqA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.2.0-rc.2.tgz", + "integrity": "sha512-VUbZ9ztkdJpv3bBPCmrrhCjLHiS3MMWVnZT5fnQlbd0v+efD+I09Z4ir8JcdP3lbhP1HbQTVbwx+OyiAHp3pfg==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.2.0-rc.0.tgz", - "integrity": "sha512-oaRqwcuPS9HazH+yTcaDnH3Wt7j04dE6JdWzL3Yj30NNo595ijnZbRlnShjILT2o8jh2DUhVI0JhnnogeMEssA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.2.0-rc.2.tgz", + "integrity": "sha512-cWm/wUU3WRA5VfQGeLa3nrrmOYmpp78pFWa1QAZUFbCZv/NWEmm1wHLqySb9O9AH5zUz3TG7F1LH75ZXI7dv0g==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.2.0-rc.0.tgz", - "integrity": "sha512-8+IPz99Py12fIuDAs89kXOdsfBszFS37XtgYpMFl9t+g4uyd7doV8jJFP8G3UnjjDuboQWhpKIJKiKCRoOmdGw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.2.0-rc.2.tgz", + "integrity": "sha512-3LPWk2mpCsYUOBiqeIdX/DDvQSM324rLMomXgxco+dmI1CvykkSJ2u3HclsmXk567d19h7+rt0k1Ap79him9+g==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.2.0-rc.0.tgz", - "integrity": "sha512-mnq3a4Wu/Uor234we97mtvfeX8nl9w0fKsH2kBAgodkjXVMQssvCOdd7MKyh6G4mXUO4/WY0HbOYOCGv2I/feQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.2.0-rc.2.tgz", + "integrity": "sha512-UagMXNgIoVzk+GyLI7S8nsskMtpADhOqcyO8mNLfppF2RVtZ7xmBUPiZ+9OsaiZFet0IcbPpg1ZtdsuNnHZydw==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.2.0-rc.0.tgz", - "integrity": "sha512-UXdiT/ROf8sKQTYge2wS4znhL4+IdpxoF4TPZr+U0k/5UQ+iQTzs6hy/GJQs5FcPnEI7gftrIHctP5O9yKsJvw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.2.0-rc.2.tgz", + "integrity": "sha512-ypp8pFp3GRXk3WLitMJp7Cg/ducZlVDKQyTqwwHap2q6RfkTwvZcLl59Bf00hgkMeTV1vVzFCMSMqLextPabQQ==", "dependencies": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-boolean-input": "1.2.0-rc.2" } }, "node_modules/@web/browser-logs": { @@ -6698,6 +6703,22 @@ "node": ">=10.0.0" } }, + "node_modules/@web/dev-server-esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@web/dev-server-esbuild/node_modules/esbuild": { "version": "0.14.54", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", @@ -6768,6 +6789,64 @@ "node": ">=10.0.0" } }, + "node_modules/@web/dev-server-rollup/node_modules/@rollup/plugin-node-resolve": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", + "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^2.42.0" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@web/dev-server-rollup/node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@web/dev-server-rollup/node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, "node_modules/@web/dev-server-rollup/node_modules/rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -8556,17 +8635,6 @@ "node": ">= 0.8" } }, - "node_modules/core-js": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.29.0.tgz", - "integrity": "sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-compat": { "version": "3.29.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.29.1.tgz", @@ -8981,12 +9049,6 @@ "node": ">=6.0.0" } }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, "node_modules/dom5": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dom5/-/dom5-3.0.1.tgz", @@ -9299,9 +9361,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz", + "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==", "dev": true, "hasInstallScript": true, "bin": { @@ -9311,28 +9373,60 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" + "@esbuild/android-arm": "0.17.15", + "@esbuild/android-arm64": "0.17.15", + "@esbuild/android-x64": "0.17.15", + "@esbuild/darwin-arm64": "0.17.15", + "@esbuild/darwin-x64": "0.17.15", + "@esbuild/freebsd-arm64": "0.17.15", + "@esbuild/freebsd-x64": "0.17.15", + "@esbuild/linux-arm": "0.17.15", + "@esbuild/linux-arm64": "0.17.15", + "@esbuild/linux-ia32": "0.17.15", + "@esbuild/linux-loong64": "0.17.15", + "@esbuild/linux-mips64el": "0.17.15", + "@esbuild/linux-ppc64": "0.17.15", + "@esbuild/linux-riscv64": "0.17.15", + "@esbuild/linux-s390x": "0.17.15", + "@esbuild/linux-x64": "0.17.15", + "@esbuild/netbsd-x64": "0.17.15", + "@esbuild/openbsd-x64": "0.17.15", + "@esbuild/sunos-x64": "0.17.15", + "@esbuild/win32-arm64": "0.17.15", + "@esbuild/win32-ia32": "0.17.15", + "@esbuild/win32-x64": "0.17.15" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, "node_modules/esbuild-darwin-64": { @@ -9351,6 +9445,214 @@ "node": ">=12" } }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/esbuild-plugin-alias": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz", @@ -9369,6 +9671,70 @@ "esbuild": ">=0.12 <1" } }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -9451,9 +9817,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", - "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "dev": true, "bin": { "eslint-config-prettier": "bin/cli.js" @@ -9992,9 +10358,9 @@ } }, "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "node_modules/esutils": { @@ -10539,9 +10905,9 @@ "dev": true }, "node_modules/flow-parser": { - "version": "0.201.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.201.0.tgz", - "integrity": "sha512-G4oeDNpNGyIrweF9EnoHatncAihMT0tQgV6NMdyM5I7fhrz9Pr13PJ2KLQ673O4wj9KooTdBpeeYHdDNAQoyyw==", + "version": "0.203.1", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.203.1.tgz", + "integrity": "sha512-Nw2M8MPP/Zb+yhvmPDEjzkCXLtgyWGKXZjAYOVftm+wIf3xd4FKa7nRI9v67rODs0WzxMbPc8IPs/7o/dyxo/Q==", "dev": true, "engines": { "node": ">=0.4.0" @@ -10932,16 +11298,6 @@ "node": ">=10" } }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "node_modules/global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -11760,12 +12116,6 @@ "node": ">=8" } }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, "node_modules/is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -12999,28 +13349,29 @@ "dev": true }, "node_modules/lit": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/lit/-/lit-2.6.1.tgz", - "integrity": "sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.7.0.tgz", + "integrity": "sha512-qSy2BAVA+OiWtNptP404egcC/izDdNRw6iHGIbUmkZtbMJvPKfNsaoKrNs8Zmsbjmv5ZX2tur1l9TfzkSWWT4g==", "dependencies": { "@lit/reactive-element": "^1.6.0", - "lit-element": "^3.2.0", - "lit-html": "^2.6.0" + "lit-element": "^3.3.0", + "lit-html": "^2.7.0" } }, "node_modules/lit-element": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.2.tgz", - "integrity": "sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.0.tgz", + "integrity": "sha512-M3OIoblNS7LZdRxOIk8g0wyLEA/lRw/UGJ1TX+767OpkuDsRdSoxBIvewpWqCo7sMd9xt1XedUNZIr9jUO1X3g==", "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.1.0", "@lit/reactive-element": "^1.3.0", - "lit-html": "^2.2.0" + "lit-html": "^2.7.0" } }, "node_modules/lit-html": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.6.1.tgz", - "integrity": "sha512-Z3iw+E+3KKFn9t2YKNjsXNEu/LRLI98mtH/C6lnFg7kvaqPIzPn124Yd4eT/43lyqrejpc5Wb6BHq3fdv4S8Rw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.0.tgz", + "integrity": "sha512-/zPOl8EfeB3HHpTzINSpnWgvgQ8N07g/j272EOAIyB0Ys2RzBqTVT23i+JZuUlNbB2WHHeSsTCFi92NtWrtpqQ==", "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -13290,9 +13641,9 @@ "dev": true }, "node_modules/markdown-to-jsx": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.9.tgz", - "integrity": "sha512-x4STVIKIJR0mGgZIZ5RyAeQD7FEZd5tS8m/htbcVGlex32J+hlSLj+ExrHCxP6nRKF1EKbcO7i6WhC1GtOpBlA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.2.0.tgz", + "integrity": "sha512-3l4/Bigjm4bEqjCR6Xr+d4DtM1X6vvtGsMGSjJYyep8RjjIvcWtrXBS8Wbfe1/P+atKNMccpsraESIaWVplzVg==", "dev": true, "engines": { "node": ">= 10" @@ -13433,15 +13784,6 @@ "node": ">=6" } }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "dependencies": { - "dom-walk": "^0.1.0" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -13521,6 +13863,11 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "node_modules/monaco-editor": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.36.1.tgz", + "integrity": "sha512-/CaclMHKQ3A6rnzBzOADfwdSJ25BFoFT0Emxsc4zYVyav5SkK9iA6lEtIeuN/oRYbwPgviJT+t3l+sjFa28jYg==" + }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -13583,16 +13930,15 @@ } }, "node_modules/msw-storybook-addon": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.7.0.tgz", - "integrity": "sha512-G/cYj7Z8NuyFbMsdVJRr17flWed8J7CmKTSPNXmuK65W6uILpqNDpXJC7KVRhOg7lUFR5Hmqwcq6z8Mow/wu5A==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.8.0.tgz", + "integrity": "sha512-dw3vZwqjixmiur0vouRSOax7wPSu9Og2Hspy9JZFHf49bZRjwDiLF0Pfn2NXEkGviYJOJiGxS1ejoTiUwoSg4A==", "dev": true, "dependencies": { - "@storybook/addons": "^6.0.0", "is-node-process": "^1.0.1" }, "peerDependencies": { - "msw": ">=0.35.0 <1.0.0" + "msw": ">=0.35.0 <2.0.0" } }, "node_modules/msw/node_modules/ansi-styles": { @@ -15809,46 +16155,12 @@ "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0" } }, - "node_modules/rollup-plugin-esbuild/node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/rollup-plugin-esbuild/node_modules/@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", - "dev": true - }, "node_modules/rollup-plugin-esbuild/node_modules/es-module-lexer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.0.tgz", "integrity": "sha512-2BMfqBDeVCcOlLaL1ZAfp+D868SczNpKArrTM3dhpd7dK/OVlogzY15qpUngt+LMTq5UC/csb9vVQAgupucSbA==", "dev": true }, - "node_modules/rollup-plugin-esbuild/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, "node_modules/rollup-plugin-url": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/rollup-plugin-url/-/rollup-plugin-url-3.0.1.tgz", @@ -15882,9 +16194,9 @@ "dev": true }, "node_modules/router-slot": { - "version": "1.6.1", - "resolved": "file:router-slot-1.6.1.tgz", - "integrity": "sha512-lrqzUL9wfSQR7L9rFvRsq/I+BGo2bw0Hn45eZ+qhrjPFv2gn+LRz2TaWa6CVqkiXhdWMrUEmEyD8nzl4cqV0Fw==", + "version": "2.0.0", + "resolved": "file:router-slot-2.0.0.tgz", + "integrity": "sha512-J2E+sDJR7Q/S761Q6vXVCTWFN1kKidX3fparKoipm/NaX9XEdwmCSOEqYyUHbnIyDDo5O5PMhsH8EazLmCQJXw==", "license": "MIT" }, "node_modules/run-async": { @@ -16452,12 +16764,12 @@ "dev": true }, "node_modules/storybook": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.0-rc.3.tgz", - "integrity": "sha512-1EFr7o7dcgFKsI6TBqvxYEKGPzKvJ8qzCl3BM/1kZP5BmWqQPbanOQLVkTb4zDb5e+Q+ibDNH5k8D1lQFdsHcg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.2.tgz", + "integrity": "sha512-/XBLhT9Vb14yNBcA9rlW15y+C6IsCA3kx5PKvK9kL10sKCi8invcY94UfCSisXe8HqsO3u6peumo2xpYucKMjw==", "dev": true, "dependencies": { - "@storybook/cli": "7.0.0-rc.3" + "@storybook/cli": "7.0.2" }, "bin": { "sb": "index.js", @@ -17206,16 +17518,16 @@ "dev": true }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", + "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/typescript-json-schema": { @@ -17644,15 +17956,15 @@ } }, "node_modules/vite": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.4.tgz", - "integrity": "sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==", "dev": true, "dependencies": { - "esbuild": "^0.16.14", + "esbuild": "^0.17.5", "postcss": "^8.4.21", "resolve": "^1.22.1", - "rollup": "^3.10.0" + "rollup": "^3.18.0" }, "bin": { "vite": "bin/vite.js" @@ -18328,9 +18640,9 @@ } }, "@babel/compat-data": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", - "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", + "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", "dev": true }, "@babel/core": { @@ -18401,22 +18713,22 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", + "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", "dev": true, "requires": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", + "@babel/compat-data": "^7.21.4", + "@babel/helper-validator-option": "^7.21.0", "browserslist": "^4.21.3", "lru-cache": "^5.1.1", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz", - "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz", + "integrity": "sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", @@ -18430,9 +18742,9 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz", - "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz", + "integrity": "sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", @@ -18872,12 +19184,12 @@ } }, "@babel/plugin-syntax-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", - "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz", + "integrity": "sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-syntax-import-assertions": { @@ -18899,12 +19211,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -18980,12 +19292,12 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-arrow-functions": { @@ -19054,9 +19366,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", - "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", + "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.20.2" @@ -19212,9 +19524,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", - "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", + "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.20.2" @@ -19308,11 +19620,12 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz", - "integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz", + "integrity": "sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==", "dev": true, "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" @@ -19338,31 +19651,31 @@ } }, "@babel/preset-env": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", - "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.4.tgz", + "integrity": "sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==", "dev": true, "requires": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", + "@babel/compat-data": "^7.21.4", + "@babel/helper-compilation-targets": "^7.21.4", "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", + "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", + "@babel/plugin-proposal-async-generator-functions": "^7.20.7", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.21.0", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.0", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -19379,40 +19692,40 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.20.7", + "@babel/plugin-transform-async-to-generator": "^7.20.7", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-block-scoping": "^7.21.0", + "@babel/plugin-transform-classes": "^7.21.0", + "@babel/plugin-transform-computed-properties": "^7.20.7", + "@babel/plugin-transform-destructuring": "^7.21.3", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-for-of": "^7.21.0", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-amd": "^7.20.11", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-modules-systemjs": "^7.20.11", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-parameters": "^7.21.3", "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.20.5", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-spread": "^7.20.7", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", + "@babel/types": "^7.21.4", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -19421,14 +19734,14 @@ } }, "@babel/preset-flow": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz", - "integrity": "sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.21.4.tgz", + "integrity": "sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-flow-strip-types": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-transform-flow-strip-types": "^7.21.0" } }, "@babel/preset-modules": { @@ -19445,14 +19758,16 @@ } }, "@babel/preset-typescript": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz", - "integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.4.tgz", + "integrity": "sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-transform-typescript": "^7.21.0" + "@babel/plugin-syntax-jsx": "^7.21.4", + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "@babel/plugin-transform-typescript": "^7.21.3" } }, "@babel/register": { @@ -19594,9 +19909,9 @@ } }, "@babel/types": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", - "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", + "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.19.4", @@ -19644,10 +19959,157 @@ "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", "dev": true }, + "@esbuild/android-arm": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz", + "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz", + "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz", + "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz", + "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==", + "dev": true, + "optional": true + }, "@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz", + "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz", + "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz", + "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz", + "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz", + "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz", + "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz", + "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz", + "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz", + "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz", + "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz", + "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz", + "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz", + "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz", + "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz", + "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz", + "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz", + "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz", + "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==", "dev": true, "optional": true }, @@ -19989,9 +20451,9 @@ "dev": true }, "@lit-labs/ssr-dom-shim": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.0.0.tgz", - "integrity": "sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.0.tgz", + "integrity": "sha512-92uQ5ARf7UXYrzaFcAX3T2rTvaS9Z1//ukV+DqjACM4c8s0ZBQd7ayJU5Dh2AFLD/Ayuyz4uMmxQec8q3U4Ong==" }, "@lit/reactive-element": { "version": "1.6.1", @@ -20200,56 +20662,31 @@ "dev": true, "requires": { "@rollup/pluginutils": "^5.0.1" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", - "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - } } }, "@rollup/plugin-node-resolve": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", - "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz", + "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==", "dev": true, "requires": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", - "is-builtin-module": "^3.1.0", + "is-builtin-module": "^3.2.0", "is-module": "^1.0.0", - "resolve": "^1.19.0" + "resolve": "^1.22.1" } }, "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", "dev": true, "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" } }, "@sinclair/typebox": { @@ -20259,40 +20696,40 @@ "dev": true }, "@storybook/addon-a11y": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-7.0.0-rc.3.tgz", - "integrity": "sha512-V/wl19IzsOA0OkUofKKbL09Qj93ywRHW3Pjq3pOLRE178zCumWuBKxpr+dS4C1lNwecIU1ffp8408RSzZ4K5sA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-7.0.2.tgz", + "integrity": "sha512-PCJaLdp/3MypMYQufLIaKL4gzZjDgU8fTW45O7feXwiUZzFUVZamBwBw5BHcHAPsDOr5CmebGvJ9+l2gByWL/g==", "dev": true, "requires": { - "@storybook/addon-highlight": "7.0.0-rc.3", - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/addon-highlight": "7.0.2", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "axe-core": "^4.2.0", "lodash": "^4.17.21", "react-resize-detector": "^7.1.2" } }, "@storybook/addon-actions": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.0-rc.3.tgz", - "integrity": "sha512-kyPuSN/PzBnW3w9D/KBEmMqfeGpBeY6Ha2VVPz3BBqcWSHfw0AbHFqvnqluubaHZl1VokE88QT6RxkdyBg33uw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-7.0.2.tgz", + "integrity": "sha512-rcj39u9MrmzsrDWYt1zsoVxrogZ1Amrv9xkEofEY/QKUr2R3xpHhTALveY9BKIlG1GoE8zLlLoP2k4nz3sNNwQ==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "dequal": "^2.0.2", "lodash": "^4.17.21", "polished": "^4.2.2", @@ -20304,65 +20741,65 @@ } }, "@storybook/addon-backgrounds": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.0-rc.3.tgz", - "integrity": "sha512-6qIwuNwzLFdsLCjj5rO6TCaBvAGUYbrLpw2EQyKg5J/5GxqhMU/HsinCViok2VEn/z45vji9FI1W6bmo7t4LNQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.2.tgz", + "integrity": "sha512-yRNHQ4PPRJ+HIORQPhDGxn5xolw1xW0ByQZoNRpMD+AMEyfUNFdWbCsRQAOWjNhawxVMHM7EeA2Exrb41zhEjA==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "memoizerific": "^1.11.3", "ts-dedent": "^2.0.0" } }, "@storybook/addon-controls": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.0-rc.3.tgz", - "integrity": "sha512-16E0AJ1+psFDbL6abOfLFg0zWhUQeJjcM3RKEzJjYZEBuKKL86LAvKhnlkyCUW3VlLN23V0akY6Gev81DR/BfA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-7.0.2.tgz", + "integrity": "sha512-dMpRtj5cmfC9vEMve5ncvbWCEC+WD9YuzJ+grdc48E/Hd//p+O2FE6klSkrz5FAjrc+rHINixdyssekpEL6nYQ==", "dev": true, "requires": { - "@storybook/blocks": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/blocks": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/manager-api": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "lodash": "^4.17.21", "ts-dedent": "^2.0.0" } }, "@storybook/addon-docs": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.0-rc.3.tgz", - "integrity": "sha512-UPy+o7IBly2TgCQ7hviaExq++KQSPS7/+/8iLUdv81mtRm3hMBMARmom+wjXfciGHp1re1bazQQYoDsOcorDhA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-7.0.2.tgz", + "integrity": "sha512-q3rDWoZEym6Lkmhqc/HBNfLDAmTY8l0WINGUZo/nF98eP5iu4B7Nk7V6BRGYGQt6Y6ZyIQ8WKH0e/eJww2zIog==", "dev": true, "requires": { "@babel/core": "^7.20.2", "@babel/plugin-transform-react-jsx": "^7.19.0", "@jest/transform": "^29.3.1", "@mdx-js/react": "^2.1.5", - "@storybook/blocks": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/csf-plugin": "7.0.0-rc.3", - "@storybook/csf-tools": "7.0.0-rc.3", + "@storybook/blocks": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/csf-plugin": "7.0.2", + "@storybook/csf-tools": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/mdx2-csf": "next", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/postinstall": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/react-dom-shim": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/mdx2-csf": "^1.0.0", + "@storybook/node-logger": "7.0.2", + "@storybook/postinstall": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/react-dom-shim": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "fs-extra": "^11.1.0", "remark-external-links": "^8.0.0", "remark-slug": "^6.0.0", @@ -20370,332 +20807,134 @@ } }, "@storybook/addon-essentials": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.0-rc.3.tgz", - "integrity": "sha512-RLA1RgjwuDsRKp2QjBAx2XsgTZ+Dura2k8xCTyBLf0yxnleC8hiAxLwTJSSdDEUuiXxWsBbu0vhHzYnCCVTDnw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.2.tgz", + "integrity": "sha512-LAsWsXa/Pp2B4Ve2WVgc990FtsiHpFDRsq7S3V7xRrZP8DYRbtJIVdszPMDS5uKC+yzbswFEXz08lqbGvq8zgQ==", "dev": true, "requires": { - "@storybook/addon-actions": "7.0.0-rc.3", - "@storybook/addon-backgrounds": "7.0.0-rc.3", - "@storybook/addon-controls": "7.0.0-rc.3", - "@storybook/addon-docs": "7.0.0-rc.3", - "@storybook/addon-highlight": "7.0.0-rc.3", - "@storybook/addon-measure": "7.0.0-rc.3", - "@storybook/addon-outline": "7.0.0-rc.3", - "@storybook/addon-toolbars": "7.0.0-rc.3", - "@storybook/addon-viewport": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", + "@storybook/addon-actions": "7.0.2", + "@storybook/addon-backgrounds": "7.0.2", + "@storybook/addon-controls": "7.0.2", + "@storybook/addon-docs": "7.0.2", + "@storybook/addon-highlight": "7.0.2", + "@storybook/addon-measure": "7.0.2", + "@storybook/addon-outline": "7.0.2", + "@storybook/addon-toolbars": "7.0.2", + "@storybook/addon-viewport": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/manager-api": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/preview-api": "7.0.2", "ts-dedent": "^2.0.0" } }, "@storybook/addon-highlight": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.0-rc.3.tgz", - "integrity": "sha512-MeFIKfDpFrF33TPdl2ko2rie485AhfG2n0MFXA73L8Yzj5JPV+LVNa5eIKUUFyOMUGSkVjfFS6n63F08eqHbCw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-7.0.2.tgz", + "integrity": "sha512-9BkL1OOanguuy73S6nLK0isUb045tOkFONd/PQldOJ0PV3agCvKxKHyzlBz7Hsba8KZhY5jQs+nVW2NiREyGYg==", "dev": true, "requires": { - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/preview-api": "7.0.0-rc.3" + "@storybook/preview-api": "7.0.2" } }, "@storybook/addon-links": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.0-rc.3.tgz", - "integrity": "sha512-K2PMxVooGAgb8hCEU2oGUMzKjPLEPACH8NcRLs/fz9PKadepmijY0hBDC50SGkZd2HWSxXxyt6d5WaXTxhP8aw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-7.0.2.tgz", + "integrity": "sha512-lPtfy2MqrcI9YjupBM2eRKGPdFKVPCz7WgO/JQQakGugORJTEGCyJrNJNtWY9jDenv8ynLZ40OxtPBZi54Sr6Q==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/router": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/router": "7.0.2", + "@storybook/types": "7.0.2", "prop-types": "^15.7.2", "ts-dedent": "^2.0.0" } }, "@storybook/addon-measure": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.0-rc.3.tgz", - "integrity": "sha512-N0HjObHjktlgWvOQcOqyC6/vFXERHzH7aP8L1RRrSnz+mP0XDO+62eBZunlnDGu4uAECH+AV/7LO+bmTMohulg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-7.0.2.tgz", + "integrity": "sha512-cf/d5MXpHAjyUiDIVfc8pLn79CPHgnryDmNNlSiP2zEFKcivrRWiu8Rmrad8pGqLkuAh+PXLKCGn9uiqDvg7QQ==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3" + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2" } }, "@storybook/addon-outline": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.0-rc.3.tgz", - "integrity": "sha512-SocPRmzzu2wR3SiqMsPskfFumOd0Ph8MUTeJ2cwnaonqqHjjqxaEaFYio8AGmGaHLpY8PKtW0s75jU0oDh9Ezg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-7.0.2.tgz", + "integrity": "sha512-thVISO4NM22xlETisBvAPvz2yFD3qLGOjgzBmj8l8r9Rv0IEdwdPrwm5j0WTv8OtbhC4A8lPpvMsn5FhY5mDXg==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "ts-dedent": "^2.0.0" } }, "@storybook/addon-toolbars": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.0-rc.3.tgz", - "integrity": "sha512-qnvMWZAa3ELRNiVjj1sy0dJb2GzE5fga9SbsbVQQT2zBvou2e8XbiPRw0WHdwUU2Zj9t9/PVjz2+av7P8B+Cqg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-7.0.2.tgz", + "integrity": "sha512-tAxZ2+nUYsJdT1sx3BrmoMAZFM19+OzWJY6qSnbEq5zoRgvGZaXGR6tLMKydDoHQBU9Ta9YHGo7N7u7h1C23yg==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3" + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2" } }, "@storybook/addon-viewport": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.0-rc.3.tgz", - "integrity": "sha512-GXBi7f4WNeM4yvKXKYNAMLDHauTOcLpimzf1wtyVapBLpwzcJHBaJTCHQ02yIcm6mU2TFbKXMmzC1uBZcCa+5w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-7.0.2.tgz", + "integrity": "sha512-TaHJWIIazPM/TerRbka9RqjMPNpwaRsGRdVRBtVoVosy1FzsEjAdQSO7RBMe4G03m5CacSqdsDiJCblI2AXaew==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", "memoizerific": "^1.11.3", "prop-types": "^15.7.2" } }, - "@storybook/addons": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.16.tgz", - "integrity": "sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ==", - "dev": true, - "requires": { - "@storybook/api": "6.5.16", - "@storybook/channels": "6.5.16", - "@storybook/client-logger": "6.5.16", - "@storybook/core-events": "6.5.16", - "@storybook/csf": "0.0.2--canary.4566f4d.1", - "@storybook/router": "6.5.16", - "@storybook/theming": "6.5.16", - "@types/webpack-env": "^1.16.0", - "core-js": "^3.8.2", - "global": "^4.4.0", - "regenerator-runtime": "^0.13.7" - }, - "dependencies": { - "@storybook/channels": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.16.tgz", - "integrity": "sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg==", - "dev": true, - "requires": { - "core-js": "^3.8.2", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/client-logger": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.16.tgz", - "integrity": "sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q==", - "dev": true, - "requires": { - "core-js": "^3.8.2", - "global": "^4.4.0" - } - }, - "@storybook/core-events": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.16.tgz", - "integrity": "sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==", - "dev": true, - "requires": { - "core-js": "^3.8.2" - } - }, - "@storybook/csf": { - "version": "0.0.2--canary.4566f4d.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", - "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "@storybook/router": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.16.tgz", - "integrity": "sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==", - "dev": true, - "requires": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "regenerator-runtime": "^0.13.7" - } - }, - "@storybook/theming": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.16.tgz", - "integrity": "sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ==", - "dev": true, - "requires": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "regenerator-runtime": "^0.13.7" - } - } - } - }, - "@storybook/api": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/api/-/api-6.5.16.tgz", - "integrity": "sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA==", - "dev": true, - "requires": { - "@storybook/channels": "6.5.16", - "@storybook/client-logger": "6.5.16", - "@storybook/core-events": "6.5.16", - "@storybook/csf": "0.0.2--canary.4566f4d.1", - "@storybook/router": "6.5.16", - "@storybook/semver": "^7.3.2", - "@storybook/theming": "6.5.16", - "core-js": "^3.8.2", - "fast-deep-equal": "^3.1.3", - "global": "^4.4.0", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3", - "regenerator-runtime": "^0.13.7", - "store2": "^2.12.0", - "telejson": "^6.0.8", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - }, - "dependencies": { - "@storybook/channels": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.16.tgz", - "integrity": "sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg==", - "dev": true, - "requires": { - "core-js": "^3.8.2", - "ts-dedent": "^2.0.0", - "util-deprecate": "^1.0.2" - } - }, - "@storybook/client-logger": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.16.tgz", - "integrity": "sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q==", - "dev": true, - "requires": { - "core-js": "^3.8.2", - "global": "^4.4.0" - } - }, - "@storybook/core-events": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.16.tgz", - "integrity": "sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==", - "dev": true, - "requires": { - "core-js": "^3.8.2" - } - }, - "@storybook/csf": { - "version": "0.0.2--canary.4566f4d.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz", - "integrity": "sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "@storybook/router": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-6.5.16.tgz", - "integrity": "sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==", - "dev": true, - "requires": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "qs": "^6.10.0", - "regenerator-runtime": "^0.13.7" - } - }, - "@storybook/theming": { - "version": "6.5.16", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.16.tgz", - "integrity": "sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ==", - "dev": true, - "requires": { - "@storybook/client-logger": "6.5.16", - "core-js": "^3.8.2", - "memoizerific": "^1.11.3", - "regenerator-runtime": "^0.13.7" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", - "dev": true - }, - "telejson": { - "version": "6.0.8", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-6.0.8.tgz", - "integrity": "sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==", - "dev": true, - "requires": { - "@types/is-function": "^1.0.0", - "global": "^4.4.0", - "is-function": "^1.0.2", - "is-regex": "^1.1.2", - "is-symbol": "^1.0.3", - "isobject": "^4.0.0", - "lodash": "^4.17.21", - "memoizerific": "^1.11.3" - } - } - } - }, "@storybook/blocks": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.0-rc.3.tgz", - "integrity": "sha512-mh4LQk2f/Q9n7Sqo6t02CspHubXmSgDY4S5vF3dTgVBM/sD0OxkAY3Pv+HTsXH36lQHYYUft7U7OfhZapgS4ng==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-7.0.2.tgz", + "integrity": "sha512-JzHmU8jZLzeQ6bunzci8j/2Ji18GBTyhrPFLk5RjEbMNGWpGjvER/yR127tZOdbPguVNr4iVbRfGzd1wGHlrzA==", "dev": true, "requires": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/components": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", - "@storybook/docs-tools": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/components": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", + "@storybook/docs-tools": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "@types/lodash": "^4.14.167", "color-convert": "^2.0.1", "dequal": "^2.0.2", @@ -20710,46 +20949,45 @@ } }, "@storybook/builder-manager": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.0-rc.3.tgz", - "integrity": "sha512-aScwYA9MWtqgiD39SkcwUlrR9RFbngv7jPoOaVMdXuMgNabMNz9417L9bCwSPwgO4XZ5a/nSEbGNLfOHfBemsw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.2.tgz", + "integrity": "sha512-Oej/n8D7eaWgmWF7nN2hXLRM53lcYOdh6umSN8Mh/LcYUfxB+dvUBFzUjoLE0xjhW6xRinrKrENT5LcP/f/HBQ==", "dev": true, "requires": { "@fal-works/esbuild-plugin-global-externals": "^2.1.2", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/manager": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", + "@storybook/core-common": "7.0.2", + "@storybook/manager": "7.0.2", + "@storybook/node-logger": "7.0.2", "@types/ejs": "^3.1.1", "@types/find-cache-dir": "^3.2.1", "@yarnpkg/esbuild-plugin-pnp": "^3.0.0-rc.10", "browser-assert": "^1.2.1", "ejs": "^3.1.8", - "esbuild": "^0.16.4", + "esbuild": "^0.17.0", "esbuild-plugin-alias": "^0.2.1", "express": "^4.17.3", "find-cache-dir": "^3.0.0", "fs-extra": "^11.1.0", "process": "^0.11.10", - "slash": "^3.0.0", "util": "^0.12.4" } }, "@storybook/builder-vite": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-7.0.0-rc.3.tgz", - "integrity": "sha512-v2d04PWfcITD7zI68d7XbCbOd+5vl3gIMEX5Xdsmuw3WcaqYxvDSE8GhL6zsBhrUyygV/8xhSaaxyfv8ImM0+w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/builder-vite/-/builder-vite-7.0.2.tgz", + "integrity": "sha512-G6CD2Gf2zwzRslvNvqgz4FeADVEA9XA4Mw6+NM6Twc+Wy/Ah482dvHS9ApSgirtGyBKjOfdHn1xQT4Z+kzbJnw==", "dev": true, "requires": { - "@storybook/channel-postmessage": "7.0.0-rc.3", - "@storybook/channel-websocket": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/csf-plugin": "7.0.0-rc.3", - "@storybook/mdx2-csf": "next", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/channel-postmessage": "7.0.2", + "@storybook/channel-websocket": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/csf-plugin": "7.0.2", + "@storybook/mdx2-csf": "^1.0.0", + "@storybook/node-logger": "7.0.2", + "@storybook/preview": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "browser-assert": "^1.2.1", "es-module-lexer": "^0.9.3", "express": "^4.17.3", @@ -20757,58 +20995,59 @@ "glob": "^8.1.0", "glob-promise": "^6.0.2", "magic-string": "^0.27.0", - "rollup": "^2.25.0 || ^3.3.0", - "slash": "^3.0.0" + "remark-external-links": "^8.0.0", + "remark-slug": "^6.0.0", + "rollup": "^2.25.0 || ^3.3.0" } }, "@storybook/channel-postmessage": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.0-rc.3.tgz", - "integrity": "sha512-1uptuCjA4vAvvoxNoIJPTIpSARzJnLU7eahRhTPwELBnCH0ObqvgInge0cvbYsaTRDNV90oBbEKlxLf1Zb1BhQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-7.0.2.tgz", + "integrity": "sha512-SZ/KqnZcx10W9hJbrzBKcP9dmgaeTaXugUhcgw1IkmjKWdsKazqFZCPwQWZZKAmhO4wYbyYOhkz3wfSIeB4mFw==", "dev": true, "requires": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", "@storybook/global": "^5.0.0", "qs": "^6.10.0", "telejson": "^7.0.3" } }, "@storybook/channel-websocket": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.0-rc.3.tgz", - "integrity": "sha512-706jopde+OZZkqsmrRuwd9utusqiKianiF8cvjAxrxogSx8LwHk8jxrEKHxHiZUEWDS3JxJoIYSV8gxH9hcjsA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.2.tgz", + "integrity": "sha512-YU3lFId6Nsi75ddA+3qfbnLfNUPswboYyx+SALhaLuXqz7zqfzX4ezMgxeS/h0gRlUJ7nf2/yJ5qie/kZaizjw==", "dev": true, "requires": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", "@storybook/global": "^5.0.0", "telejson": "^7.0.3" } }, "@storybook/channels": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.0-rc.3.tgz", - "integrity": "sha512-jaODIck+um16Fn2k1vwHK9RNk2J8hLVyzLSkoGM40TsMF5nichwI3rA6225pLk015itJbhCAi/RhaMFBI+ZtsA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/channels/-/channels-7.0.2.tgz", + "integrity": "sha512-qkI8mFy9c8mxN2f01etayKhCaauL6RAsxRzbX1/pKj6UqhHWqqUbtHwymrv4hG5qDYjV1e9pd7ae5eNF8Kui0g==", "dev": true }, "@storybook/cli": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.0-rc.3.tgz", - "integrity": "sha512-g1nWHLI1fiDK2dnLpmbhbrm6ZaAwuZkUgEGtlEQCPTHWVRZj2fJT0y5zjgBIhFpdkB/X8MZzgVxqhTJF0uX39Q==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.2.tgz", + "integrity": "sha512-xMM2QdXNGg09wuXzAGroKrbsnaHSFPmtmefX1XGALhHuKVwxOoC2apWMpek6gY/9vh5EIRTog2Dvfd2BzNrT6Q==", "dev": true, "requires": { "@babel/core": "^7.20.2", "@babel/preset-env": "^7.20.2", "@ndelangen/get-tarball": "^3.0.7", - "@storybook/codemod": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/core-server": "7.0.0-rc.3", - "@storybook/csf-tools": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/telemetry": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/codemod": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/core-server": "7.0.2", + "@storybook/csf-tools": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/telemetry": "7.0.2", + "@storybook/types": "7.0.2", "@types/semver": "^7.3.4", "boxen": "^5.1.2", "chalk": "^4.1.0", @@ -20893,20 +21132,6 @@ } } }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -20963,6 +21188,17 @@ "proxy-from-env": "^1.0.0", "rimraf": "^2.6.1", "ws": "^6.1.0" + }, + "dependencies": { + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } } }, "rimraf": { @@ -20972,6 +21208,22 @@ "dev": true, "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "semver": { @@ -20992,15 +21244,6 @@ "has-flag": "^4.0.0" } }, - "ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -21010,27 +21253,27 @@ } }, "@storybook/client-logger": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.0-rc.3.tgz", - "integrity": "sha512-cC7lq+S4n5fFooDCyefgTAOfipadiZskNuzsQF7drE9nQLZ8GflLdmTKK//5NQUHKPzF7r+4Q5DAK4I3nqIkxA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-7.0.2.tgz", + "integrity": "sha512-rv7W2BhzIQHbFpUM5/CP/acS6T5lTmaxT0MbZ9n+9h++9QQU/cFOdkZgSUbLVAb1AeUGoLsk0HYzcqPpV35Xsw==", "dev": true, "requires": { "@storybook/global": "^5.0.0" } }, "@storybook/codemod": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.0-rc.3.tgz", - "integrity": "sha512-P965X5g4WIBfrYMLYPQIvwp9wfIf5bnUIVgwjeGUDLDLIst6RXmHGik9MHLy2Ic/MXTsf/kwK5qY9pj95t8DZg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/codemod/-/codemod-7.0.2.tgz", + "integrity": "sha512-D9PdByxJlFiaDJcLkM+RN1DHCj4VfQIlSZkADOcNtI4o9H064oiMloWDGZiR1i1FCYMSXuWmW6tMsuCVebA+Nw==", "dev": true, "requires": { "@babel/core": "~7.21.0", - "@babel/preset-env": "~7.20.2", + "@babel/preset-env": "~7.21.0", "@babel/types": "~7.21.2", - "@storybook/csf": "next", - "@storybook/csf-tools": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/csf": "^0.1.0", + "@storybook/csf-tools": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/types": "7.0.2", "cross-spawn": "^7.0.3", "globby": "^11.0.2", "jscodeshift": "^0.14.0", @@ -21040,44 +21283,44 @@ } }, "@storybook/components": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.0-rc.3.tgz", - "integrity": "sha512-PeQFr2hZvLnxLswKihw1Ro5wCqmNZeSE4q+tFdifhLVIqP/OwHG+ShiLCHQ1aEa0Z3Ub+80m7uPzg69+y9m+bQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-7.0.2.tgz", + "integrity": "sha512-Ee9pY6WlpricPUdYiyR0Ov8zgHkUt541yl1CZ6Ytaom2TA12cAnRjKewbLAgVPPhIE1LsMRhOPFYql0JMtnN4Q==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/client-logger": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "memoizerific": "^1.11.3", "use-resize-observer": "^9.1.0", "util-deprecate": "^1.0.2" } }, "@storybook/core-client": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.0-rc.3.tgz", - "integrity": "sha512-epUiHzFQNoEr5PYq9069SliQzHl5fVQj94aWdGZWCQPGldxiFtCNB7o32NzwwIVzXOKPzU38qg2B4738jt/1XQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-client/-/core-client-7.0.2.tgz", + "integrity": "sha512-tr6Uv41YD2O0xiUrtgujiY1QxuznhbyUI0BRsSh49e8cx3QoW7FgPy7IVZHgb17DXKZ/wY/hgdyTTB87H6IbLA==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3" + "@storybook/client-logger": "7.0.2", + "@storybook/preview-api": "7.0.2" } }, "@storybook/core-common": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.0-rc.3.tgz", - "integrity": "sha512-uUIs14+35ubRcpYwuX0OHW05tSDC5jeNEY8gv2EjcexBLeNozfGV4Tf5/ncG8glVbp8jGUlu2S3XJZoHKHDSqQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-common/-/core-common-7.0.2.tgz", + "integrity": "sha512-DayFPTCj695tnEKLuDlogclBim8mzdrbj9U1xzFm23BUReheGSGdLl2zrb3mP1l9Zj4xJ/Ctst1KN9SFbW84vw==", "dev": true, "requires": { - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/node-logger": "7.0.2", + "@storybook/types": "7.0.2", "@types/node": "^16.0.0", "@types/pretty-hrtime": "^1.0.0", "chalk": "^4.1.0", - "esbuild": "^0.16.4", - "esbuild-register": "^3.3.3", + "esbuild": "^0.17.0", + "esbuild-register": "^3.4.0", "file-system-cache": "^2.0.0", "find-up": "^5.0.0", "fs-extra": "^11.1.0", @@ -21089,14 +21332,13 @@ "pkg-dir": "^5.0.0", "pretty-hrtime": "^1.0.3", "resolve-from": "^5.0.0", - "slash": "^3.0.0", "ts-dedent": "^2.0.0" }, "dependencies": { "@types/node": { - "version": "16.18.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.16.tgz", - "integrity": "sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA==", + "version": "16.18.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.23.tgz", + "integrity": "sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g==", "dev": true }, "ansi-styles": { @@ -21136,31 +21378,31 @@ } }, "@storybook/core-events": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.0-rc.3.tgz", - "integrity": "sha512-EBihNmxxiIJbPt6OhCTXFPl2T/9OXNVKtsy8hchBNEzp+UJGyeHx+t9K6tRvbcmt5TG/y7C7ZsYx9U28JTwNkg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-events/-/core-events-7.0.2.tgz", + "integrity": "sha512-1DCHCwHRL3+rlvnVVc/BCfReP31XaT2WYgcLeGTmkX1E43Po1MkgcM7PnJPSaa9POvSqZ+6YLZv5Bs1SXbufow==", "dev": true }, "@storybook/core-server": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.0-rc.3.tgz", - "integrity": "sha512-211514C7w8hvu/bLP97KdF7TM8FpcchgDAhldODDvKFyxFTHMcQFj3ABlptsWFO6JxZsy32hG8qi6phFUtceQA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/core-server/-/core-server-7.0.2.tgz", + "integrity": "sha512-7ipGws8YffVaiwkc+D0+MfZc/Sy52aKenG3nDJdK4Ajmp5LPAlelb/sxIhfRvoHDbDsy2FQNz++Mb55Yh03KkA==", "dev": true, "requires": { "@aw-web-design/x-default-browser": "1.4.88", "@discoveryjs/json-ext": "^0.5.3", - "@storybook/builder-manager": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", - "@storybook/csf-tools": "7.0.0-rc.3", - "@storybook/docs-mdx": "next", + "@storybook/builder-manager": "7.0.2", + "@storybook/core-common": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", + "@storybook/csf-tools": "7.0.2", + "@storybook/docs-mdx": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/manager": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/telemetry": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/telemetry": "7.0.2", + "@storybook/types": "7.0.2", "@types/detect-port": "^1.3.0", "@types/node": "^16.0.0", "@types/node-fetch": "^2.5.7", @@ -21184,7 +21426,6 @@ "read-pkg-up": "^7.0.1", "semver": "^7.3.7", "serve-favicon": "^2.5.0", - "slash": "^3.0.0", "telejson": "^7.0.3", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2", @@ -21193,9 +21434,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.16.tgz", - "integrity": "sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA==", + "version": "16.18.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.23.tgz", + "integrity": "sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g==", "dev": true }, "ansi-styles": { @@ -21259,57 +21500,57 @@ } }, "@storybook/csf": { - "version": "0.0.2-next.10", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.2-next.10.tgz", - "integrity": "sha512-m2PFgBP/xRIF85VrDhvesn9ktaD2pN3VUjvMqkAL/cINp/3qXsCyI81uw7N5VEOkQAbWrY2FcydnvEPDEdE8fA==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.0.tgz", + "integrity": "sha512-uk+jMXCZ8t38jSTHk2o5btI+aV2Ksbvl6DoOv3r6VaCM1KZqeuMwtwywIQdflkA8/6q/dKT8z8L+g8hC4GC3VQ==", "dev": true, "requires": { "type-fest": "^2.19.0" } }, "@storybook/csf-plugin": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.0-rc.3.tgz", - "integrity": "sha512-+r2m09o/5B846Q8ykDWjwPJSZXc3i4Z6vLc04SxIR/VJffF7K0Z/vFmTcPz8Qg5wFdfvy/HFqTLpaOJtVwWBdA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-7.0.2.tgz", + "integrity": "sha512-aGuo+G6G5IwSGkmc+OUA796sOfvJMaQj8QS/Zh5F0nL4ZlQvghHpXON8cRHHvmXHQqUo07KLiy7CZh2I2oq4iQ==", "dev": true, "requires": { - "@storybook/csf-tools": "7.0.0-rc.3", + "@storybook/csf-tools": "7.0.2", "unplugin": "^0.10.2" } }, "@storybook/csf-tools": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.0-rc.3.tgz", - "integrity": "sha512-I3QG2buAswIYVbYlstmZAamwLopW6daHj2+wrod+whTmeKShp0rbOrVkU0M3Hpj9CVzFM1/4YqCNOBkS2XTnsw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-7.0.2.tgz", + "integrity": "sha512-sOp355yQSpYiMqNSopmFYWZkPPRJdGgy4tpxGGLxpOZMygK3j1wQ/WQtl2Z0h61KP0S0dl6hrs0pHQz3A/eVrw==", "dev": true, "requires": { "@babel/generator": "~7.21.1", "@babel/parser": "~7.21.2", "@babel/traverse": "~7.21.2", "@babel/types": "~7.21.2", - "@storybook/csf": "next", - "@storybook/types": "7.0.0-rc.3", + "@storybook/csf": "^0.1.0", + "@storybook/types": "7.0.2", "fs-extra": "^11.1.0", "recast": "^0.23.1", "ts-dedent": "^2.0.0" } }, "@storybook/docs-mdx": { - "version": "0.0.1-next.6", - "resolved": "https://registry.npmjs.org/@storybook/docs-mdx/-/docs-mdx-0.0.1-next.6.tgz", - "integrity": "sha512-DjoSIXADmLJtdroXAjUotFiZlcZ2usWhqrS7aeOtZs0DVR0Ws5WQjnwtpDUXt8gryTSd+OZJ0cNsDcqg4JDEvQ==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@storybook/docs-mdx/-/docs-mdx-0.1.0.tgz", + "integrity": "sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg==", "dev": true }, "@storybook/docs-tools": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.0-rc.3.tgz", - "integrity": "sha512-1uGIMq0+t8AUJyj0jkta7Imr3vFLkX8oRXhX5zi7znjWMhgeXKskEFujvCcz7eI1NIU9x2WvFwbtSzWDpdC/0g==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-7.0.2.tgz", + "integrity": "sha512-w4D5BURrYjLbLGG9VKAaKU2dSdukszxRE3HWkJyhQU9R1JHvS3n8ntcMqYPqRfoHCOeBLBxP0edDYcAfzGNDYQ==", "dev": true, "requires": { "@babel/core": "^7.12.10", - "@storybook/core-common": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/core-common": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "@types/doctrine": "^0.0.3", "doctrine": "^3.0.0", "lodash": "^4.17.21" @@ -21322,25 +21563,25 @@ "dev": true }, "@storybook/manager": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.0-rc.3.tgz", - "integrity": "sha512-8Q/vpHkvWQ/fZHRPFOgGC4Qhgpmafe9GV2QKk3yRA/p9zcW4UzP9fbL4qw6tq+5GLM/kFKArBu28ZA7L7sKB9A==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/manager/-/manager-7.0.2.tgz", + "integrity": "sha512-jsFsFKG0rPNYfuRm/WSXGMBy8vnALyFWU330ObDmfU0JID3SeLlVqAOZT1GlwI6vupYpWodsN6qPZKRmC8onRw==", "dev": true }, "@storybook/manager-api": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.0-rc.3.tgz", - "integrity": "sha512-Pa+LabGYakPd9RuS8G7tCp3hPjZwGZL95Dj+yef0bM9WmYBimNjaUsqVJOGttuE4TLXjUIU9+58YImN7QrGfbQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-7.0.2.tgz", + "integrity": "sha512-PbLj9Rc5uCMPfMdaXv1wE3koA3+d0rmZ3BJI8jeq+mfZEvpvfI4OOpRioT1q04CkkVomFOVFTyO0Q/o6Rb5N7g==", "dev": true, "requires": { - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/router": "7.0.0-rc.3", - "@storybook/theming": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/router": "7.0.2", + "@storybook/theming": "7.0.2", + "@storybook/types": "7.0.2", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", @@ -21377,15 +21618,15 @@ } }, "@storybook/mdx2-csf": { - "version": "1.0.0-next.5", - "resolved": "https://registry.npmjs.org/@storybook/mdx2-csf/-/mdx2-csf-1.0.0-next.5.tgz", - "integrity": "sha512-02w0sgGZaK1agT050yCVhJ+o4rLHANWvLKWjQjeAsYbjneLC5ITt+3GDB4jRiWwJboZ8dHW1fGSK1Vg5fA34aQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@storybook/mdx2-csf/-/mdx2-csf-1.0.0.tgz", + "integrity": "sha512-dBAnEL4HfxxJmv7LdEYUoZlQbWj9APZNIbOaq0tgF8XkxiIbzqvgB0jhL/9UOrysSDbQWBiCRTu2wOVxedGfmw==", "dev": true }, "@storybook/node-logger": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.0-rc.3.tgz", - "integrity": "sha512-ViWIJUdFUTrFtcoO88T3h55ryjl73aMNyn8vPvIgejJoJfYMTB5ErI4zLquN23HNc+H9AKKm/qMFFSf9xjGORQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-7.0.2.tgz", + "integrity": "sha512-UENpXxB1yDqP7JXaODJo+pbGt5y3NFBNurBr4+pI4bMAC4ARjpgRE4wp6fxUKFPu9MAR10oCdcLEHkaVUAjYRg==", "dev": true, "requires": { "@types/npmlog": "^4.1.2", @@ -21431,115 +21672,65 @@ } }, "@storybook/postinstall": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.0-rc.3.tgz", - "integrity": "sha512-kOCJjixFwdnZxR6K45XR+6Q4UBzOLdabzh3aednQ/piiqj7ZdldaF75ZfoDhKPK4cjrd5AGU6/OWbsJQ+DLVMg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/postinstall/-/postinstall-7.0.2.tgz", + "integrity": "sha512-Hhiu3+N3ZDcbrhOCBJTDJbn/mC4l0v3ziyAP3yalq/2ZR9R5kfsEHHakKmswsKKV+ey0gNGijFTy3soU5oSs+A==", "dev": true }, "@storybook/preview": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.0-rc.3.tgz", - "integrity": "sha512-7FeJjOV2pNVesdNljzy1DvzhhShZ/pjQOmhFs4GXBXTJCPNQP5iZTSR6b3ehN8L96yVPT5JsdjX4MiyGw2QPnQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/preview/-/preview-7.0.2.tgz", + "integrity": "sha512-U7MZkDT9bBq7HggLAXmTO9gI4eqhYs26fZS0L6iTE/PCX4Wg2TJBJSq2X8jhDXRqJFOt8SrQ756+V5Vtwrh4Og==", "dev": true }, "@storybook/preview-api": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.0-rc.3.tgz", - "integrity": "sha512-iIifbFRmrFIlLzApTZyCWmI3JNt2IxfM8Dm4rNlMJBifjtgHfpxA+DsQI8mW8UGM64a8N1wF7azkN6cnRz6v2w==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-7.0.2.tgz", + "integrity": "sha512-QAlJM/r92+dQe/kB7MTTR9b/1mt9UJjxNjazGdEWipA/nw23kOF3o/hBcvKwBYkit4zGYsX70H+vuzW8hCo/lA==", "dev": true, "requires": { - "@storybook/channel-postmessage": "7.0.0-rc.3", - "@storybook/channels": "7.0.0-rc.3", - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-events": "7.0.0-rc.3", - "@storybook/csf": "next", + "@storybook/channel-postmessage": "7.0.2", + "@storybook/channels": "7.0.2", + "@storybook/client-logger": "7.0.2", + "@storybook/core-events": "7.0.2", + "@storybook/csf": "^0.1.0", "@storybook/global": "^5.0.0", - "@storybook/types": "7.0.0-rc.3", + "@storybook/types": "7.0.2", "@types/qs": "^6.9.5", "dequal": "^2.0.2", "lodash": "^4.17.21", "memoizerific": "^1.11.3", "qs": "^6.10.0", - "slash": "^3.0.0", "synchronous-promise": "^2.0.15", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" } }, "@storybook/react-dom-shim": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.0-rc.3.tgz", - "integrity": "sha512-3rQsOPwNlHyV93311GaGP28BFobEaNfw+djxDBxocNrL07xvY3u/XE6bShKOJ6R28ATaGwXUxmj2Cwtd2GxASg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-7.0.2.tgz", + "integrity": "sha512-fMl0aV7mJ3wyQKvt6z+rZuiIiSd9YinS77IJ1ETHqVZ4SxWriOS0GFKP6sZflrlpShoZBh+zl1lDPG7ZZdrQGw==", "dev": true }, "@storybook/router": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.0-rc.3.tgz", - "integrity": "sha512-D3Uoz1WRFWH3QUjyrDObwCVRYXdSGZGpCN2eh6gjlKC9VQ9ohaGerEdXSsYnAj2lovhfze8oXp+PS1VKJTlpgg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/router/-/router-7.0.2.tgz", + "integrity": "sha512-ZB2vucfayZUrMLBlXju4v6CNOQQb0YKDLw5RoojdBxOsUFtnp5UiPOE+I8PQR63EBwnRjozeibV1XSM+GlQb5w==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", "memoizerific": "^1.11.3", "qs": "^6.10.0" } }, - "@storybook/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@storybook/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==", - "dev": true, - "requires": { - "core-js": "^3.6.5", - "find-up": "^4.1.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, "@storybook/telemetry": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.0-rc.3.tgz", - "integrity": "sha512-0vPVA1aTWCA6jr3iSOPCu8x3zpNUsyxYN30B4b6d3o2iO6YU/CZdm8rxzInv+bKkz2fHFDzCDsfZTgQ5VEggEw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-7.0.2.tgz", + "integrity": "sha512-s2PIwI9nVYQBf3h40EFHLynYUfdqzRJMXyaCWJdVQuvdQfRkAn3CLXaubK+VdjC869z3ZfW20EMu3Mbgzcc0HA==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-common": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/core-common": "7.0.2", "chalk": "^4.1.0", "detect-package-manager": "^2.0.1", "fetch-retry": "^5.0.2", @@ -21586,55 +21777,55 @@ } }, "@storybook/theming": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.0-rc.3.tgz", - "integrity": "sha512-sVt8Egv9CmeDnTJYPsyvlvHE+GX8hAczc1SvuoLeXs/1gsEsnVn6ovCFGSV0Rc7sAr5oSv794/pFUsboU8tYqg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-7.0.2.tgz", + "integrity": "sha512-c9sE+QAZNbopPvLiJ6BMxBERfTaq1ATyIri97FBvTucuSotNXw7X5q+ip5/nrCOPZuvK2f5wF4DRyD2HnB/rIQ==", "dev": true, "requires": { "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@storybook/client-logger": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", "@storybook/global": "^5.0.0", "memoizerific": "^1.11.3" } }, "@storybook/types": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.0-rc.3.tgz", - "integrity": "sha512-2xxgs4zL1QZUdut+Zt5sQdgNCUP0n/y5CRbvEpDwkcuE4KWbfJYixJNumioZ6UwK17ZE9gf4ZxVgttvexmW8eg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/types/-/types-7.0.2.tgz", + "integrity": "sha512-0OCt/kAexa8MCcljxA+yZxGMn0n2U2Ync0KxotItqNbKBKVkaLQUls0+IXTWSCpC/QJvNZ049jxUHHanNi/96w==", "dev": true, "requires": { - "@storybook/channels": "7.0.0-rc.3", + "@storybook/channels": "7.0.2", "@types/babel__core": "^7.0.0", "@types/express": "^4.7.0", "file-system-cache": "^2.0.0" } }, "@storybook/web-components": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-7.0.0-rc.3.tgz", - "integrity": "sha512-enG/VoXu7i5r39Ao4qg6a4Q/aPX5LYkkFaj955BLkUJXW1ZANwjRqo6JSquC4tW8Dm1FYN8sJBAzO6M8YRlbnA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/web-components/-/web-components-7.0.2.tgz", + "integrity": "sha512-qJc5EsNZci0yBOCH9YKuUoSEHvvfetFUsUWpLQa2pzHa648z0Qb8Z1OS/hYCq7PyJN/knb+00Pd8z3zNSw9SgA==", "dev": true, "requires": { - "@storybook/client-logger": "7.0.0-rc.3", - "@storybook/core-client": "7.0.0-rc.3", - "@storybook/docs-tools": "7.0.0-rc.3", + "@storybook/client-logger": "7.0.2", + "@storybook/core-client": "7.0.2", + "@storybook/docs-tools": "7.0.2", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "7.0.0-rc.3", - "@storybook/preview-api": "7.0.0-rc.3", - "@storybook/types": "7.0.0-rc.3", + "@storybook/manager-api": "7.0.2", + "@storybook/preview-api": "7.0.2", + "@storybook/types": "7.0.2", "ts-dedent": "^2.0.0" } }, "@storybook/web-components-vite": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-7.0.0-rc.3.tgz", - "integrity": "sha512-A/+tm879pmD9UwWDJdYimwuIaSQPYyf2FSwL/+zIJ6ZS63LFimkIkt/C7hWD6pYNzk1w36VESfRhEeP3Hu4VNA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@storybook/web-components-vite/-/web-components-vite-7.0.2.tgz", + "integrity": "sha512-9c6wt+4yvOGN3d2FV3dBbtAeswjuIOS5InCQiMHLZEywjghg3SMre5yatKnO88eEk4XBJkamc6rHzSbETrc3sg==", "dev": true, "requires": { - "@storybook/builder-vite": "7.0.0-rc.3", - "@storybook/core-server": "7.0.0-rc.3", - "@storybook/node-logger": "7.0.0-rc.3", - "@storybook/web-components": "7.0.0-rc.3", + "@storybook/builder-vite": "7.0.2", + "@storybook/core-server": "7.0.2", + "@storybook/node-logger": "7.0.2", + "@storybook/web-components": "7.0.2", "magic-string": "^0.27.0" } }, @@ -21832,9 +22023,9 @@ "dev": true }, "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", "dev": true }, "@types/express": { @@ -21913,12 +22104,6 @@ "rxjs": "^7.2.0" } }, - "@types/is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q==", - "dev": true - }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -22123,13 +22308,10 @@ } }, "@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dev": true, - "requires": { - "@types/node": "*" - } + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", + "dev": true }, "@types/scheduler": { "version": "0.16.2", @@ -22213,12 +22395,6 @@ "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==", "dev": true }, - "@types/webpack-env": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.0.tgz", - "integrity": "sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==", - "dev": true - }, "@types/ws": { "version": "7.4.7", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", @@ -22229,9 +22405,9 @@ } }, "@types/yargs": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", - "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -22298,15 +22474,82 @@ } }, "@typescript-eslint/parser": { - "version": "5.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz", - "integrity": "sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==", + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.57.0.tgz", + "integrity": "sha512-orrduvpWYkgLCyAdNtR1QIWovcNZlEm6yL8nwH/eTxWLd8gsP+25pdLHYzL2QdkqrieaDwLpytHqycncv0woUQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.54.0", - "@typescript-eslint/types": "5.54.0", - "@typescript-eslint/typescript-estree": "5.54.0", + "@typescript-eslint/scope-manager": "5.57.0", + "@typescript-eslint/types": "5.57.0", + "@typescript-eslint/typescript-estree": "5.57.0", "debug": "^4.3.4" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.57.0.tgz", + "integrity": "sha512-NANBNOQvllPlizl9LatX8+MHi7bx7WGIWYjPHDmQe5Si/0YEYfxSljJpoTyTWFTgRy3X8gLYSE4xQ2U+aCozSw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.57.0", + "@typescript-eslint/visitor-keys": "5.57.0" + } + }, + "@typescript-eslint/types": { + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.57.0.tgz", + "integrity": "sha512-mxsod+aZRSyLT+jiqHw1KK6xrANm19/+VFALVFP5qa/aiJnlP38qpyaTd0fEKhWvQk6YeNZ5LGwI1pDpBRBhtQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.0.tgz", + "integrity": "sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.57.0", + "@typescript-eslint/visitor-keys": "5.57.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.57.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.0.tgz", + "integrity": "sha512-ery2g3k0hv5BLiKpPuwYt9KBkAp2ugT6VvyShXdLOkax895EC55sP0Tx5L0fZaQueiK3fBLvHVvEl3jFS5ia+g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.57.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "@typescript-eslint/scope-manager": { @@ -22431,839 +22674,780 @@ } }, "@umbraco-ui/uui": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.2.0-rc.0.tgz", - "integrity": "sha512-t5NjWxXivl5Em2xusuudQ8asJtayrpw2Y6G5Ge4P2CdyFF4YD5C1hD54HzkisfuQJDTSogERVtcNMts9y7sHeQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.2.0-rc.2.tgz", + "integrity": "sha512-E8CrJYKLBcCnshV+nTVkfkL9I+0sJbBjKMHOVr/jCOj6Dw9mGytq0bmq8EIT0QcqZ6teZZplkwW2JPQauuv5JA==", "requires": { - "@umbraco-ui/uui-action-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-avatar": "1.2.0-rc.0", - "@umbraco-ui/uui-avatar-group": "1.2.0-rc.0", - "@umbraco-ui/uui-badge": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.2.0-rc.0", - "@umbraco-ui/uui-box": "1.2.0-rc.0", - "@umbraco-ui/uui-breadcrumbs": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-button-group": "1.2.0-rc.0", - "@umbraco-ui/uui-button-inline-create": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0", - "@umbraco-ui/uui-card-content-node": "1.2.0-rc.0", - "@umbraco-ui/uui-card-media": "1.2.0-rc.0", - "@umbraco-ui/uui-card-user": "1.2.0-rc.0", - "@umbraco-ui/uui-caret": "1.2.0-rc.0", - "@umbraco-ui/uui-checkbox": "1.2.0-rc.0", - "@umbraco-ui/uui-color-area": "1.2.0-rc.0", - "@umbraco-ui/uui-color-picker": "1.2.0-rc.0", - "@umbraco-ui/uui-color-slider": "1.2.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.2.0-rc.0", - "@umbraco-ui/uui-color-swatches": "1.2.0-rc.0", - "@umbraco-ui/uui-combobox": "1.2.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0", - "@umbraco-ui/uui-dialog": "1.2.0-rc.0", - "@umbraco-ui/uui-dialog-layout": "1.2.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.0", - "@umbraco-ui/uui-file-preview": "1.2.0-rc.0", - "@umbraco-ui/uui-form": "1.2.0-rc.0", - "@umbraco-ui/uui-form-layout-item": "1.2.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0", - "@umbraco-ui/uui-input": "1.2.0-rc.0", - "@umbraco-ui/uui-input-file": "1.2.0-rc.0", - "@umbraco-ui/uui-input-lock": "1.2.0-rc.0", - "@umbraco-ui/uui-input-password": "1.2.0-rc.0", - "@umbraco-ui/uui-keyboard-shortcut": "1.2.0-rc.0", - "@umbraco-ui/uui-label": "1.2.0-rc.0", - "@umbraco-ui/uui-loader": "1.2.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-loader-circle": "1.2.0-rc.0", - "@umbraco-ui/uui-menu-item": "1.2.0-rc.0", - "@umbraco-ui/uui-pagination": "1.2.0-rc.0", - "@umbraco-ui/uui-popover": "1.2.0-rc.0", - "@umbraco-ui/uui-progress-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-radio": "1.2.0-rc.0", - "@umbraco-ui/uui-range-slider": "1.2.0-rc.0", - "@umbraco-ui/uui-ref": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-list": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-data-type": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-document-type": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-form": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-member": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-package": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node-user": "1.2.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.2.0-rc.0", - "@umbraco-ui/uui-select": "1.2.0-rc.0", - "@umbraco-ui/uui-slider": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-lock": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-more": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-sort": "1.2.0-rc.0", - "@umbraco-ui/uui-table": "1.2.0-rc.0", - "@umbraco-ui/uui-tabs": "1.2.0-rc.0", - "@umbraco-ui/uui-tag": "1.2.0-rc.0", - "@umbraco-ui/uui-textarea": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification-container": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification-layout": "1.2.0-rc.0", - "@umbraco-ui/uui-toggle": "1.2.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-avatar": "1.2.0-rc.2", + "@umbraco-ui/uui-avatar-group": "1.2.0-rc.2", + "@umbraco-ui/uui-badge": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-boolean-input": "1.2.0-rc.2", + "@umbraco-ui/uui-box": "1.2.0-rc.2", + "@umbraco-ui/uui-breadcrumbs": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-button-group": "1.2.0-rc.2", + "@umbraco-ui/uui-button-inline-create": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2", + "@umbraco-ui/uui-card-content-node": "1.2.0-rc.2", + "@umbraco-ui/uui-card-media": "1.2.0-rc.2", + "@umbraco-ui/uui-card-user": "1.2.0-rc.2", + "@umbraco-ui/uui-caret": "1.2.0-rc.2", + "@umbraco-ui/uui-checkbox": "1.2.0-rc.2", + "@umbraco-ui/uui-color-area": "1.2.0-rc.2", + "@umbraco-ui/uui-color-picker": "1.2.0-rc.2", + "@umbraco-ui/uui-color-slider": "1.2.0-rc.2", + "@umbraco-ui/uui-color-swatch": "1.2.0-rc.2", + "@umbraco-ui/uui-color-swatches": "1.2.0-rc.2", + "@umbraco-ui/uui-combobox": "1.2.0-rc.2", + "@umbraco-ui/uui-combobox-list": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2", + "@umbraco-ui/uui-dialog": "1.2.0-rc.2", + "@umbraco-ui/uui-dialog-layout": "1.2.0-rc.2", + "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.2", + "@umbraco-ui/uui-file-preview": "1.2.0-rc.2", + "@umbraco-ui/uui-form": "1.2.0-rc.2", + "@umbraco-ui/uui-form-layout-item": "1.2.0-rc.2", + "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2", + "@umbraco-ui/uui-input": "1.2.0-rc.2", + "@umbraco-ui/uui-input-file": "1.2.0-rc.2", + "@umbraco-ui/uui-input-lock": "1.2.0-rc.2", + "@umbraco-ui/uui-input-password": "1.2.0-rc.2", + "@umbraco-ui/uui-keyboard-shortcut": "1.2.0-rc.2", + "@umbraco-ui/uui-label": "1.2.0-rc.2", + "@umbraco-ui/uui-loader": "1.2.0-rc.2", + "@umbraco-ui/uui-loader-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-loader-circle": "1.2.0-rc.2", + "@umbraco-ui/uui-menu-item": "1.2.0-rc.2", + "@umbraco-ui/uui-modal": "1.2.0-rc.2", + "@umbraco-ui/uui-pagination": "1.2.0-rc.2", + "@umbraco-ui/uui-popover": "1.2.0-rc.2", + "@umbraco-ui/uui-progress-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-radio": "1.2.0-rc.2", + "@umbraco-ui/uui-range-slider": "1.2.0-rc.2", + "@umbraco-ui/uui-ref": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-list": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-data-type": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-document-type": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-form": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-member": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-package": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node-user": "1.2.0-rc.2", + "@umbraco-ui/uui-scroll-container": "1.2.0-rc.2", + "@umbraco-ui/uui-select": "1.2.0-rc.2", + "@umbraco-ui/uui-slider": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-lock": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-more": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-sort": "1.2.0-rc.2", + "@umbraco-ui/uui-table": "1.2.0-rc.2", + "@umbraco-ui/uui-tabs": "1.2.0-rc.2", + "@umbraco-ui/uui-tag": "1.2.0-rc.2", + "@umbraco-ui/uui-textarea": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification-container": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification-layout": "1.2.0-rc.2", + "@umbraco-ui/uui-toggle": "1.2.0-rc.2" } }, "@umbraco-ui/uui-action-bar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.2.0-rc.0.tgz", - "integrity": "sha512-CV40V9kMo5+fmTybbKc/ZKn6I/7xPWlkvPHifdu6WhwRsFeC4P8nPV6CKgxnrTIdrNbUjwK9Kn0UCs/UiKQ6FA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.2.0-rc.2.tgz", + "integrity": "sha512-JI9n1/gB6cr+7k0+v+HVAnfXCkZIN3UYbC8BhC+YinMsKIIWiLgo/FmgClgHmJ9zPD9EhAVqUa8wViM03npyDg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button-group": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button-group": "1.2.0-rc.2" } }, "@umbraco-ui/uui-avatar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.2.0-rc.0.tgz", - "integrity": "sha512-xlz49sZAr5nVb4eX/eCssox8Wn/Qm4slIIZTahu2jKo1tL9s75iEQFjGGjVbNJV3EfEn5fXreHez2ADwA19d5A==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.2.0-rc.2.tgz", + "integrity": "sha512-WnVicYfGExAKA7gXHjVk4dcANRrWYnXLlAWiRS9SOVDFUYezbNbX82Nt2rMGxZ5K3TJr+WWxBa0b2AYhz/pWpw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-avatar-group": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.2.0-rc.0.tgz", - "integrity": "sha512-XQjl2YFGtg6vFVrlUoF/Ulbc9tmbFAbIQxSJWP/CxvQgOqFRldoeNZ9puiTOFykvCaKDc2MBkTwC2vUI/F2DCA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.2.0-rc.2.tgz", + "integrity": "sha512-bEtJzr4tC8oL4KszNxqu3ey1DPg9hZnaEND7p8RDXCknZLpi9flhpU73esvskiCRSJr5CTu0pTwJwOR+Bhwr9Q==", "requires": { - "@umbraco-ui/uui-avatar": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-avatar": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-badge": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.2.0-rc.0.tgz", - "integrity": "sha512-QoW0puGm6yF7h77C9tq4zc8jZIDnmXsokthCVAcwks2i4BQV4SRfsEJZOQAphdNE+VOIPO5whZG5+D7smDHhCA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.2.0-rc.2.tgz", + "integrity": "sha512-Z/zxDmf5WbeXo+3CrB62TOHgg5cEcKNB4vc06NAllypzLBKdBPjRe3FtBtRL8ExwZmXoAlJmlItr6nEnfogKUQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-base": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.2.0-rc.0.tgz", - "integrity": "sha512-q/QU6MRoU/d6pepobqNjEEUu8fcUfQ2RjT4wWQA/z1CFtXF1xIQGGHemdmkb/V+RqUma8CimDscklxxR7yARRg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.2.0-rc.2.tgz", + "integrity": "sha512-rGHM+OgldohqNlq5B1BMcpVkZNMu8A0X5uN6cG74qGg+WXqXbX9XlRFxMMuoxCTgtqowGZMn7St+Tu3O8GQAiA==", "requires": { "lit": "^2.3.1" } }, "@umbraco-ui/uui-boolean-input": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.2.0-rc.0.tgz", - "integrity": "sha512-Jno5TPnwJbOi7yvSigCBmMEqK1fY2XdKUMFpB2ZXVi4T8o69cq5m+bcboARshf1NdPmkWqQMDNroMqG73gFhiA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.2.0-rc.2.tgz", + "integrity": "sha512-W3qKtrH1c+nPe0yuz8sySf6hF7rOK9Hg3I2HZ5jRmoKnDmTLiZpXhDDyaYKy1oH5n/WdRlJx9aBaZG5TMmRqpg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-box": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.2.0-rc.0.tgz", - "integrity": "sha512-+JYJ6lwoLq7MsD51acS7ZOFrVwUiWRWywL90rGtPYXHDTkw5D/MdeFgbQjBU+vcIEEZWR5iwNX0uTpA7hO3xKw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.2.0-rc.2.tgz", + "integrity": "sha512-c3rqT0KdCnBqWv8Lbzpetj/MldQSTQ7/7uxTtHcS+Wclkvr+ktKeai45NebiKqDCb6l3scy2Va0TRoJBUNmofA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2" } }, "@umbraco-ui/uui-breadcrumbs": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.2.0-rc.0.tgz", - "integrity": "sha512-SyjimBB0E7fpIepBxcVOIJSYvg8Yjgtel8fA7VG/sPVmP4YSZeGoRB2G/eHAvH/VG9L7/ENOUIzEYCFYXbHJsw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.2.0-rc.2.tgz", + "integrity": "sha512-xX93r/n6dKY1D0wWRx2FKDVtJ2Yja91KPheHExSPuBuwUI0C0hBI02U+AhWjr/6+hUl+Kc0CWOdoYNkuum3RZg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-button": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.2.0-rc.0.tgz", - "integrity": "sha512-VnA+1FoUpg5tMrGfpLnFCMLtDPM+ACAu1+XQcuo6o99XUYdSf+Z5lf/P4NBCDfdqdKXBSDut/Npu7DYJsYIFHA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.2.0-rc.2.tgz", + "integrity": "sha512-IVtsxvRPT8on8vomxCWWRwhJbDl8dDmeUxSFxOPm/LrDZ8Y3sVf5Z248mBVCvX87E9AsBYkd7WX4KRDf3vubFQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "@umbraco-ui/uui-button-group": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.2.0-rc.0.tgz", - "integrity": "sha512-ROxoZPTVDkJKhX9wcmZGOqdtWiVs13QpL/2habQTzkS2JeaTTiLhIf/KPeZpZ0JPSbJnh0yj5nCL13Ov2rS96g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.2.0-rc.2.tgz", + "integrity": "sha512-sNxAiZGCbjKE95hiCroBb5DBIiIncpojpS0ARWFHXQAbjPi99qP72cE/+D/LF61NZwDKyyP+GKrzOmzgI4BQMw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-button-inline-create": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.2.0-rc.0.tgz", - "integrity": "sha512-A/FO9mRXFku+Qjg2uDNbDNRamKpP99kckwRy3hH8hzl6MpynzD+Cr7VS/bL0lmBa/G55XVrNi0BeuGbunEGvpA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.2.0-rc.2.tgz", + "integrity": "sha512-lNIFbBuiv113JyS8igqV7VhVppObRa34gpsflcmkCaCN2Khm6XVVsG4h226RNrhnQgjJ0J+r+/QTdaIUKLYX+w==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-card": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.2.0-rc.0.tgz", - "integrity": "sha512-ZnQSb8k9N6wSeD++8pL2R7jo01FW3bKQ6SzAAlq4MFppYaylgW6BcnhIcSxiXciWRgNsb+4BJhc/0gxbJh25+g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.2.0-rc.2.tgz", + "integrity": "sha512-7hlGuunANegwsC6R4N+ILxNMHwXzB6tJzO/enMnrAQA7SkuLDEJB1rHy2TOhUOjEP1hQREM+rc+srX1wT8ZkCw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-card-content-node": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.2.0-rc.0.tgz", - "integrity": "sha512-xgS1hK8OYimUhKP//DpKt2W054ciW+1DiEV0Qr1zWRDgAN3F85IwNiLVs6JPeBjY1yM4mOvC29POG35jc/yBmg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.2.0-rc.2.tgz", + "integrity": "sha512-RA4VK+XoJQpQmc3sfkw/ZnrMGCn1HDiFowanwrR8SEYOPiMbmGUhRMnnmsa8WSOlNJ4KLpgN8vyaa7cvu93ZuA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2" } }, "@umbraco-ui/uui-card-media": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.2.0-rc.0.tgz", - "integrity": "sha512-8fH3IrLtPV9rE/dkEID5rMoTIPEg4E/9VoYHms59zNTdtyQKG8dM0vLSKTbz72zaYH+Ox5VHp4X/CVIXFDH2rw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.2.0-rc.2.tgz", + "integrity": "sha512-VDMbhevtLu0ucbhqVf17rKUrRfiNyyzttBFHX7NDUfeXGoqjTb98z6aproP5ujvqsWhECa5Q2iemTbxqVr/b7A==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.2" } }, "@umbraco-ui/uui-card-user": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.2.0-rc.0.tgz", - "integrity": "sha512-B0QmgKXWt5yU0/misn3sY8PsAjOfNzOCJ/LkC9cI2zGX/tQNbfziOFwk6bAQluQP2zJnAoab1leSghP+1PcTEA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.2.0-rc.2.tgz", + "integrity": "sha512-SVh2Rf1b/PL3WamMlSoLtm4bFLj9Ms33wS+94FVoEKikH/b/5OSHJyMnW4h6K/c2yyaMT7/y+tQhoc9oGcq5WQ==", "requires": { - "@umbraco-ui/uui-avatar": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-card": "1.2.0-rc.0" + "@umbraco-ui/uui-avatar": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-card": "1.2.0-rc.2" } }, "@umbraco-ui/uui-caret": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.2.0-rc.0.tgz", - "integrity": "sha512-V4nKfTYEqJvxG/jbwwPCzZuSK4qKra4aqWrtU6B6QMcYohYJVTaEvVE4No46AtbtrSfvKm050pMzb9sRxiMLcw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.2.0-rc.2.tgz", + "integrity": "sha512-/19J8MpMLkWT5u4QdGGmf7xqCZ0URB0YUq48rsn5y/efElWi1HG0ptJwGoqrW5hhKuLWEcZG4V1WVJxT4LgwZQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-checkbox": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.2.0-rc.0.tgz", - "integrity": "sha512-7smHPIBmniccCuaA3JaFCLia5uyClFElv3WBngX2qbz6JwKXQ9nemYaFOuM4KjcukMH9iFMQQy7sbrmRar0reg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.2.0-rc.2.tgz", + "integrity": "sha512-shjQWdFjjRnbXGaZa6BkSxC2Q1jfSh5q6xVjkDrcGToOW94q6PURF6Vm1aodsBVWZGuJUzmTdT41mhG/SjsIPg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-boolean-input": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "@umbraco-ui/uui-color-area": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.2.0-rc.0.tgz", - "integrity": "sha512-cUJdrcNEkXNAwjeQEV0Vi/Hj4xaj7rFOMm/U9Q9JlRUX05xkBRl01AjS6Qi0QDKEPtLG9YC+AnNXpFFA1rjtaw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.2.0-rc.2.tgz", + "integrity": "sha512-LwdmkwFu+3Ms9xm86sZovTItlWlHgVfHPOMnW+nxUkVMfwv1FjK4n4G7xVJ9nmpa8W4GjMwcENjvR0Qs2/JqqQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", + "@umbraco-ui/uui-base": "1.2.0-rc.2", "colord": "^2.9.3" } }, "@umbraco-ui/uui-color-picker": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.2.0-rc.0.tgz", - "integrity": "sha512-rpMBG+ZyrL10w7EX/UqtWZHhwZ3oe7MSf8cQqimK/Arn1kpBqZ4JJLpJPcZ1bwcYekHbT5LbHZBD/EuHMRP1bA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.2.0-rc.2.tgz", + "integrity": "sha512-Ibn3dRJn/N8E9mRi2EWEFxyL4BwEbraytGNq7jD+iJZ9cIaZTU/zuxYGxNFNBP3EDsdD10iLnyBA9hfyEDxRcQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", + "@umbraco-ui/uui-base": "1.2.0-rc.2", "colord": "^2.9.3" } }, "@umbraco-ui/uui-color-slider": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.2.0-rc.0.tgz", - "integrity": "sha512-04qZnUlVJmk7dN+r8BJNeZHvmu5/TqIq7WVlmHmfmbULW4hJkw18qBamfhOP7nFz06b21pfLFjBy61dqqH1tUg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.2.0-rc.2.tgz", + "integrity": "sha512-aQTTizgH0oNHBFRXXr3tjhH456SRx7TVx797elcA9b0NtSFMuFwWZZI4qqppHTaVkVGZz/0coF973Xu8s5GSGg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-color-swatch": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.2.0-rc.0.tgz", - "integrity": "sha512-acTb4xOwSMU3j1xa0IRpykdw7y9wQZoNWBPA/wWilCYJcxnJ9BeDU7QZaLrkGYOhq8vfBjtxO6+DZ4gBd5/4CA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.2.0-rc.2.tgz", + "integrity": "sha512-A7G0kz/ZEOANizHNek6nsq41XrCbCBE5XTE5Y0afUEbL3RM37yZHsjNFM4H1iJs57plt4Mfb85TQqb3h5HnHJA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2", "colord": "^2.9.3" } }, "@umbraco-ui/uui-color-swatches": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.2.0-rc.0.tgz", - "integrity": "sha512-mJIi+PYeQP9naFZ9CBWyKIT5C10kzavQXkfA5dp1WBwyoTbmJzDaXXkz0vf1IcYSKBjJ3y67PmVRdaR30J8GZA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.2.0-rc.2.tgz", + "integrity": "sha512-FskzxqYXCfi3gV0BOfoo5acDJEpiHF2ZIcjYxgrPNtG2phjVZ1Mk1BinfKRRibXqKGU/uhAQxbNIygxW/C9bJA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-color-swatch": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-color-swatch": "1.2.0-rc.2" } }, "@umbraco-ui/uui-combobox": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.2.0-rc.0.tgz", - "integrity": "sha512-TnijClKq4NK7tGY0VaG3bZaTz8FYoLFezl1eXKIHYpx/hiidbu+a22Kcyio5TAW7VNFGFjJ3h3JQt06pBRBphA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.2.0-rc.2.tgz", + "integrity": "sha512-8BctuzQ1hoiAkhV4XU6sOICoKWn4EMIesWiQavl44IILuldrJhBc9PJlSkBeaOs8raOXCwWb7yhDf0w68rlY/w==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-combobox-list": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-scroll-container": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-combobox-list": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-scroll-container": "1.2.0-rc.2" } }, "@umbraco-ui/uui-combobox-list": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.2.0-rc.0.tgz", - "integrity": "sha512-K3CcgBPXiUnV/1sZvwKtxdgmIjjYWBNDtJ8Bc2jpqcyN2C0rcFLBwJwTXzBtIxakPXj9G6vP/OyXRUnN4I+lsA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.2.0-rc.2.tgz", + "integrity": "sha512-hOnfyje4XzhPWgDlbfOlaJOIUlMvc0RmwpKmqFynZMo0wZ+zuPMQ34jjPRAkgDa7dHkkAmbhZczLHdPF6I9aFA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-css": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.2.0-rc.0.tgz", - "integrity": "sha512-eE093LnIKdr1RKggmcsVI2G7Tyr+I0lV7XH4Kuq3cPmDaOC1C1UBvRPVdVhdEtQ2LA67SAsTvXWpyEuYKZO6OQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.2.0-rc.2.tgz", + "integrity": "sha512-yEHxeUFqRPhxHblR/jjkNLabMFZXZ3aMGVGgehBvsGM01D3yQq9wvFe+qtjr4TGXs7v62DIT4bOtP0f45KfRRg==", "requires": { "lit": "^2.2.2" } }, "@umbraco-ui/uui-dialog": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.2.0-rc.0.tgz", - "integrity": "sha512-j/ZrWFJPXBXvt0IrxEB6DoUOejsDClJWlfpH8bft8bjF4bw0uDWDFXW+wlE9aSYagALYXJIJmKzyzfxPJsjyFA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.2.0-rc.2.tgz", + "integrity": "sha512-Jw0YfP4WJMaSsdvUGPjOQtFUiAlno2knxt709V2IugdbnfjgSYllBzQGNHWmbBFS1kJtURAcCWJX74B9P/qRfQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2" } }, "@umbraco-ui/uui-dialog-layout": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.2.0-rc.0.tgz", - "integrity": "sha512-ZpLOucZTNEsm9cuLxWOzN437iI0zxVdArYBaPQ8G7Mkn3AxvOoqiETHq+rnNJRIsOIh0CfMuD5XWX6hPt2w+Ug==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.2.0-rc.2.tgz", + "integrity": "sha512-gqFpO38XtYXQszCwUqt2jUqFHgcIIqf8+evlcGTXr1arFPpLfq2FWbEnXR83BjVRhHRCHhmLrbsoAZzwaJmToQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-file-dropzone": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.2.0-rc.0.tgz", - "integrity": "sha512-1dkcZ6AHsLABFDhCWwNdyu5oMrNnV25cmbUsesBSyM3zedDtYKD2MZLJ+QEBXaHBtiDxO+G8mAL6Jof952gheg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.2.0-rc.2.tgz", + "integrity": "sha512-Pm07+UkQmp+SXuvynjlKlc+/NOHBVve3k6hoPX5Z0mHWUG0XBG0WgbrTJoqgQYytbndt6AaE6vrKKyPE/VvoHw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-dropzone": "1.2.0-rc.2" } }, "@umbraco-ui/uui-file-preview": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.2.0-rc.0.tgz", - "integrity": "sha512-fqbMD+uwxvV+uFrj5akmIkq1ngASKkZunt7wgq4wFeFksAi9QCMdfvdAE0aqhy9RbzdQHfLmaxOOrL8aLh3zwA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.2.0-rc.2.tgz", + "integrity": "sha512-eG+BtfA+22KmY+UoMBp8iJDTWUoy2Iq0jLahWmHADaQ+HWUMJ/CXYFquNVfk2nQ5SmYrJV+qPC0d+ikf4UXVmQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-folder": "1.2.0-rc.2" } }, "@umbraco-ui/uui-form": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.2.0-rc.0.tgz", - "integrity": "sha512-kAR51/hAxg8rbLgam9/te3kq7aa9+HTQ2YRRyrdy2pJVVHMDIl2lKvzVf05ya7nTapW5+SMoUqWV5WjZg3lhjA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.2.0-rc.2.tgz", + "integrity": "sha512-9iCKrLzmjpUaaL7l3C50UL3iJOYxqEY3aFLx9hRbpFzyQvwMmt/hcKiUeSEVjEtAIxpk5wUTwD7WlxeRve0POA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-form-layout-item": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.2.0-rc.0.tgz", - "integrity": "sha512-fbY2B2QJtmnd+GdLwEac9+egrIADeCJiGiYgl1ohcp0TYTuQakT6yhNSdkVsBpJ4dtH1+xFbsW2j8a5oRHozoQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.2.0-rc.2.tgz", + "integrity": "sha512-jFmw83oA/ecFOItGc27oHUHa2c6gA0gpzS2qsyYs7pSYEqwUxxe5iWI4otl3Ioi/3GgJwp69qzmVaEYuBgy/Sw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-form-validation-message": "1.2.0-rc.2" } }, "@umbraco-ui/uui-form-validation-message": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.2.0-rc.0.tgz", - "integrity": "sha512-gSEqpaHVWYGs3SxpflRTxO328ITRxmRWsDj8nWXCFGKtUK7xNKdhr85P4DWxW76u4UdcCk+lReoUxmVRelMm1Q==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.2.0-rc.2.tgz", + "integrity": "sha512-rbdJIO9uvSclc+8lRNcOv3ePp9Aa7wW7pZ6S8aY1bkV03vTAp7syKILNF70NIzxSq1yOKBE8xFXspHxDftdEVw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-icon": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.2.0-rc.0.tgz", - "integrity": "sha512-U98JO00fXes3Ifjq144dDKKh9ASEJ8UkBgb9aDRlVEIuku6VfhUbENLH8r3zSpgFh3lV0ObXLJMnbIQrW+tRaA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.2.0-rc.2.tgz", + "integrity": "sha512-DKKco6oTG0XpwcYhLscRo22tF1R3Y/kQHn2tDi1T8IBez/AdknQPveYOGoUVC2jENngeNahuXNpWwgNvTpn4Zg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-icon-registry": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.2.0-rc.0.tgz", - "integrity": "sha512-CQTPh/2YE6Zxa4yJMNHPDBUOibmzkNKuyavwMwQ3oFB6pOJU5agBFasS3QOaw8p6Pv9i7wwKQC7keE14fJK26g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.2.0-rc.2.tgz", + "integrity": "sha512-Tt9RiNBCsbsZo2uh1saw0V8Z0pIXOAvRr9UgBOdn0GJIYbKDtHV1yALyqcQ//qenwkkPB5a5ly0a3tJHzeej0w==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2" } }, "@umbraco-ui/uui-icon-registry-essential": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.2.0-rc.0.tgz", - "integrity": "sha512-zSILXAwVAvb52vlFgfIkqnaPm7So9s0MaPrjKjgluC2Ii7CZIyNwr9fjaboSrPngsjoGT2C4gUYYoJjp6vw5ew==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.2.0-rc.2.tgz", + "integrity": "sha512-K93QxSybUhz7Q/UWZVqib2LGxlIQkTGF0fq7yDbGAYnx1OGJ7fKR0BjWok0G5Xz+7bCmjfNqTcb364XECUKpjw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry": "1.2.0-rc.2" } }, "@umbraco-ui/uui-input": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.2.0-rc.0.tgz", - "integrity": "sha512-e8CabJJMrD+D8wBXKDgHQ8T7SQ7Rf7iLPzL55duLUrO80PATiMxqppyIh567bW9s5soDX7DhQNBX+UIa57chsQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.2.0-rc.2.tgz", + "integrity": "sha512-+Spx/J0ofNL9Rozy05LdKBxDh8It32JzRjt3LCOuBPrN6Tme5HwCmcWtBK2Cn2HQ1zQJgnD+h1KItSyyYPXsnw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-input-file": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.2.0-rc.0.tgz", - "integrity": "sha512-kkVSCqv61AZEHd0b4p0vmoEYosDjLl/YG3a2FEuXjBn+F6lETW+RriuhKY3a0pyRA+gTI9GRR86icpSC0KpHfQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.2.0-rc.2.tgz", + "integrity": "sha512-zoFda6gYT1OSJDd9ObTzx4+xEL5/rBrzAZBniWJUQqrPPi3NfYrT+q4hY9c262F/HPbiyWYIH7xxMmr18EfNfw==", "requires": { - "@umbraco-ui/uui-action-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-action-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-file-dropzone": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "@umbraco-ui/uui-input-lock": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.2.0-rc.0.tgz", - "integrity": "sha512-k1azXchNXcFy0QgsIm5ecJWo5Yh95vPRfwTohiDUUg4kla+yHIVHcpkNosqhYD4FKm8cAv4cdQr7o2eI+ExL6A==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.2.0-rc.2.tgz", + "integrity": "sha512-jhWEm+qeJs4PZLEGNUs9DSTs3VAKe6IS70+i9fQQY0VQQgyDzMtAqf9A+93D6EgT6pLu7HdtfS1yZVIzAteEsg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-input": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-input": "1.2.0-rc.2" } }, "@umbraco-ui/uui-input-password": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.2.0-rc.0.tgz", - "integrity": "sha512-IWsAJCRUZFVdpUDnup60i7MS2A4DePU1YIp460veAbwIZZjZBG4x9mmD6EvjFkP5YDaqCwyg3k75p3hC9RiQzw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.2.0-rc.2.tgz", + "integrity": "sha512-MafMMXrAof7YUKQy+hwKfwOADwRQV7xKkDjagyobVsBp2ccCRndZKTOAyBBDTqu+7w/k0SbHd9BvC4xCvVUwrA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0", - "@umbraco-ui/uui-input": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2", + "@umbraco-ui/uui-input": "1.2.0-rc.2" } }, "@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.2.0-rc.0.tgz", - "integrity": "sha512-y5uKat6H7G752q2svp6iFi0UlnlpZuj+qlUVp7GJjLJ2tYWS7M13KnNXrhOOZW5kusXJsXSw/+g3YE30f3rydg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.2.0-rc.2.tgz", + "integrity": "sha512-iMvqmDNwU9R0w3D4xRb9nNdoYOiXQJfE+6ojwld84XhfyfMYGIwmiIlCnIzW6g8yFPIDOkF91B+wKgyk5xBlqQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-label": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.2.0-rc.0.tgz", - "integrity": "sha512-aG/oSvVx4U36mW2XK/HF+sEj42WM/PTO4a/sDYA62gDhok1Ksl+Mk6tdTDzBh3sdGYoZDemtOcWvjd87pPgimA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.2.0-rc.2.tgz", + "integrity": "sha512-eYY9e7cPGdwkw3JvM54fPpjn28bkKi3IVkfgDgvVP71vbuoBGCOk4rMP/H2XLElwKFTEM6EDRsXqrth02Ws0SA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-loader": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.2.0-rc.0.tgz", - "integrity": "sha512-hfI3wZQxrAbsq+sNca6yfZ41vUOPIlg1clZNCSh76XD5YwTgFtHDse1HBrib7NY4kkOxHhRCFW4RO7BgWJcbtA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.2.0-rc.2.tgz", + "integrity": "sha512-Vms+NrPH15BhhawaCIdTzC9vY/2oMwu4/3AdEzHznELx3OfZbrt57a+Cpaoq6ojJoynJdGHQ+Kl92cKcv2kk3A==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-loader-bar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.2.0-rc.0.tgz", - "integrity": "sha512-DA1Tbvnri0HWbbzSe5v4wVezdHang8cmAfActLawF6LG9CV6LZLxSMMsSzbDBisGS8cscc0RgAeSLXnlNaLN8w==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.2.0-rc.2.tgz", + "integrity": "sha512-dGXjMdWzndnWdbh6bNaeR3rP36Oi91l82Hx5mlByAKYVBG/q0J1nDn4gZhfczEx0ItaCq9uB8dfa3WolZKaMTw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-loader-circle": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.2.0-rc.0.tgz", - "integrity": "sha512-GrRVkZrLSk1Pjmo0JtbGNUfYCVZ4ZWIGo78GDPRPOdccuTVNLS1HwdKfNV+ZRJe0hJYt1ALglSprujuG67ORcA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.2.0-rc.2.tgz", + "integrity": "sha512-Djp2Vikv8t7y4yw7hrAveyRe5ASN2ooRCKrN49F2Tn8fKhi5NfZ0NRKMtIU+QZNzLMRA1mjrnxB2mqcD/xGsug==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-menu-item": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.2.0-rc.0.tgz", - "integrity": "sha512-XGytEGLb1tTnEP6eB6K/RJXYzGhhgfwrm7/OKuMvIANc2OI0toYpDSOeRclm7W4tQwZCM9OadnGXZYkzJGcj5Q==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.2.0-rc.2.tgz", + "integrity": "sha512-i2YRq6DtxhjjpvhdbG6AVSWGMfY1sxBtylMwyWPMWCY/l0ozQrS8wiE34CEopvQszfnxKABb9nZYM6de3ybbZA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-loader-bar": "1.2.0-rc.0", - "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-loader-bar": "1.2.0-rc.2", + "@umbraco-ui/uui-symbol-expand": "1.2.0-rc.2" } }, "@umbraco-ui/uui-modal": { - "version": "file:umbraco-ui-uui-modal-0.0.0.tgz", - "integrity": "sha512-BYfbO5UocZrtj8t1Baox3ivldbNyoKugZGvwKXl0XZ7FZVGvAMrVmzZSI6KtEvYl9Jey/I8VqkZh30QBflEM0Q==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.2.0-rc.2.tgz", + "integrity": "sha512-mWGhjqb4xk4QJsflXByYy9wvKtUdSVyIQv4064zGSBWH9VgUkSmz3hHrBpjQU2MjCpj6XW96aeEIkg7mY9J0VA==", "requires": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - }, - "dependencies": { - "@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "requires": { - "lit": "^2.2.2" - } - } - } - }, - "@umbraco-ui/uui-modal-container": { - "version": "file:umbraco-ui-uui-modal-container-0.0.0.tgz", - "integrity": "sha512-nsw2fkpOnG7pU+TqDZqXF57eNw2a4zIyN1TllVNEU4tdPrF5c4vTyIzE5O6Flsu8euCVruDZepo9SyLTm6jnew==", - "requires": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - }, - "dependencies": { - "@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "requires": { - "lit": "^2.2.2" - } - } - } - }, - "@umbraco-ui/uui-modal-dialog": { - "version": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", - "integrity": "sha512-hv3LQ/kzTZQMMXDt8NM5ZJTIsEYof5zKx9VFxbUGnhJhNRLeJ4bk9suWVl8h942VsOJwR+NbXzOs4XTIqXb9MA==", - "requires": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - }, - "dependencies": { - "@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "requires": { - "lit": "^2.2.2" - } - } - } - }, - "@umbraco-ui/uui-modal-sidebar": { - "version": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz", - "integrity": "sha512-qQTO/YD3wzACmHf6QVW5c2smWMPougDwyKLV6Zku+QdgeZleS1ZiR/AvqHVHiRjuQ84ZhKyBl4H1IcYnAMntnw==", - "requires": { - "@umbraco-ui/uui-base": "1.0.0-rc.0" - }, - "dependencies": { - "@umbraco-ui/uui-base": { - "version": "1.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.0.0-rc.0.tgz", - "integrity": "sha512-MgWuWCPKMyn4a4MzrgxCCKGb7w5tXcEnG5y6IyYKV2BNfcnSqyRwfwE3bueDRyDfeC2eclGM5AStONBsfw63eA==", - "requires": { - "lit": "^2.2.2" - } - } + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-pagination": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.2.0-rc.0.tgz", - "integrity": "sha512-ut26Z5NPaQVs4u45TcdgaCaj2Qt5jNtCgyHpgMhqfbs28lAwwuvodvLClQ1TiTv+TzE+Kzq6YyC57tQJVkRrDQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.2.0-rc.2.tgz", + "integrity": "sha512-tk5aS8NyugAPl7Dh8g8Igakup2k4eNT5clGvJacRRHIPBOn0p1gV6vKL3NDiVCmHHGLtgZMVnQQN7uSfm/Xj5w==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-button-group": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-button-group": "1.2.0-rc.2" } }, "@umbraco-ui/uui-popover": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.2.0-rc.0.tgz", - "integrity": "sha512-AVkXJsP9IuL6rGXzTvUNqvDEA80vhMOGBGLVzwumfNzV0kIjyEWtAXQWIllssUUI5pDUY1FY7hk7RIiB5QmczA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.2.0-rc.2.tgz", + "integrity": "sha512-ecxT66ZrU/xTRs0vrpPIfr7YpykVtSEh/vwwo9DSkhaaIotPorMrRXi7LixS2mllslHvsETis6STCzsBylqB3w==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-progress-bar": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.2.0-rc.0.tgz", - "integrity": "sha512-RjmEpCc3moZynCDOAM5eGKi/7y2pXPGB2ohvcjCSZVDFxX3QZAyRB5PIAAT/pNo0aPii8HxTTE3b4qJFurNxGA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.2.0-rc.2.tgz", + "integrity": "sha512-KaffpsaFfj/7w2gGziMoYLvcQLCaDFhhCvbOYZE2DyyagIcJMr59LQYbX0ma7cTtUKSaJTk4RB1SWzIEuDu9Mg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-radio": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.2.0-rc.0.tgz", - "integrity": "sha512-I2j/bOLSHSqXnJx/Fh9Jfabao+a5Xx6BYRgkJCxRCfHl0FTncufmSwDFs5WjrR45eKFUuU9gOWtbddFQjCdBMg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.2.0-rc.2.tgz", + "integrity": "sha512-jfGK/wzXue9s/E026k9ZBThCodrzRbpw/xS8xX9YHq3NvJNjfPTMABuTM2VpW4sPZtkdpkjZKNreJAfpYJoPrA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-range-slider": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.2.0-rc.0.tgz", - "integrity": "sha512-EhdQAu6POZL5a8IOjBcMraCcufa1JYesVuZ2VZwGaOojfcVGjH0rIuqngpq/Oe5GAJUMOgzqCKmYyFhFCfmLpA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.2.0-rc.2.tgz", + "integrity": "sha512-5K//peXBIAsOh9uAcY/8U+qoRxTaHGwfYl5SYjD/NnfpHXPY8xxXtMDHZcPXnSZLyVsoL2DSroFXgTLSJLsYlg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.2.0-rc.0.tgz", - "integrity": "sha512-rrpWYRjjbx+ge7baO+tRcn+Qa1nwecQ/Sl4d/0rgo3xP+pKAnT0rozt6htfc60a/9Mnbz7mbj0NGSzMOJZRtJA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.2.0-rc.2.tgz", + "integrity": "sha512-Qdat4AxQt8neF1sIWvWDGoWkTDa3BHOhc8JUw7QxmcPwvv11Hvg62tAfRN7zbiVcTmpYIPoy6GV+tgAUn7TAIQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-list": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.2.0-rc.0.tgz", - "integrity": "sha512-8h+GG1kGc3LM5ojCZxsHRjHuvopuc5ZYXtg/Upgm7G5ct32JbVnUNM8b6hjH7NHSskDTLoslO1+wnalHcPc/Bw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.2.0-rc.2.tgz", + "integrity": "sha512-t0iriFiVPLepRgB4JbCu8YNKBycHHusev3SBGtAV1NJ6uBKVcNgoKk2UCcmy4H9nq+pMAafXm/HX/Oq5F4JfZA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-node": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.2.0-rc.0.tgz", - "integrity": "sha512-v9UpY1ADCAGPaFzRBLU2OTmczBNYAUN9Y6OVG5QCHUfGIvo6lwbYWJITN1tVAiofJemaTftJI9j9wy77kDTvDw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.2.0-rc.2.tgz", + "integrity": "sha512-Ji90frchpuqcl/wro/Np4hRhQLa15pvb078UA+zOSpBLHO03Py/Bs6l3BzFYskfOntC3EFSHm6HxFntPjAKFzw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-ref": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-ref": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-node-data-type": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.2.0-rc.0.tgz", - "integrity": "sha512-TvKxerjA3vsyuLu9peVnhnOAPKzeQPsZupSKixMqm2x2oX6S1QoCPNpSbIYi6mEcDnjFMi62VFYojinbngQ3CA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.2.0-rc.2.tgz", + "integrity": "sha512-aNV5GORnxkPvu0HWKfc7xzRDGYKMzeAXPLjYpcArKKFDfI95GTTNMvR9P0M/8IBJWiGb8oXCjMe1+YsVUCBSfw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-node-document-type": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.2.0-rc.0.tgz", - "integrity": "sha512-ALhCascGg+7Gl7IDih/K2ZirWhKG9pyfH3q/m4nfmNVjutLqTT1vOkvj/9DUjJw1hPdWFdn5jFYiPr1XpfUHHw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.2.0-rc.2.tgz", + "integrity": "sha512-WC3aCJjVhDNFF0aSvMf/wZkRzQMmAvkRQzcresG0J20xzGyNh8HiDVTFp24luT7l8vYqAeAl9NlLYbCWZAEyvA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-node-form": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.2.0-rc.0.tgz", - "integrity": "sha512-tls/sJMu1MXg9vS16fpAXSKuntqKO6vkiI4oQHH1w5OV+QaS8+8nAsiWD3ogDN2P7JyOlfCMnqhj31E2EFqGPg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.2.0-rc.2.tgz", + "integrity": "sha512-UxK8tKD9pYuMU6rYfBcT3zyf/NM6LtnXCN/p9/3CWDhAeHJ4gdf6fFoPzgehZlxHl22BUQ0+bjZ2VF5/4KKtbQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-node-member": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.2.0-rc.0.tgz", - "integrity": "sha512-Z+2/Q29kJbio7hSNntRTuiw7AXL7/6Y79rmEaDtQdz51f+hkaO35f/fQTLTf5VDuWTzgG1p6jcDpdlRMq1dQhw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.2.0-rc.2.tgz", + "integrity": "sha512-I9RZAg0AZKLSlmJBu7iL9OHoNg5f+FLdDWv8cO060LRXGftjNdnjaLwlQFL5uxXvXwDI3E4i94XFThiju41fWw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-node-package": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.2.0-rc.0.tgz", - "integrity": "sha512-SBQgrbvEP7dXkoZ1b1t3q0EmWmaOXtWNmd6oH8aMtA/SL43Uwjgmhv9gbxzeP8fMjK4zGCu9D0CLSmFO+1s5sg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.2.0-rc.2.tgz", + "integrity": "sha512-2tNl9S+J17uRSy6eSFJJ47b/zUuemm3UALaBII1+c5rWmUvtvs9ZYljX77VAkuwELKEMgExWjGQKaLQBTbvFMQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "@umbraco-ui/uui-ref-node-user": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.2.0-rc.0.tgz", - "integrity": "sha512-myEYc6NkT8y/L8n1ndeRLGN584A+r0PPxbQCaMWmVAbcAq+Eb58W3ExnZM5toHJNUWjq7o2bIeX40eckYjkE3g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.2.0-rc.2.tgz", + "integrity": "sha512-sTrz9xhHrcv9Il27NMMSKTm7A50gpRF9z3vDWiZ0Ottg37oUkGiitgk4XI3AJOSWqDzNJjwuwUk6tAlwc6D5TQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-ref-node": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-ref-node": "1.2.0-rc.2" } }, "@umbraco-ui/uui-scroll-container": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.2.0-rc.0.tgz", - "integrity": "sha512-9XBHcDyact/5tdlrgCGwoEdmvcV14D5FrVS3jj/cOCqoBg0NaE1O9AS8OeLa1t4/HlOPijWYLj4oUs0aG3cyQg==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.2.0-rc.2.tgz", + "integrity": "sha512-Aj2hiU05DFZ7eXab/zAXjitP9bM/TAM7HNVPOAl08BNpkemo0DYTtdFu4VmLIkqw6WtyxIVZ/N5pSJYMYovXYA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-select": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.2.0-rc.0.tgz", - "integrity": "sha512-Kmg8pTm0Ll+t0lussikOCWpvBeVxYh0TEIlaTNyLQZNwT3jKVvdyKsY4yNU7YUBMRQaBRhl0glJOTPxUBURroA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.2.0-rc.2.tgz", + "integrity": "sha512-X17ciKmnrtEut6RTrHvsOSIfwimPc0gT6kQoQFgPcTmF14Zr6edFPd6YKhWtjQNG9rVpmW1HK5bBSyeyiw/P4w==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-slider": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.2.0-rc.0.tgz", - "integrity": "sha512-CqhSI2T7Rg3EAZemZvYaSaij9sLwS0Vk86g6QCzDVUoyF7q5QpUcd3+7vMD0rvbwBISarrPprooX+GGjTNLiAw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.2.0-rc.2.tgz", + "integrity": "sha512-PRoKMCvGTejDg37dm5fGYxO7jFrHECPn20X3fv3bsVqnF5wH7RZ88dBW5oMNoYxoreph4SSQd5AsSQabuCpT4w==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-expand": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.2.0-rc.0.tgz", - "integrity": "sha512-87Jxw6bYls7qs/srRXvqnadak3UDsbmYYItsIm2RS1CPxWvrSS3uEdLeCDhvMEoDCm+6B581ntmfiZ/k9OBxWQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.2.0-rc.2.tgz", + "integrity": "sha512-i42zskMlDb7tivcFkFo5pXPo6Z+A2Sgu/MTChDzIEw3AK3/V2Lf8jNZtjL9Anjn1ZWg0Mq4GBjR5iv+pkjHZjw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-file": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.2.0-rc.0.tgz", - "integrity": "sha512-iTZPVNB8kqQsqS/Kx/prTY1Hl70bQ+ZZKGm0+d0GxsoEoHKYB9jyQpMx80BWIO0sz5MgqM/8GA+ezAQh1v7sLw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.2.0-rc.2.tgz", + "integrity": "sha512-jIKSrcsmYwQJDyDOSeu49LbqaB7r9xq62cHB5dq2V1SRX9CYQqnX6E6hwcj2KBXwvp6oeAVWg+RzHth/8nR66A==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.2.0-rc.0.tgz", - "integrity": "sha512-59g/paTrCuUlZidjvQh87MSEqxcN/xJf33tEw2BhbXRFGCP/2zzqhIeZx/xh690e0/JKUxPTmhznqmdjOPt5Ig==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.2.0-rc.2.tgz", + "integrity": "sha512-yy6Ay2q3MW5ntJxmT+bgcCzwfSvsX9/0Fp/W7sX7sSO3gwraWobZuOBCiULiUkMe8No1t7x2HecW4Xr1mHUNXQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.2.0-rc.0.tgz", - "integrity": "sha512-huuJrD1v8hxmR02+KCS4RXmvNzwdEXDEVgLReAnDzhEQBQ3nhulEAJnyexw5MZ18LkB1l5rhNeHiRbFxh9u6lw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.2.0-rc.2.tgz", + "integrity": "sha512-hcpxQWHDfPDx8eqWz6O8hHR4C09BOZ/ukYpy5EOJ8I+nwgB6eR39Waml+rOmOoDdMue1B8qPxKUcBODzWomSJg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-folder": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.2.0-rc.0.tgz", - "integrity": "sha512-jj5n22biZIcGqt3bpBluPxCmsBqAGf5FlzU/1rEZdt9HWsJ2Yo9led+Fm26SqPTlo2Wqixm+MQhmIWJjQZxbOQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.2.0-rc.2.tgz", + "integrity": "sha512-LdNRWeuE/If+v9N6/MH2rgTWlyBwgjynffmUw+Js29OUJFuCp3docdsB2KlVOsfoDVEyAJtlGbsdAXQvf718VQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-lock": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.2.0-rc.0.tgz", - "integrity": "sha512-YmbeEYeEHAEgZo46rdubsFNTCREqzr5eOGWv4t7QGOawroKGCrLJs+xpBPqGSQkWRENVpj2etWD6pa4s3LW2Dw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.2.0-rc.2.tgz", + "integrity": "sha512-xJIf+T5VkOGEU6A62SINUlkRJjV8rAGp5bS1Buf2z8vxpe50yqLpOm4mXpJXTyvmyybGm0efrUhfX9ESXWWP2g==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-more": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.2.0-rc.0.tgz", - "integrity": "sha512-5YuXU3RsowBd6k7YbR39R4cP408apA9rVM2uYD0FhR5JE8XVJ1o/AlapEZB455zeQcYeaWNZKM3VhNY4hzpOMw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.2.0-rc.2.tgz", + "integrity": "sha512-KSJ5JoAijccGBGk233ZSN0a2sz9EDf50oWOE8x10mQvTGRUwwAgEIoxkXN39d0oBgCeY6xrkFS1JL0SC6qD4qg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-symbol-sort": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.2.0-rc.0.tgz", - "integrity": "sha512-gKqd1oMS/uZTcUUCZuqo1ZOMW13QvuVbbTL420RVzjTilC9IZ4SDZU3ZbqS/fsLYPReeKkm4U9NJZdm6a9OqpQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.2.0-rc.2.tgz", + "integrity": "sha512-LcUNh/yaKiG5Mli9f95SPcKufKLFFPFz2zaD/iR80kcem2niXfgNPzuhV145XaLpKrebktrDTYKUefsDI6xqrA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-table": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.2.0-rc.0.tgz", - "integrity": "sha512-BoGN8edf4MWhh2jxLcKht843c99ePeSN3LO1f7ICUFHxLJ1l+eEZLieWFh8ZpeErfY2zXsylRALsSSdGagnwKA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.2.0-rc.2.tgz", + "integrity": "sha512-IhHnB5vr7l+8E2Ae/CCy1ZJMH7yWITTfn1zzN+5qcAvQn5M/mm0gCCVFSvHQSRmt9Bj4s9CYSN1rRVp6Nw6gow==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-tabs": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.2.0-rc.0.tgz", - "integrity": "sha512-0vMtMCIAyQ6aPLQiTtM+K7O7qoNCtHEjcVU8LrqGJjdCERvsrktyP6hwDlcOW52MiYcb7H5p4wxXoxi8fKdi+g==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.2.0-rc.2.tgz", + "integrity": "sha512-R7kK3j8zF9Em4sB85h//hwXh2tV5h6xuJ1DawqY+am0imdZlr/7rkdv89NTJlP5y8nGGKY1P2lfy3prajxcoqQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-tag": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.2.0-rc.0.tgz", - "integrity": "sha512-oZS5eaQUMo060Uh3z2yUp7ukb62j42MpE262fK7L0hmtk80Sqn9uff7RNWf3bgwIkyj+GuLm4coakSfbd56D7Q==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.2.0-rc.2.tgz", + "integrity": "sha512-8P9ejFdgy1LTwJIWAT90DDj1cKFNbnwo/6HiqmFIHL40h43oa5/xtAh8SlwF+VzzT3EyuIS2+kOQBIaUT5CGRA==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-textarea": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.2.0-rc.0.tgz", - "integrity": "sha512-aMtDe8C2ZuEr9NLV5onhiUx5Uw/09vnN2oXILoVKaPHhxtK/oqZS6MTnoGt3rlpfjZAjwfXY049MCn8pDPOJqA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.2.0-rc.2.tgz", + "integrity": "sha512-VUbZ9ztkdJpv3bBPCmrrhCjLHiS3MMWVnZT5fnQlbd0v+efD+I09Z4ir8JcdP3lbhP1HbQTVbwx+OyiAHp3pfg==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2" } }, "@umbraco-ui/uui-toast-notification": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.2.0-rc.0.tgz", - "integrity": "sha512-oaRqwcuPS9HazH+yTcaDnH3Wt7j04dE6JdWzL3Yj30NNo595ijnZbRlnShjILT2o8jh2DUhVI0JhnnogeMEssA==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.2.0-rc.2.tgz", + "integrity": "sha512-cWm/wUU3WRA5VfQGeLa3nrrmOYmpp78pFWa1QAZUFbCZv/NWEmm1wHLqySb9O9AH5zUz3TG7F1LH75ZXI7dv0g==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-button": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0", - "@umbraco-ui/uui-icon": "1.2.0-rc.0", - "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-button": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2", + "@umbraco-ui/uui-icon": "1.2.0-rc.2", + "@umbraco-ui/uui-icon-registry-essential": "1.2.0-rc.2" } }, "@umbraco-ui/uui-toast-notification-container": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.2.0-rc.0.tgz", - "integrity": "sha512-8+IPz99Py12fIuDAs89kXOdsfBszFS37XtgYpMFl9t+g4uyd7doV8jJFP8G3UnjjDuboQWhpKIJKiKCRoOmdGw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.2.0-rc.2.tgz", + "integrity": "sha512-3LPWk2mpCsYUOBiqeIdX/DDvQSM324rLMomXgxco+dmI1CvykkSJ2u3HclsmXk567d19h7+rt0k1Ap79him9+g==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-toast-notification": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-toast-notification": "1.2.0-rc.2" } }, "@umbraco-ui/uui-toast-notification-layout": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.2.0-rc.0.tgz", - "integrity": "sha512-mnq3a4Wu/Uor234we97mtvfeX8nl9w0fKsH2kBAgodkjXVMQssvCOdd7MKyh6G4mXUO4/WY0HbOYOCGv2I/feQ==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.2.0-rc.2.tgz", + "integrity": "sha512-UagMXNgIoVzk+GyLI7S8nsskMtpADhOqcyO8mNLfppF2RVtZ7xmBUPiZ+9OsaiZFet0IcbPpg1ZtdsuNnHZydw==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-css": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-css": "1.2.0-rc.2" } }, "@umbraco-ui/uui-toggle": { - "version": "1.2.0-rc.0", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.2.0-rc.0.tgz", - "integrity": "sha512-UXdiT/ROf8sKQTYge2wS4znhL4+IdpxoF4TPZr+U0k/5UQ+iQTzs6hy/GJQs5FcPnEI7gftrIHctP5O9yKsJvw==", + "version": "1.2.0-rc.2", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.2.0-rc.2.tgz", + "integrity": "sha512-ypp8pFp3GRXk3WLitMJp7Cg/ducZlVDKQyTqwwHap2q6RfkTwvZcLl59Bf00hgkMeTV1vVzFCMSMqLextPabQQ==", "requires": { - "@umbraco-ui/uui-base": "1.2.0-rc.0", - "@umbraco-ui/uui-boolean-input": "1.2.0-rc.0" + "@umbraco-ui/uui-base": "1.2.0-rc.2", + "@umbraco-ui/uui-boolean-input": "1.2.0-rc.2" } }, "@web/browser-logs": { @@ -23408,6 +23592,13 @@ "ua-parser-js": "^1.0.2" }, "dependencies": { + "@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "dev": true, + "optional": true + }, "esbuild": { "version": "0.14.54", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", @@ -23467,6 +23658,52 @@ "whatwg-url": "^11.0.0" }, "dependencies": { + "@rollup/plugin-node-resolve": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.3.0.tgz", + "integrity": "sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "deepmerge": "^4.2.2", + "is-builtin-module": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + } + }, + "@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, "rollup": { "version": "2.79.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", @@ -24821,12 +25058,6 @@ "keygrip": "~1.1.0" } }, - "core-js": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.29.0.tgz", - "integrity": "sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==", - "dev": true - }, "core-js-compat": { "version": "3.29.1", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.29.1.tgz", @@ -25139,12 +25370,6 @@ "esutils": "^2.0.2" } }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true - }, "dom5": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dom5/-/dom5-3.0.1.tgz", @@ -25419,35 +25644,49 @@ "dev": true }, "esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "version": "0.17.15", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz", + "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==", "dev": true, "requires": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" + "@esbuild/android-arm": "0.17.15", + "@esbuild/android-arm64": "0.17.15", + "@esbuild/android-x64": "0.17.15", + "@esbuild/darwin-arm64": "0.17.15", + "@esbuild/darwin-x64": "0.17.15", + "@esbuild/freebsd-arm64": "0.17.15", + "@esbuild/freebsd-x64": "0.17.15", + "@esbuild/linux-arm": "0.17.15", + "@esbuild/linux-arm64": "0.17.15", + "@esbuild/linux-ia32": "0.17.15", + "@esbuild/linux-loong64": "0.17.15", + "@esbuild/linux-mips64el": "0.17.15", + "@esbuild/linux-ppc64": "0.17.15", + "@esbuild/linux-riscv64": "0.17.15", + "@esbuild/linux-s390x": "0.17.15", + "@esbuild/linux-x64": "0.17.15", + "@esbuild/netbsd-x64": "0.17.15", + "@esbuild/openbsd-x64": "0.17.15", + "@esbuild/sunos-x64": "0.17.15", + "@esbuild/win32-arm64": "0.17.15", + "@esbuild/win32-ia32": "0.17.15", + "@esbuild/win32-x64": "0.17.15" } }, + "esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "dev": true, + "optional": true + }, "esbuild-darwin-64": { "version": "0.14.54", "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", @@ -25455,6 +25694,97 @@ "dev": true, "optional": true }, + "esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "dev": true, + "optional": true + }, "esbuild-plugin-alias": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz", @@ -25470,6 +25800,34 @@ "debug": "^4.3.4" } }, + "esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "dev": true, + "optional": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -25634,9 +25992,9 @@ } }, "eslint-config-prettier": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", - "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "dev": true }, "eslint-import-resolver-node": { @@ -25934,9 +26292,9 @@ "dev": true }, "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, "esutils": { @@ -26373,9 +26731,9 @@ "dev": true }, "flow-parser": { - "version": "0.201.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.201.0.tgz", - "integrity": "sha512-G4oeDNpNGyIrweF9EnoHatncAihMT0tQgV6NMdyM5I7fhrz9Pr13PJ2KLQ673O4wj9KooTdBpeeYHdDNAQoyyw==", + "version": "0.203.1", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.203.1.tgz", + "integrity": "sha512-Nw2M8MPP/Zb+yhvmPDEjzkCXLtgyWGKXZjAYOVftm+wIf3xd4FKa7nRI9v67rODs0WzxMbPc8IPs/7o/dyxo/Q==", "dev": true }, "for-each": { @@ -26663,16 +27021,6 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -27272,12 +27620,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true - }, "is-generator-function": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", @@ -28213,28 +28555,29 @@ "dev": true }, "lit": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/lit/-/lit-2.6.1.tgz", - "integrity": "sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.7.0.tgz", + "integrity": "sha512-qSy2BAVA+OiWtNptP404egcC/izDdNRw6iHGIbUmkZtbMJvPKfNsaoKrNs8Zmsbjmv5ZX2tur1l9TfzkSWWT4g==", "requires": { "@lit/reactive-element": "^1.6.0", - "lit-element": "^3.2.0", - "lit-html": "^2.6.0" + "lit-element": "^3.3.0", + "lit-html": "^2.7.0" } }, "lit-element": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.2.tgz", - "integrity": "sha512-6ZgxBR9KNroqKb6+htkyBwD90XGRiqKDHVrW/Eh0EZ+l+iC+u+v+w3/BA5NGi4nizAVHGYvQBHUDuSmLjPp7NQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.0.tgz", + "integrity": "sha512-M3OIoblNS7LZdRxOIk8g0wyLEA/lRw/UGJ1TX+767OpkuDsRdSoxBIvewpWqCo7sMd9xt1XedUNZIr9jUO1X3g==", "requires": { + "@lit-labs/ssr-dom-shim": "^1.1.0", "@lit/reactive-element": "^1.3.0", - "lit-html": "^2.2.0" + "lit-html": "^2.7.0" } }, "lit-html": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.6.1.tgz", - "integrity": "sha512-Z3iw+E+3KKFn9t2YKNjsXNEu/LRLI98mtH/C6lnFg7kvaqPIzPn124Yd4eT/43lyqrejpc5Wb6BHq3fdv4S8Rw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.0.tgz", + "integrity": "sha512-/zPOl8EfeB3HHpTzINSpnWgvgQ8N07g/j272EOAIyB0Ys2RzBqTVT23i+JZuUlNbB2WHHeSsTCFi92NtWrtpqQ==", "requires": { "@types/trusted-types": "^2.0.2" } @@ -28445,9 +28788,9 @@ "dev": true }, "markdown-to-jsx": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.9.tgz", - "integrity": "sha512-x4STVIKIJR0mGgZIZ5RyAeQD7FEZd5tS8m/htbcVGlex32J+hlSLj+ExrHCxP6nRKF1EKbcO7i6WhC1GtOpBlA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.2.0.tgz", + "integrity": "sha512-3l4/Bigjm4bEqjCR6Xr+d4DtM1X6vvtGsMGSjJYyep8RjjIvcWtrXBS8Wbfe1/P+atKNMccpsraESIaWVplzVg==", "dev": true }, "marky": { @@ -28547,15 +28890,6 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -28616,6 +28950,11 @@ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "dev": true }, + "monaco-editor": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.36.1.tgz", + "integrity": "sha512-/CaclMHKQ3A6rnzBzOADfwdSJ25BFoFT0Emxsc4zYVyav5SkK9iA6lEtIeuN/oRYbwPgviJT+t3l+sjFa28jYg==" + }, "mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -28704,12 +29043,11 @@ } }, "msw-storybook-addon": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.7.0.tgz", - "integrity": "sha512-G/cYj7Z8NuyFbMsdVJRr17flWed8J7CmKTSPNXmuK65W6uILpqNDpXJC7KVRhOg7lUFR5Hmqwcq6z8Mow/wu5A==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/msw-storybook-addon/-/msw-storybook-addon-1.8.0.tgz", + "integrity": "sha512-dw3vZwqjixmiur0vouRSOax7wPSu9Og2Hspy9JZFHf49bZRjwDiLF0Pfn2NXEkGviYJOJiGxS1ejoTiUwoSg4A==", "dev": true, "requires": { - "@storybook/addons": "^6.0.0", "is-node-process": "^1.0.1" } }, @@ -30291,34 +30629,11 @@ "jsonc-parser": "^3.2.0" }, "dependencies": { - "@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - } - }, - "@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", - "dev": true - }, "es-module-lexer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.0.tgz", "integrity": "sha512-2BMfqBDeVCcOlLaL1ZAfp+D868SczNpKArrTM3dhpd7dK/OVlogzY15qpUngt+LMTq5UC/csb9vVQAgupucSbA==", "dev": true - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true } } }, @@ -30350,8 +30665,8 @@ } }, "router-slot": { - "version": "file:router-slot-1.6.1.tgz", - "integrity": "sha512-lrqzUL9wfSQR7L9rFvRsq/I+BGo2bw0Hn45eZ+qhrjPFv2gn+LRz2TaWa6CVqkiXhdWMrUEmEyD8nzl4cqV0Fw==" + "version": "file:router-slot-2.0.0.tgz", + "integrity": "sha512-J2E+sDJR7Q/S761Q6vXVCTWFN1kKidX3fparKoipm/NaX9XEdwmCSOEqYyUHbnIyDDo5O5PMhsH8EazLmCQJXw==" }, "run-async": { "version": "2.4.1", @@ -30812,12 +31127,12 @@ "dev": true }, "storybook": { - "version": "7.0.0-rc.3", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.0-rc.3.tgz", - "integrity": "sha512-1EFr7o7dcgFKsI6TBqvxYEKGPzKvJ8qzCl3BM/1kZP5BmWqQPbanOQLVkTb4zDb5e+Q+ibDNH5k8D1lQFdsHcg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-7.0.2.tgz", + "integrity": "sha512-/XBLhT9Vb14yNBcA9rlW15y+C6IsCA3kx5PKvK9kL10sKCi8invcY94UfCSisXe8HqsO3u6peumo2xpYucKMjw==", "dev": true, "requires": { - "@storybook/cli": "7.0.0-rc.3" + "@storybook/cli": "7.0.2" } }, "stream-shift": { @@ -31391,9 +31706,9 @@ "dev": true }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz", + "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", "dev": true }, "typescript-json-schema": { @@ -31709,16 +32024,16 @@ "dev": true }, "vite": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.4.tgz", - "integrity": "sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==", "dev": true, "requires": { - "esbuild": "^0.16.14", + "esbuild": "^0.17.5", "fsevents": "~2.3.2", "postcss": "^8.4.21", "resolve": "^1.22.1", - "rollup": "^3.10.0" + "rollup": "^3.18.0" } }, "vite-plugin-static-copy": { diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 1b0517f2e0..4d2661e8a5 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -28,9 +28,10 @@ "scripts": { "dev": "vite", "build": "tsc && vite build --mode staging", + "build:libs": "npm run wc-analyze && npm run wc-analyze:vscode && rollup -c rollup-libs.config.js && node utils/move-libs.js", "build:for:static": "tsc && vite build", - "build:for:cms": "tsc && npm run generate:jsonschema && vite build -c vite.cms.config.ts && node utils/build-libs.js", - "build:for:cms:watch": "vite build -c vite.cms.config.ts --watch", + "build:for:cms": "tsc && npm run build:libs && vite build -c vite.cms.config.ts", + "build:for:cms:watch": "tsc && npm run build:libs && vite build -c vite.cms.config.ts --watch", "preview": "vite preview --open", "test": "web-test-runner --coverage", "test:watch": "web-test-runner --watch", @@ -50,6 +51,7 @@ "build-storybook": "npm run wc-analyze && storybook build", "generate:icons": "node ./devops/icons/index.js", "wc-analyze": "wca **/*.element.ts --outFile custom-elements.json", + "wc-analyze:vscode": "wca **/*.element.ts --format vscode --outFile vscode-html-custom-data.json", "new-extension": "plop --plopfile ./devops/plop/plop.js", "compile": "tsc", "check": "npm run lint && npm run compile && npm run build-storybook" @@ -59,16 +61,13 @@ "npm": ">=9.5 < 10" }, "dependencies": { - "@umbraco-ui/uui": "^1.2.0-rc.0", - "@umbraco-ui/uui-css": "^1.2.0-rc.0", - "@umbraco-ui/uui-modal": "file:umbraco-ui-uui-modal-0.0.0.tgz", - "@umbraco-ui/uui-modal-container": "file:umbraco-ui-uui-modal-container-0.0.0.tgz", - "@umbraco-ui/uui-modal-dialog": "file:umbraco-ui-uui-modal-dialog-0.0.0.tgz", - "@umbraco-ui/uui-modal-sidebar": "file:umbraco-ui-uui-modal-sidebar-0.0.0.tgz", + "@umbraco-ui/uui": "^1.2.0-rc.2", + "@umbraco-ui/uui-css": "^1.2.0-rc.2", "element-internals-polyfill": "^1.1.19", - "lit": "^2.6.1", + "lit": "^2.7.0", "lodash-es": "4.17.21", - "router-slot": "file:router-slot-1.6.1.tgz", + "monaco-editor": "^0.36.1", + "router-slot": "file:router-slot-2.0.0.tgz", "rxjs": "^7.8.0", "uuid": "^9.0.0" }, @@ -78,19 +77,20 @@ "@open-wc/testing": "^3.1.7", "@playwright/test": "^1.30.0", "@rollup/plugin-json": "^6.0.0", - "@storybook/addon-a11y": "^7.0.0-rc.3", - "@storybook/addon-actions": "^7.0.0-rc.3", - "@storybook/addon-essentials": "^7.0.0-rc.3", - "@storybook/addon-links": "^7.0.0-rc.3", - "@storybook/mdx2-csf": "^1.0.0-next.5", - "@storybook/web-components": "^7.0.0-rc.3", - "@storybook/web-components-vite": "^7.0.0-rc.3", + "@rollup/plugin-node-resolve": "^15.0.1", + "@storybook/addon-a11y": "^7.0.2", + "@storybook/addon-actions": "^7.0.2", + "@storybook/addon-essentials": "^7.0.2", + "@storybook/addon-links": "^7.0.2", + "@storybook/mdx2-csf": "^1.0.0", + "@storybook/web-components": "^7.0.2", + "@storybook/web-components-vite": "^7.0.2", "@types/chai": "^4.3.4", "@types/lodash-es": "^4.17.6", "@types/mocha": "^10.0.0", "@types/uuid": "^9.0.0", "@typescript-eslint/eslint-plugin": "^5.50.0", - "@typescript-eslint/parser": "^5.54.0", + "@typescript-eslint/parser": "^5.57.0", "@web/dev-server-esbuild": "^0.3.3", "@web/dev-server-import-maps": "^0.0.7", "@web/dev-server-rollup": "^0.3.21", @@ -98,7 +98,7 @@ "@web/test-runner-playwright": "^0.9.0", "babel-loader": "^9.1.2", "eslint": "^8.32.0", - "eslint-config-prettier": "^8.6.0", + "eslint-config-prettier": "^8.8.0", "eslint-import-resolver-typescript": "^3.5.3", "eslint-plugin-import": "^2.27.4", "eslint-plugin-lit": "^1.8.2", @@ -106,9 +106,8 @@ "eslint-plugin-local-rules": "^1.3.2", "eslint-plugin-storybook": "^0.6.11", "eslint-plugin-wc": "^1.4.0", - "lit-html": "^2.6.1", "msw": "^1.1.0", - "msw-storybook-addon": "^1.7.0", + "msw-storybook-addon": "^1.8.0", "openapi-typescript-codegen": "^0.23.0", "playwright-msw": "^2.1.0", "plop": "^3.1.1", @@ -119,11 +118,11 @@ "rollup-plugin-dts": "^5.2.0", "rollup-plugin-esbuild": "^5.0.0", "rollup-plugin-url": "^3.0.1", - "storybook": "^7.0.0-rc.3", + "storybook": "^7.0.2", "tiny-glob": "^0.2.9", - "typescript": "^4.9.5", + "typescript": "^5.0.3", "typescript-json-schema": "^0.55.0", - "vite": "^4.1.4", + "vite": "^4.2.1", "vite-plugin-static-copy": "^0.13.0", "vite-tsconfig-paths": "^4.0.5", "web-component-analyzer": "^2.0.0-next.4" diff --git a/src/Umbraco.Web.UI.Client/rollup-libs.config.js b/src/Umbraco.Web.UI.Client/rollup-libs.config.js new file mode 100644 index 0000000000..18f16539aa --- /dev/null +++ b/src/Umbraco.Web.UI.Client/rollup-libs.config.js @@ -0,0 +1,33 @@ +import esbuild from 'rollup-plugin-esbuild'; +import pluginJson from '@rollup/plugin-json'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import dts from 'rollup-plugin-dts'; +import { readdirSync, lstatSync } from 'fs'; + +const libs = readdirSync('./libs').filter(lib => lstatSync(`libs/${lib}`).isDirectory()); +const outputDir = './dist/libs'; + +export default libs.map(lib => { + /** @type {import('rollup').RollupOptions[]} */ + return [ + { + input: `./libs/${lib}/index.ts`, + external: [/^@umbraco-cms\//], + output: { + file: `${outputDir}/${lib}.js`, + format: 'es', + sourcemap: true, + }, + plugins: [nodeResolve(), pluginJson(), esbuild()] + }, + { + input: `./libs/${lib}/index.ts`, + external: [/^@umbraco/, /^lit/, /^rxjs/, /^uuid/], + output: { + file: `${outputDir}/${lib}.d.ts`, + format: 'es' + }, + plugins: [dts({ respectExternal: true })], + } + ]; +}).flat(); diff --git a/src/Umbraco.Web.UI.Client/router-slot-1.6.1.tgz b/src/Umbraco.Web.UI.Client/router-slot-1.6.1.tgz deleted file mode 100644 index a5285852af..0000000000 Binary files a/src/Umbraco.Web.UI.Client/router-slot-1.6.1.tgz and /dev/null differ diff --git a/src/Umbraco.Web.UI.Client/router-slot-2.0.0.tgz b/src/Umbraco.Web.UI.Client/router-slot-2.0.0.tgz new file mode 100644 index 0000000000..e2e34160de Binary files /dev/null and b/src/Umbraco.Web.UI.Client/router-slot-2.0.0.tgz differ diff --git a/src/Umbraco.Web.UI.Client/src/app.ts b/src/Umbraco.Web.UI.Client/src/app.ts index 10fd0f49e3..5707e9ec4d 100644 --- a/src/Umbraco.Web.UI.Client/src/app.ts +++ b/src/Umbraco.Web.UI.Client/src/app.ts @@ -1,29 +1,27 @@ import '@umbraco-ui/uui-css/dist/uui-css.css'; -import '@umbraco-cms/css'; +import './core/css/custom-properties.css'; -// TODO: remove these imports when they are part of UUI -import '@umbraco-ui/uui-modal'; -import '@umbraco-ui/uui-modal-container'; -import '@umbraco-ui/uui-modal-dialog'; -import '@umbraco-ui/uui-modal-sidebar'; import 'element-internals-polyfill'; import './core/router/router-slot.element'; +import './core/router/variant-router-slot.element'; import './core/notification/layouts/default'; +import './core/modal/modal-element.element'; import { UUIIconRegistryEssential } from '@umbraco-ui/uui'; import { css, html } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; +import { customElement, property } from 'lit/decorators.js'; -import type { Guard, IRoute } from '@umbraco-cms/router'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { OpenAPI, RuntimeLevelModel, ServerResource } from '@umbraco-cms/backend-api'; -import { UmbIconStore } from '@umbraco-cms/store'; -import { umbDebugContextEventType } from '@umbraco-cms/context-api'; +import { UmbIconStore } from './core/stores/icon/icon.store'; +import type { Guard, IRoute } from '@umbraco-cms/backoffice/router'; +import { pathWithoutBasePath } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { OpenAPI, RuntimeLevelModel, ServerResource } from '@umbraco-cms/backoffice/backend-api'; +import { contextData, umbDebugContextEventType } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-app') -export class UmbApp extends UmbLitElement { +export class UmbAppElement extends UmbLitElement { static styles = css` :host { overflow: hidden; @@ -40,8 +38,7 @@ export class UmbApp extends UmbLitElement { @property({ type: String }) private umbracoUrl?: string; - @state() - private _routes: IRoute[] = [ + private _routes: IRoute[] = [ { path: 'install', component: () => import('./installer/installer.element'), @@ -71,7 +68,7 @@ export class UmbApp extends UmbLitElement { this._setup(); } - async connectedCallback() { + connectedCallback() { super.connectedCallback(); OpenAPI.BASE = @@ -82,8 +79,7 @@ export class UmbApp extends UmbLitElement { this.provideContext('UMBRACOBASE', OpenAPI.BASE); - await this._setInitStatus(); - this._redirect(); + this._setInitStatus(); // Listen for the debug event from the component this.addEventListener(umbDebugContextEventType, (event: any) => { @@ -92,35 +88,51 @@ export class UmbApp extends UmbLitElement { // we have collected whilst coming up through the DOM // and pass it back down to the callback in // the component that originally fired the event - event.callback(event.instances); + if (event.callback) { + event.callback(event.instances); + } + + // Massage the data into a simplier format + // Why? Can't send contexts data directly - browser seems to not serialize it and says its null + // But a simple object works fine for browser extension to consume + const data = { + contexts: contextData(event.instances), + }; + + // Emit this new event for the browser extension to listen for + this.dispatchEvent(new CustomEvent('umb:debug-contexts:data', { detail: data, bubbles: true })); }); } private async _setup() { + await this._setInitStatus(); this._iconRegistry.attach(this); } private async _setInitStatus() { const { data } = await tryExecuteAndNotify(this, ServerResource.getServerStatus()); this._runtimeLevel = data?.serverStatus ?? RuntimeLevelModel.UNKNOWN; + this._redirect(); } private _redirect() { switch (this._runtimeLevel) { case RuntimeLevelModel.INSTALL: - history.replaceState(null, '', '/install'); + history.replaceState(null, '', 'install'); break; case RuntimeLevelModel.UPGRADE: - history.replaceState(null, '', '/upgrade'); + history.replaceState(null, '', 'upgrade'); break; case RuntimeLevelModel.RUN: { - const pathname = - window.location.pathname === '/install' || window.location.pathname === '/upgrade' - ? '/' - : window.location.pathname; - history.replaceState(null, '', pathname); + const pathname = pathWithoutBasePath({ start: true, end: false }); + + // If we are on the installer or upgrade page, redirect to the root + // but if not, keep the current path but replace state anyway to initialize the router + const finalPath = pathname === '/install' || pathname === '/upgrade' ? '/' : location.href; + + history.replaceState(null, '', finalPath); break; } @@ -159,6 +171,6 @@ export class UmbApp extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-app': UmbApp; + 'umb-app': UmbAppElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts index 75e0738142..c4590ec1ee 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.element.ts @@ -18,10 +18,11 @@ import { UmbAppLanguageContext, } from './settings/languages/app-language-select/app-language.context'; import { UmbServerExtensionController } from './packages/repository/server-extension.controller'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { createExtensionClass, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { createExtensionClass, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { UmbEntryPointExtensionInitializer } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; // Domains import './settings'; @@ -49,12 +50,17 @@ export class UmbBackofficeElement extends UmbLitElement { font-size: 14px; box-sizing: border-box; } + umb-backoffice-modal-container { + z-index: 1000; + } `, ]; constructor() { super(); + new UmbEntryPointExtensionInitializer(this, umbExtensionsRegistry); + this.provideContext(UMB_MODAL_CONTEXT_TOKEN, new UmbModalContext(this)); this.provideContext(UMB_NOTIFICATION_CONTEXT_TOKEN, new UmbNotificationContext()); this.provideContext(UMB_CURRENT_USER_STORE_CONTEXT_TOKEN, new UmbCurrentUserStore()); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.stories.ts index a43b869b1a..3fd59b80df 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/backoffice.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbBackofficeElement } from './backoffice.element'; import './backoffice.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/manifests.ts index c56e2a1154..e059b11888 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestDashboard } from '@umbraco-cms/models'; +import type { ManifestDashboard } from '@umbraco-cms/backoffice/extensions-registry'; const dashboards: Array = [ { @@ -9,9 +9,11 @@ const dashboards: Array = [ weight: 10, meta: { label: 'Redirect Management', - sections: ['Umb.Section.Content'], pathname: 'redirect-management', }, + conditions: { + sections: ['Umb.Section.Content'], + }, }, { type: 'dashboard', @@ -21,10 +23,12 @@ const dashboards: Array = [ weight: 20, meta: { label: 'Welcome', - sections: ['Umb.Section.Content'], pathname: 'welcome', }, - } + conditions: { + sections: ['Umb.Section.Content'], + }, + }, ]; export const manifests = [...dashboards]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts index cff6bf9108..8e7de5f464 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts @@ -2,17 +2,25 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, state, query, property } from 'lit/decorators.js'; import { UUIButtonState, UUIPaginationElement, UUIPaginationEvent } from '@umbraco-ui/uui'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../shared/modals/confirm'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { RedirectManagementResource, RedirectStatusModel, RedirectUrlModel } from '@umbraco-cms/backend-api'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { + RedirectManagementResource, + RedirectStatusModel, + RedirectUrlResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; @customElement('umb-dashboard-redirect-management') export class UmbDashboardRedirectManagementElement extends UmbLitElement { static styles = [ UUITextStyles, css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + .actions { display: flex; gap: var(--uui-size-space-1); @@ -83,7 +91,7 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { itemsPerPage = 20; @state() - private _redirectData?: RedirectUrlModel[]; + private _redirectData?: RedirectUrlResponseModel[]; @state() private _trackerStatus = true; @@ -126,8 +134,8 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { if (data && data.status) this._trackerStatus = data.status === RedirectStatusModel.ENABLED ? true : false; } - private _removeRedirectHandler(data: RedirectUrlModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + private _removeRedirectHandler(data: RedirectUrlResponseModel) { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Delete', content: html`
@@ -145,20 +153,19 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { }); } - private async _removeRedirect(r: RedirectUrlModel) { - if (!r.key) return; - const res = await tryExecuteAndNotify( - this, - RedirectManagementResource.deleteRedirectManagementByKey({ key: r.key }) - ); + private async _removeRedirect(r: RedirectUrlResponseModel) { + if (!r.id) return; + const res = await tryExecuteAndNotify(this, RedirectManagementResource.deleteRedirectManagementById({ id: r.id })); if (!res.error) { // or just run a this._getRedirectData() again? - this.shadowRoot?.getElementById(`redirect-key-${r.key}`)?.remove(); + //this.shadowRoot?.getElementById(`redirect-key-${r.id}`)?.remove(); + // No no, never manipulate DOM manipulate the data for the DOM: + this._redirectData = this._redirectData?.filter((x) => x.id !== r.id); } } private _disableRedirectHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Disable URL tracker', content: html`Are you sure you want to disable the URL tracker?`, color: 'danger', @@ -209,7 +216,9 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { if (data) { this._total = data?.total; this._redirectData = data?.items; - if (this._filter?.length) this._buttonState = 'success'; + if (this._filter?.length) { + this._buttonState = 'success'; + } } } @@ -273,6 +282,7 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { } private renderTable() { + // TODO: Instead of map, use repeat lit util: return html` @@ -283,7 +293,7 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { Actions ${this._redirectData?.map((data) => { - return html` + return html` ${data.culture || '*'} ${data.originalUrl} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.stories.ts index 99d180a303..5ca04fc51e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.stories.ts @@ -1,7 +1,7 @@ import './dashboard-redirect-management.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardRedirectManagementElement } from './dashboard-redirect-management.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.test.ts index 2d960a1757..48709103be 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/redirect-management/dashboard-redirect-management.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbDashboardRedirectManagementElement } from './dashboard-redirect-management.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbDashboardRedirectManagement', () => { let element: UmbDashboardRedirectManagementElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.element.ts index 7f6d71ba41..3d8aca6433 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.element.ts @@ -4,7 +4,15 @@ import { customElement } from 'lit/decorators.js'; @customElement('umb-dashboard-welcome') export class UmbDashboardWelcomeElement extends LitElement { - static styles = [UUITextStyles, css``]; + static styles = [ + UUITextStyles, + css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + `, + ]; render() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.stories.ts index 82ad05aea5..20d0abcacb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/dashboards/welcome/dashboard-welcome.stories.ts @@ -1,7 +1,7 @@ import './dashboard-welcome.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardWelcomeElement } from './dashboard-welcome.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.detail.store.ts index c847dbb2cb..f60b478a36 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.detail.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.detail.store.ts @@ -1,8 +1,8 @@ -import type { DocumentBlueprintDetails } from '@umbraco-cms/models'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import type { DocumentBlueprintDetails } from '@umbraco-cms/backoffice/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export @@ -12,30 +12,30 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller'; */ export class UmbDocumentBlueprintStore extends UmbStoreBase { // TODO: use the right type: - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DOCUMENT_BLUEPRINT_STORE_CONTEXT_TOKEN.toString()); } /** - * @description - Request a Data Type by key. The Data Type is added to the store and is returned as an Observable. - * @param {string} key + * @description - Request a Data Type by id. The Data Type is added to the store and is returned as an Observable. + * @param {string} id * @return {*} {(Observable)} * @memberof UmbDocumentBlueprintStore */ - getByKey(key: string) { + getById(id: string) { // TODO: use backend cli when available. - fetch(`/umbraco/management/api/v1/document-blueprint/details/${key}`) + fetch(`/umbraco/management/api/v1/document-blueprint/details/${id}`) .then((res) => res.json()) .then((data) => { this.#data.append(data); }); - return this.#data.getObservablePart((documents) => documents.find((document) => document.key === key)); + return this.#data.getObservablePart((documents) => documents.find((document) => document.id === id)); } - getScaffold(entityType: string, parentKey: string | null) { + getScaffold(entityType: string, parentId: string | null) { return {} as DocumentBlueprintDetails; } @@ -75,21 +75,21 @@ export class UmbDocumentBlueprintStore extends UmbStoreBase { // TODO: How can we avoid having this in both stores? /** * @description - Delete a Data Type. - * @param {string[]} keys + * @param {string[]} ids * @memberof UmbDocumentBlueprintStore * @return {*} {Promise} */ - async delete(keys: string[]) { + async delete(ids: string[]) { // TODO: use backend cli when available. await fetch('/umbraco/backoffice/document-blueprint/delete', { method: 'POST', - body: JSON.stringify(keys), + body: JSON.stringify(ids), headers: { 'Content-Type': 'application/json', }, }); - this.#data.remove(keys); + this.#data.remove(ids); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.tree.store.ts index 08aa3e6b3e..5b56f8bea8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/document-blueprint.tree.store.ts @@ -1,6 +1,6 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export const UMB_DOCUMENT_BLUEPRINT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken( 'UmbDocumentBlueprintTreeStore' @@ -12,8 +12,8 @@ export const UMB_DOCUMENT_BLUEPRINT_TREE_STORE_CONTEXT_TOKEN = new UmbContextTok * @extends {UmbStoreBase} * @description - Tree Data Store for Document Blueprints */ -export class UmbDocumentBlueprintTreeStore extends UmbTreeStoreBase { - constructor(host: UmbControllerHostInterface) { +export class UmbDocumentBlueprintTreeStore extends UmbEntityTreeStore { + constructor(host: UmbControllerHostElement) { super(host, UMB_DOCUMENT_BLUEPRINT_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/manifests.ts index 4b80c03dbb..d4bf4ceeaa 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/manifests.ts @@ -2,7 +2,7 @@ import { UmbDocumentBlueprintStore } from './document-blueprint.detail.store'; import { UmbDocumentBlueprintTreeStore } from './document-blueprint.tree.store'; import { manifests as menuItemManifests } from './menu-item/manifests'; import { manifests as workspaceManifests } from './workspace/manifests'; -import type { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestTreeStore } from '@umbraco-cms/backoffice/extensions-registry'; export const DOCUMENT_BLUEPRINT_STORE_ALIAS = 'Umb.Store.DocumentBlueprint'; export const DOCUMENT_BLUEPRINT_TREE_STORE_ALIAS = 'Umb.Store.DocumentBlueprintTree'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/menu-item/manifests.ts index 976c314278..ef3db05bed 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/menu-item/manifests.ts @@ -1,16 +1,18 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; const menuItem: ManifestMenuItem = { type: 'menuItem', alias: 'Umb.MenuItem.DocumentBlueprints', name: 'Document Blueprints Menu Item', - weight: 90, + weight: 100, meta: { label: 'Document Blueprints', icon: 'umb:blueprint', - menus: ['Umb.Menu.Settings'], entityType: 'document-blueprint-root', }, + conditions: { + menus: ['Umb.Menu.Settings'], + }, }; export const manifests = [menuItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts index 0cd1a02646..b1440f2681 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/document-blueprint-root-workspace.element.ts @@ -4,7 +4,7 @@ import { customElement } from 'lit/decorators.js'; @customElement('umb-document-blueprint-root-workspace') export class UmbDocumentBlueprintRootWorkspaceElement extends LitElement { render() { - return html`
Document Blueprint Root Workspace
`; + return html`
Document Blueprint Root Workspace
`; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/manifests.ts index 1391409e25..50af2c386e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-blueprints/workspace/manifests.ts @@ -1,4 +1,8 @@ -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/manifests.ts index 02774edbeb..5a38adea8f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/manifests.ts @@ -2,5 +2,12 @@ import { manifests as menuItemManifests } from './menu-item/manifests'; import { manifests as treeManifests } from './tree/manifests'; import { manifests as workspaceManifests } from './workspace/manifests'; import { manifests as repositoryManifests } from './repository/manifests'; +import { manifests as modalManifests } from './modals/manifests'; -export const manifests = [...menuItemManifests, ...treeManifests, ...repositoryManifests, ...workspaceManifests]; +export const manifests = [ + ...menuItemManifests, + ...treeManifests, + ...repositoryManifests, + ...workspaceManifests, + ...modalManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/menu-item/document-types-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/menu-item/document-types-menu-item.element.ts deleted file mode 100644 index 83abf9d6b6..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/menu-item/document-types-menu-item.element.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-document-types-sidebar-menu-item') -export class UmbDocumentTypesSidebarMenuItemElement extends UmbLitElement { - @state() - private _renderTree = false; - - private _onShowChildren() { - this._renderTree = true; - } - - private _onHideChildren() { - this._renderTree = false; - } - - // TODO: check if root has children before settings the has-children attribute - // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? - // TODO: can we make this reusable? - render() { - return html` - ${this._renderTree ? html`` : nothing} - `; - } -} - -export default UmbDocumentTypesSidebarMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-document-types-sidebar-menu-item': UmbDocumentTypesSidebarMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/menu-item/manifests.ts index a74b49aab2..fcfb95f61c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/menu-item/manifests.ts @@ -1,14 +1,17 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const menuItem: ManifestMenuItem = { +const menuItem: ManifestTypes = { type: 'menuItem', + kind: 'tree', alias: 'Umb.MenuItem.DocumentTypes', name: 'Document Types Menu Item', - weight: 10, - loader: () => import('./document-types-menu-item.element'), + weight: 900, meta: { + treeAlias: 'Umb.Tree.DocumentTypes', label: 'Document Types', icon: 'umb:folder', + }, + conditions: { menus: ['Umb.Menu.Settings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/modals/allowed-document-types/allowed-document-types-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/modals/allowed-document-types/allowed-document-types-modal.element.ts new file mode 100644 index 0000000000..41f8b961b5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/modals/allowed-document-types/allowed-document-types-modal.element.ts @@ -0,0 +1,71 @@ +import { html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UmbDocumentTypeRepository } from '../../repository/document-type.repository'; +import { UmbAllowedDocumentTypesModalData, UmbAllowedDocumentTypesModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; +import { DocumentTypeTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-allowed-document-types-modal') +export class UmbAllowedDocumentTypesModalElement extends UmbModalBaseElement< + UmbAllowedDocumentTypesModalData, + UmbAllowedDocumentTypesModalResult +> { + static styles = [UUITextStyles]; + + #documentTypeRepository = new UmbDocumentTypeRepository(this); + + @state() + private _allowedDocumentTypes: DocumentTypeTreeItemResponseModel[] = []; + + async firstUpdated() { + // TODO: show error + if (!this.data?.id) return; + + const { data } = await this.#documentTypeRepository.requestAllowedChildTypesOf(this.data.id); + + if (data) { + this._allowedDocumentTypes = data; + } + } + + private _handleCancel() { + this.modalHandler?.reject(); + } + + #onClick(event: PointerEvent) { + event.stopPropagation(); + const target = event.target as HTMLButtonElement; + const documentTypeKey = target.dataset.id; + if (!documentTypeKey) throw new Error('No document type id found'); + this.modalHandler?.submit({ documentTypeKey }); + } + + render() { + return html` + + + ${this._allowedDocumentTypes.length === 0 ? html`

No allowed types

` : nothing} + ${this._allowedDocumentTypes.map( + (item) => + html` + + ${item.icon ? html`` : nothing} + + ` + )} +
+ Cancel +
+ `; + } +} + +export default UmbAllowedDocumentTypesModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-allowed-document-types-modal': UmbAllowedDocumentTypesModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/modals/manifests.ts new file mode 100644 index 0000000000..e0e2b4d05f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/modals/manifests.ts @@ -0,0 +1,12 @@ +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; + +const modals: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.AllowedDocumentTypes', + name: 'Allowed Document Types Modal', + loader: () => import('./allowed-document-types/allowed-document-types-modal.element'), + }, +]; + +export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts index 683880d36e..78c9ac203c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.repository.ts @@ -1,27 +1,21 @@ -import type { RepositoryTreeDataSource } from '../../../../../libs/repository/repository-tree-data-source.interface'; import { DocumentTypeTreeServerDataSource } from './sources/document-type.tree.server.data'; import { UmbDocumentTypeServerDataSource } from './sources/document-type.server.data'; import { UmbDocumentTypeTreeStore, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN } from './document-type.tree.store'; import { UmbDocumentTypeStore, UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN } from './document-type.store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { ProblemDetailsModel, DocumentTypeModel } from '@umbraco-cms/backend-api'; -import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface'; -import { UmbDetailRepository } from '@umbraco-cms/repository'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; +import type { UmbTreeDataSource, UmbTreeRepository, UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { ProblemDetailsModel, DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; -type ItemType = DocumentTypeModel; +type ItemType = DocumentTypeResponseModel; -// Move to documentation / JSdoc -/* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */ -// element -> context -> repository -> (store) -> data source -// All methods should be async and return a promise. Some methods might return an observable as part of the promise response. -export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRepository { +export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRepository { #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - #treeSource: RepositoryTreeDataSource; + #treeSource: UmbTreeDataSource; #treeStore?: UmbDocumentTypeTreeStore; #detailDataSource: UmbDocumentTypeServerDataSource; @@ -29,7 +23,7 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source @@ -66,34 +60,34 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; + if (!ids) { + const error: ProblemDetailsModel = { title: 'Ids are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getItems(keys); + const { data, error } = await this.#treeSource.getItems(ids); - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -101,38 +95,29 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS: - async createScaffold(parentKey: string | null) { + async createScaffold(parentId: string | null) { + if (!parentId) throw new Error('Parent id is missing'); await this.#init; - - if (!parentKey) { - throw new Error('Parent key is missing'); - } - - return this.#detailDataSource.createScaffold(parentKey); + return this.#detailDataSource.createScaffold(parentId); } - async requestByKey(key: string) { + async requestById(id: string) { + if (!id) throw new Error('Id is missing'); await this.#init; - // TODO: should we show a notification if the key is missing? - // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - const { data, error } = await this.#detailDataSource.get(key); + const { data, error } = await this.#detailDataSource.get(id); if (data) { this.#detailStore?.append(data); @@ -141,81 +126,82 @@ export class UmbDocumentTypeRepository implements UmbTreeRepository, UmbDetailRe return { data, error }; } - async byKey(key: string) { + async byId(id: string) { + if (!id) throw new Error('Id is missing'); await this.#init; - return this.#detailStore!.byKey(key); + return this.#detailStore!.byId(id); + } + + // TODO: we need to figure out where to put this + async requestAllowedChildTypesOf(id: string) { + if (!id) throw new Error('Id is missing'); + await this.#init; + return this.#detailDataSource.getAllowedChildrenOf(id); } // Could potentially be general methods: async create(template: ItemType) { + if (!template || !template.id) throw new Error('Template is missing'); await this.#init; - if (!template || !template.key) { - throw new Error('Template is missing'); - } - const { error } = await this.#detailDataSource.insert(template); if (!error) { const notification = { data: { message: `Document created` } }; this.#notificationContext?.peek('positive', notification); - } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - this.#detailStore?.append(template); - // TODO: Update tree store with the new item? or ask tree to request the new item? + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + this.#detailStore?.append(template); + // TODO: Update tree store with the new item? or ask tree to request the new item? + } return { error }; } - async save(item: ItemType) { + async save(id: string, item: any) { + if (!id) throw new Error('Id is missing'); + if (!item) throw new Error('Item is missing'); + await this.#init; - if (!item || !item.key) { - throw new Error('Document-Type is missing'); - } - - const { error } = await this.#detailDataSource.update(item); + const { error } = await this.#detailDataSource.update(id, item); if (!error) { - const notification = { data: { message: `Document saved` } }; + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a template is updated in the store while someone is editing it. + this.#detailStore?.append(item); + this.#treeStore?.updateItem(id, item); + // TODO: would be nice to align the stores on methods/methodNames. + + const notification = { data: { message: `Document Type saved` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - // Consider notify a workspace if a template is updated in the store while someone is editing it. - this.#detailStore?.append(item); - this.#treeStore?.updateItem(item.key, { name: item.name }); - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } // General: - async delete(key: string) { + async delete(id: string) { + if (!id) throw new Error('Document id is missing'); await this.#init; - if (!key) { - throw new Error('Document key is missing'); - } - - const { error } = await this.#detailDataSource.delete(key); + const { error } = await this.#detailDataSource.delete(id); if (!error) { const notification = { data: { message: `Document deleted` } }; this.#notificationContext?.peek('positive', notification); - } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server. - // Consider notify a workspace if a template is deleted from the store while someone is editing it. - this.#detailStore?.remove([key]); - this.#treeStore?.removeItem(key); - // TODO: would be nice to align the stores on methods/methodNames. + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server. + // Consider notify a workspace if a template is deleted from the store while someone is editing it. + this.#detailStore?.remove([id]); + this.#treeStore?.removeItem(id); + // TODO: would be nice to align the stores on methods/methodNames. + } return { error }; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts index 7b38c47233..23b64c0942 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.store.ts @@ -1,8 +1,8 @@ -import { DocumentTypeModel } from '@umbraco-cms/backend-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export @@ -11,14 +11,14 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller'; * @description - Data Store for Document Types */ export class UmbDocumentTypeStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); /** * Creates an instance of UmbDocumentTypeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDocumentTypeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN.toString()); } @@ -27,7 +27,7 @@ export class UmbDocumentTypeStore extends UmbStoreBase { * @param {DocumentTypeModel} document * @memberof UmbDocumentTypeStore */ - append(document: DocumentTypeModel) { + append(document: DocumentTypeResponseModel) { this.#data.append([document]); } @@ -36,8 +36,8 @@ export class UmbDocumentTypeStore extends UmbStoreBase { * @param {DocumentTypeModel} document * @memberof UmbDocumentTypeStore */ - byKey(key: DocumentTypeModel['key']) { - return this.#data.getObservablePart((x) => x.find((y) => y.key === key)); + byId(id: DocumentTypeResponseModel['id']) { + return this.#data.getObservablePart((x) => x.find((y) => y.id === id)); } /** @@ -45,11 +45,9 @@ export class UmbDocumentTypeStore extends UmbStoreBase { * @param {string[]} uniques * @memberof UmbDocumentTypeStore */ - remove(uniques: Array) { + remove(uniques: Array) { this.#data.remove(uniques); } } -export const UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken( - 'UmbDocumentTypeStore' -); +export const UMB_DOCUMENT_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbDocumentTypeStore'); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts index 0f1e5b38ca..83bcc484e2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/document-type.tree.store.ts @@ -1,6 +1,6 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export @@ -9,13 +9,13 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller'; * @description - Tree Data Store for Document-Types */ // TODO: consider if tree store could be turned into a general EntityTreeStore class? -export class UmbDocumentTypeTreeStore extends UmbTreeStoreBase { +export class UmbDocumentTypeTreeStore extends UmbEntityTreeStore { /** * Creates an instance of UmbDocumentTypeTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDocumentTypeTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/manifests.ts index 5a6bf52874..567468606f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/manifests.ts @@ -1,7 +1,7 @@ import { UmbDocumentTypeRepository } from './document-type.repository'; import { UmbDocumentTypeStore } from './document-type.store'; import { UmbDocumentTypeTreeStore } from './document-type.tree.store'; -import { ManifestRepository, ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import { ManifestRepository, ManifestStore, ManifestTreeStore } from '@umbraco-cms/backoffice/extensions-registry'; export const DOCUMENT_TYPE_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.server.data.ts index 5f1a282ed4..f6bff744b2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.server.data.ts @@ -1,7 +1,11 @@ -import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; -import { DocumentTypeResource, ProblemDetailsModel, DocumentTypeModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; +import { + DocumentTypeResource, + ProblemDetailsModel, + DocumentTypeResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Document Type that fetches data from the server @@ -9,46 +13,46 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class UmbDocumentTypeServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSource { - #host: UmbControllerHostInterface; +export class UmbDocumentTypeServerDataSource implements UmbDataSource { + #host: UmbControllerHostElement; /** * Creates an instance of UmbDocumentServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDocumentServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** - * Fetches a Document with the given key from the server - * @param {string} key + * Fetches a Document with the given id from the server + * @param {string} id * @return {*} * @memberof UmbDocumentTypeServerDataSource */ - async get(key: string) { - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; + async get(id: string) { + if (!id) { + const error: ProblemDetailsModel = { title: 'Id is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - DocumentTypeResource.getDocumentTypeByKey({ - key, + DocumentTypeResource.getDocumentTypeById({ + id: id, }) ); } /** * Creates a new Document scaffold - * @param {(string | null)} parentKey + * @param {(string | null)} parentId * @return {*} * @memberof UmbDocumentTypeServerDataSource */ - async createScaffold(parentKey: string | null) { - const data: DocumentTypeModel = { + async createScaffold(parentId: string | null) { + const data: DocumentTypeResponseModel = { properties: [], }; @@ -61,12 +65,12 @@ export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSour * @return {*} * @memberof UmbDocumentTypeServerDataSource */ - async insert(document: DocumentTypeModel) { - if (!document.key) { - //const error: ProblemDetails = { title: 'Document key is missing' }; + async insert(document: DocumentTypeResponseModel) { + if (!document.id) { + //const error: ProblemDetails = { title: 'Document id is missing' }; return Promise.reject(); } - //const payload = { key: document.key, requestBody: document }; + //const payload = { id: document.id, requestBody: document }; let body: string; @@ -78,7 +82,7 @@ export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSour } //return tryExecuteAndNotify(this.#host, DocumentTypeResource.postDocument(payload)); // TODO: use resources when end point is ready: - return tryExecuteAndNotify( + return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document-type', { method: 'POST', @@ -96,13 +100,8 @@ export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSour * @return {*} * @memberof UmbDocumentTypeServerDataSource */ - // TODO: Error mistake in this: - async update(document: DocumentTypeModel) { - if (!document.key) { - const error: ProblemDetailsModel = { title: 'Document key is missing' }; - return { error }; - } - //const payload = { key: document.key, requestBody: document }; + async update(id: string, document: any) { + if (!id) throw new Error('Id is missing'); let body: string; @@ -114,9 +113,9 @@ export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSour } // TODO: use resources when end point is ready: - return tryExecuteAndNotify( + return tryExecuteAndNotify( this.#host, - fetch(`/umbraco/management/api/v1/document-type/${document.key}`, { + fetch(`/umbraco/management/api/v1/document-type/${document.id}`, { method: 'PUT', body: body, headers: { @@ -126,40 +125,15 @@ export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSour ); } - /** - * Trash a Document on the server - * @param {Document} Document - * @return {*} - * @memberof UmbDocumentTypeServerDataSource - */ - async trash(key: string) { - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - - // TODO: use resources when end point is ready: - return tryExecuteAndNotify( - this.#host, - fetch(`/umbraco/management/api/v1/document-type/${key}`, { - method: 'DELETE', - body: JSON.stringify([key]), - headers: { - 'Content-Type': 'application/json', - }, - }) as any - ); - } - /** * Deletes a Template on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbDocumentTypeServerDataSource */ - async delete(key: string) { - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; + async delete(id: string) { + if (!id) { + const error: ProblemDetailsModel = { title: 'Id is missing' }; return { error }; } @@ -168,7 +142,7 @@ export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSour try { await fetch('/umbraco/management/api/v1/document-type/trash', { method: 'POST', - body: JSON.stringify([key]), + body: JSON.stringify([id]), headers: { 'Content-Type': 'application/json', }, @@ -186,4 +160,31 @@ export class UmbDocumentTypeServerDataSource implements RepositoryDetailDataSour ); */ } + + /** + * Get the allowed document types for a given parent id + * @param {string} id + * @return {*} + * @memberof UmbDocumentTypeServerDataSource + */ + async getAllowedChildrenOf(id: string) { + if (!id) throw new Error('Id is missing'); + + let problemDetails: ProblemDetailsModel | undefined = undefined; + let data = undefined; + + try { + const res = await fetch(`/umbraco/management/api/v1/document-type/allowed-children-of/${id}`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + data = await res.json(); + } catch (error) { + problemDetails = { title: `Get allowed children of ${id} failed` }; + } + + return { data, error: problemDetails }; + } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.tree.server.data.ts index 8e4b1fefeb..fd3cee9ccb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/repository/sources/document-type.tree.server.data.ts @@ -1,7 +1,7 @@ -import type { RepositoryTreeDataSource } from '../../../../../../libs/repository/repository-tree-data-source.interface'; -import { ProblemDetailsModel, DocumentTypeResource } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { ProblemDetailsModel, DocumentTypeResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Document tree that fetches data from the server @@ -9,17 +9,17 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class DocumentTreeServerDataSource * @implements {DocumentTreeDataSource} */ -export class DocumentTypeTreeServerDataSource implements RepositoryTreeDataSource { - #host: UmbControllerHostInterface; +export class DocumentTypeTreeServerDataSource implements UmbTreeDataSource { + #host: UmbControllerHostElement; // TODO: how do we handle trashed items? - async trashItems(keys: Array) { + async trashItems(ids: Array) { // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document-type/trash', { method: 'POST', - body: JSON.stringify(keys), + body: JSON.stringify(ids), headers: { 'Content-Type': 'application/json', }, @@ -27,13 +27,13 @@ export class DocumentTypeTreeServerDataSource implements RepositoryTreeDataSourc ); } - async moveItems(keys: Array, destination: string) { + async moveItems(ids: Array, destination: string) { // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document-type/move', { method: 'POST', - body: JSON.stringify({ keys, destination }), + body: JSON.stringify({ ids: ids, destination }), headers: { 'Content-Type': 'application/json', }, @@ -43,10 +43,10 @@ export class DocumentTypeTreeServerDataSource implements RepositoryTreeDataSourc /** * Creates an instance of DocumentTreeServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof DocumentTreeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -60,41 +60,41 @@ export class DocumentTypeTreeServerDataSource implements RepositoryTreeDataSourc } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} * @memberof DocumentTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + async getChildrenOf(parentId: string | null) { + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, DocumentTypeResource.getTreeDocumentTypeChildren({ - parentKey, + parentId, }) ); } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} * @memberof DocumentTreeServerDataSource */ - async getItems(keys: Array) { - if (keys) { + async getItems(ids: Array) { + if (ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - DocumentTypeResource.getTreeDocumentTypeItem({ - key: keys, + DocumentTypeResource.getDocumentTypeItem({ + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/tree/manifests.ts index 1a2876f55f..5a5ccaa08d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/tree/manifests.ts @@ -1,13 +1,23 @@ -import { UmbDocumentTypeRepository } from '../repository/document-type.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { DOCUMENT_TYPE_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const tree: ManifestTree = { type: 'tree', alias: 'Umb.Tree.DocumentTypes', name: 'Document Types Tree', meta: { - repository: UmbDocumentTypeRepository, + repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.DocumentType', + name: 'Document Type Tree Item', + conditions: { + entityType: 'document-type', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace-editor.element.ts new file mode 100644 index 0000000000..21d8c3e526 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace-editor.element.ts @@ -0,0 +1,154 @@ +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbDocumentTypeWorkspaceContext } from './document-type-workspace.context'; +import type { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_ICON_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-document-type-workspace-editor') +export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + + #header { + display: flex; + flex: 1 1 auto; + margin: 0 var(--uui-size-layout-1); + } + + #name { + width: 100%; + flex: 1 1 auto; + align-items: center; + } + + #alias { + height: calc(100% - 2px); + --uui-input-border-width: 0; + --uui-button-height: calc(100% -2px); + } + + #icon { + font-size: calc(var(--uui-size-layout-3) / 2); + } + `, + ]; + + // TODO: notice this format is not acceptable: + @state() + private _icon = { + color: '#000000', + name: 'umb:document-dashed-line', + }; + + #workspaceContext?: UmbDocumentTypeWorkspaceContext; + + //@state() + //private _documentType?: DocumentTypeResponseModel; + @state() + private _name?: string; + + @state() + private _alias?: string; + + private _modalContext?: UmbModalContext; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbDocumentTypeWorkspaceContext; + this.#observeDocumentType(); + }); + + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this._modalContext = instance; + }); + } + + #observeDocumentType() { + if (!this.#workspaceContext) return; + //this.observe(this.#workspaceContext.data, (data) => (this._documentType = data)); + this.observe(this.#workspaceContext.name, (name) => (this._name = name)); + this.observe(this.#workspaceContext.alias, (alias) => (this._alias = alias)); + } + + // TODO. find a way where we don't have to do this for all workspaces. + private _handleNameInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + // TODO. find a way where we don't have to do this for all workspaces. + private _handleAliasInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setAlias(target.value); + } + } + event.stopPropagation(); + } + + private async _handleIconClick() { + const modalHandler = this._modalContext?.open(UMB_ICON_PICKER_MODAL); + + modalHandler?.onSubmit().then((saved) => { + if (saved.icon) this.#workspaceContext?.setIcon(saved.icon); + // TODO save color ALIAS as well + }); + } + + render() { + return html` + + + +
+ + Keyboard Shortcuts + + ALT + + + shift + + + k + + +
+
+ `; + } +} + +export default UmbDocumentTypeWorkspaceEditorElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-editor': UmbDocumentTypeWorkspaceEditorElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.context.ts index 4fcef85092..4ee41fc2b7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.context.ts @@ -1,33 +1,73 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; import { UmbDocumentTypeRepository } from '../repository/document-type.repository'; -import type { DocumentTypeModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ObjectState } from '@umbraco-cms/observable-api'; +import { UmbWorkspacePropertyStructureManager } from '../../../shared/components/workspace/workspace-context/workspace-structure-manager.class'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; -type EntityType = DocumentTypeModel; -export class UmbWorkspaceDocumentTypeContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface +type EntityType = DocumentTypeResponseModel; +export class UmbDocumentTypeWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { - #data = new ObjectState(undefined); - data = this.#data.asObservable(); - name = this.#data.getObservablePart((data) => data?.name); + // Draft is located in structure manager - constructor(host: UmbControllerHostInterface) { + // General for content types: + readonly data; + readonly name; + readonly alias; + readonly description; + readonly icon; + + // TODO: Consider if each of these should go the view it self, but only if its used in that one view, otherwise make then go here. + readonly allowedAsRoot; + readonly variesByCulture; + readonly variesBySegment; + readonly isElement; + readonly allowedContentTypes; + readonly compositions; + + // Document type specific: + readonly allowedTemplateIds; + readonly defaultTemplateId; + readonly cleanup; + + readonly structure; + + constructor(host: UmbControllerHostElement) { super(host, new UmbDocumentTypeRepository(host)); + + this.structure = new UmbWorkspacePropertyStructureManager(this.host, this.repository); + + // General for content types: + this.data = this.structure.rootDocumentType; + this.name = this.structure.rootDocumentTypeObservablePart((data) => data?.name); + this.alias = this.structure.rootDocumentTypeObservablePart((data) => data?.alias); + this.description = this.structure.rootDocumentTypeObservablePart((data) => data?.description); + this.icon = this.structure.rootDocumentTypeObservablePart((data) => data?.icon); + this.allowedAsRoot = this.structure.rootDocumentTypeObservablePart((data) => data?.allowedAsRoot); + this.variesByCulture = this.structure.rootDocumentTypeObservablePart((data) => data?.variesByCulture); + this.variesBySegment = this.structure.rootDocumentTypeObservablePart((data) => data?.variesBySegment); + this.isElement = this.structure.rootDocumentTypeObservablePart((data) => data?.isElement); + this.allowedContentTypes = this.structure.rootDocumentTypeObservablePart((data) => data?.allowedContentTypes); + this.compositions = this.structure.rootDocumentTypeObservablePart((data) => data?.compositions); + + // Document type specific: + this.allowedTemplateIds = this.structure.rootDocumentTypeObservablePart((data) => data?.allowedTemplateIds); + this.defaultTemplateId = this.structure.rootDocumentTypeObservablePart((data) => data?.defaultTemplateId); + this.cleanup = this.structure.rootDocumentTypeObservablePart((data) => data?.defaultTemplateId); } public setPropertyValue(alias: string, value: unknown) { - throw new Error('setPropertyValue is not implemented for UmbWorkspaceDocumentTypeContext'); + throw new Error('setPropertyValue is not implemented for UmbDocumentTypeWorkspaceContext'); } getData() { - return this.#data.getValue(); + return this.structure.getRootDocumentType() || {}; } - getEntityKey() { - return this.getData()?.key || ''; + getEntityId() { + return this.getData().id; } getEntityType() { @@ -35,33 +75,42 @@ export class UmbWorkspaceDocumentTypeContext } setName(name: string) { - this.#data.update({ name }); + this.structure.updateRootDocumentType({ name }); + } + setAlias(alias: string) { + this.structure.updateRootDocumentType({ alias }); } // TODO => manage setting icon color setIcon(icon: string) { - this.#data.update({ icon }); + this.structure.updateRootDocumentType({ icon }); } - async load(entityKey: string) { - const { data } = await this.repository.requestByKey(entityKey); - if (data) { - this.#data.next(data); - } + async createScaffold(parentId: string) { + const { data } = await this.structure.createScaffold(parentId); + if (!data) return undefined; + + this.setIsNew(true); + //this.#draft.next(data); + return data || undefined; } - async createScaffold(parentKey: string | null) { - const { data } = await this.repository.createScaffold(parentKey); - if (!data) return; - this.#data.next(data); + async load(entityId: string) { + const { data } = await this.structure.loadType(entityId); + if (!data) return undefined; + + this.setIsNew(false); + //this.#draft.next(data); + return data || undefined; } async save() { - if (!this.#data.value) return; - this.repository.save(this.#data.value); + const id = this.getEntityId(); + if (!id) throw new Error('Cannot save entity without id'); + this.repository.save(id, this.getData()); } public destroy(): void { - this.#data.complete(); + this.structure.destroy(); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts index 5e5a660c77..78b74edc56 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.element.ts @@ -1,118 +1,32 @@ -import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html } from 'lit'; +import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import type { UmbWorkspaceEntityElement } from '../../../shared/components/workspace/workspace-entity-element.interface'; -import { UMB_ICON_PICKER_MODAL_TOKEN } from '../../../shared/modals/icon-picker'; -import { UmbWorkspaceDocumentTypeContext } from './document-type-workspace.context'; -import type { DocumentTypeModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { UmbDocumentTypeWorkspaceContext } from './document-type-workspace.context'; +import { UmbDocumentTypeWorkspaceEditorElement } from './document-type-workspace-editor.element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-document-type-workspace') -export class UmbDocumentTypeWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - width: 100%; - height: 100%; - } +export class UmbDocumentTypeWorkspaceElement extends UmbLitElement { + static styles = [UUITextStyles]; - #header { - display: flex; - flex: 1 1 auto; - margin: 0 var(--uui-size-layout-1); - } - - #name { - width: 100%; - flex: 1 1 auto; - align-items: center; - } - - #alias { - padding: 0 var(--uui-size-space-3); - } - - #icon { - font-size: calc(var(--uui-size-layout-3) / 2); - } - `, - ]; - - private _icon = { - color: '#000000', - name: 'umb:document-dashed-line', - }; - - private _workspaceContext: UmbWorkspaceDocumentTypeContext = new UmbWorkspaceDocumentTypeContext(this); + #workspaceContext = new UmbDocumentTypeWorkspaceContext(this); + #element = new UmbDocumentTypeWorkspaceEditorElement(); @state() - private _documentType?: DocumentTypeModel; - - private _modalContext?: UmbModalContext; - - constructor() { - super(); - - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this._modalContext = instance; - }); - - this.observe(this._workspaceContext.data, (data) => { - // TODO: make method to identify if data is of type DocumentType - this._documentType = data as DocumentType; - }); - } - - public load(entityKey: string) { - this._workspaceContext.load(entityKey); - } - - public create(parentKey: string | null) { - this._workspaceContext.createScaffold(parentKey); - } - - // TODO. find a way where we don't have to do this for all workspaces. - private _handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this._workspaceContext?.setName(target.value); - } - } - } - - private async _handleIconClick() { - const modalHandler = this._modalContext?.open(UMB_ICON_PICKER_MODAL_TOKEN); - - modalHandler?.onSubmit().then((saved) => { - if (saved.icon) this._workspaceContext?.setIcon(saved.icon); - // TODO save color ALIAS as well - }); - } + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - return html` - - - -
Keyboard Shortcuts
-
- `; + return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.stories.ts index 19eec3849c..bf851ab301 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/document-type-workspace.stories.ts @@ -1,6 +1,6 @@ -import './document-type-workspace.element'; +import './document-type-workspace-editor.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { ifDefined } from 'lit/directives/if-defined.js'; import { treeData } from '../../../../core/mocks/data/document-type.data'; import type { UmbDocumentTypeWorkspaceElement } from './document-type-workspace.element'; @@ -12,5 +12,5 @@ export default { } as Meta; export const AAAOverview: Story = () => - html` `; + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/manifests.ts index 114efb3e7e..37e4baa850 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/manifests.ts @@ -1,5 +1,9 @@ -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', @@ -16,13 +20,60 @@ const workspaceViews: Array = [ type: 'workspaceView', alias: 'Umb.WorkspaceView.DocumentType.Design', name: 'Document Type Workspace Design View', - loader: () => import('./views/design/workspace-view-document-type-design.element'), - weight: 100, + loader: () => import('./views/design/document-type-workspace-view-edit.element'), + weight: 1000, meta: { - workspaces: ['Umb.Workspace.DocumentType'], label: 'Design', pathname: 'design', - icon: 'edit', + icon: 'umb:document-dashed-line', + }, + conditions: { + workspaces: ['Umb.Workspace.DocumentType'], + }, + }, + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.DocumentType.Structure', + name: 'Document Type Workspace Structure View', + loader: () => import('./views/structure/document-type-workspace-view-structure.element'), + weight: 100, + meta: { + label: 'Structure', + pathname: 'structure', + icon: 'umb:mindmap', + }, + conditions: { + workspaces: ['Umb.Workspace.DocumentType'], + }, + }, + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.DocumentType.Permissions', + name: 'Document Type Workspace Permissions View', + loader: () => import('./views/details/document-type-workspace-view-details.element'), + weight: 100, + meta: { + label: 'Details', + pathname: 'details', + icon: 'umb:settings', + }, + conditions: { + workspaces: ['Umb.Workspace.DocumentType'], + }, + }, + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.DocumentType.Templates', + name: 'Document Type Workspace Templates View', + loader: () => import('./views/templates/document-type-workspace-view-templates.element'), + weight: 100, + meta: { + label: 'Templates', + pathname: 'templates', + icon: 'umb:layout', + }, + conditions: { + workspaces: ['Umb.Workspace.DocumentType'], }, }, ]; @@ -33,12 +84,14 @@ const workspaceActions: Array = [ alias: 'Umb.WorkspaceAction.DocumentType.Save', name: 'Save Document Type Workspace Action', meta: { - workspaces: ['Umb.Workspace.DocumentType'], label: 'Save', look: 'primary', color: 'positive', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.DocumentType'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-design.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-design.element.ts new file mode 100644 index 0000000000..5f7c657b58 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-design.element.ts @@ -0,0 +1,173 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import '../../../../../shared/property-creator/property-creator.element.ts'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-document-type-workspace-view-design') +export class UmbDocumentTypeWorkspaceViewDesignElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + } + /* TODO: This should be replaced with a general workspace bar — naming is hard */ + #workspace-tab-bar { + padding: 0 var(--uui-size-layout-1); + display: flex; + align-items: center; + justify-content: space-between; + background-color: var(--uui-color-surface); + flex-wrap: nowrap; + } + .tab-actions { + display: flex; + gap: var(--uui-size-space-4); + } + .tab-actions uui-button uui-icon { + padding-right: calc(-1 * var(--uui-size-space-4)); + } + + uui-tab { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + } + + uui-tab .trash { + display: flex; + align-items: stretch; + } + + uui-tab uui-input { + flex-grow: 1; + } + + uui-input:not(:focus) { + border: 1px solid transparent; + } + + uui-input:not(:hover, :focus) .trash { + opacity: 0; + } + + /** Property Group Wrapper */ + + #wrapper { + margin: var(--uui-size-layout-1); + } + + #add-group { + margin-top: var(--uui-size-layout-1); + width: 100%; + --uui-button-height: var(--uui-size-layout-4); + } + + .group-headline { + display: flex; + gap: var(--uui-size-space-4); + } + .group-headline uui-input { + flex-grow: 1; + } + `, + ]; + + private _workspaceContext?: UmbDocumentTypeWorkspaceContext; + + @state() + private _tabs: any[] = []; + + constructor() { + super(); + + // TODO: Figure out if this is the best way to consume the context or if it can be strongly typed with an UmbContextToken + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (documentTypeContext) => { + this._workspaceContext = documentTypeContext as UmbDocumentTypeWorkspaceContext; + this._observeDocumentType(); + }); + } + + private _observeDocumentType() { + if (!this._workspaceContext) return; + } + + render() { + return html` +
+ ${this.renderTabBar()} +
+ + + Compositions + + + + Recorder + +
+
+
+ +
+ + + +
+ +
+ Add group +
+ `; + } + + #remove(index: number) { + this._tabs.splice(index, 1); + this.requestUpdate(); + } + async #addTab() { + this._tabs = [...this._tabs, { name: 'Test' }]; + } + + renderTabBar() { + return html` + ${repeat( + this._tabs, + (tab) => tab.name, + (tab, index) => { + //TODO: Should these tabs be part of routing? + return html` +
+ + + + + +
+
`; + } + )} + + + Add tab + +
`; + } +} + +export default UmbDocumentTypeWorkspaceViewDesignElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-view-design': UmbDocumentTypeWorkspaceViewDesignElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/workspace-view-document-type-design.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-design.stories.ts similarity index 56% rename from src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/workspace-view-document-type-design.stories.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-design.stories.ts index b3d14fe840..9a9bd2290a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/workspace-view-document-type-design.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-design.stories.ts @@ -1,17 +1,17 @@ -import './workspace-view-document-type-design.element'; +import './document-type-workspace-view-design.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; //import { data } from '../../../../../core/mocks/data/document-type.data'; //import { UmbDocumentTypeContext } from '../../document-type.context'; -import type { UmbWorkspaceViewDocumentTypeDesignElement } from './workspace-view-document-type-design.element'; +import type { UmbDocumentTypeWorkspaceViewDesignElement } from './document-type-workspace-view-design.element'; export default { title: 'Workspaces/Document Type/Views/Design', - component: 'umb-workspace-view-document-type-design', - id: 'umb-workspace-view-document-type-design', + component: 'umb-document-type-workspace-view-design', + id: 'umb-document-type-workspace-view-design', decorators: [ (story) => { return html`TODO: make use of mocked workspace context??`; @@ -22,6 +22,6 @@ export default { ], } as Meta; -export const AAAOverview: Story = () => - html` `; +export const AAAOverview: Story = () => + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-properties.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-properties.element.ts new file mode 100644 index 0000000000..73eea4e334 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-properties.element.ts @@ -0,0 +1,130 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbWorkspacePropertyStructureHelper } from '../../../../../shared/components/workspace/workspace-context/workspace-property-structure-helper.class'; +import { PropertyContainerTypes } from '../../../../../shared/components/workspace/workspace-context/workspace-structure-manager.class'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DocumentTypePropertyTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_MODAL_CONTEXT_TOKEN, UMB_PROPERTY_SETTINGS_MODAL } from '@umbraco-cms/backoffice/modal'; +import './document-type-workspace-view-edit-property.element'; + +@customElement('umb-document-type-workspace-view-edit-properties') +export class UmbDocumentTypeWorkspaceViewEditPropertiesElement extends UmbLitElement { + private _containerId: string | undefined; + + public get containerId(): string | undefined { + return this._containerId; + } + public set containerId(value: string | undefined) { + if (value === this._containerId) return; + const oldValue = this._containerId; + this._containerId = value; + this.requestUpdate('containerId', oldValue); + } + + @property({ type: String, attribute: 'container-name', reflect: false }) + public get containerName(): string | undefined { + return this._propertyStructureHelper.getContainerName(); + } + public set containerName(value: string | undefined) { + this._propertyStructureHelper.setContainerName(value); + } + + @property({ type: String, attribute: 'container-type', reflect: false }) + public get containerType(): PropertyContainerTypes | undefined { + return this._propertyStructureHelper.getContainerType(); + } + public set containerType(value: PropertyContainerTypes | undefined) { + this._propertyStructureHelper.setContainerType(value); + } + + _propertyStructureHelper = new UmbWorkspacePropertyStructureHelper(this); + + @state() + _propertyStructure: Array = []; + + #modalContext?: typeof UMB_MODAL_CONTEXT_TOKEN.TYPE; + + constructor() { + super(); + + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => (this.#modalContext = instance)); + this.observe(this._propertyStructureHelper.propertyStructure, (propertyStructure) => { + this._propertyStructure = propertyStructure; + }); + } + + async #onAddProperty() { + const property = await this._propertyStructureHelper.addProperty(this._containerId); + if (!property) return; + + // Take id and parse to modal: + console.log('property id:', property.id!); + + const modalHandler = this.#modalContext?.open(UMB_PROPERTY_SETTINGS_MODAL); + + modalHandler?.onSubmit().then((result) => { + console.log(result); + }); + } + + render() { + return html`${repeat( + this._propertyStructure, + (property) => property.alias, + (property) => + html` { + this._propertyStructureHelper.partialUpdateProperty(property.id, event.detail); + }}>` + )} Add property `; + } + + static styles = [ + UUITextStyles, + css` + .property:first-of-type { + padding-top: 0; + } + .property { + border-bottom: 1px solid var(--uui-color-divider); + } + .property:last-child { + border-bottom: 0; + } + + .property { + display: grid; + grid-template-columns: 200px auto; + column-gap: var(--uui-size-layout-2); + border-bottom: 1px solid var(--uui-color-divider); + padding: var(--uui-size-layout-1) 0; + container-type: inline-size; + } + + .property > div { + grid-column: span 2; + } + + @container (width > 600px) { + .property:not([orientation='vertical']) > div { + grid-column: span 1; + } + } + + #add { + width: 100%; + } + `, + ]; +} + +export default UmbDocumentTypeWorkspaceViewEditPropertiesElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-view-edit-properties': UmbDocumentTypeWorkspaceViewEditPropertiesElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-property.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-property.element.ts new file mode 100644 index 0000000000..45fad85fcb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-property.element.ts @@ -0,0 +1,106 @@ +import { css, html, LitElement } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { PropertyTypeResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; + +/** + * @element document-type-workspace-view-edit-property + * @description - Element for displaying a property in an workspace. + * @slot editor - Slot for rendering the Property Editor + */ +@customElement('document-type-workspace-view-edit-property') +export class UmbDocumentTypeWorkspacePropertyElement extends LitElement { + /** + * Property, the data object for the property. + * @type {string} + * @attr + * @default '' + */ + @property({ type: Object }) + public property?: PropertyTypeResponseModelBaseModel; + + _firePartialUpdate(propertyName: string, value: string | number | boolean | null | undefined) { + const partialObject = {} as any; + partialObject[propertyName] = value; + + this.dispatchEvent(new CustomEvent('partial-property-update', { detail: partialObject })); + } + + render() { + // TODO: Only show alias on label if user has access to DocumentType within settings: + return this.property + ? html` + +
+ ` + : ''; + } + + static styles = [ + UUITextStyles, + css` + :host { + display: grid; + grid-template-columns: 200px auto; + column-gap: var(--uui-size-layout-2); + border-bottom: 1px solid var(--uui-color-divider); + padding: var(--uui-size-layout-1) 0; + container-type: inline-size; + } + + :host > div { + grid-column: span 2; + } + + @container (width > 600px) { + :host(:not([orientation='vertical'])) > div { + grid-column: span 1; + } + } + + :host(:last-of-type) { + border-bottom: none; + } + + :host-context(umb-variantable-property:first-of-type) { + padding-top: 0; + } + + p { + margin-bottom: 0; + } + + #header { + position: sticky; + top: var(--uui-size-space-4); + height: min-content; + z-index: 2; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + 'document-type-workspace-view-edit-property': UmbDocumentTypeWorkspacePropertyElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-tab.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-tab.element.ts new file mode 100644 index 0000000000..51782de0b7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit-tab.element.ts @@ -0,0 +1,115 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbWorkspaceContainerStructureHelper } from '../../../../../shared/components/workspace/workspace-context/workspace-container-structure-helper.class'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { PropertyTypeContainerResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; +import './document-type-workspace-view-edit-properties.element'; + +@customElement('umb-document-type-workspace-view-edit-tab') +export class UmbDocumentTypeWorkspaceViewEditTabElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + uui-box { + margin: var(--uui-size-layout-1); + } + + #add { + width: 100%; + } + `, + ]; + + private _ownerTabId?: string | undefined; + + @property({ type: String }) + public get ownerTabId(): string | undefined { + return this._ownerTabId; + } + public set ownerTabId(value: string | undefined) { + if (value === this._ownerTabId) return; + const oldValue = this._ownerTabId; + this._ownerTabId = value; + this.requestUpdate('ownerTabId', oldValue); + } + + private _tabName?: string | undefined; + + @property({ type: String }) + public get tabName(): string | undefined { + return this._groupStructureHelper.getName(); + } + public set tabName(value: string | undefined) { + if (value === this._tabName) return; + const oldValue = this._tabName; + this._tabName = value; + this._groupStructureHelper.setName(value); + this.requestUpdate('tabName', oldValue); + } + + @property({ type: Boolean }) + public get noTabName(): boolean { + return this._groupStructureHelper.getIsRoot(); + } + public set noTabName(value: boolean) { + this._groupStructureHelper.setIsRoot(value); + } + + _groupStructureHelper = new UmbWorkspaceContainerStructureHelper(this); + + @state() + _groups: Array = []; + + @state() + _hasProperties = false; + + constructor() { + super(); + + this.observe(this._groupStructureHelper.containers, (groups) => { + this._groups = groups; + }); + this.observe(this._groupStructureHelper.hasProperties, (hasProperties) => { + this._hasProperties = hasProperties; + }); + } + + #onAddGroup = () => { + // Idea, maybe we can gather the sortOrder from the last group rendered and add 1 to it? + this._groupStructureHelper.addGroup(this._ownerTabId); + }; + + render() { + return html` + ${this._hasProperties + ? html` + + + + ` + : ''} + ${repeat( + this._groups, + (group) => group.name, + (group) => html` + + ` + )} + Add Group + `; + } +} + +export default UmbDocumentTypeWorkspaceViewEditTabElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-view-edit-tab': UmbDocumentTypeWorkspaceViewEditTabElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit.element.ts new file mode 100644 index 0000000000..b09416588d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/document-type-workspace-view-edit.element.ts @@ -0,0 +1,209 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context'; +import { UmbWorkspaceContainerStructureHelper } from '../../../../../shared/components/workspace/workspace-context/workspace-container-structure-helper.class'; +import type { UmbDocumentTypeWorkspaceViewEditTabElement } from './document-type-workspace-view-edit-tab.element'; +import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { PropertyTypeContainerResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; + +@customElement('umb-document-type-workspace-view-edit') +export class UmbDocumentTypeWorkspaceViewEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + --uui-tab-background: var(--uui-color-surface); + } + + /* TODO: This should be replaced with a general workspace bar — naming is hard */ + #workspace-tab-bar { + padding: 0 var(--uui-size-layout-1); + display: flex; + align-items: center; + justify-content: space-between; + background-color: var(--uui-color-surface); + flex-wrap: nowrap; + } + `, + ]; + + //private _hasRootProperties = false; + private _hasRootGroups = false; + + @state() + private _routes: IRoute[] = []; + + @state() + _tabs: Array = []; + + @state() + private _routerPath?: string; + + @state() + private _activePath = ''; + + private _workspaceContext?: UmbDocumentTypeWorkspaceContext; + + private _tabsStructureHelper = new UmbWorkspaceContainerStructureHelper(this); + + constructor() { + super(); + + this._tabsStructureHelper.setIsRoot(true); + this._tabsStructureHelper.setContainerChildType('Tab'); + this.observe(this._tabsStructureHelper.containers, (tabs) => { + this._tabs = tabs; + this._createRoutes(); + }); + + // _hasRootProperties can be gotten via _tabsStructureHelper.hasProperties. But we do not support root properties currently. + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (workspaceContext) => { + this._workspaceContext = workspaceContext as UmbDocumentTypeWorkspaceContext; + this._observeRootGroups(); + }); + } + + private _observeRootGroups() { + if (!this._workspaceContext) return; + + this.observe( + this._workspaceContext.structure.hasRootContainers('Group'), + (hasRootGroups) => { + this._hasRootGroups = hasRootGroups; + this._createRoutes(); + }, + '_observeGroups' + ); + } + + private _createRoutes() { + const routes: IRoute[] = []; + + if (this._tabs.length > 0) { + this._tabs?.forEach((tab) => { + const tabName = tab.name; + routes.push({ + path: `tab/${encodeURI(tabName || '').toString()}`, + component: () => import('./document-type-workspace-view-edit-tab.element'), + setup: (component) => { + (component as UmbDocumentTypeWorkspaceViewEditTabElement).tabName = tabName ?? ''; + (component as UmbDocumentTypeWorkspaceViewEditTabElement).ownerTabId = tab.id; + }, + }); + }); + } + + if (this._hasRootGroups) { + routes.push({ + path: '', + component: () => import('./document-type-workspace-view-edit-tab.element'), + setup: (component) => { + (component as UmbDocumentTypeWorkspaceViewEditTabElement).noTabName = true; + }, + }); + } + + if (routes.length !== 0) { + routes.push({ + path: '**', + redirectTo: routes[0]?.path, + }); + } + + this._routes = routes; + } + + #remove(tabId: string | undefined) { + if (!tabId) return; + this._workspaceContext?.structure.removeContainer(null, tabId); + } + async #addTab() { + this._workspaceContext?.structure.createContainer(null, null, 'Tab'); + } + + renderTabsNavigation() { + return html` + ${this._hasRootGroups + ? html` + Content + ` + : ''} + ${repeat( + this._tabs, + (tab) => tab.id, + (tab) => { + // TODO: make better url folder name: + const path = this._routerPath + '/tab/' + encodeURI(tab.name || ''); + return html` + ${path === this._activePath + ? html` + + this.#remove(tab.id)} + compact> + + + ` + : tab.name} + `; + } + )} + + + Add tab + + `; + } + + renderActions() { + return html`
+ + + Compositions + + + + Recorder + +
`; + } + + render() { + return html` +
${this._routerPath ? this.renderTabsNavigation() : ''}${this.renderActions()}
+ + { + this._routerPath = event.target.absoluteRouterPath; + }} + @change=${(event: UmbRouterSlotChangeEvent) => { + this._activePath = event.target.absoluteActiveViewPath || ''; + }}> + + `; + } +} + +export default UmbDocumentTypeWorkspaceViewEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-view-edit': UmbDocumentTypeWorkspaceViewEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/workspace-view-document-type-design.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/workspace-view-document-type-design.element.ts deleted file mode 100644 index 3e48456f2d..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/design/workspace-view-document-type-design.element.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { css, html } from 'lit'; -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbWorkspaceDocumentTypeContext } from '../../document-type-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DocumentTypeModel } from '@umbraco-cms/backend-api'; -import '../../../../../shared/property-creator/property-creator.element.ts'; - -@customElement('umb-workspace-view-document-type-design') -export class UmbWorkspaceViewDocumentTypeDesignElement extends UmbLitElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - margin: var(--uui-size-space-6); - padding: var(--uui-size-space-6); - } - `, - ]; - - @state() - _documentType?: DocumentTypeModel; - - private _workspaceContext?: UmbWorkspaceDocumentTypeContext; - - constructor() { - super(); - - // TODO: Figure out if this is the best way to consume the context or if it can be strongly typed with an UmbContextToken - this.consumeContext('umbWorkspaceContext', (documentTypeContext) => { - this._workspaceContext = documentTypeContext; - this._observeDocumentType(); - }); - } - - private _observeDocumentType() { - if (!this._workspaceContext) return; - - this.observe(this._workspaceContext.data, (documentType) => { - this._documentType = documentType; - }); - } - - render() { - return html` Design of ${this._documentType?.name} - -
- -
-
`; - } -} - -export default UmbWorkspaceViewDocumentTypeDesignElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-workspace-view-document-type-design': UmbWorkspaceViewDocumentTypeDesignElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/details/document-type-workspace-view-details.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/details/document-type-workspace-view-details.element.ts new file mode 100644 index 0000000000..803fcf76a0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/details/document-type-workspace-view-details.element.ts @@ -0,0 +1,88 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-document-type-workspace-view-details') +export class UmbDocumentTypeWorkspaceViewDetailsElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + uui-box { + margin: var(--uui-size-layout-1); + } + + uui-label, + umb-property-editor-ui-number { + display: block; + } + + // TODO: is this necessary? + uui-toggle { + display: flex; + } + `, + ]; + + private _workspaceContext?: UmbDocumentTypeWorkspaceContext; + + constructor() { + super(); + + // TODO: Figure out if this is the best way to consume the context or if it can be strongly typed with an UmbContextToken + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (documentTypeContext) => { + this._workspaceContext = documentTypeContext as UmbDocumentTypeWorkspaceContext; + this._observeDocumentType(); + }); + } + + private _observeDocumentType() { + if (!this._workspaceContext) return; + } + + render() { + return html` + + +
Allow editors to create content of different languages.
+
+
+ +
Allow editors to segment their content.
+
+
+ +
+ An Element Type is used for content instances in Property Editors, like the Block Editors. +
+
+
+
+ + +
+ Allow overriding the global history cleanup settings. (TODO: this ui is not working.. ) +
+
+ + Keep all versions newer than X days + + Keep latest version per day for X days + +
+
+
+ `; + } +} + +export default UmbDocumentTypeWorkspaceViewDetailsElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-view-details': UmbDocumentTypeWorkspaceViewDetailsElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/structure/document-type-workspace-view-structure.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/structure/document-type-workspace-view-structure.element.ts new file mode 100644 index 0000000000..94ee23568c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/structure/document-type-workspace-view-structure.element.ts @@ -0,0 +1,82 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-document-type-workspace-view-structure') +export class UmbDocumentTypeWorkspaceViewStructureElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + uui-box { + margin: var(--uui-size-layout-1); + } + + uui-label, + umb-property-editor-ui-number { + display: block; + } + + // TODO: is this necessary? + uui-toggle { + display: flex; + } + `, + ]; + + private _workspaceContext?: UmbDocumentTypeWorkspaceContext; + + constructor() { + super(); + + // TODO: Figure out if this is the best way to consume the context or if it can be strongly typed with an UmbContextToken + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (documentTypeContext) => { + this._workspaceContext = documentTypeContext as UmbDocumentTypeWorkspaceContext; + this._observeDocumentType(); + }); + } + + private _observeDocumentType() { + if (!this._workspaceContext) return; + } + + render() { + return html` + + +
Allow editors to create content of this type in the root of the content tree.
+
+
+ +
+ Allow content of the specified types to be created underneath content of this type. +
+
+ + +
+
+
+ + +
+ Use this document as a collection, displaying its children in a Collection View. This could be a list or a + table. +
+
+
+
+ `; + } +} + +export default UmbDocumentTypeWorkspaceViewStructureElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-view-structure': UmbDocumentTypeWorkspaceViewStructureElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/templates/document-type-workspace-view-templates.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/templates/document-type-workspace-view-templates.element.ts new file mode 100644 index 0000000000..8563844b9f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/document-types/workspace/views/templates/document-type-workspace-view-templates.element.ts @@ -0,0 +1,84 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement } from 'lit/decorators.js'; +import { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-document-type-workspace-view-templates') +export class UmbDocumentTypeWorkspaceViewTemplatesElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + + #templates { + text-align: center; + } + + #template-card-wrapper { + display: flex; + gap: var(--uui-size-space-4); + align-items: stretch; + } + + umb-workspace-property-layout { + border-top: 1px solid var(--uui-color-border); + } + umb-workspace-property-layout:first-child { + padding-top: 0; + border: none; + } + `, + ]; + + private _workspaceContext?: UmbDocumentTypeWorkspaceContext; + + constructor() { + super(); + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (documentTypeContext) => { + this._workspaceContext = documentTypeContext as UmbDocumentTypeWorkspaceContext; + this._observeDocumentType(); + }); + } + + private _observeDocumentType() { + if (!this._workspaceContext) return; + } + + async #changeDefaultId(e: CustomEvent) { + // save new default id + console.log('workspace: default template id', e); + } + + #changeAllowedKeys(e: CustomEvent) { + // save new allowed ids + console.log('workspace: allowed templates changed', e); + } + + render() { + return html` + +
Choose which templates editors are allowed to use on content of this type
+
+ +
+
+
`; + } +} + +export default UmbDocumentTypeWorkspaceViewTemplatesElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-workspace-view-templates': UmbDocumentTypeWorkspaceViewTemplatesElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts index 0942914f4a..85d3376119 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/manifests.ts @@ -1,4 +1,4 @@ -import { ManifestCollectionView } from '@umbraco-cms/extensions-registry'; +import { ManifestCollectionView } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests: Array = [ { @@ -7,10 +7,12 @@ export const manifests: Array = [ name: 'Document Table Collection View', loader: () => import('./views/table/document-table-collection-view.element'), weight: 200, + conditions: { + entityType: 'document', + }, meta: { label: 'Table', icon: 'umb:box', - entityType: 'document', pathName: 'table', }, }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts index cd8b0fcd0a..a20182afe1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/column-layouts/document-table-actions-column-layout.element.ts @@ -1,8 +1,8 @@ import { css, html, LitElement, nothing } from 'lit'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { customElement, property, state } from 'lit/decorators.js'; import type { UmbTableColumn, UmbTableItem } from '../../../../../../shared/components/table'; -import { UmbExecutedEvent } from '@umbraco-cms/events'; +import { UmbExecutedEvent } from '@umbraco-cms/backoffice/events'; // TODO: this could be done more generic, but for now we just need it for the document table @customElement('umb-document-table-actions-column-layout') @@ -70,7 +70,7 @@ export class UmbDocumentTableActionColumnLayoutElement extends LitElement { + unique=${ifDefined(this.item.id)}>
`; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/document-table-collection-view.element.ts index e669b51c40..ec3eef7b88 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -14,12 +14,12 @@ import { UmbTableOrderedEvent, UmbTableSelectedEvent, } from '../../../../../shared/components/table'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DocumentTreeItemModel, EntityTreeItemModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DocumentTreeItemResponseModel, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; import './column-layouts/document-table-actions-column-layout.element'; -type EntityType = DocumentTreeItemModel; +type EntityType = DocumentTreeItemResponseModel; @customElement('umb-document-table-collection-view') export class UmbDocumentTableCollectionViewElement extends UmbLitElement { @@ -42,7 +42,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { ]; @state() - private _items?: Array; + private _items?: Array; @state() private _tableConfig: UmbTableConfig = { @@ -94,12 +94,12 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { }); } - private _createTableItems(items: Array) { + private _createTableItems(items: Array) { this._tableItems = items.map((item) => { - // TODO: use unique instead of key - if (!item.key) throw new Error('Item key is missing.'); + // TODO: use unique instead of id + if (!item.id) throw new Error('Item id is missing.'); return { - key: item.key, + id: item.id, icon: item.icon, data: [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create-blueprint.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create-blueprint.action.ts index a0780eb967..d0d1ebd48c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create-blueprint.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create-blueprint.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../repository/document.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbCreateDocumentBlueprintEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create/create-document-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create/create-document-modal.element.ts deleted file mode 100644 index e438a3e3e4..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create/create-document-modal.element.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { html } from 'lit'; -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement } from 'lit/decorators.js'; -import { UmbCreateDocumentModalData, UmbCreateDocumentModalResultData } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; - -@customElement('umb-create-document-modal') -export class UmbCreateDocumentModalElement extends UmbModalBaseElement< - UmbCreateDocumentModalData, - UmbCreateDocumentModalResultData -> { - static styles = [UUITextStyles]; - - private _handleCancel() { - this.modalHandler?.reject(); - } - - #onClick(event: PointerEvent) { - event.stopPropagation(); - const target = event.target as HTMLButtonElement; - const documentType = target.value; - this.modalHandler?.submit({ documentType }); - } - - render() { - return html` - -
Render list of create options for ${this.data?.unique}
- -
    -
  • -
  • -
  • -
- - Cancel -
- `; - } -} - -export default UmbCreateDocumentModalElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-create-document-modal': UmbCreateDocumentModalElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create/create.action.ts index fcdcc7be3c..62a8480101 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/create/create.action.ts @@ -1,18 +1,17 @@ -import { UmbDocumentRepository } from '../../repository/document.repository'; -import type { UmbCreateDocumentModalResultData } from '.'; -import { UMB_CREATE_DOCUMENT_MODAL_TOKEN } from '.'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; - -// TODO: temp import -import './create-document-modal.element.ts'; +import type { UmbDocumentRepository } from '../../repository/document.repository'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_ALLOWED_DOCUMENT_TYPES_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; export class UmbCreateDocumentEntityAction extends UmbEntityActionBase { #modalContext?: UmbModalContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -23,13 +22,18 @@ export class UmbCreateDocumentEntityAction extends UmbEntityActionBase('Umb.Modal.CreateDocument', { - type: 'sidebar', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/culture-and-hostnames.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/culture-and-hostnames.action.ts index 1ba8de7356..d5f6d582bc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/culture-and-hostnames.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/culture-and-hostnames.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../repository/document.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDocumentCultureAndHostnamesEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/manifests.ts index 3ae95fe8ee..ab2d9ac5b8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/manifests.ts @@ -12,8 +12,8 @@ import { UmbMoveEntityAction, UmbTrashEntityAction, UmbSortChildrenOfEntityAction, -} from '@umbraco-cms/entity-action'; -import { ManifestEntityAction, ManifestModal } from '@umbraco-cms/extensions-registry'; +} from '@umbraco-cms/backoffice/entity-action'; +import { ManifestEntityAction, ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const entityType = 'document'; @@ -24,12 +24,14 @@ const entityActions: Array = [ name: 'Create Document Entity Action', weight: 1000, meta: { - entityType, icon: 'umb:add', label: 'Create', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbCreateDocumentEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -37,12 +39,14 @@ const entityActions: Array = [ name: 'Trash Document Entity Action', weight: 900, meta: { - entityType, icon: 'umb:trash', label: 'Trash', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbTrashEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -50,12 +54,14 @@ const entityActions: Array = [ name: 'Create Document Blueprint Entity Action', weight: 800, meta: { - entityType, icon: 'umb:blueprint', label: 'Create Content Template', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbCreateDocumentBlueprintEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -63,12 +69,14 @@ const entityActions: Array = [ name: 'Move Document Entity Action', weight: 700, meta: { - entityType, icon: 'umb:enter', label: 'Move', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbMoveEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -76,12 +84,14 @@ const entityActions: Array = [ name: 'Copy Document Entity Action', weight: 600, meta: { - entityType, icon: 'umb:documents', label: 'Copy', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbCopyEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -89,12 +99,14 @@ const entityActions: Array = [ name: 'Sort Document Entity Action', weight: 500, meta: { - entityType, icon: 'umb:navigation-vertical', label: 'Sort', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbSortChildrenOfEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -102,72 +114,84 @@ const entityActions: Array = [ name: 'Culture And Hostnames Document Entity Action', weight: 400, meta: { - entityType, icon: 'umb:home', label: 'Culture And Hostnames', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbDocumentCultureAndHostnamesEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', alias: 'Umb.EntityAction.Document.Permissions', name: 'Document Permissions Entity Action', meta: { - entityType, icon: 'umb:vcard', label: 'Permissions', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbDocumentPermissionsEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', alias: 'Umb.EntityAction.Document.PublicAccess', name: 'Document Permissions Entity Action', meta: { - entityType, icon: 'umb:lock', label: 'Public Access', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbDocumentPublicAccessEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', alias: 'Umb.EntityAction.Document.Publish', name: 'Publish Document Entity Action', meta: { - entityType, icon: 'umb:globe', label: 'Publish', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbPublishDocumentEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', alias: 'Umb.EntityAction.Document.Unpublish', name: 'Unpublish Document Entity Action', meta: { - entityType, icon: 'umb:globe', label: 'Unpublish', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbUnpublishDocumentEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', alias: 'Umb.EntityAction.Document.Rollback', name: 'Rollback Document Entity Action', meta: { - entityType, icon: 'umb:undo', label: 'Rollback', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbRollbackDocumentEntityAction, }, + conditions: { + entityType, + }, }, ]; @@ -176,7 +200,7 @@ const modals: Array = [ type: 'modal', alias: 'Umb.Modal.CreateDocument', name: 'Create Document Modal', - loader: () => import('./create/create-document-modal.element'), + loader: () => import('../../document-types/modals/allowed-document-types/allowed-document-types-modal.element'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/permissions.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/permissions.action.ts index a116358cce..48493532b9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/permissions.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/permissions.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../repository/document.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDocumentPermissionsEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/public-access.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/public-access.action.ts index aff79a03b2..ca8863faff 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/public-access.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/public-access.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../repository/document.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDocumentPublicAccessEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/publish.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/publish.action.ts index 47d49c6517..dcb17adc6b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/publish.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/publish.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../repository/document.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbPublishDocumentEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/rollback.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/rollback.action.ts index 8e473ecbfb..86200e5ed4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/rollback.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/rollback.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../repository/document.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbRollbackDocumentEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/unpublish.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/unpublish.action.ts index 3820cae4d9..69c27352f4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/unpublish.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-actions/unpublish.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../repository/document.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/copy/copy.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/copy/copy.action.ts index daf1482bed..521845aceb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/copy/copy.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/copy/copy.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../../repository/document.repository'; -import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDocumentCopyEntityBulkAction extends UmbEntityBulkActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/manifests.ts index 7edd0952e3..3f3e873d4b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/manifests.ts @@ -1,7 +1,7 @@ import { DOCUMENT_REPOSITORY_ALIAS } from '../repository/manifests'; import { UmbDocumentMoveEntityBulkAction } from './move/move.action'; import { UmbDocumentCopyEntityBulkAction } from './copy/copy.action'; -import { ManifestEntityBulkAction } from '@umbraco-cms/extensions-registry'; +import { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extensions-registry'; const entityType = 'document'; @@ -12,11 +12,13 @@ const entityActions: Array = [ name: 'Move Document Entity Bulk Action', weight: 10, meta: { - entityType, label: 'Move', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbDocumentMoveEntityBulkAction, }, + conditions: { + entityType, + }, }, { type: 'entityBulkAction', @@ -24,11 +26,13 @@ const entityActions: Array = [ name: 'Copy Document Entity Bulk Action', weight: 9, meta: { - entityType, label: 'Copy', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, api: UmbDocumentCopyEntityBulkAction, }, + conditions: { + entityType, + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/move/move.action.ts index ebe5bb2a8a..436994c193 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/move/move.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/entity-bulk-actions/move/move.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentRepository } from '../../repository/document.repository'; -import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDocumentMoveEntityBulkAction extends UmbEntityBulkActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/manifests.ts index db1abd9914..61718098ac 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/manifests.ts @@ -1,5 +1,5 @@ import { manifests as collectionManifests } from './collection/manifests'; -import { manifests as menuItemManifests } from './sidebar-menu-item/manifests'; +import { manifests as menuItemManifests } from './menu-item/manifests'; import { manifests as repositoryManifests } from './repository/manifests'; import { manifests as treeManifests } from './tree/manifests'; import { manifests as workspaceManifests } from './workspace/manifests'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/menu-item/document-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/menu-item/document-menu-item.element.ts new file mode 100644 index 0000000000..07d94f6a1f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/menu-item/document-menu-item.element.ts @@ -0,0 +1,18 @@ +import { html } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-document-menu-item') +export class UmbDocumentMenuItemElement extends UmbLitElement { + render() { + return html``; + } +} + +export default UmbDocumentMenuItemElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-menu-item': UmbDocumentMenuItemElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/sidebar-menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/menu-item/manifests.ts similarity index 62% rename from src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/sidebar-menu-item/manifests.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/menu-item/manifests.ts index e4bfc4a260..5c448b6d0b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/sidebar-menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/menu-item/manifests.ts @@ -1,14 +1,16 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; const menuItem: ManifestMenuItem = { type: 'menuItem', alias: 'Umb.MenuItem.Documents', name: 'Documents Menu Item', weight: 100, - loader: () => import('./document-sidebar-menu-item.element'), + loader: () => import('./document-menu-item.element'), meta: { label: 'Documents', icon: 'umb:folder', + }, + conditions: { menus: ['Umb.Menu.Content'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.element.ts index 811c812a64..88429ab1a7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.element.ts @@ -2,8 +2,8 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import type { UmbTreeElement } from '../../../../shared/components/tree/tree.element'; -import { UmbDocumentPickerModalData, UmbDocumentPickerModalResult } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { UmbDocumentPickerModalData, UmbDocumentPickerModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; // TODO: make use of UmbPickerLayoutBase @customElement('umb-document-picker-modal') diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.stories.ts index 8c61ae22cf..ec43ba460e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/document-picker-modal.stories.ts @@ -5,7 +5,7 @@ import { Meta, Story } from '@storybook/web-components'; import { html } from 'lit'; import type { UmbDocumentPickerModalElement } from './document-picker-modal.element'; -import type { UmbDocumentPickerModalData } from './index'; +import type { UmbDocumentPickerModalData } from '@umbraco-cms/backoffice/modal'; export default { title: 'API/Modals/Layouts/Content Picker', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/index.ts deleted file mode 100644 index b67bffe04e..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-picker/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; - -export interface UmbDocumentPickerModalData { - multiple?: boolean; - selection?: Array; -} - -export interface UmbDocumentPickerModalResult { - selection: Array; -} - -export const UMB_DOCUMENT_PICKER_MODAL_TOKEN = new UmbModalToken< - UmbDocumentPickerModalData, - UmbDocumentPickerModalResult ->('Umb.Modal.DocumentPicker', { - type: 'sidebar', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-type-picker/document-type-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-type-picker/document-type-picker-modal.element.ts new file mode 100644 index 0000000000..c7e6d223a5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-type-picker/document-type-picker-modal.element.ts @@ -0,0 +1,103 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import type { UmbTreeElement } from '../../../../shared/components/tree/tree.element'; +import { UmbDocumentTypePickerModalData, UmbDocumentTypePickerModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; + +// TODO: make use of UmbPickerLayoutBase +@customElement('umb-document-type-picker-modal') +export class UmbDocumentTypePickerModalElement extends UmbModalBaseElement< + UmbDocumentTypePickerModalData, + UmbDocumentTypePickerModalResult +> { + static styles = [ + UUITextStyles, + css` + h3 { + margin-left: var(--uui-size-space-5); + margin-right: var(--uui-size-space-5); + } + + uui-input { + width: 100%; + } + + hr { + border: none; + border-bottom: 1px solid var(--uui-color-divider); + margin: 16px 0; + } + + #content-list { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-3); + } + + .content-item { + cursor: pointer; + } + + .content-item.selected { + background-color: var(--uui-color-selected); + color: var(--uui-color-selected-contrast); + } + `, + ]; + + @state() + _selection: Array = []; + + @state() + _multiple = true; + + connectedCallback() { + super.connectedCallback(); + this._selection = this.data?.selection ?? []; + this._multiple = this.data?.multiple ?? true; + } + + private _handleSelectionChange(e: CustomEvent) { + e.stopPropagation(); + const element = e.target as UmbTreeElement; + //TODO: Should multiple property be implemented here or be passed down into umb-tree? + this._selection = this._multiple ? element.selection : [element.selection[element.selection.length - 1]]; + } + + private _submit() { + this.modalHandler?.submit({ selection: this._selection }); + } + + private _close() { + this.modalHandler?.reject(); + } + + render() { + return html` + + + +
+ +
+
+ + +
+
+ `; + } +} + +export default UmbDocumentTypePickerModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-type-picker-modal': UmbDocumentTypePickerModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-type-picker/document-type-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-type-picker/document-type-picker-modal.stories.ts new file mode 100644 index 0000000000..367cc06ff3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/document-type-picker/document-type-picker-modal.stories.ts @@ -0,0 +1,26 @@ +import '../../../../shared/components/body-layout/body-layout.element'; +import './document-type-picker-modal.element'; + +import { Meta, Story } from '@storybook/web-components'; +import { html } from 'lit'; + +import type { UmbDocumentTypePickerModalElement } from './document-type-picker-modal.element'; +import type { UmbDocumentTypePickerModalData } from '@umbraco-cms/backoffice/modal'; + +export default { + title: 'API/Modals/Layouts/Content Picker', + component: 'umb-document-type-picker-modal', + id: 'umb-document-type-picker-modal', +} as Meta; + +const data: UmbDocumentTypePickerModalData = { + multiple: true, + selection: [], +}; + +export const Overview: Story = () => html` + + +`; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/manifests.ts index dcaf83f082..5e9595e6a0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { @@ -7,6 +7,12 @@ const modals: Array = [ name: 'Document Picker Modal', loader: () => import('./document-picker/document-picker-modal.element'), }, + { + type: 'modal', + alias: 'Umb.Modal.DocumentTypePicker', + name: 'Document Type Picker Modal', + loader: () => import('./document-type-picker/document-type-picker-modal.element'), + }, ]; export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts index 104b9092df..91d485f05c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.repository.ts @@ -1,27 +1,26 @@ -import type { RepositoryTreeDataSource } from '../../../../../libs/repository/repository-tree-data-source.interface'; -import { DocumentTreeServerDataSource } from './sources/document.tree.server.data'; -import { UmbDocumentTreeStore, UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from './document.tree.store'; -import { UmbDocumentStore, UMB_DOCUMENT_STORE_CONTEXT_TOKEN } from './document.store'; import { UmbDocumentServerDataSource } from './sources/document.server.data'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { ProblemDetailsModel, DocumentModel } from '@umbraco-cms/backend-api'; -import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface'; -import { UmbDetailRepository } from '@umbraco-cms/repository'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; +import { UmbDocumentStore, UMB_DOCUMENT_STORE_CONTEXT_TOKEN } from './document.store'; +import { UmbDocumentTreeStore, UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from './document.tree.store'; +import { DocumentTreeServerDataSource } from './sources/document.tree.server.data'; +import type { UmbTreeDataSource, UmbTreeRepository, UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { + ProblemDetailsModel, + DocumentResponseModel, + CreateDocumentRequestModel, + UpdateDocumentRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; -type ItemType = DocumentModel; +type ItemType = DocumentResponseModel; -// Move to documentation / JSdoc -/* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */ -// element -> context -> repository -> (store) -> data source -// All methods should be async and return a promise. Some methods might return an observable as part of the promise response. -export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailRepository { +export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailRepository { #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - #treeSource: RepositoryTreeDataSource; + #treeSource: UmbTreeDataSource; #treeStore?: UmbDocumentTreeStore; #detailDataSource: UmbDocumentServerDataSource; @@ -29,7 +28,7 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source @@ -66,34 +65,34 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getItems(keys); + const { data, error } = await this.#treeSource.getItems(ids); - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -101,38 +100,34 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS: - async createScaffold(parentKey: string | null) { + async createScaffold(documentTypeKey: string) { + if (!documentTypeKey) throw new Error('Document type id is missing'); await this.#init; - - if (!parentKey) { - throw new Error('Parent key is missing'); - } - - return this.#detailDataSource.createScaffold(parentKey); + return this.#detailDataSource.createScaffold(documentTypeKey); } - async requestByKey(key: string) { + async requestById(id: string) { await this.#init; - // TODO: should we show a notification if the key is missing? + // TODO: should we show a notification if the id is missing? // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - const { data, error } = await this.#detailDataSource.get(key); + const { data, error } = await this.#detailDataSource.get(id); if (data) { this.#store?.append(data); @@ -142,11 +137,10 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi } // Could potentially be general methods: - - async create(item: ItemType) { + async create(item: CreateDocumentRequestModel & { id: string }) { await this.#init; - if (!item || !item.key) { + if (!item || !item.id) { throw new Error('Document is missing'); } @@ -165,61 +159,57 @@ export class UmbDocumentRepository implements UmbTreeRepository, UmbDetailReposi return { error }; } - async save(item: ItemType) { + async save(id: string, item: UpdateDocumentRequestModel) { + if (!id) throw new Error('Id is missing'); + if (!item) throw new Error('Item is missing'); + await this.#init; - if (!item || !item.key) { - throw new Error('Document is missing'); - } - - const { error } = await this.#detailDataSource.update(item); + const { error } = await this.#detailDataSource.update(id, item); if (!error) { + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a document is updated in the store while someone is editing it. + this.#store?.append(item); + //this.#treeStore?.updateItem(item.id, { name: item.name });// Port data to tree store. + // TODO: would be nice to align the stores on methods/methodNames. + const notification = { data: { message: `Document saved` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - // Consider notify a workspace if a document is updated in the store while someone is editing it. - this.#store?.append(item); - //this.#treeStore?.updateItem(item.key, { name: item.name });// Port data to tree store. - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } // General: - async delete(key: string) { + async delete(id: string) { + if (!id) throw new Error('Id is missing'); await this.#init; - if (!key) { - throw new Error('Document key is missing'); - } - - const { error } = await this.#detailDataSource.delete(key); + const { error } = await this.#detailDataSource.delete(id); if (!error) { + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server. + // Consider notify a workspace if a document is deleted from the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + this.#store?.remove([id]); + this.#treeStore?.removeItem(id); + const notification = { data: { message: `Document deleted` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server. - // Consider notify a workspace if a document is deleted from the store while someone is editing it. - this.#store?.remove([key]); - this.#treeStore?.removeItem(key); - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } // Listing all currently known methods we need to implement: // these currently only covers posting data // TODO: find a good way to split these - async trash(keys: Array) { - console.log('document trash: ' + keys); + async trash(ids: Array) { + console.log('document trash: ' + ids); alert('implement trash'); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts index 0dfd392794..d53818f95e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.store.ts @@ -1,8 +1,8 @@ -import { DocumentModel } from '@umbraco-cms/backend-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export @@ -11,14 +11,14 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller'; * @description - Data Store for Template Details */ export class UmbDocumentStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); /** * Creates an instance of UmbDocumentDetailStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDocumentDetailStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DOCUMENT_STORE_CONTEXT_TOKEN.toString()); } @@ -27,7 +27,7 @@ export class UmbDocumentStore extends UmbStoreBase { * @param {DocumentDetails} document * @memberof UmbDocumentDetailStore */ - append(document: DocumentModel) { + append(document: DocumentResponseModel) { this.#data.append([document]); } @@ -36,8 +36,8 @@ export class UmbDocumentStore extends UmbStoreBase { * @param {DocumentModel} document * @memberof UmbDocumentStore */ - byKey(key: DocumentModel['key']) { - return this.#data.getObservablePart((x) => x.find((y) => y.key === key)); + byKey(id: DocumentResponseModel['id']) { + return this.#data.getObservablePart((x) => x.find((y) => y.id === id)); } /** @@ -45,7 +45,7 @@ export class UmbDocumentStore extends UmbStoreBase { * @param {string[]} uniques * @memberof UmbDocumentDetailStore */ - remove(uniques: Array) { + remove(uniques: Array) { this.#data.remove(uniques); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts index 71a563ed34..a53d41e17a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/document.tree.store.ts @@ -1,24 +1,22 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export * @class UmbDocumentTreeStore - * @extends {UmbTreeStoreBase} + * @extends {UmbEntityTreeStore} * @description - Tree Data Store for Templates */ -export class UmbDocumentTreeStore extends UmbTreeStoreBase { +export class UmbDocumentTreeStore extends UmbEntityTreeStore { /** * Creates an instance of UmbDocumentTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDocumentTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN.toString()); } } -export const UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken( - 'UmbDocumentTreeStore' -); +export const UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbDocumentTreeStore'); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/manifests.ts index da7a9197b2..b53c170e43 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbDocumentRepository } from '../repository/document.repository'; import { UmbDocumentStore } from './document.store'; import { UmbDocumentTreeStore } from './document.tree.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestRepository, ManifestStore, ManifestTreeStore } from '@umbraco-cms/backoffice/extensions-registry'; export const DOCUMENT_REPOSITORY_ALIAS = 'Umb.Repository.Document'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/document.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/document.server.data.ts index 5fe01e86d2..ae6a501479 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/document.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/document.server.data.ts @@ -1,7 +1,15 @@ -import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; -import { DocumentResource, ProblemDetailsModel, DocumentModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { v4 as uuidv4 } from 'uuid'; +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; +import { + DocumentResource, + ProblemDetailsModel, + DocumentResponseModel, + ContentStateModel, + CreateDocumentRequestModel, + UpdateDocumentRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Document that fetches data from the server @@ -9,48 +17,65 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class UmbDocumentServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbDocumentServerDataSource implements RepositoryDetailDataSource { - #host: UmbControllerHostInterface; +export class UmbDocumentServerDataSource + implements UmbDataSource +{ + #host: UmbControllerHostElement; /** * Creates an instance of UmbDocumentServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDocumentServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** - * Fetches a Document with the given key from the server - * @param {string} key + * Fetches a Document with the given id from the server + * @param {string} id * @return {*} * @memberof UmbDocumentServerDataSource */ - async get(key: string) { - if (!key) { + async get(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - DocumentResource.getDocumentByKey({ - key, + DocumentResource.getDocumentById({ + id, }) ); } /** * Creates a new Document scaffold - * @param {(string | null)} parentKey + * @param {(string | null)} parentId * @return {*} * @memberof UmbDocumentServerDataSource */ - async createScaffold(parentKey: string | null) { - const data: DocumentModel = { + async createScaffold(documentTypeId: string) { + const data: DocumentResponseModel = { + urls: [], + templateId: null, + id: uuidv4(), + contentTypeId: documentTypeId, values: [], - variants: [], + variants: [ + { + $type: '', + state: ContentStateModel.DRAFT, + publishDate: null, + culture: null, + segment: null, + name: '', + createDate: new Date().toISOString(), + updateDate: undefined, + }, + ], }; return { data }; @@ -62,12 +87,8 @@ export class UmbDocumentServerDataSource implements RepositoryDetailDataSource( + return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document/save', { method: 'POST', @@ -97,13 +118,12 @@ export class UmbDocumentServerDataSource implements RepositoryDetailDataSource( + return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document/save', { method: 'POST', @@ -133,18 +153,18 @@ export class UmbDocumentServerDataSource implements RepositoryDetailDataSource( + return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document/trash', { method: 'POST', - body: JSON.stringify([key]), + body: JSON.stringify([id]), headers: { 'Content-Type': 'application/json', }, @@ -154,12 +174,12 @@ export class UmbDocumentServerDataSource implements RepositoryDetailDataSource) { + async trashItems(ids: Array) { // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document/trash', { method: 'POST', - body: JSON.stringify(keys), + body: JSON.stringify(ids), headers: { 'Content-Type': 'application/json', }, @@ -27,13 +27,13 @@ export class DocumentTreeServerDataSource implements RepositoryTreeDataSource { ); } - async moveItems(keys: Array, destination: string) { + async moveItems(ids: Array, destination: string) { // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/document/move', { method: 'POST', - body: JSON.stringify({ keys, destination }), + body: JSON.stringify({ ids, destination }), headers: { 'Content-Type': 'application/json', }, @@ -43,10 +43,10 @@ export class DocumentTreeServerDataSource implements RepositoryTreeDataSource { /** * Creates an instance of DocumentTreeServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof DocumentTreeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -60,41 +60,41 @@ export class DocumentTreeServerDataSource implements RepositoryTreeDataSource { } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} * @memberof DocumentTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + async getChildrenOf(parentId: string | null) { + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, DocumentResource.getTreeDocumentChildren({ - parentKey, + parentId, }) ); } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} * @memberof DocumentTreeServerDataSource */ - async getItems(keys: Array) { - if (!keys) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; + async getItems(ids: Array) { + if (!ids) { + const error: ProblemDetailsModel = { title: 'Ids are missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - DocumentResource.getTreeDocumentItem({ - key: keys, + DocumentResource.getDocumentItem({ + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/index.ts index c7cc44fc92..8cbe1ec6d5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/repository/sources/index.ts @@ -1,7 +1,7 @@ -import { DocumentModel } from '@umbraco-cms/backend-api'; -import type { DataSourceResponse } from '@umbraco-cms/models'; -import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; +import type { DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbDataSource, DataSourceResponse } from '@umbraco-cms/backoffice/repository'; -export interface UmbDocumentDataSource extends RepositoryDetailDataSource { - trash(key: string): Promise>; +export interface UmbDocumentDataSource extends UmbDataSource { + createScaffold(documentTypeKey: string): Promise>; + trash(id: string): Promise>; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/sidebar-menu-item/document-sidebar-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/sidebar-menu-item/document-sidebar-menu-item.element.ts deleted file mode 100644 index d0e12bfbd7..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/sidebar-menu-item/document-sidebar-menu-item.element.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { html } from 'lit'; -import { customElement } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-document-sidebar-menu-item') -export class UmbDocumentSidebarMenuItemElement extends UmbLitElement { - render() { - return html``; - } -} - -export default UmbDocumentSidebarMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-document-sidebar-menu-item': UmbDocumentSidebarMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/manifests.ts index 1abb5fd1f5..a5dbe90321 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/manifests.ts @@ -1,5 +1,5 @@ -import { UmbDocumentRepository } from '../repository/document.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { DOCUMENT_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const treeAlias = 'Umb.Tree.Documents'; @@ -8,8 +8,18 @@ const tree: ManifestTree = { alias: treeAlias, name: 'Documents Tree', meta: { - repository: UmbDocumentRepository, // TODO: use alias instead of class + repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + alias: 'Umb.TreeItem.Document', + name: 'Document Tree Item', + loader: () => import('./tree-item/document-tree-item.element'), + conditions: { + entityType: 'document', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/tree-item/document-tree-item.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/tree-item/document-tree-item.context.ts new file mode 100644 index 0000000000..4fcde2bd4f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/tree-item/document-tree-item.context.ts @@ -0,0 +1,10 @@ +import { UmbTreeItemContextBase } from '../../../../shared/components/tree/tree-item-base/tree-item-base.context'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { DocumentTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +// TODO get unique method from an document repository static method +export class UmbDocumentTreeItemContext extends UmbTreeItemContextBase { + constructor(host: UmbControllerHostElement) { + super(host, (x: DocumentTreeItemResponseModel) => x.id); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/tree-item/document-tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/tree-item/document-tree-item.element.ts new file mode 100644 index 0000000000..e71f162a4b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/tree/tree-item/document-tree-item.element.ts @@ -0,0 +1,78 @@ +import { css, html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { UmbDocumentTreeItemContext } from './document-tree-item.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DocumentTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-document-tree-item') +export class UmbDocumentTreeItemElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + #icon-container { + position: relative; + } + + #icon { + vertical-align: middle; + } + + #status-symbol { + width: 8px; + height: 8px; + background-color: blue; + display: block; + position: absolute; + bottom: 0; + right: 0; + border-radius: 100%; + } + `, + ]; + + private _item?: DocumentTreeItemResponseModel; + @property({ type: Object, attribute: false }) + public get item() { + return this._item; + } + public set item(value: DocumentTreeItemResponseModel | undefined) { + this._item = value; + this.#context.setTreeItem(value); + } + + #context = new UmbDocumentTreeItemContext(this); + + render() { + if (!this.item) return nothing; + return html` + ${this.#renderIconWithStatusSymbol()} ${this.#renderLabel()} + `; + } + + // TODO: implement correct status symbol + #renderIconWithStatusSymbol() { + return html` + + ${this.item?.icon + ? html` + + ` + : nothing} + + `; + } + + // TODO: lower opacity if item is not published + #renderLabel() { + return html` ${this.item?.name} `; + } +} + +export default UmbDocumentTreeItemElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-tree-item': UmbDocumentTreeItemElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-preview.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-preview.action.ts index 10470f8d25..8879e08aa5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-preview.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-preview.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; -import { UmbWorkspaceActionBase } from '@umbraco-cms/workspace'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbWorkspaceActionBase } from '@umbraco-cms/backoffice/workspace'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDocumentSaveAndPreviewWorkspaceAction extends UmbWorkspaceActionBase { - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-publish.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-publish.action.ts index ef49816688..2ca1793f3c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-publish.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-publish.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; -import { UmbWorkspaceActionBase } from '@umbraco-cms/workspace'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbWorkspaceActionBase } from '@umbraco-cms/backoffice/workspace'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDocumentSaveAndPublishWorkspaceAction extends UmbWorkspaceActionBase { - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-schedule.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-schedule.action.ts index aa630bbc6e..8097100a33 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-schedule.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/actions/save-and-schedule.action.ts @@ -1,9 +1,9 @@ import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; -import { UmbWorkspaceActionBase } from '@umbraco-cms/workspace'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbWorkspaceActionBase } from '@umbraco-cms/backoffice/workspace'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbSaveAndScheduleDocumentWorkspaceAction extends UmbWorkspaceActionBase { - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace-editor.element.ts new file mode 100644 index 0000000000..dd2f4c5fdf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace-editor.element.ts @@ -0,0 +1,143 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbVariantId } from '../../../shared/variants/variant-id.class'; +import { ActiveVariant } from '../../../shared/components/workspace/workspace-context/workspace-split-view-manager.class'; +import { UmbDocumentWorkspaceContext } from './document-workspace.context'; +import { UmbDocumentWorkspaceSplitViewElement } from './document-workspace-split-view.element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import type { UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import '../../../shared/components/workspace/workspace-variant/workspace-variant.element'; +import { VariantModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-document-workspace-editor') +export class UmbDocumentWorkspaceEditorElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + `, + ]; + + //private _defaultVariant?: VariantViewModelBaseModel; + private splitViewElement = new UmbDocumentWorkspaceSplitViewElement(); + + @state() + _unique?: string; + + @state() + _routes?: Array; + + @state() + _availableVariants: Array = []; + + @state() + _workspaceSplitViews: Array = []; + + #workspaceContext?: UmbDocumentWorkspaceContext; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbDocumentWorkspaceContext; + this.#observeVariants(); + this.#observeSplitViews(); + }); + } + + #observeVariants() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.variants, (variants) => { + this._availableVariants = variants; + this._generateRoutes(); + }); + } + + #observeSplitViews() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.splitView.activeVariantsInfo, (variants) => { + this._workspaceSplitViews = variants; + }); + } + + private _handleVariantFolderPart(index: number, folderPart: string) { + const variantSplit = folderPart.split('_'); + const culture = variantSplit[0]; + const segment = variantSplit[1]; + this.#workspaceContext?.splitView.setActiveVariant(index, culture, segment); + } + + private _generateRoutes() { + if (!this._availableVariants || this._availableVariants.length === 0) return; + + // Generate split view routes for all available routes + const routes: Array = []; + + // Split view routes: + this._availableVariants.forEach((variantA) => { + this._availableVariants.forEach((variantB) => { + routes.push({ + path: new UmbVariantId(variantA).toString() + '_&_' + new UmbVariantId(variantB).toString(), + component: this.splitViewElement, + setup: (_component, info) => { + // Set split view/active info.. + const variantSplit = info.match.fragments.consumed.split('_&_'); + variantSplit.forEach((part, index) => { + this._handleVariantFolderPart(index, part); + }); + }, + }); + }); + }); + + // Single view: + this._availableVariants.forEach((variant) => { + routes.push({ + path: new UmbVariantId(variant).toString(), + component: this.splitViewElement, + setup: (_component, info) => { + // cause we might come from a split-view, we need to reset index 1. + this.#workspaceContext?.splitView.removeActiveVariant(1); + this._handleVariantFolderPart(0, info.match.fragments.consumed); + }, + }); + }); + + if (routes.length !== 0) { + // Using first single view as the default route for now (hence the math below): + routes.push({ + path: '**', + redirectTo: routes[this._availableVariants.length * this._availableVariants.length]?.path, + }); + } + + this._routes = routes; + } + + private _gotWorkspaceRoute = (e: UmbRouterSlotInitEvent) => { + this.#workspaceContext?.splitView.setWorkspaceRoute(e.target.absoluteRouterPath); + }; + + render() { + return this._routes + ? html`${this.splitViewElement}` + : ''; + } +} + +export default UmbDocumentWorkspaceEditorElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-workspace-editor': UmbDocumentWorkspaceEditorElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace-split-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace-split-view.element.ts index ec66755894..936b5c7783 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace-split-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace-split-view.element.ts @@ -4,8 +4,9 @@ import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { ActiveVariant } from '../../../shared/components/workspace/workspace-context/workspace-split-view-manager.class'; import { UmbDocumentWorkspaceContext } from './document-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import '../../../shared/components/workspace/workspace-variant/workspace-variant.element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-document-workspace-split-view') export class UmbDocumentWorkspaceSplitViewElement extends UmbLitElement { @@ -24,7 +25,7 @@ export class UmbDocumentWorkspaceSplitViewElement extends UmbLitElement { #splitViews { display: flex; width: 100%; - height: 100%; + height: calc(100% - var(--umb-footer-layout-height)); } #breadcrumbs { @@ -44,8 +45,8 @@ export class UmbDocumentWorkspaceSplitViewElement extends UmbLitElement { constructor() { super(); - this.consumeContext('umbWorkspaceContext', (context) => { - this._workspaceContext = context; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (context) => { + this._workspaceContext = context as UmbDocumentWorkspaceContext; this._observeActiveVariantInfo(); }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts index f62c5943fc..e4d3f0b984 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.context.ts @@ -3,18 +3,18 @@ import { UmbDocumentRepository } from '../repository/document.repository'; import { UmbDocumentTypeRepository } from '../../document-types/repository/document-type.repository'; import { UmbWorkspaceVariableEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-variable-entity-context.interface'; import { UmbVariantId } from '../../../shared/variants/variant-id.class'; -import { UmbWorkspacePropertyStructureManager } from '../../../shared/components/workspace/workspace-context/workspace-property-structure-manager.class'; +import { UmbWorkspacePropertyStructureManager } from '../../../shared/components/workspace/workspace-context/workspace-structure-manager.class'; import { UmbWorkspaceSplitViewManager } from '../../../shared/components/workspace/workspace-context/workspace-split-view-manager.class'; -import type { DocumentModel } from '@umbraco-cms/backend-api'; -import { partialUpdateFrozenArray, ObjectState, UmbObserverController } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import type { CreateDocumentRequestModel, DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { partialUpdateFrozenArray, ObjectState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; // TODO: should this context be called DocumentDraft instead of workspace? or should the draft be part of this? // TODO: Should we have a DocumentStructureContext and maybe even a DocumentDraftContext? -type EntityType = DocumentModel; +type EntityType = DocumentResponseModel; export class UmbDocumentWorkspaceContext - extends UmbWorkspaceContext + extends UmbWorkspaceContext implements UmbWorkspaceVariableEntityContextInterface { /** @@ -28,27 +28,39 @@ export class UmbDocumentWorkspaceContext * The document is the current state/draft version of the document. */ #draft = new ObjectState(undefined); - readonly unique = this.#draft.getObservablePart((data) => data?.key); - readonly documentTypeKey = this.#draft.getObservablePart((data) => data?.contentTypeKey); + readonly unique = this.#draft.getObservablePart((data) => data?.id); + readonly documentTypeKey = this.#draft.getObservablePart((data) => data?.contentTypeId); readonly variants = this.#draft.getObservablePart((data) => data?.variants || []); readonly urls = this.#draft.getObservablePart((data) => data?.urls || []); - readonly templateKey = this.#draft.getObservablePart((data) => data?.templateKey || null); + readonly templateId = this.#draft.getObservablePart((data) => data?.templateId || null); readonly structure; readonly splitView; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbDocumentRepository(host)); this.structure = new UmbWorkspacePropertyStructureManager(this.host, new UmbDocumentTypeRepository(this.host)); this.splitView = new UmbWorkspaceSplitViewManager(this.host); - new UmbObserverController(this.host, this.documentTypeKey, (key) => this.structure.loadType(key)); + new UmbObserverController(this.host, this.documentTypeKey, (id) => this.structure.loadType(id)); + + /* + TODO: Concept for ensure variant values: + new UmbObserverController(this.host, this.variants, (variants) => { + if (!variants) return; + const draft = this.#draft.getValue(); + if (!draft) return; + + // Gather all properties from all document types. + // Loop through all properties for each variant and insert missing value objects. + } + */ } - async load(entityKey: string) { - const { data } = await this.repository.requestByKey(entityKey); + async load(entityId: string) { + const { data } = await this.repository.requestById(entityId); if (!data) return undefined; this.setIsNew(false); @@ -57,8 +69,8 @@ export class UmbDocumentWorkspaceContext return data || undefined; } - async createScaffold(parentKey: string | null) { - const { data } = await this.repository.createScaffold(parentKey); + async createScaffold(documentTypeKey: string) { + const { data } = await this.repository.createScaffold(documentTypeKey); if (!data) return undefined; this.setIsNew(true); @@ -77,8 +89,8 @@ export class UmbDocumentWorkspaceContext } */ - getEntityKey() { - return this.getData().key; + getEntityId() { + return this.getData().id; } getEntityType() { @@ -151,17 +163,21 @@ export class UmbDocumentWorkspaceContext async save() { if (!this.#draft.value) return; + if (!this.#draft.value.id) return; + if (this.getIsNew()) { - await this.repository.create(this.#draft.value); + // TODO: typescript hack until we get the create type + const value = this.#draft.value as CreateDocumentRequestModel & { id: string }; + await this.repository.create(value); } else { - await this.repository.save(this.#draft.value); + await this.repository.save(this.#draft.value.id, this.#draft.value); } // If it went well, then its not new anymore?. this.setIsNew(false); } - async delete(key: string) { - await this.repository.delete(key); + async delete(id: string) { + await this.repository.delete(id); } /* @@ -178,5 +194,8 @@ export class UmbDocumentWorkspaceContext public destroy(): void { this.#draft.complete(); + this.structure.destroy(); } } + +export default UmbDocumentWorkspaceContext; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts index d2f69c3f86..19301cf90a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.element.ts @@ -1,144 +1,44 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html } from 'lit'; +import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { IRoute, IRoutingInfo } from 'router-slot'; -import type { UmbWorkspaceEntityElement } from '../../../shared/components/workspace/workspace-entity-element.interface'; -import { UmbVariantId } from '../../../shared/variants/variant-id.class'; -import { ActiveVariant } from '../../../shared/components/workspace/workspace-context/workspace-split-view-manager.class'; import { UmbDocumentWorkspaceContext } from './document-workspace.context'; -import { UmbDocumentWorkspaceSplitViewElement } from './document-workspace-split-view.element'; -import { UmbLitElement } from '@umbraco-cms/element'; -import '../../../shared/components/workspace/workspace-variant/workspace-variant.element'; -import { DocumentModel, VariantViewModelBaseModel } from '@umbraco-cms/backend-api'; -import { UmbRouterSlotInitEvent } from '@umbraco-cms/router'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +import './document-workspace-editor.element'; @customElement('umb-document-workspace') -export class UmbDocumentWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - width: 100%; - height: 100%; - } - `, +export class UmbDocumentWorkspaceElement extends UmbLitElement { + static styles = [UUITextStyles]; + + #workspaceContext = new UmbDocumentWorkspaceContext(this); + #element = document.createElement('umb-document-workspace-editor'); + + @state() + _routes: IRoute[] = [ + { + path: 'create/:parentId/:documentTypeKey', + component: () => this.#element, + setup: async (_component, info) => { + // TODO: use parent id: + // TODO: Notice the perspective of permissions here, we need to check if the user has access to create a document of this type under this parent? + const parentId = info.match.params.parentId; + const documentTypeKey = info.match.params.documentTypeKey; + this.#workspaceContext.createScaffold(documentTypeKey); + }, + }, + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, ]; - private _workspaceContext: UmbDocumentWorkspaceContext = new UmbDocumentWorkspaceContext(this); - //private _defaultVariant?: VariantViewModelBaseModel; - private splitViewElement = new UmbDocumentWorkspaceSplitViewElement(); - - @state() - _unique?: string; - - @state() - _routes?: Array; - - @state() - _availableVariants: Array = []; - - @state() - _workspaceSplitViews: Array = []; - - constructor() { - super(); - - this.observe(this._workspaceContext.variants, (variants) => { - this._availableVariants = variants; - this._generateRoutes(); - }); - this.observe(this._workspaceContext.splitView.activeVariantsInfo, (variants) => { - this._workspaceSplitViews = variants; - }); - } - - public async load(entityKey: string) { - const data = await this._workspaceContext.load(entityKey); - this._gotDocumentData(data); - } - - public async create(parentKey: string | null) { - const data = await this._workspaceContext.createScaffold(parentKey); - this._gotDocumentData(data); - } - - private _gotDocumentData(data: DocumentModel | undefined) { - if (data && data.variants && data.variants.length > 0) { - //this._defaultVariant = data.variants[0]; - this._unique = data.key; - // Maybe we need to re-generate routes here? - } else { - // Fail beautifully? - } - } - - private _handleVariantFolderPart(index: number, folderPart: string) { - const variantSplit = folderPart.split('_'); - const culture = variantSplit[0]; - const segment = variantSplit[1]; - this._workspaceContext.splitView.setActiveVariant(index, culture, segment); - } - - private _generateRoutes() { - if (!this._availableVariants || this._availableVariants.length === 0) return; - - // Generate split view routes for all available routes - const routes: Array = []; - - // Split view routes: - this._availableVariants.forEach((variantA) => { - this._availableVariants.forEach((variantB) => { - routes.push({ - path: new UmbVariantId(variantA).toString() + '_&_' + new UmbVariantId(variantB).toString(), - //component: () => import('./document-workspace-split-view.element'), - component: this.splitViewElement, - setup: (component: HTMLElement | Promise, info: IRoutingInfo) => { - // Set split view/active info.. - const variantSplit = info.match.fragments.consumed.split('_&_'); - variantSplit.forEach((part, index) => { - this._handleVariantFolderPart(index, part); - }); - }, - }); - }); - }); - - // Single view: - this._availableVariants.forEach((variant) => { - routes.push({ - path: new UmbVariantId(variant).toString(), - //component: () => import('./document-workspace-split-view.element'), - component: this.splitViewElement, - setup: (component: HTMLElement | Promise, info: IRoutingInfo) => { - // cause we might come from a split-view, we need to reset index 1. - this._workspaceContext.splitView.removeActiveVariant(1); - this._handleVariantFolderPart(0, info.match.fragments.consumed); - }, - }); - }); - - if (routes.length !== 0) { - // Using first single view as the default route for now (hence the math below): - routes.push({ - path: '**', - redirectTo: routes[this._availableVariants.length * this._availableVariants.length]?.path, - }); - } - - this._routes = routes; - } - - private _gotWorkspaceRoute = (e: UmbRouterSlotInitEvent) => { - this._workspaceContext.splitView.setWorkspaceRoute(e.target.absoluteRouterPath); - }; - render() { - return this._routes - ? html`${this.splitViewElement}` - : ''; + return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.stories.ts index 8475de493d..e50ce69c05 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.stories.ts @@ -1,7 +1,6 @@ -import './document-workspace.element'; +import './document-workspace-editor.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; -import { data as documentNodes } from '../../../../core/mocks/data/document.data'; +import { html } from 'lit'; import type { UmbDocumentWorkspaceElement } from './document-workspace.element'; export default { @@ -11,5 +10,5 @@ export default { } as Meta; export const AAAOverview: Story = () => - html` `; + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.test.ts index 3849929e42..3bf624e247 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/document-workspace.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbDocumentWorkspaceElement } from './document-workspace.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbDocumentWorkspaceElement', () => { let element: UmbDocumentWorkspaceElement; @@ -17,13 +17,4 @@ describe('UmbDocumentWorkspaceElement', () => { // TODO: should we use shadowDom here? await expect(element).to.be.accessible(defaultA11yConfig); }); - - describe('methods', () => { - it('has a load method', () => { - expect(element).to.have.property('load').that.is.a('function'); - }); - it('has a create method', () => { - expect(element).to.have.property('create').that.is.a('function'); - }); - }); }); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/manifests.ts index be404bc875..d8ada1659b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/manifests.ts @@ -1,14 +1,13 @@ -import { DOCUMENT_REPOSITORY_ALIAS } from '../repository/manifests'; import { UmbDocumentSaveAndPublishWorkspaceAction } from './actions/save-and-publish.action'; import { UmbDocumentSaveAndPreviewWorkspaceAction } from './actions/save-and-preview.action'; import { UmbSaveAndScheduleDocumentWorkspaceAction } from './actions/save-and-schedule.action'; -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView, ManifestWorkspaceViewCollection, -} from '@umbraco-cms/models'; +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', @@ -25,28 +24,31 @@ const workspaceViews: Array = [ type: 'workspaceView', alias: 'Umb.WorkspaceView.Document.Edit', name: 'Document Workspace Edit View', - loader: () => import('./views/document-workspace-view-edit.element'), + loader: () => import('./views/edit/document-workspace-view-edit.element'), weight: 200, meta: { - workspaces: ['Umb.Workspace.Document'], label: 'Content', pathname: 'content', icon: 'document', }, + conditions: { + workspaces: ['Umb.Workspace.Document'], + }, }, { type: 'workspaceView', alias: 'Umb.WorkspaceView.Document.Info', name: 'Document Workspace Info View', - loader: () => - import('../../../shared/components/workspace/workspace-content/views/info/workspace-view-content-info.element'), + loader: () => import('./views/info/document-info-workspace-view.element'), weight: 100, meta: { - workspaces: ['Umb.Workspace.Document'], label: 'Info', pathname: 'info', icon: 'info', }, + conditions: { + workspaces: ['Umb.Workspace.Document'], + }, }, ]; @@ -59,13 +61,15 @@ const workspaceViewCollections: Array = [ name: 'Document Workspace Collection View', weight: 300, meta: { - workspaces: ['Umb.Workspace.Document'], label: 'Documents', pathname: 'collection', icon: 'umb:grid', entityType: 'document', repositoryAlias: DOCUMENT_REPOSITORY_ALIAS, }, + conditions: { + workspaces: ['Umb.Workspace.Document'], + } }, */ ]; @@ -77,12 +81,14 @@ const workspaceActions: Array = [ name: 'Save And Publish Document Workspace Action', weight: 100, meta: { - workspaces: ['Umb.Workspace.Document'], label: 'Save And Publish', look: 'primary', color: 'positive', api: UmbDocumentSaveAndPublishWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Document'], + }, }, { type: 'workspaceAction', @@ -90,11 +96,13 @@ const workspaceActions: Array = [ name: 'Save Document Workspace Action', weight: 90, meta: { - workspaces: ['Umb.Workspace.Document'], label: 'Save', look: 'secondary', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Document'], + }, }, { type: 'workspaceAction', @@ -102,10 +110,12 @@ const workspaceActions: Array = [ name: 'Save And Preview Document Workspace Action', weight: 80, meta: { - workspaces: ['Umb.Workspace.Document'], label: 'Save And Preview', api: UmbDocumentSaveAndPreviewWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Document'], + }, }, { type: 'workspaceAction', @@ -113,10 +123,12 @@ const workspaceActions: Array = [ name: 'Save And Schedule Document Workspace Action', weight: 70, meta: { - workspaces: ['Umb.Workspace.Document'], label: 'Save And Schedule', api: UmbSaveAndScheduleDocumentWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Document'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-properties.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-properties.element.ts deleted file mode 100644 index 6bd3840d8a..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-properties.element.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { css, html } from 'lit'; -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, property, state } from 'lit/decorators.js'; -import { repeat } from 'lit/directives/repeat.js'; -import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DocumentTypePropertyTypeModel, PropertyTypeContainerViewModelBaseModel } from '@umbraco-cms/backend-api'; - -@customElement('umb-document-workspace-view-edit-properties') -export class UmbDocumentWorkspaceViewEditPropertiesElement extends UmbLitElement { - static styles = [ - UUITextStyles, - css` - .property { - border-bottom: 1px solid var(--uui-color-divider); - } - .property:last-child { - border-bottom: 0; - } - `, - ]; - - private _containerName?: string; - - @property({ type: String, attribute: 'container-name', reflect: false }) - public get containerName(): string | undefined { - return this._containerName; - } - public set containerName(value: string | undefined) { - if (this._containerName === value) return; - this._containerName = value; - this._observeGroupContainers(); - } - - private _containerType?: 'Group' | 'Tab'; - - @property({ type: String, attribute: 'container-type', reflect: false }) - public get containerType(): 'Group' | 'Tab' | undefined { - return this._containerType; - } - public set containerType(value: 'Group' | 'Tab' | undefined) { - if (this._containerType === value) return; - this._containerType = value; - this._observeGroupContainers(); - } - - @state() - _groupContainers: Array = []; - - @state() - _propertyStructure: Array = []; - - private _workspaceContext?: UmbDocumentWorkspaceContext; - - constructor() { - super(); - - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext('umbWorkspaceContext', (workspaceContext) => { - this._workspaceContext = workspaceContext; - this._observeGroupContainers(); - }); - } - - private _observeGroupContainers() { - if (!this._workspaceContext || !this._containerName || !this._containerType) return; - - // TODO: Should be no need to update this observable if its already there. - this.observe( - this._workspaceContext!.structure.containersByNameAndType(this._containerName, this._containerType), - (groupContainers) => { - this._groupContainers = groupContainers || []; - groupContainers.forEach((group) => { - if (group.key) { - // Gather property aliases of this group, by group key. - this._observePropertyStructureOfGroup(group); - } - }); - }, - '_observeGroupContainers' - ); - } - - private _observePropertyStructureOfGroup(group: PropertyTypeContainerViewModelBaseModel) { - if (!this._workspaceContext || !group.key) return; - - // TODO: Should be no need to update this observable if its already there. - this.observe( - this._workspaceContext.structure.propertyStructuresOf(group.key), - (properties) => { - // If this need to be able to remove properties, we need to clean out the ones of this group.key before inserting them: - this._propertyStructure = this._propertyStructure.filter((x) => x.containerKey !== group.key); - - properties?.forEach((property) => { - if (!this._propertyStructure.find((x) => x.alias === property.alias)) { - this._propertyStructure.push(property); - } - }); - - if (this._propertyStructure.length > 0) { - // TODO: Missing sort order? - //this._propertyStructure.sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); - } - }, - '_observePropertyStructureOfGroup' + group.key - ); - - // cache observable - } - - render() { - return repeat( - this._propertyStructure, - (property) => property.alias, - (property) => html` ` - ); - } -} - -export default UmbDocumentWorkspaceViewEditPropertiesElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-document-workspace-view-edit-properties': UmbDocumentWorkspaceViewEditPropertiesElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-tab.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-tab.element.ts deleted file mode 100644 index 9f1f88145d..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit-tab.element.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { css, html } from 'lit'; -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, property, state } from 'lit/decorators.js'; -import { repeat } from 'lit/directives/repeat.js'; -import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { PropertyTypeContainerViewModelBaseModel } from '@umbraco-cms/backend-api'; -import './document-workspace-view-edit-properties.element'; - -@customElement('umb-document-workspace-view-edit-tab') -export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - margin: var(--uui-size-layout-1); - } - - uui-box { - margin-bottom: var(--uui-size-layout-1); - } - `, - ]; - - private _tabName?: string | undefined; - - @property({ type: String }) - public get tabName(): string | undefined { - return this._tabName; - } - public set tabName(value: string | undefined) { - const oldValue = this._tabName; - if (oldValue === value) return; - this._tabName = value; - this._observeTabContainers(); - this.requestUpdate('tabName', oldValue); - } - - private _noTabName = false; - - @property({ type: Boolean }) - public get noTabName(): boolean { - return this._noTabName; - } - public set noTabName(value: boolean) { - const oldValue = this._noTabName; - if (oldValue === value) return; - this._noTabName = value; - if (this._noTabName) { - this._tabName = undefined; - } - this._observeTabContainers(); - this.requestUpdate('noTabName', oldValue); - } - - @state() - _tabContainers: PropertyTypeContainerViewModelBaseModel[] = []; - - @state() - _hasTabProperties = false; - - @state() - _groups: Array = []; - - private _workspaceContext?: UmbDocumentWorkspaceContext; - - constructor() { - super(); - - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext('umbWorkspaceContext', (workspaceContext) => { - this._workspaceContext = workspaceContext; - this._observeTabContainers(); - }); - } - - private _observeHasTabProperties() { - if (!this._workspaceContext) return; - - this._tabContainers.forEach((container) => { - this.observe( - this._workspaceContext!.structure.hasPropertyStructuresOf(container.key!), - (hasTabProperties) => { - this._hasTabProperties = hasTabProperties; - }, - '_observeHasTabProperties_' + container.key - ); - }); - } - - private _observeTabContainers() { - if (!this._workspaceContext) return; - - if (this._tabName) { - this._groups = []; - this.observe( - this._workspaceContext.structure.containersByNameAndType(this._tabName, 'Tab'), - (tabContainers) => { - this._tabContainers = tabContainers || []; - if (this._tabContainers.length > 0) { - this._observeHasTabProperties(); - this._observeGroups(); - } - }, - '_observeTabContainers' - ); - } else if (this._noTabName) { - this._groups = []; - this._observeRootGroups(); - } - } - - private _observeGroups() { - if (!this._workspaceContext || !this._tabName) return; - - this._tabContainers.forEach((container) => { - this.observe( - this._workspaceContext!.structure.containersOfParentKey(container.key, 'Group'), - this._insertGroupContainers, - '_observeGroupsOf_' + container.key - ); - }); - } - - private _observeRootGroups() { - if (!this._workspaceContext || !this._noTabName) return; - - // This is where we potentially could observe root properties as well. - this.observe( - this._workspaceContext!.structure.rootContainers('Group'), - this._insertGroupContainers, - '_observeRootGroups' - ); - } - - private _insertGroupContainers = (groupContainers: PropertyTypeContainerViewModelBaseModel[]) => { - groupContainers.forEach((group) => { - if (group.name) { - if (!this._groups.find((x) => x.name === group.name)) { - this._groups.push(group); - this._groups.sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); - } - } - }); - }; - - render() { - // TODO: only show tab properties if there was any. We might do this with an event? to tell us when the properties is empty. - return html` - ${this._hasTabProperties - ? html` - - - - ` - : ''} - ${repeat( - this._groups, - (group) => group.name, - (group) => html` - - ` - )} - `; - } -} - -export default UmbDocumentWorkspaceViewEditTabElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-document-workspace-view-edit-tab': UmbDocumentWorkspaceViewEditTabElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit-properties.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit-properties.element.ts new file mode 100644 index 0000000000..2cc4063213 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit-properties.element.ts @@ -0,0 +1,68 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbWorkspacePropertyStructureHelper } from '../../../../../shared/components/workspace/workspace-context/workspace-property-structure-helper.class'; +import { PropertyContainerTypes } from '../../../../../shared/components/workspace/workspace-context/workspace-structure-manager.class'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DocumentTypePropertyTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-document-workspace-view-edit-properties') +export class UmbDocumentWorkspaceViewEditPropertiesElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + .property { + border-bottom: 1px solid var(--uui-color-divider); + } + .property:last-child { + border-bottom: 0; + } + `, + ]; + + @property({ type: String, attribute: 'container-name', reflect: false }) + public get containerName(): string | undefined { + return this._propertyStructureHelper.getContainerName(); + } + public set containerName(value: string | undefined) { + this._propertyStructureHelper.setContainerName(value); + } + + @property({ type: String, attribute: 'container-type', reflect: false }) + public get containerType(): PropertyContainerTypes | undefined { + return this._propertyStructureHelper.getContainerType(); + } + public set containerType(value: PropertyContainerTypes | undefined) { + this._propertyStructureHelper.setContainerType(value); + } + + _propertyStructureHelper = new UmbWorkspacePropertyStructureHelper(this); + + @state() + _propertyStructure: Array = []; + + constructor() { + super(); + + this.observe(this._propertyStructureHelper.propertyStructure, (propertyStructure) => { + this._propertyStructure = propertyStructure; + }); + } + + render() { + return repeat( + this._propertyStructure, + (property) => property.alias, + (property) => html` ` + ); + } +} + +export default UmbDocumentWorkspaceViewEditPropertiesElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-workspace-view-edit-properties': UmbDocumentWorkspaceViewEditPropertiesElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit-tab.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit-tab.element.ts new file mode 100644 index 0000000000..6febfe89a9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit-tab.element.ts @@ -0,0 +1,92 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbWorkspaceContainerStructureHelper } from '../../../../../shared/components/workspace/workspace-context/workspace-container-structure-helper.class'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { PropertyTypeContainerResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; +import './document-workspace-view-edit-properties.element'; + +@customElement('umb-document-workspace-view-edit-tab') +export class UmbDocumentWorkspaceViewEditTabElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + uui-box { + margin: var(--uui-size-layout-1); + } + `, + ]; + + private _tabName?: string | undefined; + + @property({ type: String }) + public get tabName(): string | undefined { + return this._groupStructureHelper.getName(); + } + public set tabName(value: string | undefined) { + if (value === this._tabName) return; + const oldValue = this._tabName; + this._tabName = value; + this._groupStructureHelper.setName(value); + this.requestUpdate('tabName', oldValue); + } + + @property({ type: Boolean }) + public get noTabName(): boolean { + return this._groupStructureHelper.getIsRoot(); + } + public set noTabName(value: boolean) { + this._groupStructureHelper.setIsRoot(value); + } + + _groupStructureHelper = new UmbWorkspaceContainerStructureHelper(this); + + @state() + _groups: Array = []; + + @state() + _hasProperties = false; + + constructor() { + super(); + + this.observe(this._groupStructureHelper.containers, (groups) => { + this._groups = groups; + }); + this.observe(this._groupStructureHelper.hasProperties, (hasProperties) => { + this._hasProperties = hasProperties; + }); + } + + render() { + return html` + ${this._hasProperties + ? html` + + + + ` + : ''} + ${repeat( + this._groups, + (group) => group.name, + (group) => html` + + ` + )} + `; + } +} + +export default UmbDocumentWorkspaceViewEditTabElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-workspace-view-edit-tab': UmbDocumentWorkspaceViewEditTabElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit.element.ts similarity index 65% rename from src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit.element.ts index 6dfc9ca79b..e1b10e8229 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/document-workspace-view-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/edit/document-workspace-view-edit.element.ts @@ -2,10 +2,13 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { UmbDocumentWorkspaceContext } from '../document-workspace.context'; -import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent, IRoute } from '@umbraco-cms/router'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { PropertyTypeContainerViewModelBaseModel } from '@umbraco-cms/backend-api'; +import { UmbDocumentWorkspaceContext } from '../../document-workspace.context'; +import { UmbWorkspaceContainerStructureHelper } from '../../../../../shared/components/workspace/workspace-context/workspace-container-structure-helper.class'; +import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { PropertyTypeContainerResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; +import { IRoute } from '@umbraco-cms/backoffice/router'; @customElement('umb-document-workspace-view-edit') export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement { @@ -26,7 +29,7 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement { private _routes: IRoute[] = []; @state() - _tabs: Array = []; + _tabs: Array = []; @state() private _routerPath?: string; @@ -36,58 +39,41 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement { private _workspaceContext?: UmbDocumentWorkspaceContext; + private _tabsStructureHelper = new UmbWorkspaceContainerStructureHelper(this); + constructor() { super(); - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext('umbWorkspaceContext', (workspaceContext) => { - this._workspaceContext = workspaceContext; - this._observeTabs(); + this._tabsStructureHelper.setIsRoot(true); + this._tabsStructureHelper.setContainerChildType('Tab'); + this.observe(this._tabsStructureHelper.containers, (tabs) => { + this._tabs = tabs; + this._createRoutes(); + }); + + // _hasRootProperties can be gotten via _tabsStructureHelper.hasProperties. But we do not support root properties currently. + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (workspaceContext) => { + this._workspaceContext = workspaceContext as UmbDocumentWorkspaceContext; + this._observeRootGroups(); }); } - private _observeTabs() { + private _observeRootGroups() { if (!this._workspaceContext) return; - this.observe( - this._workspaceContext.structure.rootContainers('Tab'), - (tabs) => { - tabs.forEach((tab) => { - // Only add each tab name once, as our containers merge on name: - if (!this._tabs.find((x) => x.name === tab.name || '')) { - this._tabs.push(tab); - } - }); - this._createRoutes(); - }, - '_observeTabs' - ); - - /* - Impleent this, when it becomes an option to have properties directly in the root of the document. - this.observe( - this._workspaceContext.rootPropertyStructures(), - (rootPropertyStructure) => { - console.log('rootPropertyStructure', rootPropertyStructure); - this._hasRootProperties = rootPropertyStructure.length > 0; - this._createRoutes(); - }, - '_observeTabs' - ); - */ - this.observe( this._workspaceContext.structure.hasRootContainers('Group'), (hasRootGroups) => { this._hasRootGroups = hasRootGroups; this._createRoutes(); }, - '_observeTabs' + '_observeGroups' ); } private _createRoutes() { - const routes: any[] = []; + const routes: IRoute[] = []; if (this._tabs.length > 0) { this._tabs?.forEach((tab) => { @@ -95,7 +81,7 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement { routes.push({ path: `tab/${encodeURI(tabName || '').toString()}`, component: () => import('./document-workspace-view-edit-tab.element'), - setup: (component: Promise) => { + setup: (component) => { (component as any).tabName = tabName; }, }); @@ -106,7 +92,7 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement { routes.push({ path: '', component: () => import('./document-workspace-view-edit-tab.element'), - setup: (component: Promise) => { + setup: (component) => { (component as any).noTabName = true; }, }); @@ -140,6 +126,7 @@ export class UmbDocumentWorkspaceViewEditElement extends UmbLitElement { this._tabs, (tab) => tab.name, (tab) => { + // TODO: make better url folder name: const path = this._routerPath + '/tab/' + encodeURI(tab.name || ''); return html`${tab.name}; + private _workspaceContext?: typeof UMB_ENTITY_WORKSPACE_CONTEXT.TYPE; private itemsPerPage = 10; constructor() { super(); - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext>('umbWorkspaceContext', (nodeContext) => { + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (nodeContext) => { this._workspaceContext = nodeContext; this._observeContent(); }); @@ -329,10 +327,10 @@ export class UmbWorkspaceViewContentInfoElement extends UmbLitElement { } } -export default UmbWorkspaceViewContentInfoElement; +export default UmbDocumentInfoWorkspaceViewElement; declare global { interface HTMLElementTagNameMap { - 'umb-workspace-view-content-info': UmbWorkspaceViewContentInfoElement; + 'umb-document-info-workspace-view': UmbDocumentInfoWorkspaceViewElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/info/workspace-view-content-info.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/info/document-info-workspace-view.stories.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/info/workspace-view-content-info.stories.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/info/document-info-workspace-view.stories.ts index f5eed2b094..60431116de 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/info/workspace-view-content-info.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/documents/workspace/views/info/document-info-workspace-view.stories.ts @@ -1,17 +1,17 @@ -import './workspace-view-content-info.element'; +import './document-info-workspace-view.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; // import { data } from '../../../../../../core/mocks/data/document.data'; // import { UmbNodeContext } from '../../node.context'; -import type { UmbWorkspaceViewContentInfoElement } from './workspace-view-content-info.element'; +import type { UmbDocumentInfoWorkspaceViewElement } from './document-info-workspace-view.element'; export default { - title: 'Workspaces/Shared/Node/Views/Info', - component: 'umb-workspace-view-content-info', - id: 'umb-workspace-view-content-info', + title: 'Workspaces/Documents/Views/Info', + component: 'umb-document-info-workspace-view', + id: 'umb-document-info-workspace-view', decorators: [ (story) => { return html`TODO: make use of mocked workspace context??`; @@ -22,6 +22,6 @@ export default { ], } as Meta; -export const AAAOverview: Story = () => - html` `; +export const AAAOverview: Story = () => + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/index.ts index 7cfabc7cce..96b85feed0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/index.ts @@ -5,8 +5,8 @@ import { manifests as documentBlueprintManifests } from './document-blueprints/m import { manifests as documentTypeManifests } from './document-types/manifests'; import { manifests as documentManifests } from './documents/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [ ...dashboardManifests, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/menu.manifests.ts index 1595462273..d9c7475351 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/menu.manifests.ts @@ -1,4 +1,4 @@ -import { ManifestMenu } from '@umbraco-cms/extensions-registry'; +import { ManifestMenu } from '@umbraco-cms/backoffice/extensions-registry'; const menu: ManifestMenu = { type: 'menu', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/documents/section.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/documents/section.manifests.ts index d8919a3689..f92e70697c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/documents/section.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/documents/section.manifests.ts @@ -1,8 +1,9 @@ -import type { ManifestSection, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; +import { ManifestSectionSidebarAppMenuKind } from '@umbraco-cms/backoffice/extensions-registry'; const sectionAlias = 'Umb.Section.Content'; -const section: ManifestSection = { +const section: ManifestTypes = { type: 'section', alias: sectionAlias, name: 'Content Section', @@ -13,16 +14,19 @@ const section: ManifestSection = { }, }; -const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = { - type: 'menuSectionSidebarApp', +const menuSectionSidebarApp: ManifestSectionSidebarAppMenuKind = { + type: 'sectionSidebarApp', + kind: 'menu', alias: 'Umb.SidebarMenu.Content', name: 'Content Sidebar Menu', weight: 100, meta: { label: 'Content', - sections: [sectionAlias], menu: 'Umb.Menu.Content', }, + conditions: { + sections: [sectionAlias], + }, }; export const manifests = [section, menuSectionSidebarApp]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/index.ts index 76a1e6c199..c6eb537f80 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/index.ts @@ -3,8 +3,8 @@ import { manifests as mediaMenuManifests } from './menu.manifests'; import { manifests as mediaManifests } from './media/manifests'; import { manifests as mediaTypesManifests } from './media-types/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [...mediaSectionManifests, ...mediaMenuManifests, ...mediaManifests, ...mediaTypesManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/create.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/create.action.ts index 9d5c7cdf57..5f77849dea 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/create.action.ts @@ -1,9 +1,9 @@ import { UmbMediaTypeRepository } from '../repository/media-type.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbCreateMediaTypeEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/manifests.ts index cd094dcd3d..0535ffc768 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/manifests.ts @@ -1,8 +1,8 @@ import { MEDIA_TYPE_REPOSITORY_ALIAS } from '../repository/manifests'; import { UmbCreateMediaTypeEntityAction } from './create.action'; import UmbReloadMediaTypeEntityAction from './reload.action'; -import { UmbDeleteEntityAction, UmbMoveEntityAction, UmbCopyEntityAction } from '@umbraco-cms/entity-action'; -import type { ManifestEntityAction } from '@umbraco-cms/models'; +import { UmbDeleteEntityAction, UmbMoveEntityAction, UmbCopyEntityAction } from '@umbraco-cms/backoffice/entity-action'; +import type { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; const entityType = 'media-type'; const repositoryAlias = MEDIA_TYPE_REPOSITORY_ALIAS; @@ -14,12 +14,14 @@ const entityActions: Array = [ name: 'Create Media Type Entity Action', weight: 500, meta: { - entityType, icon: 'umb:add', label: 'Create', repositoryAlias, api: UmbCreateMediaTypeEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -27,12 +29,14 @@ const entityActions: Array = [ name: 'Move Media Type Entity Action', weight: 400, meta: { - entityType, icon: 'umb:enter', label: 'Move', repositoryAlias, api: UmbMoveEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -40,12 +44,14 @@ const entityActions: Array = [ name: 'Copy Media Type Entity Action', weight: 300, meta: { - entityType, icon: 'umb:documents', label: 'Copy', repositoryAlias, api: UmbCopyEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -53,12 +59,14 @@ const entityActions: Array = [ name: 'Delete Media Type Entity Action', weight: 200, meta: { - entityType, icon: 'umb:trash', label: 'Delete', repositoryAlias, api: UmbDeleteEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -66,12 +74,14 @@ const entityActions: Array = [ name: 'Reload Media Type Entity Action', weight: 100, meta: { - entityType, icon: 'umb:refresh', label: 'Reload', repositoryAlias, api: UmbReloadMediaTypeEntityAction, }, + conditions: { + entityType, + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/reload.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/reload.action.ts index e12ee63785..17e28e6d4c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/reload.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/entity-actions/reload.action.ts @@ -1,12 +1,12 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { UmbMediaTypeRepository } from '../repository/media-type.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export default class UmbReloadMediaTypeEntityAction extends UmbEntityActionBase { static styles = [UUITextStyles]; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/menu-item/manifests.ts index 5cb7de2e11..d9a5d50037 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/menu-item/manifests.ts @@ -1,14 +1,17 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const menuItem: ManifestMenuItem = { +const menuItem: ManifestTypes = { type: 'menuItem', + kind: 'tree', alias: 'Umb.MenuItem.MediaTypes', name: 'Media Types Menu Item', - weight: 20, - loader: () => import('./media-types-menu-item.element'), + weight: 800, meta: { label: 'Media Types', icon: 'umb:folder', + treeAlias: 'Umb.Tree.MediaTypes', + }, + conditions: { menus: ['Umb.Menu.Settings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/menu-item/media-types-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/menu-item/media-types-menu-item.element.ts deleted file mode 100644 index f38a1bb8d1..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/menu-item/media-types-menu-item.element.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-media-types-menu-item') -export class UmbMediaTypesMenuItemElement extends UmbLitElement { - @state() - private _renderTree = false; - - private _onShowChildren() { - this._renderTree = true; - } - - private _onHideChildren() { - this._renderTree = false; - } - - // TODO: check if root has children before settings the has-children attribute - // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? - // TODO: can we make this reusable? - render() { - return html` - ${this._renderTree ? html`` : nothing} - `; - } -} - -export default UmbMediaTypesMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-media-types-menu-item': UmbMediaTypesMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/manifests.ts index dc5de79647..57dd021694 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbMediaTypeRepository } from './media-type.repository'; import { UmbMediaTypeStore } from './media-type.detail.store'; import { UmbMediaTypeTreeStore } from './media-type.tree.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const MEDIA_TYPE_REPOSITORY_ALIAS = 'Umb.Repository.MediaType'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts index 57dc378d61..d6ef9c0fa9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.detail.store.ts @@ -1,8 +1,8 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import type { MediaTypeDetails } from '@umbraco-cms/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models'; /** * @export @@ -11,9 +11,9 @@ import type { MediaTypeDetails } from '@umbraco-cms/models'; * @description - Details Data Store for Media Types */ export class UmbMediaTypeStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEDIA_TYPE_STORE_CONTEXT_TOKEN.toString()); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts index 8123483e57..898e1ab966 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.repository.ts @@ -2,19 +2,19 @@ import { UmbMediaTypeTreeStore, UMB_MEDIA_TYPE_TREE_STORE_CONTEXT_TOKEN } from ' import { UmbMediaTypeDetailServerDataSource } from './sources/media-type.detail.server.data'; import { UmbMediaTypeStore, UMB_MEDIA_TYPE_STORE_CONTEXT_TOKEN } from './media-type.detail.store'; import { MediaTypeTreeServerDataSource } from './sources/media-type.tree.server.data'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import type { MediaTypeDetails } from '@umbraco-cms/models'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import { UmbTreeRepository, RepositoryTreeDataSource } from '@umbraco-cms/repository'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; export class UmbMediaTypeRepository implements UmbTreeRepository { #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - #treeSource: RepositoryTreeDataSource; + #treeSource: UmbTreeDataSource; #treeStore?: UmbMediaTypeTreeStore; #detailSource: UmbMediaTypeDetailServerDataSource; @@ -22,7 +22,7 @@ export class UmbMediaTypeRepository implements UmbTreeRepository { #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source @@ -56,34 +56,34 @@ export class UmbMediaTypeRepository implements UmbTreeRepository { return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getItems(keys); + const { data, error } = await this.#treeSource.getItems(ids); - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -91,14 +91,14 @@ export class UmbMediaTypeRepository implements UmbTreeRepository { return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS @@ -108,16 +108,16 @@ export class UmbMediaTypeRepository implements UmbTreeRepository { return this.#detailSource.createScaffold(); } - async requestDetails(key: string) { + async requestDetails(id: string) { await this.#init; - // TODO: should we show a notification if the key is missing? + // TODO: should we show a notification if the id is missing? // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; + if (!id) { + const error: ProblemDetailsModel = { title: 'Id is missing' }; return { error }; } - const { data, error } = await this.#detailSource.get(key); + const { data, error } = await this.#detailSource.get(id); if (data) { this.#store?.append(data); @@ -125,9 +125,9 @@ export class UmbMediaTypeRepository implements UmbTreeRepository { return { data, error }; } - async delete(key: string) { + async delete(id: string) { await this.#init; - return this.#detailSource.delete(key); + return this.#detailSource.delete(id); } async save(mediaType: MediaTypeDetails) { @@ -135,7 +135,7 @@ export class UmbMediaTypeRepository implements UmbTreeRepository { // TODO: should we show a notification if the media type is missing? // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!mediaType || !mediaType.key) { + if (!mediaType || !mediaType.id) { const error: ProblemDetailsModel = { title: 'Media Type is missing' }; return { error }; } @@ -151,7 +151,7 @@ export class UmbMediaTypeRepository implements UmbTreeRepository { // Consider to look up the data before fetching from the server // Consider notify a workspace if a media type is updated in the store while someone is editing it. this.#store?.append(mediaType); - this.#treeStore?.updateItem(mediaType.key, { name: mediaType.name }); + this.#treeStore?.updateItem(mediaType.id, { name: mediaType.name }); // TODO: would be nice to align the stores on methods/methodNames. return { error }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts index a70127f5d6..14d86a3344 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/media-type.tree.store.ts @@ -1,20 +1,20 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export * @class UmbMediaTypeTreeStore - * @extends {UmbTreeStoreBase} + * @extends {UmbEntityTreeStore} * @description - Tree Data Store for Media Types */ -export class UmbMediaTypeTreeStore extends UmbTreeStoreBase { +export class UmbMediaTypeTreeStore extends UmbEntityTreeStore { /** * Creates an instance of UmbMediaTypeTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbMediaTypeTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEDIA_TYPE_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.detail.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.detail.server.data.ts index d0fe79bfc7..701b0dcf21 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.detail.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.detail.server.data.ts @@ -1,8 +1,8 @@ import { MediaTypeDetailDataSource } from './media-type.details.server.data.interface'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import type { MediaTypeDetails } from '@umbraco-cms/models'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * @description - A data source for the Media Type detail that fetches data from the server @@ -11,9 +11,9 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @implements {MediaTypeDetailDataSource} */ export class UmbMediaTypeDetailServerDataSource implements MediaTypeDetailDataSource { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -31,15 +31,15 @@ export class UmbMediaTypeDetailServerDataSource implements MediaTypeDetailDataSo } /** - * @description - Fetches a MediaType with the given key from the server - * @param {string} key + * @description - Fetches a MediaType with the given id from the server + * @param {string} id * @return {*} * @memberof UmbMediaTypeDetailServerDataSource */ - get(key: string) { - //return tryExecuteAndNotify(this.#host, MediaTypeResource.getMediaTypeByKey({ key })) as any; + get(id: string) { + //return tryExecuteAndNotify(this.#host, MediaTypeResource.getMediaTypeByKey({ id })) as any; // TODO: use backend cli when available. - return tryExecuteAndNotify(this.#host, fetch(`/umbraco/management/api/v1/media-type/${key}`)) as any; + return tryExecuteAndNotify(this.#host, fetch(`/umbraco/management/api/v1/media-type/${id}`)) as any; } /** @@ -49,18 +49,18 @@ export class UmbMediaTypeDetailServerDataSource implements MediaTypeDetailDataSo * @memberof UmbMediaTypeDetailServerDataSource */ async update(mediaType: MediaTypeDetails) { - if (!mediaType.key) { - const error: ProblemDetailsModel = { title: 'MediaType key is missing' }; + if (!mediaType.id) { + const error: ProblemDetailsModel = { title: 'MediaType id is missing' }; return { error }; } - const payload = { key: mediaType.key, requestBody: mediaType }; + const payload = { id: mediaType.id, requestBody: mediaType }; //return tryExecuteAndNotify(this.#host, MediaTypeResource.putMediaTypeByKey(payload)); // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, - fetch(`/umbraco/management/api/v1/media-type/${mediaType.key}`, { + fetch(`/umbraco/management/api/v1/media-type/${mediaType.id}`, { method: 'PUT', body: JSON.stringify(payload), headers: { @@ -93,21 +93,21 @@ export class UmbMediaTypeDetailServerDataSource implements MediaTypeDetailDataSo /** * @description - Deletes a MediaType on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbMediaTypeDetailServerDataSource */ - async delete(key: string) { - if (!key) { + async delete(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - //return await tryExecuteAndNotify(this.#host, MediaTypeResource.deleteMediaTypeByKey({ key })); + //return await tryExecuteAndNotify(this.#host, MediaTypeResource.deleteMediaTypeByKey({ id })); // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, - fetch(`/umbraco/management/api/v1/media-type/${key}`, { + fetch(`/umbraco/management/api/v1/media-type/${id}`, { method: 'DELETE', }) ) as any; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.details.server.data.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.details.server.data.interface.ts index b3a4306511..7da7f1a9b2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.details.server.data.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.details.server.data.interface.ts @@ -1,10 +1,11 @@ -import type { DataSourceResponse, MediaTypeDetails } from '@umbraco-cms/models'; +import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models'; +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; // TODO => Use models when they exist export interface MediaTypeDetailDataSource { - createScaffold(parentKey: string): Promise>; - get(key: string): Promise>; + createScaffold(parentId: string): Promise>; + get(id: string): Promise>; insert(data: any): Promise; update(data: any): Promise; - delete(key: string): Promise; + delete(id: string): Promise; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.tree.server.data.ts index b24810721b..6d164599f4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/repository/sources/media-type.tree.server.data.ts @@ -1,7 +1,7 @@ -import { MediaTypeResource, ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { RepositoryTreeDataSource } from '@umbraco-cms/repository'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { MediaTypeResource, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the MediaType tree that fetches data from the server @@ -9,15 +9,15 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class MediaTypeTreeServerDataSource * @implements {MediaTypeTreeDataSource} */ -export class MediaTypeTreeServerDataSource implements RepositoryTreeDataSource { - #host: UmbControllerHostInterface; +export class MediaTypeTreeServerDataSource implements UmbTreeDataSource { + #host: UmbControllerHostElement; /** * Creates an instance of MediaTypeTreeDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof MediaTypeTreeDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -31,41 +31,41 @@ export class MediaTypeTreeServerDataSource implements RepositoryTreeDataSource { } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} * @memberof MediaTypeTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + async getChildrenOf(parentId: string | null) { + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, MediaTypeResource.getTreeMediaTypeChildren({ - parentKey, + parentId, }) ); } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} * @memberof MediaTypeTreeServerDataSource */ - async getItems(keys: Array) { - if (!keys || keys.length === 0) { + async getItems(ids: Array) { + if (!ids || ids.length === 0) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - MediaTypeResource.getTreeMediaTypeItem({ - key: keys, + MediaTypeResource.getMediaTypeItem({ + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/tree/manifests.ts index 2b64d4357b..fff9c37137 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/tree/manifests.ts @@ -1,13 +1,23 @@ -import { UmbMediaTypeRepository } from '../repository/media-type.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { MEDIA_TYPE_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const tree: ManifestTree = { type: 'tree', alias: 'Umb.Tree.MediaTypes', name: 'Media Types Tree', meta: { - repository: UmbMediaTypeRepository, + repositoryAlias: MEDIA_TYPE_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.MediaType', + name: 'Media Type Tree Item', + conditions: { + entityType: 'media-type', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/manifests.ts index e7dae7efa0..b7965aad4b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/manifests.ts @@ -3,7 +3,7 @@ import type { ManifestWorkspaceAction, ManifestWorkspaceView, ManifestWorkspaceViewCollection, -} from '@umbraco-cms/models'; +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace-edit.element.ts new file mode 100644 index 0000000000..7d2d0e4214 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace-edit.element.ts @@ -0,0 +1,70 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UmbWorkspaceMediaTypeContext } from './media-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-media-type-workspace-edit') +export class UmbMediaTypeWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + #header { + display: flex; + padding: 0 var(--uui-size-layout-1); + gap: var(--uui-size-space-4); + width: 100%; + } + uui-input { + width: 100%; + } + `, + ]; + + @state() + private _mediaTypeName?: string | null = ''; + #workspaceContext?: UmbWorkspaceMediaTypeContext; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbWorkspaceMediaTypeContext; + this.#observeName(); + }); + } + + #observeName() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.name, (name) => { + this._mediaTypeName = name; + }); + } + + // TODO. find a way where we don't have to do this for all Workspaces. + #handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + render() { + return html` + + `; + } +} + +export default UmbMediaTypeWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-type-workspace-edit': UmbMediaTypeWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.context.ts index 2e89adea0b..648c880015 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.context.ts @@ -1,20 +1,20 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; import { UmbMediaTypeRepository } from '../repository/media-type.repository'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ObjectState } from '@umbraco-cms/observable-api'; -import type { MediaTypeDetails } from '@umbraco-cms/models'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; +import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models'; type EntityType = MediaTypeDetails; export class UmbWorkspaceMediaTypeContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { #data = new ObjectState(undefined); data = this.#data.asObservable(); name = this.#data.getObservablePart((data) => data?.name); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbMediaTypeRepository(host)); } @@ -22,8 +22,8 @@ export class UmbWorkspaceMediaTypeContext return this.#data.getValue(); } - getEntityKey() { - return this.getData()?.key || ''; + getEntityId() { + return this.getData()?.id || ''; } getEntityType() { @@ -38,8 +38,8 @@ export class UmbWorkspaceMediaTypeContext // TODO => Implement setPropertyValue } - async load(entityKey: string) { - const { data } = await this.repository.requestDetails(entityKey); + async load(entityId: string) { + const { data } = await this.repository.requestDetails(entityId); if (data) { this.#data.next(data); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.element.ts index 10c235c581..a2f98ec9c6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media-types/workspace/media-type-workspace.element.ts @@ -1,19 +1,19 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; -import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; -import { UmbWorkspaceEntityElement } from '../../../../backoffice/shared/components/workspace/workspace-entity-element.interface'; +import { customElement, state } from 'lit/decorators.js'; import { UmbWorkspaceMediaTypeContext } from './media-type-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbMediaTypeWorkspaceEditElement } from './media-type-workspace-edit.element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; @customElement('umb-media-type-workspace') -export class UmbMediaTypeWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement { +export class UmbMediaTypeWorkspaceElement extends UmbLitElement { static styles = [ UUITextStyles, css` #header { display: flex; - padding: 0 var(--uui-size-space-6); + padding: 0 var(--uui-size-layout-1); gap: var(--uui-size-space-4); width: 100%; } @@ -23,49 +23,23 @@ export class UmbMediaTypeWorkspaceElement extends UmbLitElement implements UmbWo `, ]; - @state() - private _unique?: string; - - @state() - private _mediaTypeName?: string | null = ''; - - @property() - id!: string; - #workspaceContext = new UmbWorkspaceMediaTypeContext(this); + #element = new UmbMediaTypeWorkspaceEditElement(); - public load(entityKey: string) { - this.#workspaceContext.load(entityKey); - this._unique = entityKey; - } - - public create() { - this.#workspaceContext.createScaffold(); - } - - async connectedCallback() { - super.connectedCallback(); - - this.observe(this.#workspaceContext.name, (name) => { - this._mediaTypeName = name; - }); - } - - // TODO. find a way where we don't have to do this for all Workspaces. - #handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this.#workspaceContext.setName(target.value); - } - } - } + @state() + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - return html` - - `; + return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-test.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/collection-view-media-test.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-test.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/collection-view-media-test.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/manifests.ts similarity index 60% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/manifests.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/manifests.ts index 87f14782b3..f5170bc0c8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/manifests.ts @@ -1,33 +1,35 @@ -import type { ManifestCollectionView } from '@umbraco-cms/models'; +import type { ManifestCollectionView } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests: Array = [ { type: 'collectionView', - alias: 'Umb.CollectionView.Grid', - name: 'Grid', - elementName: 'umb-collection-view-media-grid', - loader: () => import('./collection-view-media-grid.element'), + alias: 'Umb.CollectionView.MediaGrid', + name: 'Media Grid Collection View', + loader: () => import('./media-grid-collection-view.element'), weight: 300, meta: { label: 'Grid', icon: 'umb:grid', - entityType: 'media', pathName: 'grid', }, + conditions: { + entityType: 'media', + }, }, { type: 'collectionView', - alias: 'Umb.CollectionView.Table', - name: 'Table', - elementName: 'umb-collection-view-media-table', - loader: () => import('./collection-view-media-table.element'), + alias: 'Umb.CollectionView.MediaTable', + name: 'Media Table Collection View', + loader: () => import('./media-table-collection-view.element'), weight: 200, meta: { label: 'Table', icon: 'umb:box', - entityType: 'media', pathName: 'table', }, + conditions: { + entityType: 'media', + }, }, { type: 'collectionView', @@ -39,8 +41,10 @@ export const manifests: Array = [ meta: { label: 'Test', icon: 'umb:newspaper', - entityType: 'media', pathName: 'test', }, + conditions: { + entityType: 'media', + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-grid.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/media-grid-collection-view.element.ts similarity index 77% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-grid.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/media-grid-collection-view.element.ts index 722d32d8fc..a34369425c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-grid.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/media-grid-collection-view.element.ts @@ -2,12 +2,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../collection.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { EntityTreeItemModel } from '@umbraco-cms/backend-api'; +import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../../../shared/collection/collection.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +// TODO: this should be a lib import -@customElement('umb-collection-view-media-grid') -export class UmbCollectionViewsMediaGridElement extends UmbLitElement { +@customElement('umb-media-grid-collection-view') +export class UmbMediaGridCollectionViewElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -65,12 +66,12 @@ export class UmbCollectionViewsMediaGridElement extends UmbLitElement { ]; @state() - private _mediaItems?: Array; + private _mediaItems?: Array; @state() private _selection: Array = []; - private _collectionContext?: UmbCollectionContext; + private _collectionContext?: UmbCollectionContext; constructor() { super(); @@ -115,31 +116,31 @@ export class UmbCollectionViewsMediaGridElement extends UmbLitElement { }); } - private _handleOpenItem(mediaItem: EntityTreeItemModel) { + private _handleOpenItem(mediaItem: EntityTreeItemResponseModel) { //TODO: Fix when we have dynamic routing - history.pushState(null, '', 'section/media/media/edit/' + mediaItem.key); + history.pushState(null, '', 'section/media/media/edit/' + mediaItem.id); } - private _handleSelect(mediaItem: EntityTreeItemModel) { - if (mediaItem.key) { - this._collectionContext?.select(mediaItem.key); + private _handleSelect(mediaItem: EntityTreeItemResponseModel) { + if (mediaItem.id) { + this._collectionContext?.select(mediaItem.id); } } - private _handleDeselect(mediaItem: EntityTreeItemModel) { - if (mediaItem.key) { - this._collectionContext?.deselect(mediaItem.key); + private _handleDeselect(mediaItem: EntityTreeItemResponseModel) { + if (mediaItem.id) { + this._collectionContext?.deselect(mediaItem.id); } } - private _isSelected(mediaItem: EntityTreeItemModel) { - if (mediaItem.key) { - return this._selection.includes(mediaItem.key); + private _isSelected(mediaItem: EntityTreeItemResponseModel) { + if (mediaItem.id) { + return this._selection.includes(mediaItem.id); } return false; } - private _renderMediaItem(item: EntityTreeItemModel) { + private _renderMediaItem(item: EntityTreeItemResponseModel) { const name = item.name || ''; //TODO: fix the file extension when media items have a file extension. return html` (file.key || '') + index, + (file, index) => (file.id || '') + index, (file) => this._renderMediaItem(file) ) : ''} @@ -175,8 +176,10 @@ export class UmbCollectionViewsMediaGridElement extends UmbLitElement { } } +export default UmbMediaGridCollectionViewElement; + declare global { interface HTMLElementTagNameMap { - 'umb-collection-view-media-grid': UmbCollectionViewsMediaGridElement; + 'umb-media-grid-collection-view': UmbMediaGridCollectionViewElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-table.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/media-table-collection-view.element.ts similarity index 84% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-table.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/media-table-collection-view.element.ts index 7b3d0be363..7e5a02a213 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/views/collection-view-media-table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/collection-view/media-table-collection-view.element.ts @@ -1,8 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../collection.context'; -import { +import type { UmbTableColumn, UmbTableConfig, UmbTableDeselectedEvent, @@ -10,13 +9,14 @@ import { UmbTableItem, UmbTableOrderedEvent, UmbTableSelectedEvent, -} from '../../components/table'; -import type { MediaDetails } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { EntityTreeItemModel } from '@umbraco-cms/backend-api'; +} from '../../../shared/components/table'; +import type { MediaDetails } from '../'; +import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../../../shared/collection/collection.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; -@customElement('umb-collection-view-media-table') -export class UmbCollectionViewMediaTableElement extends UmbLitElement { +@customElement('umb-media-table-collection-view') +export class UmbMediaTableCollectionViewElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -36,7 +36,7 @@ export class UmbCollectionViewMediaTableElement extends UmbLitElement { ]; @state() - private _mediaItems?: Array; + private _mediaItems?: Array; @state() private _tableConfig: UmbTableConfig = { @@ -85,7 +85,7 @@ export class UmbCollectionViewMediaTableElement extends UmbLitElement { // TODO: I guess the type error will go away when we get an entity based MediaDetails model instead of tree based. this._tableItems = mediaItems.map((item) => { return { - key: item.key, + id: item.id, icon: item.icon, data: [ { @@ -132,8 +132,10 @@ export class UmbCollectionViewMediaTableElement extends UmbLitElement { } } +export default UmbMediaTableCollectionViewElement; + declare global { interface HTMLElementTagNameMap { - 'umb-collection-view-media-table': UmbCollectionViewMediaTableElement; + 'umb-media-table-collection-view': UmbMediaTableCollectionViewElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/manifests.ts index e34ec47335..c8b4e44629 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-actions/manifests.ts @@ -1,6 +1,6 @@ import { MEDIA_REPOSITORY_ALIAS } from '../repository/manifests'; -import { UmbTrashEntityAction } from '@umbraco-cms/entity-action'; -import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models'; +import type { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbTrashEntityAction } from '@umbraco-cms/backoffice/entity-action'; const entityActions: Array = [ { @@ -8,12 +8,14 @@ const entityActions: Array = [ alias: 'Umb.EntityAction.Media.Trash', name: 'Trash Media Entity Action ', meta: { - entityType: 'media', icon: 'umb:trash', label: 'Trash', api: UmbTrashEntityAction, repositoryAlias: MEDIA_REPOSITORY_ALIAS, }, + conditions: { + entityType: 'media', + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/copy/copy.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/copy/copy.action.ts index 273334c4b7..72b49b7426 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/copy/copy.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/copy/copy.action.ts @@ -1,9 +1,9 @@ import type { UmbMediaRepository } from '../../repository/media.repository'; -import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbMediaCopyEntityBulkAction extends UmbEntityBulkActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/manifests.ts index 86b84b2856..1574cf57c3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/manifests.ts @@ -2,7 +2,7 @@ import { MEDIA_REPOSITORY_ALIAS } from '../repository/manifests'; import { UmbMediaMoveEntityBulkAction } from './move/move.action'; import { UmbMediaCopyEntityBulkAction } from './copy/copy.action'; import { UmbMediaTrashEntityBulkAction } from './trash/trash.action'; -import { ManifestEntityBulkAction } from '@umbraco-cms/extensions-registry'; +import { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extensions-registry'; const entityType = 'media'; @@ -13,11 +13,13 @@ const entityActions: Array = [ name: 'Move Media Entity Bulk Action', weight: 100, meta: { - entityType, label: 'Move', repositoryAlias: MEDIA_REPOSITORY_ALIAS, api: UmbMediaMoveEntityBulkAction, }, + conditions: { + entityType, + }, }, { type: 'entityBulkAction', @@ -25,11 +27,13 @@ const entityActions: Array = [ name: 'Copy Media Entity Bulk Action', weight: 90, meta: { - entityType, label: 'Copy', repositoryAlias: MEDIA_REPOSITORY_ALIAS, api: UmbMediaCopyEntityBulkAction, }, + conditions: { + entityType, + }, }, { type: 'entityBulkAction', @@ -37,11 +41,13 @@ const entityActions: Array = [ name: 'Trash Media Entity Bulk Action', weight: 80, meta: { - entityType, label: 'Trash', repositoryAlias: MEDIA_REPOSITORY_ALIAS, api: UmbMediaTrashEntityBulkAction, }, + conditions: { + entityType, + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts index 42f84f7b43..6f34b483ca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/entity-bulk-actions/move/move.action.ts @@ -1,14 +1,13 @@ import type { UmbMediaRepository } from '../../repository/media.repository'; -import { UMB_MEDIA_PICKER_MODAL_TOKEN } from '../../modals/media-picker'; -import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_MEDIA_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase { #modalContext?: UmbModalContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -18,7 +17,7 @@ export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase { #modalContext?: UmbModalContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -26,7 +25,7 @@ export class UmbMediaTrashEntityBulkAction extends UmbEntityBulkActionBase; + data: Array; + variants: Array; // TODO: define variant data + //layout?: any; // TODO: define layout type - make it non-optional +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts index 785dfaf736..cd5d6c0b79 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/manifests.ts @@ -1,3 +1,4 @@ +import { manifests as collectionViewManifests } from './collection-view/manifests'; import { manifests as repositoryManifests } from './repository/manifests'; import { manifests as menuItemManifests } from './menu-item/manifests'; import { manifests as treeManifests } from './tree/manifests'; @@ -7,6 +8,7 @@ import { manifests as entityBulkActionsManifests } from './entity-bulk-actions/m import { manifests as modalManifests } from './modals/manifests'; export const manifests = [ + ...collectionViewManifests, ...repositoryManifests, ...menuItemManifests, ...treeManifests, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/manifests.ts index e4287b17f3..fa30637221 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; const menuItem: ManifestMenuItem = { type: 'menuItem', @@ -9,6 +9,8 @@ const menuItem: ManifestMenuItem = { meta: { label: 'Media', icon: 'umb:folder', + }, + conditions: { menus: ['Umb.Menu.Media'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/media-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/media-menu-item.element.ts index 6bba1af067..6a4157ece4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/media-menu-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/menu-item/media-menu-item.element.ts @@ -1,6 +1,6 @@ import { html } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-media-menu-item') export class UmbMediaMenuItemElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/manifests.ts index a1230b8792..cced5231cb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/media-picker/media-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/media-picker/media-picker-modal.element.ts index 82fa6411f0..e141291a0b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/media-picker/media-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/modals/media-picker/media-picker-modal.element.ts @@ -2,8 +2,8 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { UmbTreeElement } from '../../../../shared/components/tree/tree.element'; -import { UmbMediaPickerModalData, UmbMediaPickerModalResult } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { UmbMediaPickerModalData, UmbMediaPickerModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; @customElement('umb-media-picker-modal') export class UmbMediaPickerModalElement extends UmbModalBaseElement< diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/manifests.ts index 0cbeb9aede..7ccfb8b76a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbMediaRepository } from './media.repository'; import { UmbMediaStore } from './media.store'; import { UmbMediaTreeStore } from './media.tree.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const MEDIA_REPOSITORY_ALIAS = 'Umb.Repository.Media'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts index 9adb982bff..28e2aed79d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.repository.ts @@ -1,28 +1,27 @@ +import type { MediaDetails } from '../'; import { MediaTreeServerDataSource } from './sources/media.tree.server.data'; import { UmbMediaTreeStore, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN } from './media.tree.store'; import { UmbMediaStore, UMB_MEDIA_STORE_CONTEXT_TOKEN } from './media.store'; import { UmbMediaDetailServerDataSource } from './sources/media.detail.server.data'; -import type { RepositoryTreeDataSource } from '@umbraco-cms/repository'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface'; -import { UmbDetailRepository } from '@umbraco-cms/repository'; -import type { MediaDetails } from '@umbraco-cms/models'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; +import type { UmbTreeRepository, UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { + CreateMediaRequestModel, + ProblemDetailsModel, + UpdateMediaRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; type ItemDetailType = MediaDetails; -// Move to documentation / JSdoc -/* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */ -// element -> context -> repository -> (store) -> data source -// All methods should be async and return a promise. Some methods might return an observable as part of the promise response. -export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepository { - #init!: Promise; +export class UmbMediaRepository + implements UmbTreeRepository, UmbDetailRepository +{ + #host: UmbControllerHostElement; - #host: UmbControllerHostInterface; - - #treeSource: RepositoryTreeDataSource; + #treeSource: UmbTreeDataSource; #treeStore?: UmbMediaTreeStore; #detailDataSource: UmbMediaDetailServerDataSource; @@ -30,26 +29,42 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + #initResolver?: () => void; + #initialized = false; + + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source this.#treeSource = new MediaTreeServerDataSource(this.#host); this.#detailDataSource = new UmbMediaDetailServerDataSource(this.#host); - this.#init = Promise.all([ - new UmbContextConsumerController(this.#host, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN, (instance) => { - this.#treeStore = instance; - }), + new UmbContextConsumerController(this.#host, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN, (instance) => { + this.#treeStore = instance; + this.#checkIfInitialized(); + }); - new UmbContextConsumerController(this.#host, UMB_MEDIA_STORE_CONTEXT_TOKEN, (instance) => { - this.#store = instance; - }), + new UmbContextConsumerController(this.#host, UMB_MEDIA_STORE_CONTEXT_TOKEN, (instance) => { + this.#store = instance; + this.#checkIfInitialized(); + }); - new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { - this.#notificationContext = instance; - }), - ]); + new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { + this.#notificationContext = instance; + this.#checkIfInitialized(); + }); + } + + // TODO: make a generic way to wait for initialization + #init = new Promise((resolve) => { + this.#initialized ? resolve() : (this.#initResolver = resolve); + }); + + #checkIfInitialized() { + if (this.#treeStore && this.#store && this.#notificationContext) { + this.#initialized = true; + this.#initResolver?.(); + } } async requestRootTreeItems() { @@ -64,34 +79,34 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getItems(keys); + const { data, error } = await this.#treeSource.getItems(ids); - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -99,38 +114,29 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS: - async createScaffold(parentKey: string | null) { + async createScaffold(parentId: string | null) { + if (!parentId) throw new Error('Parent id is missing'); await this.#init; - - if (!parentKey) { - throw new Error('Parent key is missing'); - } - - return this.#detailDataSource.createScaffold(parentKey); + return this.#detailDataSource.createScaffold(parentId); } - async requestByKey(key: string) { + async requestById(id: string) { + if (!id) throw new Error('Id is missing'); await this.#init; - // TODO: should we show a notification if the key is missing? - // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - const { data, error } = await this.#detailDataSource.get(key); + const { data, error } = await this.#detailDataSource.get(id); if (data) { this.#store?.append(data); @@ -141,62 +147,58 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor // Could potentially be general methods: - async create(template: ItemDetailType) { + async create(media: CreateMediaRequestModel) { + if (!media) throw new Error('Media is missing'); + await this.#init; - if (!template || !template.key) { - throw new Error('Template is missing'); - } - - const { error } = await this.#detailDataSource.insert(template); + const { error } = await this.#detailDataSource.insert(media); if (!error) { + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // TODO: Update tree store with the new item? or ask tree to request the new item? + //this.#store?.append(media); + const notification = { data: { message: `Media created` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - this.#store?.append(template); - // TODO: Update tree store with the new item? or ask tree to request the new item? - return { error }; } - async save(document: ItemDetailType) { + async save(id: string, updatedItem: UpdateMediaRequestModel) { + if (!id) throw new Error('Id is missing'); + if (!updatedItem) throw new Error('Updated media item is missing'); + await this.#init; - if (!document || !document.key) { - throw new Error('Template is missing'); - } - - const { error } = await this.#detailDataSource.update(document); + const { error } = await this.#detailDataSource.update(id, updatedItem); if (!error) { - const notification = { data: { message: `Document saved` } }; + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a template is updated in the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + // this.#store?.append(updatedMediaItem); + // this.#treeStore?.updateItem(id, updatedItem); + + const notification = { data: { message: `Media saved` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - // Consider notify a workspace if a template is updated in the store while someone is editing it. - this.#store?.append(document); - this.#treeStore?.updateItem(document.key, { name: document.name }); - - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } // General: - async delete(key: string) { + async delete(id: string) { await this.#init; - if (!key) { - throw new Error('Document key is missing'); + if (!id) { + throw new Error('Document id is missing'); } - const { error } = await this.#detailDataSource.delete(key); + const { error } = await this.#detailDataSource.delete(id); if (!error) { const notification = { data: { message: `Document deleted` } }; @@ -206,23 +208,23 @@ export class UmbMediaRepository implements UmbTreeRepository, UmbDetailRepositor // TODO: we currently don't use the detail store for anything. // Consider to look up the data before fetching from the server. // Consider notify a workspace if a template is deleted from the store while someone is editing it. - this.#store?.remove([key]); - this.#treeStore?.removeItem(key); + this.#store?.remove([id]); + this.#treeStore?.removeItem(id); // TODO: would be nice to align the stores on methods/methodNames. return { error }; } - async trash(keys: Array) { - console.log('media trash: ' + keys); + async trash(ids: Array) { + console.log('media trash: ' + ids); alert('implement trash'); } - async move(keys: Array, destination: string) { + async move(ids: Array, destination: string) { // TODO: use backend cli when available. const res = await fetch('/umbraco/management/api/v1/media/move', { method: 'POST', - body: JSON.stringify({ keys, destination }), + body: JSON.stringify({ ids, destination }), headers: { 'Content-Type': 'application/json', }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.store.ts index 070a596885..ddc1a8b5fc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.store.ts @@ -1,8 +1,8 @@ -import type { MediaDetails } from '@umbraco-cms/models'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import type { MediaDetails } from '../'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export @@ -11,14 +11,14 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller'; * @description - Data Store for Template Details */ export class UmbMediaStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); /** * Creates an instance of UmbMediaStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbMediaStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEDIA_STORE_CONTEXT_TOKEN.toString()); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts index a070665602..9c63d9c946 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/media.tree.store.ts @@ -1,26 +1,26 @@ -import { EntityTreeItemModel } from '@umbraco-cms/backend-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export const UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbMediaTreeStore'); /** * @export * @class UmbMediaTreeStore - * @extends {UmbTreeStoreBase} + * @extends {UmbEntityTreeStore} * @description - Tree Data Store for Media */ -export class UmbMediaTreeStore extends UmbTreeStoreBase { - #data = new ArrayState([], (x) => x.key); +export class UmbMediaTreeStore extends UmbEntityTreeStore { + #data = new ArrayState([], (x) => x.id); /** * Creates an instance of UmbMediaTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbMediaTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.detail.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.detail.server.data.ts index 2cbbe19cc0..797329b01a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.detail.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.detail.server.data.ts @@ -1,8 +1,12 @@ -import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import type { MediaDetails } from '@umbraco-cms/models'; +import type { MediaDetails } from '../../'; +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; +import { + CreateMediaRequestModel, + ProblemDetailsModel, + UpdateMediaRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Template detail that fetches data from the server @@ -10,26 +14,28 @@ import type { MediaDetails } from '@umbraco-cms/models'; * @class UmbTemplateDetailServerDataSource * @implements {TemplateDetailDataSource} */ -export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSource { - #host: UmbControllerHostInterface; +export class UmbMediaDetailServerDataSource + implements UmbDataSource +{ + #host: UmbControllerHostElement; /** * Creates an instance of UmbMediaDetailServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbMediaDetailServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** - * Fetches a Media with the given key from the server - * @param {string} key + * Fetches a Media with the given id from the server + * @param {string} id * @return {*} * @memberof UmbMediaDetailServerDataSource */ - async get(key: string) { - if (!key) { + async get(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } @@ -37,7 +43,7 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc return tryExecuteAndNotify( this.#host, // TODO: use backend cli when available. - fetch(`/umbraco/management/api/v1/media/details/${key}`) + fetch(`/umbraco/management/api/v1/media/details/${id}`) .then((res) => res.json()) .then((res) => res[0] || undefined) ); @@ -45,39 +51,20 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc /** * Creates a new Media scaffold - * @param {(string | null)} parentKey + * @param {(string | null)} parentId * @return {*} * @memberof UmbMediaDetailServerDataSource */ - async createScaffold(parentKey: string | null) { - const data: MediaDetails = { - $type: '', - key: '', + async createScaffold(parentId: string | null) { + const data = { + id: '', name: '', icon: '', - type: '', - hasChildren: false, - parentKey: parentKey ?? '', - isTrashed: false, - properties: [ - { - alias: '', - label: '', - description: '', - dataTypeKey: '', - }, - ], - data: [ - { - alias: '', - value: '', - }, - ], - variants: [ - { - name: '', - }, - ], + parentId, + contentTypeId: '', + properties: [], + data: [], + variants: [], }; return { data }; @@ -89,12 +76,8 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc * @return {*} * @memberof UmbMediaDetailServerDataSource */ - async insert(media: MediaDetails) { - if (!media.key) { - //const error: ProblemDetails = { title: 'Media key is missing' }; - return Promise.reject(); - } - //const payload = { key: media.key, requestBody: media }; + async insert(media: CreateMediaRequestModel) { + if (!media) throw new Error('Media is missing'); let body: string; @@ -124,12 +107,9 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc * @memberof UmbMediaDetailServerDataSource */ // TODO: Error mistake in this: - async update(media: MediaDetails) { - if (!media.key) { - const error: ProblemDetailsModel = { title: 'Media key is missing' }; - return { error }; - } - //const payload = { key: media.key, requestBody: media }; + async update(id: string, media: UpdateMediaRequestModel) { + if (!id) throw new Error('Key is missing'); + if (!media) throw new Error('Media is missing'); let body: string; @@ -158,8 +138,8 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc * @return {*} * @memberof UmbMediaDetailServerDataSource */ - async trash(key: string) { - if (!key) { + async trash(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } @@ -168,7 +148,7 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc this.#host, fetch('/umbraco/management/api/v1/media/trash', { method: 'POST', - body: JSON.stringify([key]), + body: JSON.stringify([id]), headers: { 'Content-Type': 'application/json', }, @@ -178,12 +158,12 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc /** * Deletes a Template on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbTemplateDetailServerDataSource */ - async delete(key: string) { - if (!key) { + async delete(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } @@ -193,7 +173,7 @@ export class UmbMediaDetailServerDataSource implements RepositoryDetailDataSourc try { await fetch('/umbraco/management/api/v1/media/delete', { method: 'POST', - body: JSON.stringify([key]), + body: JSON.stringify([id]), headers: { 'Content-Type': 'application/json', }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.tree.server.data.ts index 3ea980f8f5..096d2b2814 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/repository/sources/media.tree.server.data.ts @@ -1,7 +1,7 @@ -import type { RepositoryTreeDataSource } from '../../../../../../libs/repository/repository-tree-data-source.interface'; -import { ProblemDetailsModel, MediaResource } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { ProblemDetailsModel, MediaResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Media tree that fetches data from the server @@ -9,17 +9,17 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class MediaTreeServerDataSource * @implements {MediaTreeDataSource} */ -export class MediaTreeServerDataSource implements RepositoryTreeDataSource { - #host: UmbControllerHostInterface; +export class MediaTreeServerDataSource implements UmbTreeDataSource { + #host: UmbControllerHostElement; // TODO: how do we handle trashed items? - async trashItems(keys: Array) { + async trashItems(ids: Array) { // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/media/trash', { method: 'POST', - body: JSON.stringify(keys), + body: JSON.stringify(ids), headers: { 'Content-Type': 'application/json', }, @@ -27,13 +27,13 @@ export class MediaTreeServerDataSource implements RepositoryTreeDataSource { ); } - async moveItems(keys: Array, destination: string) { + async moveItems(ids: Array, destination: string) { // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, fetch('/umbraco/management/api/v1/media/move', { method: 'POST', - body: JSON.stringify({ keys, destination }), + body: JSON.stringify({ ids, destination }), headers: { 'Content-Type': 'application/json', }, @@ -43,10 +43,10 @@ export class MediaTreeServerDataSource implements RepositoryTreeDataSource { /** * Creates an instance of MediaTreeServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof MediaTreeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -60,33 +60,33 @@ export class MediaTreeServerDataSource implements RepositoryTreeDataSource { } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} * @memberof MediaTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + async getChildrenOf(parentId: string | null) { + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, MediaResource.getTreeMediaChildren({ - parentKey, + parentId, }) ); } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} * @memberof MediaTreeServerDataSource */ - async getItems(keys: Array) { - if (!keys) { + async getItems(ids: Array) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { error }; } @@ -94,7 +94,7 @@ export class MediaTreeServerDataSource implements RepositoryTreeDataSource { return tryExecuteAndNotify( this.#host, MediaResource.getTreeMediaItem({ - key: keys, + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/tree/manifests.ts index 0e60c1d4af..b66042c3ba 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/tree/manifests.ts @@ -1,5 +1,5 @@ -import { UmbMediaRepository } from '../repository/media.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { MEDIA_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const treeAlias = 'Umb.Tree.Media'; @@ -8,8 +8,18 @@ const tree: ManifestTree = { alias: treeAlias, name: 'Media Tree', meta: { - repository: UmbMediaRepository, // TODO: use alias instead of class + repositoryAlias: MEDIA_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.Media', + name: 'Media Tree Item', + conditions: { + entityType: 'media', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/manifests.ts index 3c363283c7..7dbf6b198f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/manifests.ts @@ -1,11 +1,11 @@ import { MEDIA_REPOSITORY_ALIAS } from '../repository/manifests'; -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView, ManifestWorkspaceViewCollection, -} from '@umbraco-cms/models'; +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', @@ -22,29 +22,31 @@ const workspaceViews: Array = [ type: 'workspaceView', alias: 'Umb.WorkspaceView.Media.Edit', name: 'Media Workspace Edit View', - loader: () => - import('../../../shared/components/workspace/workspace-content/views/edit/workspace-view-content-edit.element'), + loader: () => import('./views/edit/media-edit-workspace-view.element'), weight: 200, meta: { - workspaces: ['Umb.Workspace.Media'], label: 'Media', pathname: 'media', icon: 'umb:picture', }, + conditions: { + workspaces: ['Umb.Workspace.Media'], + }, }, { type: 'workspaceView', alias: 'Umb.WorkspaceView.Media.Info', name: 'Media Workspace Info View', - loader: () => - import('../../../shared/components/workspace/workspace-content/views/info/workspace-view-content-info.element'), + loader: () => import('./views/info/media-info-workspace-view.element'), weight: 100, meta: { - workspaces: ['Umb.Workspace.Media'], label: 'Info', pathname: 'info', icon: 'info', }, + conditions: { + workspaces: ['Umb.Workspace.Media'], + }, }, ]; @@ -55,13 +57,15 @@ const workspaceViewCollections: Array = [ name: 'Media Workspace Collection View', weight: 300, meta: { - workspaces: ['Umb.Workspace.Media'], label: 'Media', pathname: 'collection', icon: 'umb:grid', entityType: 'media', repositoryAlias: MEDIA_REPOSITORY_ALIAS, }, + conditions: { + workspaces: ['Umb.Workspace.Media'], + }, }, ]; @@ -71,12 +75,14 @@ const workspaceActions: Array = [ alias: 'Umb.WorkspaceAction.Media.Save', name: 'Save Media Workspace Action', meta: { - workspaces: ['Umb.Workspace.Media'], label: 'Save', look: 'primary', color: 'positive', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Media'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace-edit.element.ts new file mode 100644 index 0000000000..81224bde73 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace-edit.element.ts @@ -0,0 +1,67 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html, nothing } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbMediaWorkspaceContext } from './media-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-media-workspace-edit') +export class UmbMediaWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + + #header { + margin: 0 var(--uui-size-layout-1); + flex: 1 1 auto; + } + + #footer { + margin: 0 var(--uui-size-layout-1); + } + `, + ]; + + @state() + _id?: string; + + #umbWorkspaceContext?: UmbMediaWorkspaceContext; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#umbWorkspaceContext = instance as UmbMediaWorkspaceContext; + this.#observeId(); + }); + } + + #observeId() { + if (!this.#umbWorkspaceContext) return; + this.observe(this.#umbWorkspaceContext.data, (data) => (this._id = data?.id)); + } + + render() { + if (!this._id) return nothing; + return html` + + + `; + } +} + +export default UmbMediaWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-workspace-edit': UmbMediaWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.context.ts index 89847721d6..751b587560 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.context.ts @@ -1,20 +1,20 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; import { UmbMediaRepository } from '../repository/media.repository'; -import type { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; -import { appendToFrozenArray, ObjectState } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import type { MediaDetails } from '@umbraco-cms/models'; +import type { MediaDetails } from '../'; +import type { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import { appendToFrozenArray, ObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; type EntityType = MediaDetails; export class UmbMediaWorkspaceContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { #data = new ObjectState(undefined); data = this.#data.asObservable(); name = this.#data.getObservablePart((data) => data?.name); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbMediaRepository(host)); } @@ -22,8 +22,9 @@ export class UmbMediaWorkspaceContext return this.#data.getValue(); } - getEntityKey() { - return this.getData()?.key || ''; + // TODO: this should be async because it can only return the id if the data is loaded. + getEntityId() { + return this.getData()?.id || ''; } getEntityType() { @@ -45,19 +46,21 @@ export class UmbMediaWorkspaceContext } } - async load(entityKey: string) { - const { data } = await this.repository.requestByKey(entityKey); + async load(entityId: string) { + const { data } = await this.repository.requestById(entityId); if (data) { this.setIsNew(false); this.#data.next(data); } } - async createScaffold(parentKey: string | null) { - const { data } = await this.repository.createScaffold(parentKey); + async createScaffold(parentId: string | null) { + const { data } = await this.repository.createScaffold(parentId); if (!data) return; this.setIsNew(true); - this.#data.next(data); + // TODO: This is a hack to get around the fact that the data is not typed correctly. + // Create and response models are different. We need to look into this. + this.#data.next(data as unknown as MediaDetails); } async save() { @@ -65,14 +68,14 @@ export class UmbMediaWorkspaceContext if (this.isNew) { await this.repository.create(this.#data.value); } else { - await this.repository.save(this.#data.value); + await this.repository.save(this.#data.value.id, this.#data.value); } // If it went well, then its not new anymore?. this.setIsNew(false); } - async delete(key: string) { - await this.repository.delete(key); + async delete(id: string) { + await this.repository.delete(id); } public destroy(): void { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.element.ts index 3b0a59f0d5..aab70442d0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.element.ts @@ -1,12 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, nothing } from 'lit'; +import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import type { UmbWorkspaceEntityElement } from '../../../shared/components/workspace/workspace-entity-element.interface'; import { UmbMediaWorkspaceContext } from './media-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbMediaWorkspaceEditElement } from './media-workspace-edit.element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-media-workspace') -export class UmbMediaWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement { +export class UmbMediaWorkspaceElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -18,31 +19,23 @@ export class UmbMediaWorkspaceElement extends UmbLitElement implements UmbWorksp `, ]; - private _workspaceContext: UmbMediaWorkspaceContext = new UmbMediaWorkspaceContext(this); + #workspaceContext = new UmbMediaWorkspaceContext(this); + #element = new UmbMediaWorkspaceEditElement(); @state() - _unique?: string; - - public load(entityKey: string) { - this._workspaceContext.load(entityKey); - this._unique = entityKey; - } - - public create(parentKey: string | null) { - this._workspaceContext.createScaffold(parentKey); - } + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - return html` - ${this._unique - ? html` - - ` - : nothing} - `; + return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.stories.ts index 019047dc04..162440cfe3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/media-workspace.stories.ts @@ -1,6 +1,7 @@ import './media-workspace.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { data as mediaNodes } from '../../../../core/mocks/data/media.data'; import type { UmbMediaWorkspaceElement } from './media-workspace.element'; @@ -11,5 +12,5 @@ export default { } as Meta; export const AAAOverview: Story = () => - html` `; + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/edit/media-edit-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/edit/media-edit-workspace-view.element.ts new file mode 100644 index 0000000000..3c0bd2eb8c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/edit/media-edit-workspace-view.element.ts @@ -0,0 +1,21 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-media-edit-workspace-view') +export class UmbMediaEditWorkspaceViewElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + render() { + return html`
Render Media Props
`; + } +} + +export default UmbMediaEditWorkspaceViewElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-edit-workspace-view': UmbMediaEditWorkspaceViewElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/edit/media-edit-workspace-view.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/edit/media-edit-workspace-view.stories.ts new file mode 100644 index 0000000000..b0e7827cae --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/edit/media-edit-workspace-view.stories.ts @@ -0,0 +1,27 @@ +import './media-edit-workspace-view.element'; + +import { Meta, Story } from '@storybook/web-components'; +import { html } from 'lit'; + +// import { data } from '../../../../../../core/mocks/data/media.data'; +// import { UmbNodeContext } from '../../node.context'; + +import type { UmbMediaEditWorkspaceViewElement } from './media-edit-workspace-view.element'; + +export default { + title: 'Workspaces/Media/Views/Edit', + component: 'umb-media-edit-workspace-view', + id: 'umb-media-edit-workspace-view', + decorators: [ + (story) => { + return html`TODO: make use of mocked workspace context??`; + /*html` + ${story()} + `,*/ + }, + ], +} as Meta; + +export const AAAOverview: Story = () => + html` `; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/info/media-info-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/info/media-info-workspace-view.element.ts new file mode 100644 index 0000000000..a6e840c2c7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/info/media-info-workspace-view.element.ts @@ -0,0 +1,21 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-media-info-workspace-view') +export class UmbMediaInfoWorkspaceViewElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + render() { + return html`
Media info
`; + } +} + +export default UmbMediaInfoWorkspaceViewElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-info-workspace-view': UmbMediaInfoWorkspaceViewElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/info/media-info-workspace-view.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/info/media-info-workspace-view.stories.ts new file mode 100644 index 0000000000..b05665cbb3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/media/workspace/views/info/media-info-workspace-view.stories.ts @@ -0,0 +1,27 @@ +import './media-info-workspace-view.element'; + +import { Meta, Story } from '@storybook/web-components'; +import { html } from 'lit'; + +// import { data } from '../../../../../../core/mocks/data/media.data'; +// import { UmbNodeContext } from '../../node.context'; + +import type { UmbMediaInfoWorkspaceViewElement } from './media-info-workspace-view.element'; + +export default { + title: 'Workspaces/Media/Views/Info', + component: 'umb-media-info-workspace-view', + id: 'umb-media-info-workspace-view', + decorators: [ + (story) => { + return html`TODO: make use of mocked workspace context??`; + /*html` + ${story()} + `,*/ + }, + ], +} as Meta; + +export const AAAOverview: Story = () => + html` `; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/menu.manifests.ts index 48f15abb44..46ae89c9d2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/menu.manifests.ts @@ -1,4 +1,4 @@ -import { ManifestMenu } from '@umbraco-cms/extensions-registry'; +import { ManifestMenu } from '@umbraco-cms/backoffice/extensions-registry'; const menu: ManifestMenu = { type: 'menu', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/media/section.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/media/section.manifests.ts index 9ba71485a5..425af38e6d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/media/section.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/media/section.manifests.ts @@ -1,5 +1,9 @@ import { MEDIA_REPOSITORY_ALIAS } from './media/repository/manifests'; -import type { ManifestDashboardCollection, ManifestSection, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models'; +import type { + ManifestDashboardCollection, + ManifestSection, + ManifestTypes, +} from '@umbraco-cms/backoffice/extensions-registry'; const sectionAlias = 'Umb.Section.Media'; @@ -22,24 +26,29 @@ const dashboards: Array = [ weight: 10, meta: { label: 'Media', - sections: [sectionAlias], pathname: 'media-management', - entityType: 'media', repositoryAlias: MEDIA_REPOSITORY_ALIAS, }, + conditions: { + sections: [sectionAlias], + entityType: 'media', + }, }, ]; -const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = { - type: 'menuSectionSidebarApp', +const menuSectionSidebarApp: ManifestTypes = { + type: 'sectionSidebarApp', + kind: 'menu', alias: 'Umb.SectionSidebarMenu.Media', name: 'Media Section Sidebar Menu', weight: 100, meta: { label: 'Media', - sections: [sectionAlias], menu: 'Umb.Menu.Media', }, + conditions: { + sections: [sectionAlias], + }, }; export const manifests = [section, menuSectionSidebarApp, ...dashboards]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.element.ts index dc86656085..3b2acc07eb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.element.ts @@ -4,7 +4,15 @@ import { customElement } from 'lit/decorators.js'; @customElement('umb-dashboard-members-welcome') export class UmbDashboardMembersWelcomeElement extends LitElement { - static styles = [UUITextStyles, css``]; + static styles = [ + UUITextStyles, + css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + `, + ]; render() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.stories.ts index ab8c3929e2..0f85b67184 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/dashboards/welcome/dashboard-members-welcome.stories.ts @@ -1,7 +1,7 @@ import './dashboard-members-welcome.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardMembersWelcomeElement } from './dashboard-members-welcome.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/index.ts index 386a38582f..ec7c105679 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/index.ts @@ -4,8 +4,8 @@ import { manifests as memberGroupManifests } from './member-groups/manifests'; import { manifests as memberTypeManifests } from './member-types/manifests'; import { manifests as memberManifests } from './members/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [ ...memberSectionManifests, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/entity-actions/manifests.ts index e132cc6f8f..90bd62d4f2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/entity-actions/manifests.ts @@ -1,6 +1,6 @@ import { MEMBER_GROUP_REPOSITORY_ALIAS } from '../repository/manifests'; -import { UmbDeleteEntityAction } from '@umbraco-cms/entity-action'; -import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models'; +import type { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbDeleteEntityAction } from '@umbraco-cms/backoffice/entity-action'; const entityActions: Array = [ { @@ -8,12 +8,14 @@ const entityActions: Array = [ alias: 'Umb.EntityAction.MemberGroup.Delete', name: 'Delete Member Group Entity Action ', meta: { - entityType: 'member-group', icon: 'umb:trash', label: 'Delete', api: UmbDeleteEntityAction, repositoryAlias: MEMBER_GROUP_REPOSITORY_ALIAS, }, + conditions: { + entityType: 'member-group', + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/menu-item/manifests.ts index cccc4c0247..d9c2d2b8a1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/menu-item/manifests.ts @@ -1,14 +1,17 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const menuItem: ManifestMenuItem = { +const menuItem: ManifestTypes = { type: 'menuItem', + kind: 'tree', alias: 'Umb.MenuItem.MemberGroups', name: 'Member Groups Menu Item', weight: 800, - loader: () => import('./member-groups-menu-item.element'), meta: { label: 'Member Groups', icon: 'umb:folder', + treeAlias: 'Umb.Tree.MemberGroups', + }, + conditions: { menus: ['Umb.Menu.Members'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/menu-item/member-groups-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/menu-item/member-groups-menu-item.element.ts deleted file mode 100644 index aaa72bd20a..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/menu-item/member-groups-menu-item.element.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-member-groups-menu-item') -export class UmbMemberGroupsMenuItemElement extends UmbLitElement { - @state() - private _renderTree = false; - - private _onShowChildren() { - this._renderTree = true; - } - - private _onHideChildren() { - this._renderTree = false; - } - - // TODO: check if root has children before settings the has-children attribute - // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? - // TODO: can we make this reusable? - render() { - return html` - ${this._renderTree ? html`` : nothing} - `; - } -} - -export default UmbMemberGroupsMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-member-groups-menu-item': UmbMemberGroupsMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/manifests.ts index c4fb973526..038a11fe8e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbMemberGroupRepository } from './member-group.repository'; import { UmbMemberGroupStore } from './member-group.store'; import { UmbMemberGroupTreeStore } from './member-group.tree.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const MEMBER_GROUP_REPOSITORY_ALIAS = 'Umb.Repository.MemberGroup'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts index 0c0f315b71..572e6d7fd0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.repository.ts @@ -2,20 +2,20 @@ import { UmbMemberGroupTreeStore, UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN } fr import { UmbMemberGroupDetailServerDataSource } from './sources/member-group.detail.server.data'; import { UmbMemberGroupStore, UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN } from './member-group.store'; import { MemberGroupTreeServerDataSource } from './sources/member-group.tree.server.data'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import type { MemberGroupDetails } from '@umbraco-cms/models'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import type { RepositoryTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; // TODO => Update type when backend updated -export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRepository { +export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRepository { #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - #treeSource: RepositoryTreeDataSource; + #treeSource: UmbTreeDataSource; #treeStore?: UmbMemberGroupTreeStore; #detailSource: UmbMemberGroupDetailServerDataSource; @@ -23,7 +23,7 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source this.#treeSource = new MemberGroupTreeServerDataSource(this.#host); @@ -54,20 +54,20 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep return { data, error }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { const error: ProblemDetailsModel = { title: 'Not implemented' }; return { data: undefined, error }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; + if (!ids) { + const error: ProblemDetailsModel = { title: 'Ids are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getItems(keys); + const { data, error } = await this.#treeSource.getItems(ids); return { data, error }; } @@ -77,14 +77,14 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAIL @@ -94,16 +94,16 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep return this.#detailSource.createScaffold(); } - async requestByKey(key: string) { + async requestById(id: string) { await this.#init; - // TODO: should we show a notification if the key is missing? + // TODO: should we show a notification if the id is missing? // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; + if (!id) { + const error: ProblemDetailsModel = { title: 'Id is missing' }; return { error }; } - const { data, error } = await this.#detailSource.get(key); + const { data, error } = await this.#detailSource.get(id); if (data) { this.#store?.append(data); @@ -129,49 +129,44 @@ export class UmbMemberGroupRepository implements UmbTreeRepository, UmbDetailRep return { data, error }; } - async save(memberGroup: MemberGroupDetails) { + async save(id: string, memberGroup: MemberGroupDetails) { + if (!id) throw new Error('Id is missing'); + if (!memberGroup) throw new Error('Member group is missing'); + await this.#init; - if (!memberGroup || !memberGroup.name) { - const error: ProblemDetailsModel = { title: 'Member group is missing' }; - return { error }; - } - - const { error } = await this.#detailSource.update(memberGroup); + const { error } = await this.#detailSource.update(id, memberGroup); if (!error) { + this.#store?.append(memberGroup); + this.#treeStore?.updateItem(memberGroup.id, memberGroup); + const notification = { data: { message: `Member group '${memberGroup.name} saved` } }; this.#notificationContext?.peek('positive', notification); } - this.#store?.append(memberGroup); - this.#treeStore?.updateItem(memberGroup.key, { name: memberGroup.name }); - return { error }; } - async delete(key: string) { + async delete(id: string) { + if (!id) throw new Error('Id is missing'); + await this.#init; - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - - const { error } = await this.#detailSource.delete(key); + const { error } = await this.#detailSource.delete(id); if (!error) { + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server. + // Consider notify a workspace if a template is deleted from the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + this.#store?.remove([id]); + this.#treeStore?.removeItem(id); + const notification = { data: { message: `Document deleted` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server. - // Consider notify a workspace if a template is deleted from the store while someone is editing it. - this.#store?.remove([key]); - this.#treeStore?.removeItem(key); - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.store.ts index 864430facf..38fd8ede11 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.store.ts @@ -1,8 +1,8 @@ -import type { MemberGroupDetails } from '@umbraco-cms/models'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbStoreBase } from '@umbraco-cms/store'; +import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; /** * @export @@ -11,9 +11,9 @@ import { UmbStoreBase } from '@umbraco-cms/store'; * @description - Data Store for Member Groups */ export class UmbMemberGroupStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEMBER_GROUP_STORE_CONTEXT_TOKEN.toString()); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts index 4d1f4ce44a..5247506b6c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/member-group.tree.store.ts @@ -1,20 +1,20 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export * @class UmbMemberGroupTreeStore - * @extends {UmbTreeStoreBase} + * @extends {UmbEntityTreeStore} * @description - Tree Data Store for Member Groups */ -export class UmbMemberGroupTreeStore extends UmbTreeStoreBase { +export class UmbMemberGroupTreeStore extends UmbEntityTreeStore { /** * Creates an instance of UmbMemberGroupTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbMemberGroupTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEMBER_GROUP_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.detail.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.detail.server.data.ts index 354888fb1a..11503e3873 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.detail.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.detail.server.data.ts @@ -1,8 +1,8 @@ -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import type { MemberGroupDetails } from '@umbraco-cms/models'; -import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; /** * @description - A data source for the MemberGroup detail that fetches data from the server @@ -11,10 +11,10 @@ import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; * @implements {MemberGroupDetailDataSource} */ // TODO => Provide type when it is available -export class UmbMemberGroupDetailServerDataSource implements RepositoryDetailDataSource { - #host: UmbControllerHostInterface; +export class UmbMemberGroupDetailServerDataSource implements UmbDataSource { + #host: UmbControllerHostElement; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -32,15 +32,15 @@ export class UmbMemberGroupDetailServerDataSource implements RepositoryDetailDat } /** - * @description - Fetches a MemberGroup with the given key from the server - * @param {string} key + * @description - Fetches a MemberGroup with the given id from the server + * @param {string} id * @return {*} * @memberof UmbMemberGroupDetailServerDataSource */ - get(key: string) { - //return tryExecuteAndNotify(this.#host, MemberGroupResource.getMemberGroup({ key })) as any; + get(id: string) { + //return tryExecuteAndNotify(this.#host, MemberGroupResource.getMemberGroup({ id })) as any; // TODO: use backend cli when available. - return tryExecuteAndNotify(this.#host, fetch(`/umbraco/management/api/v1/member-group/${key}`)) as any; + return tryExecuteAndNotify(this.#host, fetch(`/umbraco/management/api/v1/member-group/${id}`)) as any; } /** @@ -49,18 +49,18 @@ export class UmbMemberGroupDetailServerDataSource implements RepositoryDetailDat * @return {*} * @memberof UmbMemberGroupDetailServerDataSource */ - async update(memberGroup: MemberGroupDetails) { - if (!memberGroup.key) { - const error: ProblemDetailsModel = { title: 'Member Group key is missing' }; + async update(id: string, memberGroup: MemberGroupDetails) { + if (!memberGroup.id) { + const error: ProblemDetailsModel = { title: 'Member Group id is missing' }; return { error }; } - const payload = { key: memberGroup.key, requestBody: memberGroup }; + const payload = { id: memberGroup.id, requestBody: memberGroup }; //return tryExecuteAndNotify(this.#host, MemberGroupResource.putMemberGroupByKey(payload)); // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, - fetch(`/umbraco/management/api/v1/member-group/${memberGroup.key}`, { + fetch(`/umbraco/management/api/v1/member-group/${memberGroup.id}`, { method: 'PUT', body: JSON.stringify(payload), headers: { @@ -97,31 +97,31 @@ export class UmbMemberGroupDetailServerDataSource implements RepositoryDetailDat /** * @description - Deletes a MemberGroup on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbMemberGroupDetailServerDataSource */ - async trash(key: string) { - return this.delete(key); + async trash(id: string) { + return this.delete(id); } /** * @description - Deletes a MemberGroup on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbMemberGroupDetailServerDataSource */ - async delete(key: string) { - if (!key) { + async delete(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - //return await tryExecuteAndNotify(this.#host, MemberGroupResource.deleteMemberGroupByKey({ key })); + //return await tryExecuteAndNotify(this.#host, MemberGroupResource.deleteMemberGroupByKey({ id })); // TODO: use backend cli when available. return tryExecuteAndNotify( this.#host, - fetch(`/umbraco/management/api/v1/member-group/${key}`, { + fetch(`/umbraco/management/api/v1/member-group/${id}`, { method: 'DELETE', }) ) as any; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.tree.server.data.ts index c0e3cce038..bfb95a7473 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/repository/sources/member-group.tree.server.data.ts @@ -1,7 +1,7 @@ -import { MemberGroupResource, ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { RepositoryTreeDataSource } from '@umbraco-cms/repository'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { MemberGroupResource, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Member Group tree that fetches data from the server @@ -9,55 +9,55 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class MemberGroupTreeServerDataSource * @implements {MemberGroupTreeDataSource} */ -export class MemberGroupTreeServerDataSource implements RepositoryTreeDataSource { - #host: UmbControllerHostInterface; +export class MemberGroupTreeServerDataSource implements UmbTreeDataSource { + #host: UmbControllerHostElement; /** * Creates an instance of MemberGroupTreeServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof MemberGroupTreeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** - * Fetches the root items for the tree from the server - * @return {*} - * @memberof MemberGroupTreeServerDataSource - */ - async getRootItems() { - return tryExecuteAndNotify(this.#host, MemberGroupResource.getTreeMemberGroupRoot({})); - } + * Fetches the root items for the tree from the server + * @return {*} + * @memberof MemberGroupTreeServerDataSource + */ + async getRootItems() { + return tryExecuteAndNotify(this.#host, MemberGroupResource.getTreeMemberGroupRoot({})); + } - /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey - * @return {*} - * @memberof MemberGroupTreeServerDataSource - */ - async getChildrenOf(parentKey: string | null) { - // Not implemented for this tree - return {}; - } + /** + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId + * @return {*} + * @memberof MemberGroupTreeServerDataSource + */ + async getChildrenOf(parentId: string | null) { + // Not implemented for this tree + return {}; + } - /** - * Fetches the items for the given keys from the server - * @param {Array} keys - * @return {*} - * @memberof MemberGroupTreeServerDataSource - */ - async getItems(keys: Array) { - if (!keys || keys.length === 0) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; - return { error }; - } + /** + * Fetches the items for the given ids from the server + * @param {Array} ids + * @return {*} + * @memberof MemberGroupTreeServerDataSource + */ + async getItems(ids: Array) { + if (!ids || ids.length === 0) { + const error: ProblemDetailsModel = { title: 'Keys are missing' }; + return { error }; + } - return tryExecuteAndNotify( - this.#host, - MemberGroupResource.getTreeMemberGroupItem({ - key: keys, - }) - ); - } + return tryExecuteAndNotify( + this.#host, + MemberGroupResource.getMemberGroupItem({ + id: ids, + }) + ); + } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/tree/manifests.ts index 32cdd97328..5d379a3782 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/tree/manifests.ts @@ -1,5 +1,5 @@ -import { UmbMemberGroupRepository } from '../repository/member-group.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { MEMBER_GROUP_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const treeAlias = 'Umb.Tree.MemberGroups'; @@ -9,8 +9,18 @@ const tree: ManifestTree = { name: 'Member Groups Tree', weight: 100, meta: { - repository: UmbMemberGroupRepository, + repositoryAlias: MEMBER_GROUP_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.MemberGroup', + name: 'Member Group Tree Item', + conditions: { + entityType: 'member-group', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/manifests.ts index 74c4fd94d3..05b69158ab 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/manifests.ts @@ -1,5 +1,9 @@ -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', @@ -19,26 +23,30 @@ const workspaceViews: Array = [ loader: () => import('./views/info/workspace-view-member-group-info.element'), weight: 90, meta: { - workspaces: ['Umb.Workspace.MemberGroup'], label: 'Info', pathname: 'info', icon: 'info', }, + conditions: { + workspaces: ['Umb.Workspace.MemberGroup'], + }, }, ]; const workspaceActions: Array = [ { type: 'workspaceAction', - alias: 'Umb.WorkspaceAction.MemberGroup.SaveAndPublish', + alias: 'Umb.WorkspaceAction.MemberGroup.Save', name: 'Save Member Group Workspace Action', meta: { - workspaces: ['Umb.Workspace.MemberGroup'], label: 'Save', look: 'primary', color: 'positive', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.MemberGroup'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace-edit.element.ts new file mode 100644 index 0000000000..05f8b8a5f6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace-edit.element.ts @@ -0,0 +1,83 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UmbWorkspaceMemberGroupContext } from './member-group-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +/** + * @element umb-member-group-edit-workspace + * @description - Element for displaying a Member Group Workspace + */ +@customElement('umb-member-group-workspace-edit') +export class UmbMemberGroupWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + + #header { + margin: 0 var(--uui-size-layout-1); + flex: 1 1 auto; + } + + #name { + width: 100%; + flex: 1 1 auto; + align-items: center; + } + `, + ]; + + #workspaceContext?: UmbWorkspaceMemberGroupContext; + + @state() + private _memberGroup?: MemberGroupDetails; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbWorkspaceMemberGroupContext; + this.#observeMemberGroup(); + }); + } + + #observeMemberGroup() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.data, (data) => (this._memberGroup = data)); + } + + // TODO. find a way where we don't have to do this for all workspaces. + #handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + render() { + return html` + + `; + } +} + +export default UmbMemberGroupWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-member-group-workspace-edit': UmbMemberGroupWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.context.ts index 6acdae22d8..ecf64222eb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.context.ts @@ -1,20 +1,20 @@ -import { UmbWorkspaceEntityContextInterface } from '../../../../backoffice/shared/components/workspace/workspace-context/workspace-entity-context.interface'; import { UmbWorkspaceContext } from '../../../../backoffice/shared/components/workspace/workspace-context/workspace-context'; import { UmbMemberGroupRepository } from '../repository/member-group.repository'; -import type { MemberGroupDetails } from '@umbraco-cms/models'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ObjectState } from '@umbraco-cms/observable-api'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; type EntityType = MemberGroupDetails; export class UmbWorkspaceMemberGroupContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { #data = new ObjectState(undefined); data = this.#data.asObservable(); name = this.#data.getObservablePart((data) => data?.name); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbMemberGroupRepository(host)); } @@ -22,8 +22,8 @@ export class UmbWorkspaceMemberGroupContext return this.#data.getValue(); } - getEntityKey() { - return this.getData()?.key || ''; + getEntityId() { + return this.getData()?.id || ''; } getEntityType() { @@ -40,8 +40,8 @@ export class UmbWorkspaceMemberGroupContext return; } - async load(entityKey: string) { - const { data } = await this.repository.requestByKey(entityKey); + async load(entityId: string) { + const { data } = await this.repository.requestById(entityId); if (data) { this.#data.next(data); } @@ -56,7 +56,7 @@ export class UmbWorkspaceMemberGroupContext async save() { if (!this.#data.value) return; - await this.repository.save(this.#data.value); + await this.repository.save(this.#data.value.id, this.#data.value); this.setIsNew(true); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.element.ts index 745e405049..8639559f35 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.element.ts @@ -1,17 +1,17 @@ -import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbWorkspaceEntityElement } from '../../../../backoffice/shared/components/workspace/workspace-entity-element.interface'; import { UmbWorkspaceMemberGroupContext } from './member-group-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbMemberGroupWorkspaceEditElement } from './member-group-workspace-edit.element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-member-group-workspace * @description - Element for displaying a Member Group Workspace */ @customElement('umb-member-group-workspace') -export class UmbMemberGroupWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement { +export class UmbMemberGroupWorkspaceElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -20,59 +20,26 @@ export class UmbMemberGroupWorkspaceElement extends UmbLitElement implements Umb width: 100%; height: 100%; } - - #header { - /* TODO: can this be applied from layout slot CSS? */ - margin: 0 var(--uui-size-layout-1); - flex: 1 1 auto; - } `, ]; - + + #workspaceContext = new UmbWorkspaceMemberGroupContext(this); + #element = new UmbMemberGroupWorkspaceEditElement(); + @state() - _unique?: string; - - @state() - private _memberGroupName = ''; - - #workspaceContext: UmbWorkspaceMemberGroupContext = new UmbWorkspaceMemberGroupContext(this); - - public load(entityKey: string) { - this.#workspaceContext.load(entityKey); - this._unique = entityKey; - } - - public create() { - this.#workspaceContext.createScaffold(); - } - - async connectedCallback() { - super.connectedCallback(); - - this.observe(this.#workspaceContext.data, (memberGroup) => { - if (memberGroup && memberGroup.name !== this._memberGroupName) { - this._memberGroupName = memberGroup.name ?? ''; - } - }); - } - - // TODO. find a way where we don't have to do this for all Workspaces. - private _handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this.#workspaceContext.setName(target.value); - } - } - } + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - return html` - - - - `; + return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.stories.ts index 844cd022ab..404d9313ca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/member-group-workspace.stories.ts @@ -1,7 +1,7 @@ import './member-group-workspace.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { data } from '../../../../core/mocks/data/member-group.data'; @@ -14,5 +14,5 @@ export default { } as Meta; export const AAAOverview: Story = () => - html` `; + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.element.ts index faf7d7e59d..a8e5d16e0a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.element.ts @@ -2,8 +2,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbWorkspaceMemberGroupContext } from '../../member-group-workspace.context'; -import type { MemberGroupDetails } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-workspace-view-member-group-info') export class UmbWorkspaceViewMemberGroupInfoElement extends UmbLitElement { @@ -40,8 +41,8 @@ export class UmbWorkspaceViewMemberGroupInfoElement extends UmbLitElement { super(); // TODO: Figure out if this is the best way to consume the context or if it can be strongly typed with an UmbContextToken - this.consumeContext('umbWorkspaceContext', (instance) => { - this.#workspaceContext = instance; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbWorkspaceMemberGroupContext; this.#observeMemberGroup(); }); } @@ -62,7 +63,7 @@ export class UmbWorkspaceViewMemberGroupInfoElement extends UmbLitElement { return html` -
${this._memberGroup?.key}
+
${this._memberGroup?.id}
`; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.stories.ts index 6ef526d298..97b745c4ad 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-groups/workspace/views/info/workspace-view-member-group-info.stories.ts @@ -1,7 +1,7 @@ import './workspace-view-member-group-info.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; //import { data } from '../../../../../core/mocks/data/data-type.data'; //import { UmbDataTypeContext } from '../../data-type.context'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/entity-actions/manifests.ts index 71e673d409..db52c2c7a8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/entity-actions/manifests.ts @@ -1,6 +1,6 @@ import { MEMBER_TYPES_REPOSITORY_ALIAS } from '../repository/manifests'; -import { UmbDeleteEntityAction } from '@umbraco-cms/entity-action'; -import type { ManifestEntityAction } from '@umbraco-cms/models'; +import { UmbDeleteEntityAction } from '@umbraco-cms/backoffice/entity-action'; +import type { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; const entityType = 'member-type'; const repositoryAlias = MEMBER_TYPES_REPOSITORY_ALIAS; @@ -12,12 +12,14 @@ const entityActions: Array = [ name: 'Delete Member Type Entity Action', weight: 100, meta: { - entityType, icon: 'umb:trash', label: 'Delete', repositoryAlias, api: UmbDeleteEntityAction, }, + conditions: { + entityType, + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/menu-item/manifests.ts index 02892c46d9..2a6ea47ac4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/menu-item/manifests.ts @@ -1,14 +1,17 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const menuItem: ManifestMenuItem = { +const menuItem: ManifestTypes = { type: 'menuItem', + kind: 'tree', alias: 'Umb.MenuItem.MemberTypes', name: 'Member Types Menu Item', - weight: 30, - loader: () => import('./member-types-menu-item.element'), + weight: 700, meta: { label: 'Member Types', icon: 'umb:folder', + treeAlias: 'Umb.Tree.MemberTypes', + }, + conditions: { menus: ['Umb.Menu.Settings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/menu-item/member-types-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/menu-item/member-types-menu-item.element.ts deleted file mode 100644 index 42e3449cc6..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/menu-item/member-types-menu-item.element.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-member-types-menu-item') -export class UmbMemberTypesMenuItemElement extends UmbLitElement { - @state() - private _renderTree = false; - - private _onShowChildren() { - this._renderTree = true; - } - - private _onHideChildren() { - this._renderTree = false; - } - - // TODO: check if root has children before settings the has-children attribute - // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? - // TODO: can we make this reusable? - render() { - return html` - ${this._renderTree ? html`` : nothing} - `; - } -} - -export default UmbMemberTypesMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-member-types-menu-item': UmbMemberTypesMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/manifests.ts index f40c631433..3c06da7999 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/manifests.ts @@ -1,7 +1,7 @@ import { UmbMemberTypeRepository } from './member-type.repository'; import { UmbMemberTypeStore } from './member-type.store'; import { UmbMemberTypeTreeStore } from './member-type.tree.store'; -import type { ManifestRepository, ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestRepository, ManifestStore, ManifestTreeStore } from '@umbraco-cms/backoffice/extensions-registry'; export const MEMBER_TYPES_REPOSITORY_ALIAS = 'Umb.Repository.MemberType'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts index 83120d5b3d..620347e0b4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.repository.ts @@ -2,22 +2,23 @@ import { MemberTypeTreeServerDataSource } from './sources/member-type.tree.serve import { UmbMemberTypeTreeStore, UMB_MEMBER_TYPE_TREE_STORE_CONTEXT_TOKEN } from './member-type.tree.store'; import { UmbMemberTypeStore, UMB_MEMBER_TYPE_STORE_CONTEXT_TOKEN } from './member-type.store'; import { UmbMemberTypeDetailServerDataSource } from './sources/member-type.detail.server.data'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { RepositoryTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/repository'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import type { MemberTypeDetails } from '@umbraco-cms/models'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import type { MemberTypeDetails } from '@umbraco-cms/backoffice/models'; // TODO => use correct type when available type ItemType = any; +type TreeItemType = any; -export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepository { +export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepository { #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - #treeSource: RepositoryTreeDataSource; + #treeSource: UmbTreeDataSource; #treeStore?: UmbMemberTypeTreeStore; #detailSource: UmbMemberTypeDetailServerDataSource; @@ -25,7 +26,7 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source @@ -59,34 +60,34 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getItems(keys); + const { data, error } = await this.#treeSource.getItems(ids); - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -94,14 +95,14 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS @@ -111,16 +112,16 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo return this.#detailSource.createScaffold(); } - async requestByKey(key: string) { + async requestById(id: string) { await this.#init; - // TODO: should we show a notification if the key is missing? + // TODO: should we show a notification if the id is missing? // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - const { data, error } = await this.#detailSource.requestByKey(key); + const { data, error } = await this.#detailSource.requestById(id); if (data) { this.#store?.append(data); @@ -128,15 +129,15 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo return { data, error }; } - async delete(key: string) { + async delete(id: string) { await this.#init; - if (!key) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - const { error } = await this.#detailSource.delete(key); + const { error } = await this.#detailSource.delete(id); if (!error) { const notification = { data: { message: `Member type deleted` } }; @@ -146,37 +147,33 @@ export class UmbMemberTypeRepository implements UmbTreeRepository, UmbDetailRepo // TODO: we currently don't use the detail store for anything. // Consider to look up the data before fetching from the server. // Consider notify a workspace if a member type is deleted from the store while someone is editing it. - this.#store?.remove([key]); - this.#treeStore?.removeItem(key); + this.#store?.remove([id]); + this.#treeStore?.removeItem(id); // TODO: would be nice to align the stores on methods/methodNames. return { error }; } - async save(detail: ItemType) { + async save(id: string, updatedMemberType: any) { + if (!id) throw new Error('Key is missing'); + if (!updatedMemberType) throw new Error('Member Type is missing'); + await this.#init; - // TODO: should we show a notification if the MemberType is missing? - // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!detail || !detail.key) { - const error: ProblemDetailsModel = { title: 'Member type is missing' }; - return { error }; - } - - const { error } = await this.#detailSource.save(detail); + const { error } = await this.#detailSource.save(id, updatedMemberType); if (!error) { - const notification = { data: { message: `Member type '${detail.name}' saved` } }; + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a member type is updated in the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + //this.#store?.append(detail); + this.#treeStore?.updateItem(id, updatedMemberType); + + const notification = { data: { message: `Member type '${updatedMemberType.name}' saved` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - // Consider notify a workspace if a member type is updated in the store while someone is editing it. - this.#store?.append(detail); - this.#treeStore?.updateItem(detail.key, { name: detail.name }); - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.store.ts index c13dacc56f..b9afd506a2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.store.ts @@ -1,8 +1,8 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import type { MemberTypeDetails } from '@umbraco-cms/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import type { MemberTypeDetails } from '@umbraco-cms/backoffice/models'; /** * @export @@ -11,9 +11,9 @@ import type { MemberTypeDetails } from '@umbraco-cms/models'; * @description - Data Store for Member Types */ export class UmbMemberTypeStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEMBER_TYPE_STORE_CONTEXT_TOKEN.toString()); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts index d10cf2953e..be451afb24 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/member-type.tree.store.ts @@ -1,6 +1,6 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export @@ -8,8 +8,8 @@ import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; * @extends {UmbStoreBase} * @description - Tree Data Store for Member Types */ -export class UmbMemberTypeTreeStore extends UmbTreeStoreBase { - constructor(host: UmbControllerHostInterface) { +export class UmbMemberTypeTreeStore extends UmbEntityTreeStore { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEMBER_TYPE_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.detail.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.detail.server.data.ts index 58ec90e115..ab8466c03c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.detail.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.detail.server.data.ts @@ -1,8 +1,8 @@ -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import type { MemberTypeDetails } from '@umbraco-cms/models'; -import { UmbDetailRepository } from '@umbraco-cms/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import type { MemberTypeDetails } from '@umbraco-cms/backoffice/models'; +import { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; /** * @description - A data source for the MemberType detail that fetches data from the server @@ -10,10 +10,10 @@ import { UmbDetailRepository } from '@umbraco-cms/repository'; * @class UmbMemberTypeDetailServerDataSource * @implements {MemberTypeDetailDataSource} */ -export class UmbMemberTypeDetailServerDataSource implements UmbDetailRepository { - #host: UmbControllerHostInterface; +export class UmbMemberTypeDetailServerDataSource implements UmbDetailRepository { + #host: UmbControllerHostElement; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -28,15 +28,15 @@ export class UmbMemberTypeDetailServerDataSource implements UmbDetailRepository< } /** - * @description - Fetches a MemberType with the given key from the server - * @param {string} key + * @description - Fetches a MemberType with the given id from the server + * @param {string} id * @return {*} * @memberof UmbMemberTypeDetailServerDataSource */ - requestByKey(key: string) { - //return tryExecuteAndNotify(this.#host, MemberTypeResource.getMemberTypeByKey({ key })); + requestById(id: string) { + //return tryExecuteAndNotify(this.#host, MemberTypeResource.getMemberTypeByKey({ id })); // TODO => use backend cli when available. - return tryExecuteAndNotify(this.#host, fetch(`/umbraco/management/api/v1/member-group/${key}`)) as any; + return tryExecuteAndNotify(this.#host, fetch(`/umbraco/management/api/v1/member-group/${id}`)) as any; } /** @@ -45,19 +45,16 @@ export class UmbMemberTypeDetailServerDataSource implements UmbDetailRepository< * @return {*} * @memberof UmbMemberTypeDetailServerDataSource */ - async save(memberType: MemberTypeDetails) { - if (!memberType.key) { - const error: ProblemDetailsModel = { title: 'MemberType key is missing' }; - return { error }; - } + async save(id: string, memberType: any) { + if (!id) throw new Error('Member Type id is missing'); - const payload = { key: memberType.key, requestBody: memberType }; + const payload = { id: memberType.id, requestBody: memberType }; //return tryExecuteAndNotify(this.#host, MemberTypeResource.putMemberTypeByKey(payload)); // TODO => use backend cli when available. return tryExecuteAndNotify( this.#host, - fetch(`/umbraco/management/api/v1/member-type/${memberType.key}`, { + fetch(`/umbraco/management/api/v1/member-type/${memberType.id}`, { method: 'PUT', body: JSON.stringify(payload), headers: { @@ -94,21 +91,21 @@ export class UmbMemberTypeDetailServerDataSource implements UmbDetailRepository< /** * @description - Deletes a MemberType on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbMemberTypeDetailServerDataSource */ - async delete(key: string) { - if (!key) { + async delete(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - //return await tryExecuteAndNotify(this.#host, MemberTypeResource.deleteMemberTypeByKey({ key })); + //return await tryExecuteAndNotify(this.#host, MemberTypeResource.deleteMemberTypeByKey({ id })); // TODO => use backend cli when available. return tryExecuteAndNotify( this.#host, - fetch(`/umbraco/management/api/v1/member-type/${key}`, { + fetch(`/umbraco/management/api/v1/member-type/${id}`, { method: 'DELETE', }) ) as any; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.tree.server.data.ts index 8e147af77d..0c1abf952a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/repository/sources/member-type.tree.server.data.ts @@ -1,7 +1,7 @@ -import { MemberTypeResource, ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { RepositoryTreeDataSource } from '@umbraco-cms/repository'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { MemberTypeResource, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the MemberType tree that fetches data from the server @@ -9,15 +9,15 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class MemberTypeTreeServerDataSource * @implements {MemberTypeTreeDataSource} */ -export class MemberTypeTreeServerDataSource implements RepositoryTreeDataSource { - #host: UmbControllerHostInterface; +export class MemberTypeTreeServerDataSource implements UmbTreeDataSource { + #host: UmbControllerHostElement; /** * Creates an instance of MemberTypeTreeDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof MemberTypeTreeDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -31,32 +31,32 @@ export class MemberTypeTreeServerDataSource implements RepositoryTreeDataSource } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} * @memberof MemberTypeTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { + async getChildrenOf(parentId: string | null) { const error: ProblemDetailsModel = { title: 'Not implemented for Member Type' }; return { error }; } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} * @memberof MemberTypeTreeServerDataSource */ - async getItems(keys: Array) { - if (!keys || keys.length === 0) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; + async getItems(ids: Array) { + if (!ids || ids.length === 0) { + const error: ProblemDetailsModel = { title: 'Ids are missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - MemberTypeResource.getTreeMemberTypeItem({ - key: keys, + MemberTypeResource.getMemberTypeItem({ + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/tree/manifests.ts index 2e16d022d4..6781a419f4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/tree/manifests.ts @@ -1,5 +1,5 @@ -import { UmbMemberTypeRepository } from '../repository/member-type.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { MEMBER_TYPES_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const treeAlias = 'Umb.Tree.MemberTypes'; @@ -8,8 +8,18 @@ const tree: ManifestTree = { alias: treeAlias, name: 'Member Types Tree', meta: { - repository: UmbMemberTypeRepository, + repositoryAlias: MEMBER_TYPES_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.MemberType', + name: 'Member Type Tree Item', + conditions: { + entityType: 'member-type', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/manifests.ts index a90305204e..7eb06e2bf4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/manifests.ts @@ -1,4 +1,8 @@ -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace-edit.element.ts new file mode 100644 index 0000000000..eac47341ec --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace-edit.element.ts @@ -0,0 +1,38 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-member-type-workspace-edit') +export class UmbMemberTypeWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + + #header { + /* TODO: can this be applied from layout slot CSS? */ + margin: 0 var(--uui-size-layout-1); + flex: 1 1 auto; + } + `, + ]; + + render() { + return html` + Member Type Workspace + `; + } +} + +export default UmbMemberTypeWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-member-type-workspace-edit': UmbMemberTypeWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.context.ts index ac7107e361..8274bec279 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.context.ts @@ -1,25 +1,25 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; import { UmbMemberTypeRepository } from '../repository/member-type.repository'; -import { ObjectState } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; // TODO => use correct tpye type EntityType = any; -export class UmbWorkspaceMemberTypeContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface +export class UmbMemberTypeWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { #data = new ObjectState(undefined); name = this.#data.getObservablePart((data) => data?.name); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbMemberTypeRepository(host)); } - async load(entityKey: string) { - const { data } = await this.repository.requestByKey(entityKey); + async load(entityId: string) { + const { data } = await this.repository.requestById(entityId); if (data) { this.setIsNew(false); this.#data.next(data); @@ -37,8 +37,8 @@ export class UmbWorkspaceMemberTypeContext return this.#data.getValue(); } - getEntityKey() { - return this.getData()?.key || ''; + getEntityId() { + return this.getData()?.id || ''; } getEntityType() { @@ -55,17 +55,19 @@ export class UmbWorkspaceMemberTypeContext async save() { if (!this.#data.value) return; + if (!this.#data.value.id) return; + if (this.isNew) { await this.repository.create(this.#data.value); } else { - await this.repository.save(this.#data.value); + await this.repository.save(this.#data.value.id, this.#data.value); } // If it went well, then its not new anymore?. this.setIsNew(false); } - async delete(key: string) { - await this.repository.delete(key); + async delete(id: string) { + await this.repository.delete(id); } public destroy(): void { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.element.ts index 2b27e9c6e8..f7cbc5f788 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/member-types/workspace/member-type-workspace.element.ts @@ -1,9 +1,10 @@ -import { UUIInputEvent, UUIInputElement } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbWorkspaceMemberTypeContext } from './member-type-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbMemberTypeWorkspaceEditElement } from './member-type-workspace-edit.element'; +import { UmbMemberTypeWorkspaceContext } from './member-type-workspace.context'; +import { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-member-type-workspace') export class UmbMemberTypeWorkspaceElement extends UmbLitElement { @@ -15,58 +16,26 @@ export class UmbMemberTypeWorkspaceElement extends UmbLitElement { width: 100%; height: 100%; } - - #header { - /* TODO: can this be applied from layout slot CSS? */ - margin: 0 var(--uui-size-layout-1); - flex: 1 1 auto; - } `, ]; - @state() - private _memberTypeName = ''; + #workspaceContext = new UmbMemberTypeWorkspaceContext(this); + #element = new UmbMemberTypeWorkspaceEditElement(); @state() - private _unique?: string; - - #workspaceContext = new UmbWorkspaceMemberTypeContext(this); - - public load(entityKey: string) { - this.#workspaceContext?.load(entityKey); - this._unique = entityKey; - } - - public create() { - this.#workspaceContext.createScaffold(); - } - - constructor() { - super(); - this.observe(this.#workspaceContext.name, (memberTypeName) => { - if (memberTypeName !== this._memberTypeName) { - this._memberTypeName = memberTypeName ?? ''; - } - }); - } - - // TODO. find a way where we don't have to do this for all Workspaces. - private _handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this.#workspaceContext.setName(target.value); - } - } - } + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - return html` - - - - `; + return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/entity-actions/manifests.ts index 57654c41d0..9f2f9a28b2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/entity-actions/manifests.ts @@ -1,6 +1,6 @@ import { MEMBER_REPOSITORY_ALIAS } from '../repository/manifests'; -import { UmbDeleteEntityAction } from '@umbraco-cms/entity-action'; -import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models'; +import type { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbDeleteEntityAction } from '@umbraco-cms/backoffice/entity-action'; const entityActions: Array = [ { @@ -8,12 +8,14 @@ const entityActions: Array = [ alias: 'Umb.EntityAction.Member.Delete', name: 'Delete Member Entity Action ', meta: { - entityType: 'member', icon: 'umb:trash', label: 'Delete', api: UmbDeleteEntityAction, repositoryAlias: MEMBER_REPOSITORY_ALIAS, }, + conditions: { + entityType: 'member', + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/member.detail.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/member.detail.store.ts index a3a52703fb..973f79f5c4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/member.detail.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/member.detail.store.ts @@ -1,10 +1,10 @@ import { Observable } from 'rxjs'; import { umbMemberData } from '../../../core/mocks/data/member.data'; -import type { MemberDetails, MemberGroupDetails } from '@umbraco-cms/models'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState, createObservablePart } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/store'; +import type { MemberDetails, MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState, createObservablePart } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/backoffice/store'; /** * @export @@ -13,37 +13,37 @@ import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/store'; * @description - Data Store for Members */ export class UmbMemberStore extends UmbStoreBase implements UmbEntityDetailStore { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); public groups = this.#data.asObservable(); - constructor(private host: UmbControllerHostInterface) { + constructor(private host: UmbControllerHostElement) { super(host, UMB_MEMBER_STORE_CONTEXT_TOKEN.toString()); } - getScaffold(entityType: string, parentKey: string | null) { + getScaffold(entityType: string, parentId: string | null) { return {} as MemberDetails; } /** - * @description - Request a Member by key. The Member is added to the store and is returned as an Observable. - * @param {string} key + * @description - Request a Member by id. The Member is added to the store and is returned as an Observable. + * @param {string} id * @return {*} {(Observable)} * @memberof UmbMemberStore */ - getByKey(key: string): Observable { - // tryExecuteAndNotify(this.host, MemberResource.getMemberByKey({ key })).then(({ data }) => { + getByKey(id: string): Observable { + // tryExecuteAndNotify(this.host, MemberResource.getMemberByKey({ id })).then(({ data }) => { // if (data) {} // this.#data.appendOne(data); // } // }); // temp until Resource is updated - const member = umbMemberData.getByKey(key); + const member = umbMemberData.getById(id); if (member) { this.#data.appendOne(member); } - return createObservablePart(this.#data, (members) => members.find((member) => member.key === key) as MemberDetails); + return createObservablePart(this.#data, (members) => members.find((member) => member.id === id) as MemberDetails); } async save(member: Array): Promise { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/menu-item/manifests.ts index 4ab22621b1..93d9cbbc5b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/menu-item/manifests.ts @@ -1,15 +1,18 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const menuItem: ManifestMenuItem = { +const menuItem: ManifestTypes = { type: 'menuItem', + kind: 'tree', alias: 'Umb.MenuItem.Members', name: 'Members Menu Item', weight: 400, - loader: () => import('./members-menu-item.element'), meta: { label: 'Members', icon: 'umb:folder', entityType: 'member', + treeAlias: 'Umb.Tree.Members', + }, + conditions: { menus: ['Umb.Menu.Members'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/menu-item/members-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/menu-item/members-menu-item.element.ts deleted file mode 100644 index a5ab1f7248..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/menu-item/members-menu-item.element.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-members-menu-item') -export class UmbMembersMenuItemElement extends UmbLitElement { - @state() - private _renderTree = false; - - private _onShowChildren() { - this._renderTree = true; - } - - private _onHideChildren() { - this._renderTree = false; - } - - // TODO: check if root has children before settings the has-children attribute - // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? - // TODO: can we make this reusable? - render() { - return html` - ${this._renderTree ? html`` : nothing} - `; - } -} - -export default UmbMembersMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-members-menu-item': UmbMembersMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/manifests.ts index a2e150c0ca..15c055c885 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbMemberRepository } from './member.repository'; import { UmbMemberStore } from './member.store'; import { UmbMemberTreeStore } from './member.tree.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const MEMBER_REPOSITORY_ALIAS = 'Umb.Repository.Member'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts index 74b1d752fe..cf91bf0bf9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.repository.ts @@ -1,20 +1,20 @@ import { UmbMemberTreeStore, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN } from './member.tree.store'; import { MemberTreeServerDataSource } from './sources/member.tree.server.data'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbTreeRepository } from '@umbraco-cms/repository'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; export class UmbMemberRepository implements UmbTreeRepository { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #dataSource: MemberTreeServerDataSource; #treeStore?: UmbMemberTreeStore; #notificationContext?: UmbNotificationContext; #initResolver?: () => void; #initialized = false; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source this.#dataSource = new MemberTreeServerDataSource(this.#host); @@ -53,20 +53,20 @@ export class UmbMemberRepository implements UmbTreeRepository { return { data, error }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { const error: ProblemDetailsModel = { title: 'Not implemented' }; return { data: undefined, error }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#dataSource.getItems(keys); + const { data, error } = await this.#dataSource.getItems(ids); return { data, error }; } @@ -76,13 +76,13 @@ export class UmbMemberRepository implements UmbTreeRepository { return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.store.ts index 991ada05f4..4b01b1a8d8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.store.ts @@ -1,8 +1,8 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import type { MemberDetails } from '@umbraco-cms/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import type { MemberDetails } from '@umbraco-cms/backoffice/models'; /** * @export @@ -11,9 +11,9 @@ import type { MemberDetails } from '@umbraco-cms/models'; * @description - Data Store for Members */ export class UmbMemberStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEMBER_STORE_CONTEXT_TOKEN.toString()); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts index 6dd095fded..49568a0fff 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/member.tree.store.ts @@ -1,22 +1,22 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export const UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbMemberTreeStore'); /** * @export * @class UmbMemberTreeStore - * @extends {UmbTreeStoreBase} + * @extends {UmbEntityTreeStore} * @description - Tree Data Store for Members */ -export class UmbMemberTreeStore extends UmbTreeStoreBase { +export class UmbMemberTreeStore extends UmbEntityTreeStore { /** * Creates an instance of UmbTemplateTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbMemberGroupTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_MEMBER_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/index.ts index 66a63ad20d..2b26859baf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/index.ts @@ -1,7 +1,10 @@ -import type { DataSourceResponse } from '@umbraco-cms/models'; -import type { EntityTreeItemModel, PagedEntityTreeItemModel } from '@umbraco-cms/backend-api'; +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; +import type { + EntityTreeItemResponseModel, + PagedEntityTreeItemResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; export interface MemberTreeDataSource { - getRootItems(): Promise>; - getItems(key: Array): Promise>; + getRootItems(): Promise>; + getItems(id: Array): Promise>; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/member.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/member.tree.server.data.ts index 4f4fce08c8..b386fb52e2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/member.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/repository/sources/member.tree.server.data.ts @@ -1,5 +1,5 @@ import { MemberTreeDataSource } from '.'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * A data source for the Member tree that fetches data from the server @@ -8,14 +8,14 @@ import { UmbControllerHostInterface } from '@umbraco-cms/controller'; * @implements {MemberTreeDataSource} */ export class MemberTreeServerDataSource implements MemberTreeDataSource { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; /** * Creates an instance of MemberTreeServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof MemberTreeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -33,26 +33,26 @@ export class MemberTreeServerDataSource implements MemberTreeDataSource { } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} * @memberof MemberTreeServerDataSource */ - async getItems(keys: Array) { + async getItems(ids: Array) { const response = await fetch('/umbraco/management/api/v1/tree/member/item'); const data = await response.json(); return { data, error: undefined }; - // if (keys) { - // const error: ProblemDetailsModel = { title: 'Keys are missing' }; + // if (ids) { + // const error: ProblemDetailsModel = { title: 'Ids are missing' }; // return { error }; // } // return tryExecuteAndNotify( // this.#host, // MemberResource.getTreeMemberItem({ - // key: keys, + // id: ids, // }) // ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/manifests.ts index b059f518fd..e30a124927 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/tree/manifests.ts @@ -1,5 +1,5 @@ -import { UmbMemberRepository } from '../repository/member.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { MEMBER_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const tree: ManifestTree = { type: 'tree', @@ -7,8 +7,18 @@ const tree: ManifestTree = { name: 'Members Tree', weight: 10, meta: { - repository: UmbMemberRepository, + repositoryAlias: MEMBER_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.Member', + name: 'Member Tree Item', + conditions: { + entityType: 'member', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/manifests.ts index e4b4fe560f..a2e1875688 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/manifests.ts @@ -1,4 +1,8 @@ -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace-edit.element.ts new file mode 100644 index 0000000000..abebd0f1da --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace-edit.element.ts @@ -0,0 +1,29 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('umb-member-workspace-edit') +export class UmbMemberWorkspaceEditElement extends LitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + `, + ]; + + render() { + return html` Member Workspace `; + } +} + +export default UmbMemberWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-member-workspace-edit': UmbMemberWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.context.ts index a032a5fefc..3edd6f8b1e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.context.ts @@ -1,39 +1,38 @@ -import { UmbEntityWorkspaceManager } from '../../../shared/components/workspace/workspace-context/entity-manager-controller'; import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; -import { UMB_MEMBER_STORE_CONTEXT_TOKEN } from '../member.detail.store'; import { UmbMemberRepository } from '../repository/member.repository'; -import type { MemberDetails } from '@umbraco-cms/models'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { MemberDetails } from '@umbraco-cms/backoffice/models'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; -export class UmbWorkspaceMemberContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface +export class UmbMemberWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { - #manager = new UmbEntityWorkspaceManager(this.host, 'member', UMB_MEMBER_STORE_CONTEXT_TOKEN); - - public readonly data = this.#manager.state.asObservable(); - public readonly name = this.#manager.state.getObservablePart((state) => state?.name); - - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbMemberRepository(host)); } - setPropertyValue(alias: string, value: string) { - return; + getEntityType(): string { + return 'member'; } - setName(name: string) { - this.#manager.state.update({ name }); + getEntityId() { + return '1234'; } - getEntityType = this.#manager.getEntityType; - getUnique = this.#manager.getEntityKey; - getEntityKey = this.#manager.getEntityKey; - getStore = this.#manager.getStore; - getData = this.#manager.getData as any; // TODO: fix this type mismatch, but this will be done when we move to repositories. - load = this.#manager.load; - create = this.#manager.create; - save = this.#manager.save; - destroy = this.#manager.destroy; + getData() { + return 'fake' as unknown as MemberDetails; + } + + async save() { + console.log('save'); + } + + async load(id: string) { + console.log('load', id); + } + + public destroy(): void { + console.log('destroy'); + } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.element.ts index a7d516bdf0..dbe2e140cf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.element.ts @@ -1,9 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, LitElement } from 'lit'; -import { customElement, property } from 'lit/decorators.js'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbMemberWorkspaceEditElement } from './member-workspace-edit.element'; +import { UmbMemberWorkspaceContext } from './member-workspace.context'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-member-workspace') -export class UmbMemberWorkspaceElement extends LitElement { +export class UmbMemberWorkspaceElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -15,11 +19,23 @@ export class UmbMemberWorkspaceElement extends LitElement { `, ]; - @property() - id!: string; + #workspaceContext = new UmbMemberWorkspaceContext(this); + #element = new UmbMemberWorkspaceEditElement(); + + @state() + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - return html` Member Workspace `; + return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.stories.ts index 4a9f3778ae..2af3d29bf2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/members/workspace/member-workspace.stories.ts @@ -1,7 +1,7 @@ import './member-workspace.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { data } from '../../../../core/mocks/data/member.data'; @@ -14,5 +14,5 @@ export default { } as Meta; export const AAAOverview: Story = () => - html` `; + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/menu.manifests.ts index 1bd7ca6a85..b5ffba5eb7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/menu.manifests.ts @@ -1,4 +1,4 @@ -import { ManifestMenu } from '@umbraco-cms/extensions-registry'; +import { ManifestMenu } from '@umbraco-cms/backoffice/extensions-registry'; const menu: ManifestMenu = { type: 'menu', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/members/section.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/members/section.manifests.ts index bfc8719566..8165066175 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/members/section.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/members/section.manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestDashboard, ManifestSection, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models'; +import type { ManifestDashboard, ManifestSection, ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; const sectionAlias = 'Umb.Section.Members'; @@ -22,22 +22,27 @@ const dashboards: Array = [ loader: () => import('./dashboards/welcome/dashboard-members-welcome.element'), meta: { label: 'Members', - sections: [sectionAlias], pathname: 'members', }, + conditions: { + sections: [sectionAlias], + }, }, ]; -const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = { - type: 'menuSectionSidebarApp', +const menuSectionSidebarApp: ManifestTypes = { + type: 'sectionSidebarApp', + kind: 'menu', alias: 'Umb.SectionSidebarMenu.Members', name: 'Members Section Sidebar Menu', weight: 100, meta: { label: 'Members', - sections: [sectionAlias], menu: 'Umb.Menu.Members', }, + conditions: { + sections: [sectionAlias], + }, }; export const manifests = [section, menuSectionSidebarApp, ...dashboards]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/index.ts index f0a7107779..41064c5222 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/index.ts @@ -3,8 +3,8 @@ import { manifests as packageBuilderManifests } from './package-builder/manifest import { manifests as packageRepoManifests } from './package-repo/manifests'; import { manifests as packageSectionManifests } from './package-section/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [ ...repositoryManifests, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/manifests.ts index 7218ebf120..e9a0e23c03 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/manifests.ts @@ -3,7 +3,7 @@ import type { ManifestWorkspaceAction, ManifestWorkspaceView, ManifestWorkspaceViewCollection, -} from '@umbraco-cms/models'; +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts index 26b897a91b..9dce5a6dca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-builder/workspace/workspace-package-builder.element.ts @@ -2,14 +2,14 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { UUIBooleanInputEvent, UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; import { css, html, nothing } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbInputDocumentPickerElement } from '../../../shared/components/input-document-picker/input-document-picker.element'; import { UmbInputMediaPickerElement } from '../../../shared/components/input-media-picker/input-media-picker.element'; import { UmbInputLanguagePickerElement } from '../../../shared/components/input-language-picker/input-language-picker.element'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { PackageDefinitionModel, PackageResource } from '@umbraco-cms/backend-api'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { PackageDefinitionResponseModel, PackageResource } from '@umbraco-cms/backoffice/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; @customElement('umb-workspace-package-builder') export class UmbWorkspacePackageBuilderElement extends UmbLitElement { @@ -38,10 +38,10 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { ]; @property() - entityKey?: string; + entityId?: string; @state() - private _package: PackageDefinitionModel = {}; + private _package: PackageDefinitionResponseModel = {}; @query('#package-name-input') private _packageNameInput!: UUIInputElement; @@ -57,22 +57,19 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { connectedCallback(): void { super.connectedCallback(); - if (this.entityKey) this.#getPackageCreated(); + if (this.entityId) this.#getPackageCreated(); } async #getPackageCreated() { - if (!this.entityKey) return; - const { data } = await tryExecuteAndNotify(this, PackageResource.getPackageCreatedByKey({ key: this.entityKey })); + if (!this.entityId) return; + const { data } = await tryExecuteAndNotify(this, PackageResource.getPackageCreatedById({ id: this.entityId })); if (!data) return; - this._package = data as PackageDefinitionModel; + this._package = data as PackageDefinitionResponseModel; } async #download() { - if (!this._package?.key) return; - const response = await tryExecuteAndNotify( - this, - PackageResource.getPackageCreatedByKeyDownload({ key: this._package.key }) - ); + if (!this._package?.id) return; + await tryExecuteAndNotify(this, PackageResource.getPackageCreatedByIdDownload({ id: this._package.id })); } #nameDefined() { @@ -88,16 +85,16 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { PackageResource.postPackageCreated({ requestBody: this._package }) ); if (!response.data || response.error) return; - this._package = response.data as PackageDefinitionModel; + this._package = response.data as PackageDefinitionResponseModel; this.#navigateBack(); } async #update() { if (!this.#nameDefined()) return; - if (!this._package?.key) return; + if (!this._package?.id) return; const response = await tryExecuteAndNotify( this, - PackageResource.putPackageCreatedByKey({ key: this._package.key, requestBody: this._package }) + PackageResource.putPackageCreatedById({ id: this._package.id, requestBody: this._package }) ); if (response.error) return; @@ -105,7 +102,7 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { } #navigateBack() { - window.history.pushState({}, '', '/section/packages/view/created'); + window.history.pushState({}, '', 'section/packages/view/created'); } render() { @@ -135,13 +132,13 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { #renderActions() { return html`
- ${this._package?.key + ${this._package?.id ? html` Download ` : nothing} @@ -203,7 +200,7 @@ export class UmbWorkspacePackageBuilderElement extends UmbLitElement { .value=${this._package.contentNodeId ?? ''} max="1" @change="${(e: CustomEvent) => - (this._package.contentNodeId = (e.target as UmbInputDocumentPickerElement).selectedKeys[0])}"> + (this._package.contentNodeId = (e.target as UmbInputDocumentPickerElement).selectedIds[0])}"> + (this._package.mediaIds = (e.target as UmbInputMediaPickerElement).selectedIds)}"> = [ alias: 'Umb.SectionView.Packages.Repo', name: 'Packages Repo Section View', loader: () => import('./views/market-place/packages-market-place-section-view.element'), + weight: 300, meta: { - sections: [sectionAlias], label: 'Packages', pathname: 'packages', - weight: 300, icon: 'umb:cloud', }, + conditions: { + sections: [sectionAlias], + }, }, { type: 'sectionView', alias: 'Umb.SectionView.Packages.Installed', name: 'Installed Packages Section View', loader: () => import('./views/installed/installed-packages-section-view.element'), + weight: 200, meta: { - sections: [sectionAlias], label: 'Installed', pathname: 'installed', - weight: 200, icon: 'umb:box', }, + conditions: { + sections: [sectionAlias], + }, }, { type: 'sectionView', alias: 'Umb.SectionView.Packages.Builder', name: 'Packages Builder Section View', loader: () => import('./views/created/created-packages-section-view.element'), + weight: 100, meta: { - sections: [sectionAlias], label: 'Created', pathname: 'created', - weight: 100, icon: 'umb:files', }, + conditions: { + sections: [sectionAlias], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts index 15f3abadbf..4f22319e4f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/created-packages-section-view.element.ts @@ -1,9 +1,9 @@ import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import type { IRoute, IRoutingInfo } from '@umbraco-cms/router'; -import type { ManifestTree, ManifestWorkspace } from '@umbraco-cms/models'; -import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import type { ManifestTree, ManifestWorkspace } from '@umbraco-cms/backoffice/extensions-registry'; +import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-created-packages-section-view') export class UmbCreatedPackagesSectionViewElement extends UmbLitElement { @@ -23,7 +23,7 @@ export class UmbCreatedPackagesSectionViewElement extends UmbLitElement { } private _createRoutes() { - const routes: any[] = [ + const routes: IRoute[] = [ { path: 'overview', component: () => import('./packages-created-overview.element'), @@ -33,12 +33,12 @@ export class UmbCreatedPackagesSectionViewElement extends UmbLitElement { // TODO: find a way to make this reuseable across: this._workspaces?.map((workspace: ManifestWorkspace) => { routes.push({ - path: `${workspace.meta.entityType}/:key`, + path: `${workspace.meta.entityType}/:id`, component: () => createExtensionElement(workspace), - setup: (component: Promise, info: IRoutingInfo) => { - component.then((el: HTMLElement) => { - (el as any).entityKey = info.match.params.key; - }); + setup: (component, info) => { + if (component) { + (component as any).entityId = info.match.params.id; + } }, }); routes.push({ diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts index 5d85638acc..0ae1e74eec 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/created/packages-created-overview.element.ts @@ -3,11 +3,10 @@ import { ifDefined } from 'lit/directives/if-defined.js'; import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { UUIPaginationEvent } from '@umbraco-ui/uui'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../../shared/modals/confirm'; -import { PackageDefinitionModel, PackageResource } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { PackageDefinitionResponseModel, PackageResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; @customElement('umb-packages-created-overview') export class UmbPackagesCreatedOverviewElement extends UmbLitElement { @@ -44,7 +43,7 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { private _loading = true; @state() - private _createdPackages: PackageDefinitionModel[] = []; + private _createdPackages: PackageDefinitionResponseModel[] = []; @state() private _currentPage = 1; @@ -78,7 +77,7 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { } #createNewPackage() { - window.history.pushState({}, '', `/section/packages/view/created/package-builder`); + window.history.pushState({}, '', `section/packages/view/created/package-builder`); } render() { @@ -96,14 +95,14 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { ${repeat( this._createdPackages, - (item) => item.key, + (item) => item.id, (item) => this.#renderPackageItem(item) )} `; } - #renderPackageItem(p: PackageDefinitionModel) { + #renderPackageItem(p: PackageDefinitionResponseModel) { return html` this.#deletePackage(p)} label="Delete package"> @@ -113,9 +112,9 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { `; } - #packageBuilder(p: PackageDefinitionModel) { - if (!p.key) return; - window.history.pushState({}, '', `/section/packages/view/created/package-builder/${p.key}`); + #packageBuilder(p: PackageDefinitionResponseModel) { + if (!p.id) return; + window.history.pushState({}, '', `section/packages/view/created/package-builder/${p.id}`); } #renderPagination() { @@ -133,9 +132,9 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { this.#getPackages(); } - async #deletePackage(p: PackageDefinitionModel) { - if (!p.key) return; - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + async #deletePackage(p: PackageDefinitionResponseModel) { + if (!p.id) return; + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { color: 'danger', headline: `Remove ${p.name}?`, content: 'Are you sure you want to delete this package', @@ -144,9 +143,9 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { await modalHandler?.onSubmit(); - const { error } = await tryExecuteAndNotify(this, PackageResource.deletePackageCreatedByKey({ key: p.key })); + const { error } = await tryExecuteAndNotify(this, PackageResource.deletePackageCreatedById({ id: p.id })); if (error) return; - const index = this._createdPackages.findIndex((x) => x.key === p.key); + const index = this._createdPackages.findIndex((x) => x.id === p.id); this._createdPackages.splice(index, 1); this.requestUpdate(); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts index 063afe1b25..d3f537e95e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view-item.element.ts @@ -3,19 +3,17 @@ import { ifDefined } from 'lit/directives/if-defined.js'; import { customElement, property, state } from 'lit/decorators.js'; import { firstValueFrom, map } from 'rxjs'; import { UUIButtonState } from '@umbraco-ui/uui'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../../shared/modals/confirm'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; - -import type { ManifestPackageView } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { PackageResource } from '@umbraco-cms/backend-api'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; +import type { ManifestPackageView } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { PackageResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; @customElement('umb-installed-packages-section-view-item') -export class UmbInstalledPackagesSectionViewItem extends UmbLitElement { +export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement { static styles = css` :host { display: flex; @@ -27,7 +25,7 @@ export class UmbInstalledPackagesSectionViewItem extends UmbLitElement { name?: string; @property() - version?: string; + version?: string | null; @property() hasPendingMigrations = false; @@ -82,7 +80,7 @@ export class UmbInstalledPackagesSectionViewItem extends UmbLitElement { async _onMigration() { if (!this.name) return; - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { color: 'positive', headline: `Run migrations for ${this.name}?`, content: `Do you want to start run migrations for ${this.name}`, @@ -106,7 +104,7 @@ export class UmbInstalledPackagesSectionViewItem extends UmbLitElement { return html` ${this.customIcon ? html`` : nothing} @@ -153,6 +151,6 @@ export class UmbInstalledPackagesSectionViewItem extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-installed-packages-section-view-item': UmbInstalledPackagesSectionViewItem; + 'umb-installed-packages-section-view-item': UmbInstalledPackagesSectionViewItemElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts index 7880202c02..578403d9dd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/installed/installed-packages-section-view.element.ts @@ -4,13 +4,13 @@ import { repeat } from 'lit/directives/repeat.js'; import { combineLatest } from 'rxjs'; import { UUITextStyles } from '@umbraco-ui/uui-css'; import { UmbPackageRepository } from '../../../repository/package.repository'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { UmbPackageWithMigrationStatus } from '@umbraco-cms/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { UmbPackageWithMigrationStatus } from '@umbraco-cms/backoffice/models'; import './installed-packages-section-view-item.element'; @customElement('umb-installed-packages-section-view') -export class UmbInstalledPackagesSectionView extends UmbLitElement { +export class UmbInstalledPackagesSectionViewElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -138,10 +138,10 @@ export class UmbInstalledPackagesSectionView extends UmbLitElement { } } -export default UmbInstalledPackagesSectionView; +export default UmbInstalledPackagesSectionViewElement; declare global { interface HTMLElementTagNameMap { - 'umb-installed-packages-section-view': UmbInstalledPackagesSectionView; + 'umb-installed-packages-section-view': UmbInstalledPackagesSectionViewElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/market-place/packages-market-place-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/market-place/packages-market-place-section-view.element.ts index fb4eb3af97..d73c1a27dc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/market-place/packages-market-place-section-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/package-section/views/market-place/packages-market-place-section-view.element.ts @@ -3,21 +3,27 @@ import { customElement, property } from 'lit/decorators.js'; @customElement('umb-packages-market-place-section-view') export class UmbPackagesMarketPlaceSectionViewElement extends LitElement { - static styles = [css` - #container { - height: 100%; - display: flex; - align-items: stretch; - } + static styles = [ + css` + :host { + height: calc(100% - var(--umb-header-layout-height)); + display: block; + } + #container { + height: 100%; + display: flex; + align-items: stretch; + } - iframe { - width: 100%; - height: 100%; - overflow: hidden; - border: none; - } - `]; + iframe { + width: 100%; + height: 100%; + overflow: hidden; + border: none; + } + `, + ]; // TODO: This URL comes from the server // Was previously found in 'Umbraco.Sys.ServerVariables.umbracoUrls.marketplaceUrl' @@ -25,15 +31,14 @@ export class UmbPackagesMarketPlaceSectionViewElement extends LitElement { marketplaceUrl = 'https://marketplace.umbraco.com/?umbversion=11.1.0&style=backoffice'; render() { - return html` -
- -
`; + return html`
+ +
`; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/manifests.ts index ab052945f7..b2a0069d5b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/manifests.ts @@ -1,7 +1,6 @@ import { UmbPackageRepository } from './package.repository'; import { UmbPackageStore } from './package.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const PACKAGE_REPOSITORY_ALIAS = 'Umb.Repository.Package'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts index f28c63c378..abe8c7deda 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.repository.ts @@ -1,10 +1,10 @@ import { UmbPackageStore, UMB_PACKAGE_STORE_TOKEN } from './package.store'; import { UmbPackageServerDataSource } from './sources/package.server.data'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { ManifestBase } from '@umbraco-cms/extensions-registry'; -import { isManifestJSType } from "@umbraco-cms/extensions-api"; -import { OpenAPI } from "@umbraco-cms/backend-api"; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import type { ManifestBase } from '@umbraco-cms/backoffice/extensions-registry'; +import { isManifestJSType } from '@umbraco-cms/backoffice/extensions-api'; +import { OpenAPI } from '@umbraco-cms/backoffice/backend-api'; // TODO: Figure out if we should base stores like this on something more generic for "collections" rather than trees. @@ -18,7 +18,7 @@ export class UmbPackageRepository { #packageSource: UmbPackageServerDataSource; #apiBaseUrl = OpenAPI.BASE; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#packageSource = new UmbPackageServerDataSource(host); this.#init = new Promise((res) => { new UmbContextConsumerController(host, UMB_PACKAGE_STORE_TOKEN, (instance) => { @@ -51,7 +51,6 @@ export class UmbPackageRepository { // Crudely validate that the extension at least follows a basic manifest structure // Idea: Use `Zod` to validate the manifest if (this.isManifestBase(e)) { - /** * Crude check to see if extension is of type "js" since it is safe to assume we do not * need to load any other types of extensions in the backoffice (we need a js file to load) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts index 18120d46a9..8ed4792471 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/package.store.ts @@ -1,10 +1,11 @@ import { ReplaySubject } from 'rxjs'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import type { ManifestBase, UmbPackage } from '@umbraco-cms/models'; -import type { PackageMigrationStatusModel } from '@umbraco-cms/backend-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import type { UmbPackage } from '@umbraco-cms/backoffice/models'; +import type { PackageMigrationStatusResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { ManifestBase } from '@umbraco-cms/backoffice/extensions-registry'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; export const UMB_PACKAGE_STORE_TOKEN = new UmbContextToken('UmbPackageStore'); @@ -22,7 +23,7 @@ export class UmbPackageStore extends UmbStoreBase { #extensions = new ArrayState([], (e) => e.alias); - #migrations = new ArrayState([], (e) => e.packageName); + #migrations = new ArrayState([], (e) => e.packageName); /** * Observable of packages with extensions @@ -37,10 +38,10 @@ export class UmbPackageStore extends UmbStoreBase { /** * Creates an instance of PackageStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof PackageStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_PACKAGE_STORE_TOKEN.toString()); } @@ -56,7 +57,7 @@ export class UmbPackageStore extends UmbStoreBase { this.#extensions.append(extensions); } - appendMigrations(migrations: PackageMigrationStatusModel[]) { + appendMigrations(migrations: PackageMigrationStatusResponseModel[]) { this.#migrations.append(migrations); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts index 74a3db7ea0..c3f33ced28 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/server-extension.controller.ts @@ -1,14 +1,14 @@ import { Subject, takeUntil } from 'rxjs'; import { UmbPackageRepository } from './package.repository'; -import { UmbController, UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbExtensionRegistry } from '@umbraco-cms/extensions-api'; +import { UmbController, UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbExtensionRegistry } from '@umbraco-cms/backoffice/extensions-api'; export class UmbServerExtensionController extends UmbController { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #unobserve = new Subject(); #repository: UmbPackageRepository; - constructor(host: UmbControllerHostInterface, private readonly extensionRegistry: UmbExtensionRegistry) { + constructor(host: UmbControllerHostElement, private readonly extensionRegistry: UmbExtensionRegistry) { super(host, UmbServerExtensionController.name); this.#host = host; this.#repository = new UmbPackageRepository(host); @@ -33,7 +33,7 @@ export class UmbServerExtensionController extends UmbController { ) .subscribe((extensions) => { extensions.forEach((extension) => { - this.extensionRegistry.register(extension, this.#host); + this.extensionRegistry.register(extension); }); }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts index 251f76608c..5e25807032 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/packages/repository/sources/package.server.data.ts @@ -1,23 +1,20 @@ -import { PackageResource } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { PackageResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * Data source for packages from the server * @export */ export class UmbPackageServerDataSource { - constructor(private readonly host: UmbControllerHostInterface) {} + constructor(private readonly host: UmbControllerHostElement) {} /** * Get the root items from the server * @memberof UmbPackageServerDataSource */ getRootItems() { - return tryExecuteAndNotify( - this.host, - PackageResource.getPackageManifest() - ); + return tryExecuteAndNotify(this.host, PackageResource.getPackageManifest()); } /** diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/search/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/search/index.ts index e0d341e7cc..040b21d817 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/search/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/search/index.ts @@ -1,7 +1,7 @@ import { manifests as searchManifests } from '../search/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [...searchManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/search/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/search/manifests.ts index ea025667f8..adc42d3da1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/search/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/search/manifests.ts @@ -1,18 +1,31 @@ -import type { ManifestHeaderApp } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const headerApps: Array = [ +const headerApps: Array = [ { type: 'headerApp', alias: 'Umb.HeaderApp.Search', name: 'Header App Search', loader: () => import('./umb-search-header-app.element'), - weight: 10, + weight: 900, meta: { label: 'Search', icon: 'search', pathname: 'search', }, }, + + { + type: 'headerApp', + kind: 'button', + alias: 'Umb.HeaderApp.HackDemo', + name: 'Header App Search', + weight: 10, + meta: { + label: 'Hack Demo', + icon: 'document', + href: '/section/content/workspace/document/edit/c05da24d-7740-447b-9cdc-bd8ce2172e38/en-us/view/content/tab/Local%20blog%20tab', + }, + }, ]; export const manifests = [...headerApps]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/manifests.ts index 7765c306fc..e90acac916 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/search/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/search/index.ts deleted file mode 100644 index 9859d03434..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/search/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; - -export const UMB_SEARCH_MODAL_TOKEN = new UmbModalToken('Umb.Modal.Search'); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/search/search-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/search/search-modal.element.ts index b294c49eda..9c44c331c3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/search/search-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/search/modals/search/search-modal.element.ts @@ -1,6 +1,6 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, LitElement, nothing } from 'lit'; -import { repeat } from 'lit-html/directives/repeat.js'; +import { repeat } from 'lit/directives/repeat.js'; import { customElement, query, state } from 'lit/decorators.js'; export type SearchItem = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts index 64a53e5e3b..9335c24119 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/search/umb-search-header-app.element.ts @@ -1,11 +1,11 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-search-header-app') -export class UmbSearchHeaderApp extends UmbLitElement { +export class UmbSearchHeaderAppElement extends UmbLitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -39,10 +39,10 @@ export class UmbSearchHeaderApp extends UmbLitElement { } } -export default UmbSearchHeaderApp; +export default UmbSearchHeaderAppElement; declare global { interface HTMLElementTagNameMap { - 'umb-search-header-app': UmbSearchHeaderApp; + 'umb-search-header-app': UmbSearchHeaderAppElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts index 8e68ea40b5..38caacad96 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/culture.repository.ts @@ -1,17 +1,17 @@ import { UmbCultureServerDataSource } from './sources/culture.server.data'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; export class UmbCultureRepository { #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #dataSource: UmbCultureServerDataSource; #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; this.#dataSource = new UmbCultureServerDataSource(this.#host); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/manifests.ts index 7502a562d3..0496f4acff 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/manifests.ts @@ -1,5 +1,5 @@ import { UmbCultureRepository } from '../repository/culture.repository'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; +import { ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const CULTURE_REPOSITORY_ALIAS = 'Umb.Repository.Culture'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/culture.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/culture.server.data.ts index 02ac62a9bb..b9525c1906 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/culture.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/culture.server.data.ts @@ -1,7 +1,7 @@ import { UmbCultureDataSource } from '.'; -import { CultureResource } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { CultureResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Language that fetches data from the server @@ -10,14 +10,14 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @implements {RepositoryDetailDataSource} */ export class UmbCultureServerDataSource implements UmbCultureDataSource { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; /** * Creates an instance of UmbLanguageServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbLanguageServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/index.ts index 8b3555ed3f..a365433abe 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/cultures/repository/sources/index.ts @@ -1,5 +1,5 @@ -import { PagedCultureModel } from '@umbraco-cms/backend-api'; -import type { DataSourceResponse } from '@umbraco-cms/models'; +import { PagedCultureReponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; // TODO: This is a temporary solution until we have a proper paging interface type paging = { @@ -8,5 +8,5 @@ type paging = { }; export interface UmbCultureDataSource { - getCollection(paging: paging): Promise>; + getCollection(paging: paging): Promise>; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.element.ts index a82f3676bc..3c9b8fe4db 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.element.ts @@ -3,9 +3,10 @@ import { customElement, state } from 'lit/decorators.js'; import { UmbDashboardExamineIndexElement } from './views/section-view-examine-indexers'; import { UmbDashboardExamineSearcherElement } from './views/section-view-examine-searchers'; -import type { IRoute, IRoutingInfo, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/router'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-dashboard-examine-management') export class UmbDashboardExamineManagementElement extends UmbLitElement { @@ -26,7 +27,7 @@ export class UmbDashboardExamineManagementElement extends UmbLitElement { { path: `/index/:indexerName`, component: () => import('./views/section-view-examine-indexers'), - setup: (component: HTMLElement, info: IRoutingInfo) => { + setup: (component, info) => { const element = component as UmbDashboardExamineIndexElement; element.indexName = info.match.params.indexerName; }, @@ -34,7 +35,7 @@ export class UmbDashboardExamineManagementElement extends UmbLitElement { { path: `/searcher/:searcherName`, component: () => import('./views/section-view-examine-searchers'), - setup: (component: HTMLElement, info: IRoutingInfo) => { + setup: (component, info) => { const element = component as UmbDashboardExamineSearcherElement; element.searcherName = info.match.params.searcherName; }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.stories.ts index 3e3b5c194e..1631ca4528 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/dashboard-examine-management.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardExamineManagementElement } from './dashboard-examine-management.element'; import './dashboard-examine-management.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-settings.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-settings.element.ts index 8da8cf647e..337623cfcc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-settings.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-settings.element.ts @@ -1,8 +1,8 @@ import { html, css } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; -import { UmbCreateDocumentModalResultData, UmbExamineFieldsSettingsModalData } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { UmbCreateDocumentModalResultData, UmbExamineFieldsSettingsModalData } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; @customElement('umb-examine-fields-settings-modal') export class UmbExamineFieldsSettingsModalElement extends UmbModalBaseElement< diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts index 9ef00638de..df1870aba9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/modal-views/fields-viewer.element.ts @@ -1,11 +1,11 @@ import { html, css, nothing } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement } from 'lit/decorators.js'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; -import type { SearchResultModel } from '@umbraco-cms/backend-api'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; +import type { SearchResultResponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-modal-element-fields-viewer') -export class UmbModalElementFieldsViewerElement extends UmbModalBaseElement { +export class UmbModalElementFieldsViewerElement extends UmbModalBaseElement { static styles = [ UUITextStyles, css` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts index 99d08ebf41..9dcfc67150 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-indexers.ts @@ -2,11 +2,10 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUIButtonState } from '@umbraco-ui/uui-button'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../../shared/modals/confirm'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { HealthStatusModel, IndexModel, IndexerResource } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { HealthStatusModel, IndexResponseModel, IndexerResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import './section-view-examine-searchers'; @@ -85,7 +84,7 @@ export class UmbDashboardExamineIndexElement extends UmbLitElement { private _buttonState?: UUIButtonState = undefined; @state() - private _indexData?: IndexModel; + private _indexData?: IndexResponseModel; @state() private _loading = true; @@ -118,7 +117,7 @@ export class UmbDashboardExamineIndexElement extends UmbLitElement { } private async _onRebuildHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: `Rebuild ${this.indexName}`, content: html` This will cause the index to be rebuilt.
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts index 3ac9fb989b..75c2996779 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-overview.ts @@ -4,19 +4,24 @@ import { customElement, state } from 'lit/decorators.js'; import { HealthStatusModel, - IndexModel, + IndexResponseModel, IndexerResource, - SearcherModel, + SearcherResponseModel, SearcherResource, -} from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; @customElement('umb-dashboard-examine-overview') export class UmbDashboardExamineOverviewElement extends UmbLitElement { static styles = [ UUITextStyles, css` + :host { + display:block; + margin:var(--uui-size-layout-1); + } + uui-box + uui-box { margin-top: var(--uui-size-space-5); } @@ -58,10 +63,10 @@ export class UmbDashboardExamineOverviewElement extends UmbLitElement { ]; @state() - private _indexers?: IndexModel[]; + private _indexers?: IndexResponseModel[]; @state() - private _searchers?: SearcherModel[]; + private _searchers?: SearcherResponseModel[]; @state() private _loadingIndexers = false; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts index fd7f1b6f14..18cad41a37 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/examine-management/views/section-view-examine-searchers.ts @@ -1,14 +1,21 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, state, query, property } from 'lit/decorators.js'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { SearchResultModel, SearcherResource, FieldModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_EXAMINE_FIELDS_SETTINGS_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import { + SearchResultResponseModel, + SearcherResource, + FieldPresentationModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import './modal-views/fields-viewer.element'; import './modal-views/fields-settings.element'; -import { UMB_EXAMINE_FIELDS_SETTINGS_MODAL_TOKEN } from './modal-views'; interface ExposedSearchResultField { name?: string | null; @@ -106,7 +113,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement { searcherName!: string; @state() - private _searchResults?: SearchResultModel[]; + private _searchResults?: SearchResultResponseModel[]; @state() private _exposedFields?: ExposedSearchResultField[]; @@ -174,7 +181,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement { } private _onFieldFilterClick() { - const modalHandler = this._modalContext?.open(UMB_EXAMINE_FIELDS_SETTINGS_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_EXAMINE_FIELDS_SETTINGS_MODAL, { ...this._exposedFields, }); modalHandler?.onSubmit().then(({ fields } = {}) => { @@ -202,7 +209,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement { } // Find the field named 'nodeName' and return its value if it exists in the fields array - private getSearchResultNodeName(searchResult: SearchResultModel): string { + private getSearchResultNodeName(searchResult: SearchResultResponseModel): string { const nodeNameField = searchResult.fields?.find((field) => field.name?.toUpperCase() === 'NODENAME'); return nodeNameField?.values?.join(', ') ?? ''; } @@ -284,7 +291,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement { })}`; } - renderBodyCells(cellData: FieldModel[]) { + renderBodyCells(cellData: FieldPresentationModel[]) { return html`${this._exposedFields?.map((slot) => { return cellData.map((field) => { return slot.exposed && field.name == slot.name diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.element.ts index ce95990d04..cce292cb19 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.element.ts @@ -6,12 +6,12 @@ import { UMB_HEALTHCHECK_DASHBOARD_CONTEXT_TOKEN, } from './health-check-dashboard.context'; import { UmbHealthCheckContext } from './health-check.context'; -import type { IRoute, IRoutingInfo } from '@umbraco-cms/router'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { ManifestHealthCheck } from '@umbraco-cms/extensions-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { HealthCheckGroupModel, HealthCheckResource } from '@umbraco-cms/backend-api'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { ManifestHealthCheck } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { HealthCheckGroupResponseModel, HealthCheckResource } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-dashboard-health-check') export class UmbDashboardHealthCheckElement extends UmbLitElement { @@ -20,7 +20,7 @@ export class UmbDashboardHealthCheckElement extends UmbLitElement { { path: `/:groupName`, component: () => import('./views/health-check-group.element'), - setup: (component: HTMLElement, info: IRoutingInfo) => { + setup: (component, info) => { const element = component as UmbDashboardHealthCheckGroupElement; element.groupName = decodeURI(info.match.params.groupName); }, @@ -53,7 +53,7 @@ export class UmbDashboardHealthCheckElement extends UmbLitElement { this.#register(manifests); }; - #createManifests(groups: HealthCheckGroupModel[]): Array { + #createManifests(groups: HealthCheckGroupResponseModel[]): Array { return groups.map((group) => { return { type: 'healthCheck', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.stories.ts index e444c665c2..b45b7e3d99 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/dashboard-health-check.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardHealthCheckOverviewElement } from './views/health-check-overview.element'; import './views/health-check-overview.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts index 73f987fdea..0d3d4cd0a3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check-dashboard.context.ts @@ -1,6 +1,6 @@ import { UmbHealthCheckContext } from './health-check.context'; -import type { ManifestHealthCheck } from '@umbraco-cms/models'; -import { UmbContextToken } from '@umbraco-cms/context-api'; +import type { ManifestHealthCheck } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; export class UmbHealthCheckDashboardContext { #manifests: ManifestHealthCheck[] = []; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts index 920af65be7..5aead9d1aa 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/health-check.context.ts @@ -1,19 +1,23 @@ import { BehaviorSubject } from 'rxjs'; -import { HealthCheckGroupModel, HealthCheckGroupWithResultModel, HealthCheckResource } from '@umbraco-cms/backend-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { + HealthCheckGroupPresentationModel, + HealthCheckGroupWithResultResponseModel, + HealthCheckResource, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; export class UmbHealthCheckContext { - private _checks = new BehaviorSubject(undefined); + private _checks = new BehaviorSubject(undefined); public readonly checks = this._checks.asObservable(); - private _results = new BehaviorSubject(undefined); + private _results = new BehaviorSubject(undefined); public readonly results = this._results.asObservable(); - public host: UmbControllerHostInterface; + public host: UmbControllerHostElement; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.host = host; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-action.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-action.element.ts index 606c606c4e..adb82e765b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-action.element.ts @@ -4,9 +4,9 @@ import { css, html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; -import { HealthCheckActionModel, HealthCheckResource } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { HealthCheckActionRequestModel, HealthCheckResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; @customElement('umb-dashboard-health-check-action') export class UmbDashboardHealthCheckActionElement extends UmbLitElement { @@ -54,7 +54,7 @@ export class UmbDashboardHealthCheckActionElement extends UmbLitElement { ]; @property({ reflect: true }) - action!: HealthCheckActionModel; + action!: HealthCheckActionRequestModel; @state() private _buttonState?: UUIButtonState; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group-box-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group-box-overview.element.ts index 31fa419b08..53296360cf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group-box-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group-box-overview.element.ts @@ -6,10 +6,10 @@ import { UMB_HEALTHCHECK_DASHBOARD_CONTEXT_TOKEN, UmbHealthCheckDashboardContext, } from '../health-check-dashboard.context'; -import { ensureSlash, path } from '@umbraco-cms/router'; -import type { ManifestHealthCheck } from '@umbraco-cms/models'; -import { HealthCheckGroupWithResultModel, StatusResultTypeModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { ensureSlash, path } from '@umbraco-cms/backoffice/router'; +import type { ManifestHealthCheck } from '@umbraco-cms/backoffice/extensions-registry'; +import { HealthCheckGroupWithResultResponseModel, StatusResultTypeModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-health-check-group-box-overview') export class UmbHealthCheckGroupBoxOverviewElement extends UmbLitElement { @@ -64,7 +64,7 @@ export class UmbHealthCheckGroupBoxOverviewElement extends UmbLitElement { private _tagResults?: any = []; @state() - private _keyResults?: HealthCheckGroupWithResultModel; + private _keyResults?: HealthCheckGroupWithResultResponseModel; constructor() { super(); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group.element.ts index 45f503dd59..8480c9d534 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-group.element.ts @@ -10,15 +10,15 @@ import { UMB_HEALTHCHECK_DASHBOARD_CONTEXT_TOKEN, } from '../health-check-dashboard.context'; import { - HealthCheckActionModel, - HealthCheckGroupModel, + HealthCheckActionRequestModel, + HealthCheckGroupPresentationModel, HealthCheckModel, HealthCheckResource, - HealthCheckWithResultModel, + HealthCheckWithResultPresentationModel, StatusResultTypeModel, -} from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import './health-check-action.element'; @customElement('umb-dashboard-health-check-group') @@ -26,8 +26,13 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { static styles = [ UUITextStyles, css` - uui-box { - margin-bottom: var(--uui-size-space-5); + :host { + display: block; + margin: var(--uui-size-layout-1); + } + + uui-box + uui-box { + margin-top: var(--uui-size-space-5); } p { @@ -74,7 +79,7 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { private _buttonState: UUIButtonState; @state() - private _group?: HealthCheckGroupModel; + private _group?: HealthCheckGroupPresentationModel; private _healthCheckContext?: UmbHealthCheckDashboardContext; @@ -82,7 +87,7 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { private _checks?: HealthCheckModel[]; @state() - private _keyResults?: HealthCheckWithResultModel[]; + private _idResults?: HealthCheckWithResultPresentationModel[]; private _api?: UmbHealthCheckContext; @@ -101,7 +106,7 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { }); this._api?.results.subscribe((results) => { - this._keyResults = results?.checks; + this._idResults = results?.checks; }); }); } @@ -112,7 +117,7 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { this._buttonState = 'success'; } - private _onActionClick(action: HealthCheckActionModel) { + private _onActionClick(action: HealthCheckActionRequestModel) { return tryExecuteAndNotify(this, HealthCheckResource.postHealthCheckExecuteAction({ requestBody: action })); } @@ -138,18 +143,18 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { ${this._group?.checks?.map((check) => { return html`

${check.description}

- ${check.key ? this.renderCheckResults(check.key) : nothing} + ${check.id ? this.renderCheckResults(check.id) : nothing}
`; })}
`; } - renderCheckResults(key: string) { - if (!this._keyResults) { + renderCheckResults(id: string) { + if (!this._idResults) { return nothing; } - const checkResults = this._keyResults.find((x) => x.key === key); + const checkResults = this._idResults.find((x) => x.id === id); if (!checkResults) { return nothing; @@ -197,7 +202,7 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { } } - private renderActions(actions: HealthCheckActionModel[]) { + private renderActions(actions: HealthCheckActionRequestModel[]) { if (actions.length) return html`
${actions.map( diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-overview.element.ts index cb1d908195..dddf878b38 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/health-check/views/health-check-overview.element.ts @@ -7,10 +7,7 @@ import { UmbHealthCheckDashboardContext, UMB_HEALTHCHECK_DASHBOARD_CONTEXT_TOKEN, } from '../health-check-dashboard.context'; -import { UmbLitElement } from '@umbraco-cms/element'; - -import { ManifestHealthCheck } from '@umbraco-cms/extensions-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import './health-check-group-box-overview.element'; @@ -19,6 +16,11 @@ export class UmbDashboardHealthCheckOverviewElement extends UmbLitElement { static styles = [ UUITextStyles, css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + uui-box + uui-box { margin-top: var(--uui-size-space-5); } @@ -26,6 +28,7 @@ export class UmbDashboardHealthCheckOverviewElement extends UmbLitElement { .flex { display: flex; justify-content: space-between; + align-items:center; } .grid { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/manifests.ts index f3475347ba..a3227bd94e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestDashboard, ManifestModal } from '@umbraco-cms/models'; +import type { ManifestDashboard, ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const dashboards: Array = [ { @@ -10,9 +10,11 @@ const dashboards: Array = [ weight: 500, meta: { label: 'Welcome', - sections: ['Umb.Section.Settings'], pathname: 'welcome', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }, { type: 'dashboard', @@ -23,9 +25,11 @@ const dashboards: Array = [ weight: 400, meta: { label: 'Examine Management', - sections: ['Umb.Section.Settings'], pathname: 'examine-management', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }, { type: 'dashboard', @@ -36,9 +40,11 @@ const dashboards: Array = [ weight: 300, meta: { label: 'Models Builder', - sections: ['Umb.Section.Settings'], pathname: 'models-builder', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }, { type: 'dashboard', @@ -49,9 +55,11 @@ const dashboards: Array = [ weight: 200, meta: { label: 'Published Status', - sections: ['Umb.Section.Settings'], pathname: 'published-status', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }, { type: 'dashboard', @@ -62,9 +70,11 @@ const dashboards: Array = [ weight: 102, meta: { label: 'Health Check', - sections: ['Umb.Section.Settings'], pathname: 'health-check', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }, { type: 'dashboard', @@ -75,9 +85,11 @@ const dashboards: Array = [ weight: 101, meta: { label: 'Profiling', - sections: ['Umb.Section.Settings'], pathname: 'profiling', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }, { type: 'dashboard', @@ -88,9 +100,11 @@ const dashboards: Array = [ weight: 100, meta: { label: 'Telemetry Data', - sections: ['Umb.Section.Settings'], pathname: 'telemetry', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts index a9f60aa0c8..249718f61e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.element.ts @@ -3,15 +3,24 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { ModelsBuilderModel, ModelsBuilderResource, ModelsModeModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { + ModelsBuilderResponseModel, + ModelsBuilderResource, + ModelsModeModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; @customElement('umb-dashboard-models-builder') export class UmbDashboardModelsBuilderElement extends UmbLitElement { static styles = [ UUITextStyles, css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + .headline { display: flex; justify-content: space-between; @@ -41,7 +50,7 @@ export class UmbDashboardModelsBuilderElement extends UmbLitElement { ]; @state() - private _modelsBuilder?: ModelsBuilderModel; + private _modelsBuilder?: ModelsBuilderResponseModel; @state() private _buttonStateBuild: UUIButtonState = undefined; @@ -90,7 +99,11 @@ export class UmbDashboardModelsBuilderElement extends UmbLitElement {

Models Builder

- + Reload
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.stories.ts index a4174331da..98bc351222 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/models-builder/dashboard-models-builder.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardModelsBuilderElement } from './dashboard-models-builder.element'; import './dashboard-models-builder.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts index fb74431a4b..c0db4a1944 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.element.ts @@ -1,15 +1,20 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { ProfilingResource } from '@umbraco-cms/backend-api'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { ProfilingResource } from '@umbraco-cms/backoffice/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-dashboard-performance-profiling') export class UmbDashboardPerformanceProfilingElement extends UmbLitElement { static styles = [ UUITextStyles, css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + uui-toggle { font-weight: bold; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.stories.ts index fedf360d27..affb5f940b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/performance-profiling/dashboard-performance-profiling.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardPerformanceProfilingElement } from './dashboard-performance-profiling.element'; import './dashboard-performance-profiling.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts index 3d79b89afc..e011fa7bc3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.element.ts @@ -2,17 +2,21 @@ import { UUIButtonState } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../shared/modals/confirm'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { PublishedCacheResource } from '@umbraco-cms/backend-api'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { PublishedCacheResource } from '@umbraco-cms/backoffice/backend-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-dashboard-published-status') export class UmbDashboardPublishedStatusElement extends UmbLitElement { static styles = [ UUITextStyles, css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + uui-box + uui-box { margin-top: var(--uui-size-space-5); } @@ -81,7 +85,7 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { } } private async _onReloadCacheHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Reload', content: html` Trigger a in-memory and local file cache reload on all servers. `, color: 'danger', @@ -104,7 +108,7 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { } private async _onRebuildCacheHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Rebuild', content: html` Rebuild content in cmsContentNu database table. Expensive.`, color: 'danger', @@ -132,7 +136,7 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { render() { return html` - +

${this._publishedStatusText}

Refresh Status + label="Refresh Status" + @click=${this._onRefreshCacheHandler}> + Refresh Status +
@@ -156,10 +161,11 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { type="button" look="primary" color="danger" + label="Reload Memory Cache" @click=${this._onReloadCacheHandler} - .state=${this._buttonStateReload} - >Reload Memory Cache + .state=${this._buttonStateReload}> + Reload Memory Cache + @@ -172,10 +178,11 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { type="button" look="primary" color="danger" + label="Rebuild Database Cache" @click=${this._onRebuildCacheHandler} - .state=${this._buttonStateRebuild} - >Rebuild Database Cache + .state=${this._buttonStateRebuild}> + Rebuild Database Cache + @@ -187,10 +194,11 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { type="button" look="primary" color="danger" + label="Snapshot Internal Cache" @click=${this._onSnapshotCacheHandler} - .state=${this._buttonStateCollect} - >Snapshot Internal Cache + .state=${this._buttonStateCollect}> + Snapshot Internal Cache + `; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.stories.ts index c8fe24cd10..7c80cdeaa1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardPublishedStatusElement } from './dashboard-published-status.element'; import './dashboard-published-status.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.test.ts index ed4c366109..ce625f94c8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/published-status/dashboard-published-status.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbDashboardPublishedStatusElement } from './dashboard-published-status.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbDashboardPublishedStatus', () => { let element: UmbDashboardPublishedStatusElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.element.ts index 4bb62e1605..f5363ec0ae 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.element.ts @@ -2,64 +2,112 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; - @customElement('umb-dashboard-settings-welcome') export class UmbDashboardSettingsWelcomeElement extends LitElement { - static styles = [UUITextStyles, css` - #settings-dashboard { - display: grid; - grid-gap:var(--uui-size-7); - grid-template-columns: repeat(3, 1fr); - } - - @media(max-width: 1200px) { + static styles = [ + UUITextStyles, + css` #settings-dashboard { - grid-template-columns: repeat(2, 1fr); + display: grid; + grid-gap: var(--uui-size-7); + grid-template-columns: repeat(3, 1fr); + margin: var(--uui-size-layout-1); } - } - @media(max-width: 800px) { - #settings-dashboard { - grid-template-columns: repeat(1, 1fr); + @media (max-width: 1200px) { + #settings-dashboard { + grid-template-columns: repeat(2, 1fr); + } } - } - `]; + + @media (max-width: 800px) { + #settings-dashboard { + grid-template-columns: repeat(1, 1fr); + } + } + `, + ]; render() { return html` -
+

Documentation

Read more about working with the items in Settings in our Documentation.

- Get the help you need + + Get the help you need +

Community

Ask a question in the community forum or our Discord community

- Go to the forum - Chat with the community + + Go to the forum + + + Chat with the community +

Training

+

Find out about real-life training and certification opportunities

- Get Certified + + Get Certified +

Support

Ask a question in the community forum or our Discord community.

- Get the help you need + + Get the help you need +

Videos

-

Watch our free tutorial videos on the Umbraco Learning Base YouTube channel, to get upto speed quickly with Umbraco.

- Watch the videos +

+ Watch our free tutorial videos on the Umbraco Learning Base YouTube channel, to get upto speed quickly with + Umbraco. +

+ + Watch the videos +
-
- + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.stories.ts index a6b3b2a257..82f0475336 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardSettingsWelcomeElement } from './dashboard-settings-welcome.element'; import './dashboard-settings-welcome.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.test.ts index 1ca8ac3378..7cd3eee814 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/settings-welcome/dashboard-settings-welcome.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbDashboardSettingsWelcomeElement } from './dashboard-settings-welcome.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbDashboardSettingsWelcomeElement', () => { let element: UmbDashboardSettingsWelcomeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts index 71a89c4b72..7fdcb95d64 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.element.ts @@ -3,17 +3,18 @@ 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 { TelemetryModel, TelemetryLevelModel, TelemetryResource } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { TelemetryResponseModel, TelemetryLevelModel, TelemetryResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; @customElement('umb-dashboard-telemetry') export class UmbDashboardTelemetryElement extends UmbLitElement { static styles = [ UUITextStyles, css` - .italic { - font-style: italic; + :host { + display: block; + margin: var(--uui-size-layout-1); } `, ]; @@ -22,7 +23,7 @@ export class UmbDashboardTelemetryElement extends UmbLitElement { private _telemetryFormData = TelemetryLevelModel.BASIC; @state() - private _telemetryLevels: TelemetryModel[] = []; + private _telemetryLevels: TelemetryResponseModel[] = []; @state() private _errorMessage = ''; @@ -120,7 +121,7 @@ export class UmbDashboardTelemetryElement extends UmbLitElement { return html`

Consent for telemetry data

-
+

In order to improve Umbraco and add new functionality based on as relevant information as possible, we would like to collect system- and usage information from your installation. Aggregate data will be shared on a diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.stories.ts index cb92a9de25..c101e73f41 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardTelemetryElement } from './dashboard-telemetry.element'; import './dashboard-telemetry.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.test.ts index 72662348af..a77fe00869 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/dashboards/telemetry/dashboard-telemetry.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbDashboardTelemetryElement } from './dashboard-telemetry.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbDashboardTelemetryElement', () => { let element: UmbDashboardTelemetryElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/create.action.ts new file mode 100644 index 0000000000..bf87193435 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/create.action.ts @@ -0,0 +1,27 @@ +import { UmbDataTypeRepository } from '../../repository/data-type.repository'; +import { UMB_DATA_TYPE_CREATE_OPTIONS_MODAL } from './modal'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; + +export class UmbCreateDataTypeEntityAction extends UmbEntityActionBase { + #modalContext?: UmbModalContext; + + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { + super(host, repositoryAlias, unique); + + new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.#modalContext = instance; + }); + } + + async execute() { + if (!this.#modalContext) throw new Error('Modal context is not available'); + if (!this.repository) throw new Error('Repository is not available'); + + this.#modalContext?.open(UMB_DATA_TYPE_CREATE_OPTIONS_MODAL, { + parentKey: this.unique, + }); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/manifests.ts new file mode 100644 index 0000000000..4603e3f25f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/manifests.ts @@ -0,0 +1,29 @@ +import { DATA_TYPE_REPOSITORY_ALIAS } from '../../repository/manifests'; +import { UmbCreateDataTypeEntityAction } from './create.action'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; + +const entityActions: Array = [ + { + type: 'entityAction', + alias: 'Umb.EntityAction.DataType.Create', + name: 'Create Data Type Entity Action', + weight: 1000, + meta: { + icon: 'umb:add', + label: 'Create', + repositoryAlias: DATA_TYPE_REPOSITORY_ALIAS, + api: UmbCreateDataTypeEntityAction, + }, + conditions: { + entityType: 'data-type', + }, + }, + { + type: 'modal', + alias: 'Umb.Modal.DataTypeCreateOptions', + name: 'Data Type Create Options Modal', + loader: () => import('./modal/data-type-create-options-modal.element'), + }, +]; + +export const manifests = [...entityActions]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/modal/data-type-create-options-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/modal/data-type-create-options-modal.element.ts new file mode 100644 index 0000000000..f4c615847c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/modal/data-type-create-options-modal.element.ts @@ -0,0 +1,77 @@ +import { html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { DATA_TYPE_REPOSITORY_ALIAS } from '../../../repository/manifests'; +import { UmbDataTypeCreateOptionsModalData } from '.'; +import { + UmbModalContext, + UmbModalHandler, + UMB_FOLDER_MODAL, + UMB_MODAL_CONTEXT_TOKEN, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-data-type-create-options-modal') +export class UmbDataTypeCreateOptionsModalElement extends UmbLitElement { + static styles = [UUITextStyles]; + + @property({ attribute: false }) + modalHandler?: UmbModalHandler; + + @property({ type: Object }) + data?: UmbDataTypeCreateOptionsModalData; + + #modalContext?: UmbModalContext; + + constructor() { + super(); + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.#modalContext = instance; + }); + } + + #onClick(event: PointerEvent) { + event.stopPropagation(); + const folderModalHandler = this.#modalContext?.open(UMB_FOLDER_MODAL, { + repositoryAlias: DATA_TYPE_REPOSITORY_ALIAS, + }); + folderModalHandler?.onSubmit().then(() => this.modalHandler?.submit()); + } + + // close the modal when navigating to data type + #onNavigate() { + this.modalHandler?.submit(); + } + + #onCancel() { + this.modalHandler?.reject(); + } + + render() { + return html` + + + + + } + + + } + + + Cancel + + `; + } +} + +export default UmbDataTypeCreateOptionsModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-data-type-create-options-modal': UmbDataTypeCreateOptionsModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/modal/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/modal/index.ts new file mode 100644 index 0000000000..c6565fb240 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/create/modal/index.ts @@ -0,0 +1,13 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbDataTypeCreateOptionsModalData { + parentKey: string | null; +} + +export const UMB_DATA_TYPE_CREATE_OPTIONS_MODAL = new UmbModalToken( + 'Umb.Modal.DataTypeCreateOptions', + { + type: 'sidebar', + size: 'small', + } +); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/manifests.ts new file mode 100644 index 0000000000..54e8288b16 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/entity-actions/manifests.ts @@ -0,0 +1,58 @@ +import { DATA_TYPE_REPOSITORY_ALIAS } from '../repository/manifests'; +import { manifests as createManifests } from './create/manifests'; +import { + UmbDeleteEntityAction, + UmbDeleteFolderEntityAction, + UmbFolderUpdateEntityAction, +} from '@umbraco-cms/backoffice/entity-action'; +import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; + +const entityActions: Array = [ + { + type: 'entityAction', + alias: 'Umb.EntityAction.DataType.Delete', + name: 'Delete Data Type Entity Action', + weight: 900, + meta: { + icon: 'umb:trash', + label: 'Delete...', + repositoryAlias: DATA_TYPE_REPOSITORY_ALIAS, + api: UmbDeleteEntityAction, + }, + conditions: { + entityType: 'data-type', + }, + }, + { + type: 'entityAction', + alias: 'Umb.EntityAction.DataType.DeleteFolder', + name: 'Delete Data Type Folder Entity Action', + weight: 800, + meta: { + icon: 'umb:trash', + label: 'Delete Folder...', + repositoryAlias: DATA_TYPE_REPOSITORY_ALIAS, + api: UmbDeleteFolderEntityAction, + }, + conditions: { + entityType: 'data-type', + }, + }, + { + type: 'entityAction', + alias: 'Umb.EntityAction.DataType.RenameFolder', + name: 'Rename Data Type Folder Entity Action', + weight: 700, + meta: { + icon: 'umb:edit', + label: 'Rename Folder...', + repositoryAlias: DATA_TYPE_REPOSITORY_ALIAS, + api: UmbFolderUpdateEntityAction, + }, + conditions: { + entityType: 'data-type', + }, + }, +]; + +export const manifests = [...entityActions, ...createManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/manifests.ts index ddaa4babdc..fac58d2628 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/manifests.ts @@ -1,6 +1,13 @@ +import { manifests as entityActions } from './entity-actions/manifests'; import { manifests as repositoryManifests } from './repository/manifests'; import { manifests as menuItemManifests } from './menu-item/manifests'; import { manifests as treeManifests } from './tree/manifests'; import { manifests as workspaceManifests } from './workspace/manifests'; -export const manifests = [...repositoryManifests, ...menuItemManifests, ...treeManifests, ...workspaceManifests]; +export const manifests = [ + ...entityActions, + ...repositoryManifests, + ...menuItemManifests, + ...treeManifests, + ...workspaceManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/menu-item/data-types-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/menu-item/data-types-menu-item.element.ts deleted file mode 100644 index 2887568f1b..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/menu-item/data-types-menu-item.element.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-data-types-menu-item') -export class UmbDataTypesMenuItemElement extends UmbLitElement { - @state() - private _renderTree = false; - - private _onShowChildren() { - this._renderTree = true; - } - - private _onHideChildren() { - this._renderTree = false; - } - - // TODO: check if root has children before settings the has-children attribute - // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? - // TODO: can we make this reusable? - render() { - return html` - ${this._renderTree ? html`` : nothing} - `; - } -} - -export default UmbDataTypesMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-data-types-menu-item': UmbDataTypesMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/menu-item/manifests.ts index 25eb1fdef7..29c995c92a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/menu-item/manifests.ts @@ -1,15 +1,18 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const menuItem: ManifestMenuItem = { +const menuItem: ManifestTypes = { type: 'menuItem', + kind: 'tree', alias: 'Umb.MenuItem.DataTypes', name: 'Data Types Menu Item', - weight: 40, - loader: () => import('./data-types-menu-item.element'), + weight: 600, meta: { label: 'Data Types', icon: 'umb:folder', entityType: 'data-type', + treeAlias: 'Umb.Tree.DataTypes', + }, + conditions: { menus: ['Umb.Menu.Settings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts index e440812256..21a4d02041 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.repository.ts @@ -1,40 +1,54 @@ -import type { RepositoryTreeDataSource } from '../../../../../libs/repository/repository-tree-data-source.interface'; -import { UmbDataTypeTreeStore, UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN } from './data-type.tree.store'; -import { UmbDataTypeServerDataSource } from './sources/data-type.server.data'; +import { UmbDataTypeTreeServerDataSource } from './sources/data-type.tree.server.data'; import { UmbDataTypeStore, UMB_DATA_TYPE_STORE_CONTEXT_TOKEN } from './data-type.store'; -import { DataTypeTreeServerDataSource } from './sources/data-type.tree.server.data'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { ProblemDetailsModel, DataTypeModel } from '@umbraco-cms/backend-api'; -import type { UmbTreeRepository } from 'libs/repository/tree-repository.interface'; -import { UmbDetailRepository } from '@umbraco-cms/repository'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; +import { UmbDataTypeServerDataSource } from './sources/data-type.server.data'; +import { UmbDataTypeTreeStore, UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN } from './data-type.tree.store'; +import { UmbDataTypeFolderServerDataSource } from './sources/data-type-folder.server.data'; +import type { + UmbTreeDataSource, + UmbTreeRepository, + UmbDetailRepository, + UmbFolderDataSource, + UmbDataSource, +} from '@umbraco-cms/backoffice/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { + CreateDataTypeRequestModel, + CreateFolderRequestModel, + DataTypeResponseModel, + FolderModelBaseModel, + FolderTreeItemResponseModel, + UpdateDataTypeRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { UmbFolderRepository } from '@umbraco-cms/backoffice/repository'; -type ItemType = DataTypeModel; - -// Move to documentation / JSdoc -/* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */ -// element -> context -> repository -> (store) -> data source -// All methods should be async and return a promise. Some methods might return an observable as part of the promise response. -export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailRepository { +export class UmbDataTypeRepository + implements + UmbTreeRepository, + UmbDetailRepository, + UmbFolderRepository +{ #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - #treeSource: RepositoryTreeDataSource; - #treeStore?: UmbDataTypeTreeStore; + #treeSource: UmbTreeDataSource; + #detailSource: UmbDataSource; + #folderSource: UmbFolderDataSource; - #detailDataSource: UmbDataTypeServerDataSource; #detailStore?: UmbDataTypeStore; + #treeStore?: UmbDataTypeTreeStore; #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source - this.#treeSource = new DataTypeTreeServerDataSource(this.#host); - this.#detailDataSource = new UmbDataTypeServerDataSource(this.#host); + this.#treeSource = new UmbDataTypeTreeServerDataSource(this.#host); + this.#detailSource = new UmbDataTypeServerDataSource(this.#host); + this.#folderSource = new UmbDataTypeFolderServerDataSource(this.#host); this.#init = Promise.all([ new UmbContextConsumerController(this.#host, UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN, (instance) => { @@ -51,9 +65,6 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi ]); } - // TODO: Trash - // TODO: Move - async requestRootTreeItems() { await this.#init; @@ -66,34 +77,26 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { + if (!parentId) throw new Error('Parent id is missing'); await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; - return { data: undefined, error }; - } - - const { data, error } = await this.#treeSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { + if (!ids) throw new Error('Keys are missing'); await this.#init; - if (!keys) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; - return { data: undefined, error }; - } + const { data, error } = await this.#treeSource.getItems(ids); - const { data, error } = await this.#treeSource.getItems(keys); - - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -101,38 +104,31 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { + if (parentId === undefined) throw new Error('Parent id is missing'); await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS: - async createScaffold(parentKey: string | null) { + async createScaffold(parentId: string | null) { + if (parentId === undefined) throw new Error('Parent id is missing'); await this.#init; - if (!parentKey) { - throw new Error('Parent key is missing'); - } - - return this.#detailDataSource.createScaffold(parentKey); + return this.#detailSource.createScaffold(parentId); } - async requestByKey(key: string) { + async requestById(id: string) { + if (!id) throw new Error('Key is missing'); await this.#init; - // TODO: should we show a notification if the key is missing? - // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - const { data, error } = await this.#detailDataSource.get(key); + const { data, error } = await this.#detailSource.get(id); if (data) { this.#detailStore?.append(data); @@ -141,82 +137,161 @@ export class UmbDataTypeRepository implements UmbTreeRepository, UmbDetailReposi return { data, error }; } - async byKey(key: string) { + async byId(id: string) { + if (!id) throw new Error('Key is missing'); await this.#init; - return this.#detailStore!.byKey(key); + return this.#detailStore!.byId(id); } - // Could potentially be general methods: + async create(dataType: CreateDataTypeRequestModel) { + if (!dataType) throw new Error('Data Type is missing'); + if (!dataType.id) throw new Error('Data Type id is missing'); - async create(template: ItemType) { await this.#init; - if (!template || !template.key) { - throw new Error('Template is missing'); - } - - const { error } = await this.#detailDataSource.insert(template); + const { error } = await this.#detailSource.insert(dataType); if (!error) { - const notification = { data: { message: `Document created` } }; + // TODO: We need to push a new item to the tree store to update the tree. How do we want to create the tree items? + const treeItem = createTreeItem(dataType); + this.#treeStore?.appendItems([treeItem]); + //this.#detailStore?.append(dataType); + + const notification = { data: { message: `Data Type created` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - this.#detailStore?.append(template); - // TODO: Update tree store with the new item? or ask tree to request the new item? - return { error }; } - async save(item: ItemType) { + async save(id: string, updatedDataType: UpdateDataTypeRequestModel) { + if (!id) throw new Error('Data Type id is missing'); + if (!updatedDataType) throw new Error('Data Type is missing'); + await this.#init; - if (!item || !item.key) { - throw new Error('Document-Type is missing'); - } - - const { error } = await this.#detailDataSource.update(item); + const { error } = await this.#detailSource.update(id, updatedDataType); if (!error) { - const notification = { data: { message: `Document saved` } }; + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a template is updated in the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + // this.#detailStore?.append(dataType); + this.#treeStore?.updateItem(id, updatedDataType); + + const notification = { data: { message: `Data Type saved` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - // Consider notify a workspace if a template is updated in the store while someone is editing it. - this.#detailStore?.append(item); - this.#treeStore?.updateItem(item.key, { name: item.name }); - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } // General: - async delete(key: string) { + async delete(id: string) { + if (!id) throw new Error('Data Type id is missing'); await this.#init; - if (!key) { - throw new Error('Document key is missing'); - } - - const { error } = await this.#detailDataSource.delete(key); + const { error } = await this.#detailSource.delete(id); if (!error) { - const notification = { data: { message: `Document deleted` } }; + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server. + // Consider notify a workspace if a template is deleted from the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + this.#detailStore?.remove([id]); + this.#treeStore?.removeItem(id); + + const notification = { data: { message: `Data Type deleted` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server. - // Consider notify a workspace if a template is deleted from the store while someone is editing it. - this.#detailStore?.remove([key]); - this.#treeStore?.removeItem(key); - // TODO: would be nice to align the stores on methods/methodNames. + return { error }; + } + + // folder + async createFolderScaffold(parentId: string | null) { + if (parentId === undefined) throw new Error('Parent id is missing'); + return this.#folderSource.createScaffold(parentId); + } + + // TODO: temp create type until backend is ready. Remove the id addition when new types are generated. + async createFolder(folderRequest: CreateFolderRequestModel & { id?: string | undefined }) { + if (!folderRequest) throw new Error('folder request is missing'); + await this.#init; + + const { error } = await this.#folderSource.insert(folderRequest); + + if (!error) { + // TODO: We need to push a new item to the tree store to update the tree. How do we want to create the tree items? + const folderTreeItem = createFolderTreeItem(folderRequest); + this.#treeStore?.appendItems([folderTreeItem]); + } return { error }; } + + async deleteFolder(id: string) { + if (!id) throw new Error('Key is missing'); + + const { error } = await this.#folderSource.delete(id); + + if (!error) { + this.#treeStore?.removeItem(id); + } + + return { error }; + } + + async updateFolder(id: string, folder: FolderModelBaseModel) { + if (!id) throw new Error('Key is missing'); + if (!folder) throw new Error('Folder data is missing'); + + const { error } = await this.#folderSource.update(id, folder); + + if (!error) { + this.#treeStore?.updateItem(id, { name: folder.name }); + } + + return { error }; + } + + async requestFolder(id: string) { + if (!id) throw new Error('Key is missing'); + + const { data, error } = await this.#folderSource.get(id); + + if (data) { + this.#treeStore?.appendItems([data]); + } + + return { data, error }; + } } + +export const createTreeItem = (item: CreateDataTypeRequestModel): FolderTreeItemResponseModel => { + if (!item) throw new Error('item is null or undefined'); + if (!item.id) throw new Error('item.id is null or undefined'); + + return { + $type: 'FolderTreeItemResponseModel', + type: 'data-type', + parentId: item.parentId, + name: item.name, + id: item.id, + isFolder: false, + isContainer: false, + hasChildren: false, + }; +}; + +export const createFolderTreeItem = (item: CreateFolderRequestModel): FolderTreeItemResponseModel => { + if (!item) throw new Error('item is null or undefined'); + if (!item.id) throw new Error('item.id is null or undefined'); + + return { + ...createTreeItem(item), + isFolder: true, + }; +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts index d6d8ef2d94..71db9b0013 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.store.ts @@ -1,8 +1,8 @@ -import type { DataTypeModel } from '@umbraco-cms/backend-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export const UMB_DATA_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbDataTypeStore'); @@ -13,14 +13,14 @@ export const UMB_DATA_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); /** * Creates an instance of UmbDataTypeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDataTypeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DATA_TYPE_STORE_CONTEXT_TOKEN.toString()); } @@ -29,17 +29,17 @@ export class UmbDataTypeStore extends UmbStoreBase { * @param {DataTypeModel} dataType * @memberof UmbDataTypeStore */ - append(dataType: DataTypeModel) { + append(dataType: DataTypeResponseModel) { this.#data.append([dataType]); } /** * Append a data-type to the store - * @param {key} DataTypeModel key. + * @param {id} DataTypeModel id. * @memberof UmbDataTypeStore */ - byKey(key: DataTypeModel['key']) { - return this.#data.getObservablePart((x) => x.find((y) => y.key === key)); + byId(id: DataTypeResponseModel['id']) { + return this.#data.getObservablePart((x) => x.find((y) => y.id === id)); } /** @@ -47,7 +47,7 @@ export class UmbDataTypeStore extends UmbStoreBase { * @param {string[]} uniques * @memberof UmbDataTypeStore */ - remove(uniques: Array) { + remove(uniques: Array) { this.#data.remove(uniques); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts index a29ae02cf8..560c70160d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/data-type.tree.store.ts @@ -1,6 +1,6 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; /** * @export @@ -9,17 +9,15 @@ import { UmbTreeStoreBase } from '@umbraco-cms/store'; * @description - Tree Data Store for Data-Types */ // TODO: consider if tree store could be turned into a general EntityTreeStore class? -export class UmbDataTypeTreeStore extends UmbTreeStoreBase { +export class UmbDataTypeTreeStore extends UmbEntityTreeStore { /** * Creates an instance of UmbDataTypeTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDataTypeTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN.toString()); } } -export const UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken( - 'UmbDataTypeTreeStore' -); +export const UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbDataTypeTreeStore'); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/manifests.ts index 4d54186a90..0217359bf7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbDataTypeRepository } from '../repository/data-type.repository'; import { UmbDataTypeStore } from './data-type.store'; import { UmbDataTypeTreeStore } from './data-type.tree.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const DATA_TYPE_REPOSITORY_ALIAS = 'Umb.Repository.DataType'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type-folder.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type-folder.server.data.ts new file mode 100644 index 0000000000..dffb153689 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type-folder.server.data.ts @@ -0,0 +1,112 @@ +import { v4 as uuidv4 } from 'uuid'; +import { UmbFolderDataSource } from '@umbraco-cms/backoffice/repository'; +import { + DataTypeResource, + FolderReponseModel, + CreateFolderRequestModel, + FolderModelBaseModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * A data source for a Data Type folder that fetches data from the server + * @export + * @class UmbDataTypeFolderServerDataSource + * @implements {RepositoryDetailDataSource} + */ +export class UmbDataTypeFolderServerDataSource implements UmbFolderDataSource { + #host: UmbControllerHostElement; + + /** + * Creates an instance of UmbDataTypeFolderServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbDataTypeFolderServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + + /** + * Creates a Data Type folder with the given id from the server + * @param {string} parentId + * @return {*} + * @memberof UmbDataTypeFolderServerDataSource + */ + async createScaffold(parentId: string | null) { + const scaffold: FolderReponseModel = { + $type: 'FolderReponseModel', + name: '', + id: uuidv4(), + parentId, + }; + + return { data: scaffold }; + } + + /** + * Fetches a Data Type folder with the given id from the server + * @param {string} id + * @return {*} + * @memberof UmbDataTypeFolderServerDataSource + */ + async get(id: string) { + if (!id) throw new Error('Key is missing'); + return tryExecuteAndNotify( + this.#host, + DataTypeResource.getDataTypeFolderById({ + id: id, + }) + ); + } + + /** + * Inserts a new Data Type folder on the server + * @param {folder} folder + * @return {*} + * @memberof UmbDataTypeFolderServerDataSource + */ + async insert(folder: CreateFolderRequestModel) { + if (!folder) throw new Error('Folder is missing'); + return tryExecuteAndNotify( + this.#host, + DataTypeResource.postDataTypeFolder({ + requestBody: folder, + }) + ); + } + + /** + * Updates a Data Type folder on the server + * @param {folder} folder + * @return {*} + * @memberof UmbDataTypeFolderServerDataSource + */ + async update(id: string, folder: FolderModelBaseModel) { + if (!id) throw new Error('Key is missing'); + if (!id) throw new Error('Folder data is missing'); + return tryExecuteAndNotify( + this.#host, + DataTypeResource.putDataTypeFolderById({ + id: id, + requestBody: folder, + }) + ); + } + + /** + * Deletes a Data Type folder with the given id on the server + * @param {string} id + * @return {*} + * @memberof UmbDataTypeServerDataSource + */ + async delete(id: string) { + if (!id) throw new Error('Key is missing'); + return tryExecuteAndNotify( + this.#host, + DataTypeResource.deleteDataTypeFolderById({ + id: id, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.server.data.ts index 2af70e06fe..0d70c24d85 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.server.data.ts @@ -1,13 +1,14 @@ -import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; +import { v4 as uuidv4 } from 'uuid'; +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; import { - ProblemDetailsModel, DataTypeResource, - DataTypeModel, - DataTypeCreateModel, - DataTypeUpdateModel, -} from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; + DataTypeResponseModel, + DataTypeModelBaseModel, + CreateDataTypeRequestModel, + UpdateDataTypeRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Data Type that fetches data from the server @@ -15,48 +16,46 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class UmbDataTypeServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbDataTypeServerDataSource implements RepositoryDetailDataSource { - #host: UmbControllerHostInterface; +export class UmbDataTypeServerDataSource + implements UmbDataSource +{ + #host: UmbControllerHostElement; /** * Creates an instance of UmbDataTypeServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDataTypeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** - * Fetches a Data Type with the given key from the server - * @param {string} key + * Fetches a Data Type with the given id from the server + * @param {string} id * @return {*} * @memberof UmbDataTypeServerDataSource */ - async get(key: string) { - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - + async get(id: string) { + if (!id) throw new Error('Key is missing'); return tryExecuteAndNotify( this.#host, - DataTypeResource.getDataTypeByKey({ - key, + DataTypeResource.getDataTypeById({ + id: id, }) ); } /** * Creates a new Data Type scaffold - * @param {(string | null)} parentKey - * @return {*} + * @param {(string | null)} parentId + * @return { CreateDataTypeRequestModel } * @memberof UmbDataTypeServerDataSource */ - async createScaffold(parentKey: string | null) { - const data: DataTypeModel = { - $type: '', - parentKey: parentKey, + async createScaffold(parentId?: string | null) { + const data: CreateDataTypeRequestModel = { + id: uuidv4(), + parentId, }; return { data }; @@ -68,89 +67,49 @@ export class UmbDataTypeServerDataSource implements RepositoryDetailDataSource( + return tryExecuteAndNotify( this.#host, - // TODO: avoid this any?.. - tryExecuteAndNotify( - this.#host, - DataTypeResource.postDataType({ - requestBody, - }) - ) as any - ); - } - - /** - * Updates a DataType on the server - * @param {DataTypeModel} DataType - * @return {*} - * @memberof UmbDataTypeServerDataSource - */ - // TODO: Error mistake in this: - async update(dataType: DataTypeModel) { - if (!dataType.key) { - const error: ProblemDetailsModel = { title: 'DataType key is missing' }; - return { error }; - } - - const requestBody: DataTypeUpdateModel = { ...dataType }; - - // TODO: use resources when end point is ready: - return tryExecuteAndNotify( - this.#host, - DataTypeResource.putDataTypeByKey({ - key: dataType.key, - requestBody, + DataTypeResource.postDataType({ + requestBody: dataType, }) ); } /** - * Trash a Document on the server - * @param {Document} Document + * Updates a DataType on the server + * @param {DataTypeResponseModel} DataType * @return {*} * @memberof UmbDataTypeServerDataSource */ - async trash(key: string) { - if (!key) { - const error: ProblemDetailsModel = { title: 'DataType key is missing' }; - return { error }; - } + async update(id: string, data: DataTypeModelBaseModel) { + if (!id) throw new Error('Key is missing'); - // TODO: use resources when end point is ready: - return tryExecuteAndNotify( + return tryExecuteAndNotify( this.#host, - DataTypeResource.deleteDataTypeByKey({ - key, + DataTypeResource.putDataTypeById({ + id: id, + requestBody: data, }) ); } /** * Deletes a Data Type on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbDataTypeServerDataSource */ - async delete(key: string) { - if (!key) { - const error: ProblemDetailsModel = { title: 'DataType key is missing' }; - return { error }; - } + async delete(id: string) { + if (!id) throw new Error('Key is missing'); - // TODO: use resources when end point is ready: - return tryExecuteAndNotify( + return tryExecuteAndNotify( this.#host, - DataTypeResource.deleteDataTypeByKey({ - key, + DataTypeResource.deleteDataTypeById({ + id: id, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.tree.server.data.ts index 1ddaf7e517..f1da0afaa9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/repository/sources/data-type.tree.server.data.ts @@ -1,104 +1,64 @@ -import type { RepositoryTreeDataSource } from '../../../../../../libs/repository/repository-tree-data-source.interface'; -import { ProblemDetailsModel, DataTypeResource } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import type { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { DataTypeResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Document tree that fetches data from the server * @export - * @class DocumentTreeServerDataSource + * @class UmbDataTypeTreeServerDataSource * @implements {DocumentTreeDataSource} */ -export class DataTypeTreeServerDataSource implements RepositoryTreeDataSource { - #host: UmbControllerHostInterface; - - // TODO: how do we handle trashed items? - async trashItems(keys: Array) { - if (!keys) { - const error: ProblemDetailsModel = { title: 'DataType keys is missing' }; - return { error }; - } - - // TODO: use resources when end point is ready: - /* - return tryExecuteAndNotify( - this.#host, - DataTypeResource.deleteDataTypeByKey({ - key: keys, - }) - ); - */ - return Promise.resolve({ error: null, data: null }); - } - - async moveItems(keys: Array, destination: string) { - // TODO: use backend cli when available. - return tryExecuteAndNotify( - this.#host, - fetch('/umbraco/management/api/v1/data-type/move', { - method: 'POST', - body: JSON.stringify({ keys, destination }), - headers: { - 'Content-Type': 'application/json', - }, - }) - ); - } +export class UmbDataTypeTreeServerDataSource implements UmbTreeDataSource { + #host: UmbControllerHostElement; /** - * Creates an instance of DocumentTreeServerDataSource. - * @param {UmbControllerHostInterface} host - * @memberof DocumentTreeServerDataSource + * Creates an instance of UmbDataTypeTreeServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbDataTypeTreeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** * Fetches the root items for the tree from the server * @return {*} - * @memberof DocumentTreeServerDataSource + * @memberof UmbDataTypeTreeServerDataSource */ async getRootItems() { return tryExecuteAndNotify(this.#host, DataTypeResource.getTreeDataTypeRoot({})); } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} - * @memberof DocumentTreeServerDataSource + * @memberof UmbDataTypeTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; - return { error }; - } + async getChildrenOf(parentId: string | null) { + if (!parentId) throw new Error('Parent id is missing'); return tryExecuteAndNotify( this.#host, DataTypeResource.getTreeDataTypeChildren({ - parentKey, + parentId, }) ); } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} - * @memberof DocumentTreeServerDataSource + * @memberof UmbDataTypeTreeServerDataSource */ - async getItems(keys: Array) { - if (keys) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; - return { error }; - } - + async getItems(ids: Array) { + if (!ids) throw new Error('Ids are missing'); return tryExecuteAndNotify( this.#host, - DataTypeResource.getTreeDataTypeItem({ - key: keys, + DataTypeResource.getDataTypeItem({ + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/manifests.ts index 6d1c73262f..49c0a602a4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/tree/manifests.ts @@ -1,13 +1,23 @@ -import { UmbDataTypeRepository } from '../repository/data-type.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { DATA_TYPE_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const tree: ManifestTree = { type: 'tree', alias: 'Umb.Tree.DataTypes', name: 'Data Types Tree', meta: { - repository: UmbDataTypeRepository, + repositoryAlias: DATA_TYPE_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.DataType', + name: 'Data Type Tree Item', + conditions: { + entityType: 'data-type', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace-edit.element.ts new file mode 100644 index 0000000000..2b065e6bb1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace-edit.element.ts @@ -0,0 +1,89 @@ +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; +import { UmbDataTypeWorkspaceContext } from './data-type-workspace.context'; +import { UmbRouteLocation } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { ManifestWorkspace } from '@umbraco-cms/backoffice/extensions-registry'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +/** + * @element umb-data-type-workspace-edit-element + * @description - Element for displaying the Data Type Workspace edit route. + */ +@customElement('umb-data-type-workspace-edit-element') +export class UmbDataTypeWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + + #header { + /* TODO: can this be applied from layout slot CSS? */ + margin: 0 var(--uui-size-layout-1); + flex: 1 1 auto; + } + `, + ]; + + @property() + manifest?: ManifestWorkspace; + + @property() + location?: UmbRouteLocation; + + @state() + private _dataTypeName = ''; + + #workspaceContext?: UmbDataTypeWorkspaceContext; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (workspaceContext) => { + this.#workspaceContext = workspaceContext as UmbDataTypeWorkspaceContext; + this.#observeName(); + }); + } + + #observeName() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.name, (dataTypeName) => { + if (dataTypeName !== this._dataTypeName) { + this._dataTypeName = dataTypeName ?? ''; + } + }); + } + + // TODO. find a way where we don't have to do this for all Workspaces. + #handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + render() { + return html` + + + + `; + } +} + +export default UmbDataTypeWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-data-type-workspace-edit-element': UmbDataTypeWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.context.ts index 531531c39d..127850dc1f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.context.ts @@ -1,44 +1,48 @@ import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; import { UmbDataTypeRepository } from '../repository/data-type.repository'; -import type { DataTypeModel } from '@umbraco-cms/backend-api'; -import { appendToFrozenArray, ObjectState } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { CreateDataTypeRequestModel, DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { appendToFrozenArray, ObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbDataTypeWorkspaceContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { - #data = new ObjectState(undefined); + // TODO: revisit. temp solution because the create and response models are different. + #data = new ObjectState(undefined); data = this.#data.asObservable(); - name = this.#data.getObservablePart((data) => data?.name); - key = this.#data.getObservablePart((data) => data?.key); - constructor(host: UmbControllerHostInterface) { + name = this.#data.getObservablePart((data) => data?.name); + id = this.#data.getObservablePart((data) => data?.id); + + constructor(host: UmbControllerHostElement) { super(host, new UmbDataTypeRepository(host)); } - async load(key: string) { - const { data } = await this.repository.requestByKey(key); + async load(id: string) { + const { data } = await this.repository.requestById(id); if (data) { this.setIsNew(false); this.#data.update(data); } } - async createScaffold(parentKey: string | null) { - const { data } = await this.repository.createScaffold(parentKey); - if (!data) return; + async createScaffold(parentId: string | null) { + const { data } = await this.repository.createScaffold(parentId); this.setIsNew(true); - this.#data.next(data); + // TODO: This is a hack to get around the fact that the data is not typed correctly. + // Create and response models are different. We need to look into this. + this.#data.next(data as unknown as DataTypeResponseModel); + return { data }; } getData() { return this.#data.getValue(); } - getEntityKey() { - return this.getData()?.key || ''; + getEntityId() { + return this.getData()?.id || ''; } getEntityType() { @@ -63,24 +67,26 @@ export class UmbDataTypeWorkspaceContext const currentData = this.#data.value; if (currentData) { // TODO: make a partial update method for array of data, (idea/concept, use if this case is getting common) - const newDataSet = appendToFrozenArray(currentData.data || [], entry, (x) => x.alias); - this.#data.update({ data: newDataSet }); + const newDataSet = appendToFrozenArray(currentData.values || [], entry, (x) => x.alias); + this.#data.update({ values: newDataSet }); } } async save() { if (!this.#data.value) return; + if (!this.#data.value.id) return; + if (this.isNew) { await this.repository.create(this.#data.value); } else { - await this.repository.save(this.#data.value); + await this.repository.save(this.#data.value.id, this.#data.value); } // If it went well, then its not new anymore?. this.setIsNew(false); } - async delete(key: string) { - await this.repository.delete(key); + async delete(id: string) { + await this.repository.delete(id); } public destroy(): void { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.element.ts index 9dbc32333b..69f1f01de7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.element.ts @@ -1,73 +1,42 @@ -import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbDataTypeWorkspaceContext } from './data-type-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +import './data-type-workspace-edit.element'; -/** - * @element umb-data-type-workspace - * @description - Element for displaying a Data Type Workspace - */ @customElement('umb-data-type-workspace') export class UmbDataTypeWorkspaceElement extends UmbLitElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - width: 100%; - height: 100%; - } - - #header { - /* TODO: can this be applied from layout slot CSS? */ - margin: 0 var(--uui-size-layout-1); - flex: 1 1 auto; - } - `, - ]; + static styles = [UUITextStyles, css``]; #workspaceContext = new UmbDataTypeWorkspaceContext(this); + #element = document.createElement('umb-data-type-workspace-edit-element'); + @state() - private _dataTypeName = ''; - - public load(value: string) { - this.#workspaceContext?.load(value); - //this._unique = entityKey; - } - - public create(parentKey: string | null) { - this.#workspaceContext.createScaffold(parentKey); - } - - constructor() { - super(); - this.observe(this.#workspaceContext.name, (dataTypeName) => { - if (dataTypeName !== this._dataTypeName) { - this._dataTypeName = dataTypeName ?? ''; - } - }); - } - - // TODO. find a way where we don't have to do this for all Workspaces. - #handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this.#workspaceContext.setName(target.value); - } - } - } + _routes: IRoute[] = [ + { + path: 'create/:parentId', + component: () => this.#element, + setup: (_component, info) => { + const parentId = info.match.params.parentId === 'null' ? null : info.match.params.parentId; + this.#workspaceContext.createScaffold(parentId); + }, + }, + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - return html` - - - - `; + return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.stories.ts index 254a12f137..61c3a003d2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/data-type-workspace.stories.ts @@ -1,8 +1,9 @@ import './data-type-workspace.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { data } from '../../../../core/mocks/data/data-type.data'; import type { UmbDataTypeWorkspaceElement } from './data-type-workspace.element'; @@ -14,5 +15,5 @@ export default { } as Meta; export const AAAOverview: Story = () => - html` `; + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/manifests.ts index f23cb76d4e..f743839a8f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/manifests.ts @@ -1,9 +1,15 @@ -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; + +const DATA_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.DataType'; const workspace: ManifestWorkspace = { type: 'workspace', - alias: 'Umb.Workspace.DataType', + alias: DATA_TYPE_WORKSPACE_ALIAS, name: 'Data Type Workspace', loader: () => import('./data-type-workspace.element'), meta: { @@ -16,14 +22,16 @@ const workspaceViews: Array = [ type: 'workspaceView', alias: 'Umb.WorkspaceView.DataType.Edit', name: 'Data Type Workspace Edit View', - loader: () => import('./views/edit/data-type-workspace-view-edit.element'), + loader: () => import('./views/details/data-type-details-workspace-view.element'), weight: 90, meta: { - workspaces: ['Umb.Workspace.DataType'], - label: 'Edit', - pathname: 'edit', + label: 'Details', + pathname: 'details', icon: 'edit', }, + conditions: { + workspaces: [DATA_TYPE_WORKSPACE_ALIAS], + }, }, { type: 'workspaceView', @@ -32,11 +40,13 @@ const workspaceViews: Array = [ loader: () => import('./views/info/workspace-view-data-type-info.element'), weight: 90, meta: { - workspaces: ['Umb.Workspace.DataType'], label: 'Info', pathname: 'info', icon: 'info', }, + conditions: { + workspaces: [DATA_TYPE_WORKSPACE_ALIAS], + }, }, ]; @@ -46,12 +56,14 @@ const workspaceActions: Array = [ alias: 'Umb.WorkspaceAction.DataType.Save', name: 'Save Data Type Workspace Action', meta: { - workspaces: ['Umb.Workspace.DataType'], label: 'Save', look: 'primary', color: 'positive', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: [DATA_TYPE_WORKSPACE_ALIAS], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/details/data-type-details-workspace-view.element.ts similarity index 82% rename from src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/details/data-type-details-workspace-view.element.ts index fd12cca7b2..6b0213cc0b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/details/data-type-details-workspace-view.element.ts @@ -2,17 +2,21 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbDataTypeWorkspaceContext } from '../../data-type-workspace.context'; -import { UMB_PROPERTY_EDITOR_UI_PICKER_MODAL_TOKEN } from '../../../../../shared/property-editors/modals/property-editor-ui-picker'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DataTypeModel } from '@umbraco-cms/backend-api'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_PROPERTY_EDITOR_UI_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; import '../../../../../shared/property-editors/shared/property-editor-config/property-editor-config.element'; import '../../../../../shared/components/ref-property-editor-ui/ref-property-editor-ui.element'; -@customElement('umb-data-type-workspace-view-edit') -export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement { +@customElement('umb-data-type-details-workspace-view') +export class UmbDataTypeDetailsWorkspaceViewEditElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -24,7 +28,7 @@ export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement { ]; @state() - _dataType?: DataTypeModel; + _dataType?: DataTypeResponseModel; @state() private _propertyEditorUIIcon = ''; @@ -52,8 +56,8 @@ export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement { }); // TODO: Figure out if this is the best way to consume a context or if it could be strongly typed using UmbContextToken - this.consumeContext('umbWorkspaceContext', (_instance) => { - this._workspaceContext = _instance; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (_instance) => { + this._workspaceContext = _instance as UmbDataTypeWorkspaceContext; this._observeDataType(); }); } @@ -73,8 +77,8 @@ export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement { this._observePropertyEditorUI(this._dataType.propertyEditorUiAlias || undefined); } - if (this._dataType.data && this._dataType.data !== this._data) { - this._data = this._dataType.data; + if (this._dataType.values && this._dataType.values !== this._data) { + this._data = this._dataType.values; } }); } @@ -101,7 +105,7 @@ export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement { private _openPropertyEditorUIPicker() { if (!this._dataType) return; - const modalHandler = this._modalContext?.open(UMB_PROPERTY_EDITOR_UI_PICKER_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_PROPERTY_EDITOR_UI_PICKER_MODAL, { selection: this._propertyEditorUiAlias ? [this._propertyEditorUiAlias] : [], }); @@ -168,10 +172,10 @@ export class UmbDataTypeWorkspaceViewEditElement extends UmbLitElement { } } -export default UmbDataTypeWorkspaceViewEditElement; +export default UmbDataTypeDetailsWorkspaceViewEditElement; declare global { interface HTMLElementTagNameMap { - 'umb-data-type-workspace-view-edit': UmbDataTypeWorkspaceViewEditElement; + 'umb-data-type-details-workspace-view': UmbDataTypeDetailsWorkspaceViewEditElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/details/data-type-details-workspace-view.stories.ts similarity index 73% rename from src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.stories.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/details/data-type-details-workspace-view.stories.ts index 5e3aab4cdf..42cce1558e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/edit/data-type-workspace-view-edit.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/details/data-type-details-workspace-view.stories.ts @@ -1,11 +1,11 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; //import { data } from '../../../../../core/mocks/data/data-type.data'; -import type { UmbDataTypeWorkspaceViewEditElement } from './data-type-workspace-view-edit.element'; +import type { UmbDataTypeDetailsWorkspaceViewEditElement } from './data-type-details-workspace-view.element'; -import './data-type-workspace-view-edit.element'; +import './data-type-details-workspace-view.element'; //import { UmbDataTypeWorkspaceContext } from '../../workspace-data-type.context'; export default { @@ -22,6 +22,6 @@ export default { ], } as Meta; -export const AAAOverview: Story = () => +export const AAAOverview: Story = () => html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.element.ts index d7e9f35ac5..03b7ef49a0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.element.ts @@ -2,16 +2,25 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbDataTypeWorkspaceContext } from '../../data-type-workspace.context'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DataTypeModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-workspace-view-data-type-info') export class UmbWorkspaceViewDataTypeInfoElement extends UmbLitElement { - static styles = [UUITextStyles, css``]; + static styles = [ + UUITextStyles, + css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + `, + ]; @state() - _dataType?: DataTypeModel; + _dataType?: DataTypeResponseModel; private _workspaceContext?: UmbDataTypeWorkspaceContext; @@ -19,8 +28,8 @@ export class UmbWorkspaceViewDataTypeInfoElement extends UmbLitElement { super(); // TODO: Figure out if this is the best way to consume the context or if it can be strongly typed with an UmbContextToken - this.consumeContext('umbWorkspaceContext', (dataTypeContext) => { - this._workspaceContext = dataTypeContext; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (dataTypeContext) => { + this._workspaceContext = dataTypeContext as UmbDataTypeWorkspaceContext; this._observeDataType(); }); } @@ -41,8 +50,8 @@ export class UmbWorkspaceViewDataTypeInfoElement extends UmbLitElement { private _renderGeneralInfo() { return html` - -

${this._dataType?.key}
+ +
${this._dataType?.id}
${this._dataType?.propertyEditorAlias}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.stories.ts index 81ff7b8607..b819c5c983 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/data-types/workspace/views/info/workspace-view-data-type-info.stories.ts @@ -1,7 +1,7 @@ import './workspace-view-data-type-info.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; //import { data } from '../../../../../core/mocks/data/data-type.data'; //import { UmbDataTypeContext } from '../../data-type.context'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/menu-item/manifests.ts index aa8ba20a12..235c44f796 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/menu-item/manifests.ts @@ -1,14 +1,16 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; const menuItem: ManifestMenuItem = { type: 'menuItem', alias: 'Umb.MenuItem.Extensions', name: 'Extensions Menu Item', - weight: 100, + weight: 0, meta: { label: 'Extensions', icon: 'umb:wand', entityType: 'extension-root', + }, + conditions: { menus: ['Umb.Menu.Settings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts index 2f5d2ecfcb..5831501295 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.element.ts @@ -1,15 +1,23 @@ -import { html } from 'lit'; +import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../shared/modals/confirm'; -import { isManifestElementNameType, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import type { ManifestBase } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { map } from 'rxjs'; +import { isManifestElementNameType, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; @customElement('umb-extension-root-workspace') export class UmbExtensionRootWorkspaceElement extends UmbLitElement { + static styles = [ + css` + uui-box { + margin: var(--uui-size-layout-1); + } + `, + ]; + @state() - private _extensions?: Array = undefined; + private _extensions?: Array = undefined; private _modalContext?: UmbModalContext; @@ -23,13 +31,27 @@ export class UmbExtensionRootWorkspaceElement extends UmbLitElement { } private _observeExtensions() { - this.observe(umbExtensionsRegistry.extensionsSortedByTypeAndWeight(), (extensions) => { - this._extensions = extensions || undefined; - }); + this.observe( + umbExtensionsRegistry.extensions.pipe( + map((exts) => + exts.sort((a, b) => { + // If type is the same, sort by weight + if (a.type === b.type) { + return (b.weight || 0) - (a.weight || 0); + } + // Otherwise sort by type + return a.type.localeCompare(b.type); + }) + ) + ), + (extensions) => { + this._extensions = extensions || undefined; + } + ); } - async #removeExtension(extension: ManifestBase) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + async #removeExtension(extension: ManifestTypes) { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Unload extension', confirmLabel: 'Unload', content: html`

Are you sure you want to unload the extension ${extension.alias}?

`, @@ -42,7 +64,7 @@ export class UmbExtensionRootWorkspaceElement extends UmbLitElement { render() { return html` - + diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.stories.ts index 65223c1522..55f8ef3fbd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/extension-root-workspace.stories.ts @@ -1,7 +1,7 @@ import './extension-root-workspace.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbExtensionRootWorkspaceElement } from './extension-root-workspace.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/manifests.ts index b6fb47aaf6..e0496a26ae 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/extensions/workspace/manifests.ts @@ -1,4 +1,8 @@ -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/index.ts index abe3d1ba75..a578c12d5c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/index.ts @@ -2,13 +2,14 @@ import { manifests as settingsSectionManifests } from './section.manifests'; import { manifests as settingsMenuManifests } from './menu.manifests'; import { manifests as dashboardManifests } from './dashboards/manifests'; import { manifests as dataTypeManifests } from './data-types/manifests'; +import { manifests as relationTypeManifests } from './relation-types/manifests'; import { manifests as extensionManifests } from './extensions/manifests'; import { manifests as cultureManifests } from './cultures/manifests'; import { manifests as languageManifests } from './languages/manifests'; import { manifests as logviewerManifests } from './logviewer/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [ ...settingsSectionManifests, @@ -19,6 +20,7 @@ export const manifests = [ ...cultureManifests, ...languageManifests, ...logviewerManifests, + ...relationTypeManifests, ]; const registerExtensions = (manifests: Array) => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts index a69f693017..9ccf25f8e7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language-select.element.ts @@ -2,12 +2,12 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UUIMenuItemEvent } from '@umbraco-ui/uui'; import { UmbLanguageRepository } from '../repository/language.repository'; import { UMB_APP_LANGUAGE_CONTEXT_TOKEN, UmbAppLanguageContext } from './app-language.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { LanguageModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-app-language-select') export class UmbAppLanguageSelectElement extends UmbLitElement { @@ -43,10 +43,10 @@ export class UmbAppLanguageSelectElement extends UmbLitElement { ]; @state() - private _languages: Array = []; + private _languages: Array = []; @state() - private _appLanguage?: LanguageModel; + private _appLanguage?: LanguageResponseModel; @state() private _isOpen = false; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts index 867f876579..6f85f5c271 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/app-language.context.ts @@ -1,19 +1,19 @@ import { UmbLanguageRepository } from '../repository/language.repository'; -import { ObjectState, UmbObserverController } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { LanguageModel } from '@umbraco-cms/backend-api'; +import { ObjectState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; export class UmbAppLanguageContext { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #languageRepository: UmbLanguageRepository; - #languages: Array = []; + #languages: Array = []; - #appLanguage = new ObjectState(undefined); + #appLanguage = new ObjectState(undefined); appLanguage = this.#appLanguage.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; this.#languageRepository = new UmbLanguageRepository(this.#host); this.#observeLanguages(); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/manifests.ts index 345c971563..356740c865 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/app-language-select/manifests.ts @@ -1,4 +1,4 @@ -import { ManifestSectionSidebarApp } from '@umbraco-cms/extensions-registry'; +import { ManifestSectionSidebarApp } from '@umbraco-cms/backoffice/extensions-registry'; const entityActions: Array = [ { @@ -6,7 +6,8 @@ const entityActions: Array = [ alias: 'Umb.SectionSidebarItem.LanguageSelect', name: 'App Language Select Section Sidebar Item', loader: () => import('./app-language-select.element'), - meta: { + weight: 900, + conditions: { sections: ['Umb.Section.Content'], }, }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/entity-actions/manifests.ts index 7852f3e09c..c917cfb11b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/entity-actions/manifests.ts @@ -1,6 +1,6 @@ import { LANGUAGE_REPOSITORY_ALIAS } from '../repository/manifests'; -import { UmbDeleteEntityAction } from '@umbraco-cms/entity-action'; -import { ManifestEntityAction } from '@umbraco-cms/extensions-registry'; +import { UmbDeleteEntityAction } from '@umbraco-cms/backoffice/entity-action'; +import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; const entityType = 'language'; @@ -10,12 +10,14 @@ const entityActions: Array = [ alias: 'Umb.EntityAction.Language.Delete', name: 'Delete Language Entity Action', meta: { - entityType, repositoryAlias: LANGUAGE_REPOSITORY_ALIAS, icon: 'umb:trash', label: 'Delete', api: UmbDeleteEntityAction, }, + conditions: { + entityType, + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/menu-item/manifests.ts index 258f0a95c1..fd4125fab1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/menu-item/manifests.ts @@ -1,14 +1,16 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; const menuItem: ManifestMenuItem = { type: 'menuItem', alias: 'Umb.MenuItem.Languages', name: 'Languages Menu Item', - weight: 80, + weight: 100, meta: { label: 'Languages', icon: 'umb:globe', entityType: 'language-root', + }, + conditions: { menus: ['Umb.Menu.Settings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/language-picker/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/language-picker/index.ts deleted file mode 100644 index 5f551178ad..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/language-picker/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { LanguageModel } from '@umbraco-cms/backend-api'; -import { UmbModalToken } from '@umbraco-cms/modal'; - -export interface UmbLanguagePickerModalData { - multiple?: boolean; - selection?: Array; - filter?: (language: LanguageModel) => boolean; -} - -export interface UmbLanguagePickerModalResult { - selection: Array; -} - -export const UMB_LANGUAGE_PICKER_MODAL_TOKEN = new UmbModalToken< - UmbLanguagePickerModalData, - UmbLanguagePickerModalResult ->('Umb.Modal.LanguagePicker', { - type: 'sidebar', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/language-picker/language-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/language-picker/language-picker-modal.element.ts index 98a4407e97..e59782b652 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/language-picker/language-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/language-picker/language-picker-modal.element.ts @@ -1,19 +1,19 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { repeat } from 'lit-html/directives/repeat.js'; +import { repeat } from 'lit/directives/repeat.js'; import { UUIMenuItemElement, UUIMenuItemEvent } from '@umbraco-ui/uui'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbLanguageRepository } from '../../repository/language.repository'; -import { UmbModalElementPickerBase } from '@umbraco-cms/modal'; -import { LanguageModel } from '@umbraco-cms/backend-api'; +import { UmbModalElementPickerBase } from '@umbraco-cms/internal/modal'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-language-picker-modal') -export class UmbLanguagePickerModalElement extends UmbModalElementPickerBase { +export class UmbLanguagePickerModalElement extends UmbModalElementPickerBase { static styles = [UUITextStyles, css``]; @state() - private _languages: Array = []; + private _languages: Array = []; private _languageRepository = new UmbLanguageRepository(this); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/manifests.ts index 06cf317a04..8b9b68e450 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts index ef87ea9abe..d37dada762 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.repository.ts @@ -1,21 +1,21 @@ import { UmbLanguageServerDataSource } from './sources/language.server.data'; import { UmbLanguageStore, UMB_LANGUAGE_STORE_CONTEXT_TOKEN } from './language.store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import { LanguageModel, ProblemDetailsModel } from '@umbraco-cms/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { LanguageResponseModel, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; export class UmbLanguageRepository { #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #dataSource: UmbLanguageServerDataSource; #languageStore?: UmbLanguageStore; #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; this.#dataSource = new UmbLanguageServerDataSource(this.#host); @@ -84,7 +84,7 @@ export class UmbLanguageRepository { return this.#dataSource.createScaffold(); } - async create(language: LanguageModel) { + async create(language: LanguageResponseModel) { await this.#init; const { error } = await this.#dataSource.insert(language); @@ -104,10 +104,12 @@ export class UmbLanguageRepository { * @return {*} * @memberof UmbLanguageRepository */ - async save(language: LanguageModel) { + async save(language: LanguageResponseModel) { + if (!language.isoCode) throw new Error('Language iso code is missing'); + await this.#init; - const { error } = await this.#dataSource.update(language); + const { error } = await this.#dataSource.update(language.isoCode, language); if (!error) { const notification = { data: { message: `Language saved` } }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts index 3da9a5a38a..820b66fc50 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/language.store.ts @@ -1,8 +1,8 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { LanguageModel } from '@umbraco-cms/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; export const UMB_LANGUAGE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbLanguageStore'); @@ -13,14 +13,14 @@ export const UMB_LANGUAGE_STORE_CONTEXT_TOKEN = new UmbContextToken([], (x) => x.isoCode); + #data = new ArrayState([], (x) => x.isoCode); data = this.#data.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_LANGUAGE_STORE_CONTEXT_TOKEN.toString()); } - append(language: LanguageModel) { + append(language: LanguageResponseModel) { this.#data.append([language]); } @@ -33,4 +33,3 @@ export class UmbLanguageStore extends UmbStoreBase { return this.#data.getObservablePart((items) => items.filter((item) => isoCodes.includes(item.isoCode ?? ''))); } } - diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/manifests.ts index a69836165b..75dcb127c4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/manifests.ts @@ -1,7 +1,6 @@ import { UmbLanguageRepository } from '../repository/language.repository'; import { UmbLanguageStore } from './language.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const LANGUAGE_REPOSITORY_ALIAS = 'Umb.Repository.Language'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/index.ts deleted file mode 100644 index 81efc0303f..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { LanguageModel, PagedLanguageModel } from '@umbraco-cms/backend-api'; -import type { DataSourceResponse } from '@umbraco-cms/models'; -import { RepositoryDetailDataSource } from '@umbraco-cms/repository'; - -// TODO: This is a temporary solution until we have a proper paging interface -type paging = { - skip: number; - take: number; -}; - -export interface UmbLanguageDataSource extends RepositoryDetailDataSource { - createScaffold(): Promise>; - get(isoCode: string): Promise>; - delete(isoCode: string): Promise>; - getCollection(paging: paging): Promise>; -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts index cca5af2960..6764a51dea 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/repository/sources/language.server.data.ts @@ -1,6 +1,12 @@ -import { ProblemDetailsModel, LanguageResource, LanguageModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { + ProblemDetailsModel, + LanguageResource, + LanguageResponseModel, + CreateLanguageRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; /** * A data source for the Language that fetches data from the server @@ -8,15 +14,17 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class UmbLanguageServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbLanguageServerDataSource implements UmbLanguageServerDataSource { - #host: UmbControllerHostInterface; +export class UmbLanguageServerDataSource + implements UmbDataSource +{ + #host: UmbControllerHostElement; /** * Creates an instance of UmbLanguageServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbLanguageServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -27,11 +35,7 @@ export class UmbLanguageServerDataSource implements UmbLanguageServerDataSource * @memberof UmbLanguageServerDataSource */ async get(isoCode: string) { - if (!isoCode) { - const error: ProblemDetailsModel = { title: 'Iso Code is missing' }; - return { error }; - } - + if (!isoCode) throw new Error('Iso Code is missing'); return tryExecuteAndNotify( this.#host, LanguageResource.getLanguageByIsoCode({ @@ -47,11 +51,10 @@ export class UmbLanguageServerDataSource implements UmbLanguageServerDataSource * @memberof UmbLanguageServerDataSource */ async createScaffold() { - const data: LanguageModel = { + const data: LanguageResponseModel = { name: '', isDefault: false, isMandatory: false, - fallbackIsoCode: '', isoCode: '', }; @@ -60,11 +63,11 @@ export class UmbLanguageServerDataSource implements UmbLanguageServerDataSource /** * Inserts a new Language on the server - * @param {LanguageModel} language + * @param {LanguageResponseModel} language * @return {*} * @memberof UmbLanguageServerDataSource */ - async insert(language: LanguageModel) { + async insert(language: CreateLanguageRequestModel) { if (!language.isoCode) { const error: ProblemDetailsModel = { title: 'Language iso code is missing' }; return { error }; @@ -75,11 +78,11 @@ export class UmbLanguageServerDataSource implements UmbLanguageServerDataSource /** * Updates a Language on the server - * @param {LanguageModel} language + * @param {LanguageResponseModel} language * @return {*} * @memberof UmbLanguageServerDataSource */ - async update(language: LanguageModel) { + async update(iscoCode: string, language: LanguageResponseModel) { if (!language.isoCode) { const error: ProblemDetailsModel = { title: 'Language iso code is missing' }; return { error }; @@ -98,15 +101,8 @@ export class UmbLanguageServerDataSource implements UmbLanguageServerDataSource * @memberof UmbLanguageServerDataSource */ async delete(isoCode: string) { - if (!isoCode) { - const error: ProblemDetailsModel = { title: 'Iso code is missing' }; - return { error }; - } - - return tryExecuteAndNotify( - this.#host, - tryExecuteAndNotify(this.#host, LanguageResource.deleteLanguageByIsoCode({ isoCode })).then(() => isoCode) - ); + if (!isoCode) throw new Error('Iso Code is missing'); + return tryExecuteAndNotify(this.#host, LanguageResource.deleteLanguageByIsoCode({ isoCode })); } /** diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/language-root-table-delete-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/components/language-root-table-delete-column-layout.element.ts similarity index 76% rename from src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/language-root-table-delete-column-layout.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/components/language-root-table-delete-column-layout.element.ts index d318a967fa..56493b1112 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/language-root-table-delete-column-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/components/language-root-table-delete-column-layout.element.ts @@ -1,16 +1,16 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { LanguageModel } from '@umbraco-cms/backend-api'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-language-root-table-delete-column-layout') export class UmbLanguageRootTableDeleteColumnLayoutElement extends UmbLitElement { static styles = [UUITextStyles, css``]; @property({ attribute: false }) - value!: LanguageModel; + value!: LanguageResponseModel; @state() _isOpen = false; @@ -34,7 +34,9 @@ export class UmbLanguageRootTableDeleteColumnLayoutElement extends UmbLitElement return html` - + + + ${this.value.name}`; + return html`${this.value.name}`; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/language-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/language-root-workspace.element.ts index aba3ffb008..61065379ef 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/language-root-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/language-root-workspace.element.ts @@ -3,11 +3,11 @@ import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbTableColumn, UmbTableConfig, UmbTableItem } from '../../../../shared/components/table'; import { UmbLanguageRepository } from '../../repository/language.repository'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { LanguageModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; -import './language-root-table-delete-column-layout.element'; -import './language-root-table-name-column-layout.element'; +import './components/language-root-table-delete-column-layout.element'; +import './components/language-root-table-name-column-layout.element'; @customElement('umb-language-root-workspace') export class UmbLanguageRootWorkspaceElement extends UmbLitElement { @@ -21,7 +21,7 @@ export class UmbLanguageRootWorkspaceElement extends UmbLitElement { } #main { - margin: var(--uui-size-space-6); + margin: var(--uui-size-layout-1); } `, ]; @@ -65,6 +65,7 @@ export class UmbLanguageRootWorkspaceElement extends UmbLitElement { private _tableItems: Array = []; #languageRepository = new UmbLanguageRepository(this); + private _cultureNames = new Intl.DisplayNames('en', { type: 'language' }); connectedCallback() { super.connectedCallback(); @@ -79,17 +80,17 @@ export class UmbLanguageRootWorkspaceElement extends UmbLitElement { } } - #createTableItems(languages: Array) { + #createTableItems(languages: Array) { this._tableItems = languages.map((language) => { return { - key: language.isoCode ?? '', + id: language.isoCode ?? '', icon: 'umb:globe', data: [ { columnAlias: 'languageName', value: { - name: language.name, - key: language.isoCode, + name: language.name ? language.name : this._cultureNames.of(language.isoCode ?? ''), + isoCode: language.isoCode, }, }, { @@ -126,7 +127,7 @@ export class UmbLanguageRootWorkspaceElement extends UmbLitElement { label="Add language" look="outline" color="default" - href="section/settings/language/create/root"> + href="section/settings/workspace/language/create">
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/manifests.ts index c70acd49cc..d04dc6b395 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language-root/manifests.ts @@ -1,4 +1,8 @@ -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace-edit.element.ts new file mode 100644 index 0000000000..2647b15a1c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace-edit.element.ts @@ -0,0 +1,106 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UmbLanguageWorkspaceContext } from './language-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-language-workspace-edit') +export class UmbLanguageWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + #header { + display: flex; + padding: 0 var(--uui-size-space-6); + gap: var(--uui-size-space-4); + width: 100%; + } + + uui-input { + width: 100%; + } + + strong { + display: flex; + align-items: center; + } + + #footer { + padding: 0 var(--uui-size-layout-1); + } + + uui-input:not(:focus) { + border: 1px solid transparent; + } + `, + ]; + + #workspaceContext?: UmbLanguageWorkspaceContext; + + @state() + _language?: LanguageResponseModel; + + @state() + _isNew = false; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (context) => { + this.#workspaceContext = context as UmbLanguageWorkspaceContext; + this.#observeData(); + }); + } + + #observeData() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.data, (data) => { + this._language = data; + }); + this.observe(this.#workspaceContext.isNew, (isNew) => { + this._isNew = isNew; + }); + } + + #handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + render() { + return html` + + + `; + } +} + +export default UmbLanguageWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-language-workspace-edit': UmbLanguageWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.context.ts index a31db582a7..5a7ce69293 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/language-workspace.context.ts @@ -1,18 +1,22 @@ import { UmbLanguageRepository } from '../../repository/language.repository'; import { UmbWorkspaceContext } from '../../../../shared/components/workspace/workspace-context/workspace-context'; -import type { LanguageModel } from '@umbraco-cms/backend-api'; -import { ObjectState } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; -export class UmbLanguageWorkspaceContext extends UmbWorkspaceContext { - #data = new ObjectState(undefined); +export class UmbLanguageWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface +{ + #data = new ObjectState(undefined); data = this.#data.asObservable(); // TODO: this is a temp solution to bubble validation errors to the UI #validationErrors = new ObjectState(undefined); validationErrors = this.#validationErrors.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbLanguageRepository(host)); } @@ -29,6 +33,7 @@ export class UmbLanguageWorkspaceContext extends UmbWorkspaceContext { - this._language = data; - }); - } - - load(key: string): void { - this.#languageWorkspaceContext.load(key); - } - - create(): void { - this.#languageWorkspaceContext.createScaffold(); - } - - #handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this.#languageWorkspaceContext?.setName(target.value); - } - } - } + @state() + _routes: IRoute[] = [ + { + path: 'edit/:isoCode', + component: () => this.#element, + setup: (_component, info) => { + this.#languageWorkspaceContext.load(info.match.params.isoCode); + }, + }, + { + path: 'create', + component: () => this.#element, + setup: () => { + this.#languageWorkspaceContext.createScaffold(); + }, + }, + ]; render() { - if (!this._language) return nothing; - - return html` - - - - `; + return html` { + this.#routerPath = event.target.absoluteRouterPath; + }}>`; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/manifests.ts index 94bc97a049..4e85e5b348 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/manifests.ts @@ -1,6 +1,9 @@ -import { LANGUAGE_REPOSITORY_ALIAS } from '../../repository/manifests'; -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', @@ -15,16 +18,18 @@ const workspace: ManifestWorkspace = { const workspaceViews: Array = [ { type: 'workspaceView', - alias: 'Umb.WorkspaceView.Language.Edit', - name: 'Language Workspace Edit View', - loader: () => import('./views/edit/edit-language-workspace-view.element'), + alias: 'Umb.WorkspaceView.Language.Details', + name: 'Language Workspace Details View', + loader: () => import('./views/details/language-details-workspace-view.element'), weight: 90, meta: { - workspaces: ['Umb.Workspace.Language'], - label: 'Edit', - pathname: 'edit', + label: 'Details', + pathname: 'details', icon: 'edit', }, + conditions: { + workspaces: ['Umb.Workspace.Language'], + }, }, ]; @@ -34,12 +39,14 @@ const workspaceActions: Array = [ alias: 'Umb.WorkspaceAction.Language.Save', name: 'Save Language Workspace Action', meta: { - workspaces: ['Umb.Workspace.Language'], look: 'primary', color: 'positive', label: 'Save', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Language'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/edit/edit-language-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/details/language-details-workspace-view.element.ts similarity index 76% rename from src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/edit/edit-language-workspace-view.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/details/language-details-workspace-view.element.ts index 0c27e84f7d..a2c0d105d7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/edit/edit-language-workspace-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/languages/workspace/language/views/details/language-details-workspace-view.element.ts @@ -4,14 +4,15 @@ import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbLanguageWorkspaceContext } from '../../language-workspace.context'; -import UmbInputCultureSelectElement from '../../../../../../shared/components/input-culture-select/input-culture-select.element'; -import UmbInputLanguagePickerElement from '../../../../../../shared/components/input-language-picker/input-language-picker.element'; -import { UmbChangeEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { LanguageModel } from '@umbraco-cms/backend-api'; +import { UmbInputCultureSelectElement } from '../../../../../../shared/components/input-culture-select/input-culture-select.element'; +import { UmbInputLanguagePickerElement } from '../../../../../../shared/components/input-language-picker/input-language-picker.element'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; -@customElement('umb-edit-language-workspace-view') -export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { +@customElement('umb-language-details-workspace-view') +export class UmbLanguageDetailsWorkspaceViewElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -45,7 +46,7 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { ]; @state() - _language?: LanguageModel; + _language?: LanguageResponseModel; @state() _isDefaultLanguage = false; @@ -65,8 +66,8 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { In the language workspace we want to clear a default language change warning and reset the initial state after a save action has been executed. */ let initialStateSet = false; - this.consumeContext('umbWorkspaceContext', (instance) => { - this.#languageWorkspaceContext = instance; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#languageWorkspaceContext = instance as UmbLanguageWorkspaceContext; this.observe(this.#languageWorkspaceContext.data, (language) => { this._language = language; @@ -97,6 +98,11 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { const isoCode = target.value.toString(); const cultureName = target.selectedCultureName; + // If there is no cultureName, it was probably an unknown event that triggered the change event, so ignore it. + if (!cultureName) { + return; + } + if (!isoCode) { // If the isoCode is empty, we reset the value to the original value. // Provides a way better UX @@ -142,15 +148,13 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { } render() { - if (!this._language) return nothing; - return html`
@@ -162,14 +166,15 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { -
${this._language.isoCode}
+
${this._language?.isoCode}
Default language @@ -177,14 +182,17 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement {
- ${this._language.isDefault !== this._isDefaultLanguage + ${this._language?.isDefault && this._language?.isDefault !== this._isDefaultLanguage ? html`
Switching default language may result in default content missing.
` : nothing}
- +
Mandatory language
Properties on this language have to be filled out before the node can be published.
@@ -197,11 +205,11 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { label="Fallback language" description="To allow multi-lingual content to fall back to another language if not present in the requested language, select it here."> + .filter=${(language: LanguageResponseModel) => language.isoCode !== this._language?.isoCode}> @@ -209,10 +217,10 @@ export class UmbEditLanguageWorkspaceViewElement extends UmbLitElement { } } -export default UmbEditLanguageWorkspaceViewElement; +export default UmbLanguageDetailsWorkspaceViewElement; declare global { interface HTMLElementTagNameMap { - 'umb-edit-language-workspace-view': UmbEditLanguageWorkspaceViewElement; + 'umb-language-details-workspace-view': UmbLanguageDetailsWorkspaceViewElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/menu-item/manifests.ts index 558df963b7..5d2069c1b4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/menu-item/manifests.ts @@ -1,14 +1,16 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; const menuItem: ManifestMenuItem = { type: 'menuItem', alias: 'Umb.MenuItem.LogViewer', name: 'LogViewer Menu Item', - weight: 70, + weight: 300, meta: { label: 'Log Viewer', icon: 'umb:box-alt', entityType: 'logviewer', + }, + conditions: { menus: ['Umb.Menu.Settings'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/log-viewer.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/log-viewer.repository.ts index 5870e28762..15ad25e1b0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/log-viewer.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/log-viewer.repository.ts @@ -1,22 +1,22 @@ import { UmbLogMessagesServerDataSource, UmbLogSearchesServerDataSource } from './sources/log-viewer.server.data'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import { DirectionModel, LogLevelModel } from '@umbraco-cms/backend-api'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { DirectionModel, LogLevelModel } from '@umbraco-cms/backoffice/backend-api'; // Move to documentation / JSdoc /* We need to create a new instance of the repository from within the element context. We want the notifications to be displayed in the right context. */ // element -> context -> repository -> (store) -> data source // All methods should be async and return a promise. Some methods might return an observable as part of the promise response. export class UmbLogViewerRepository { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #searchDataSource: UmbLogSearchesServerDataSource; #messagesDataSource: UmbLogMessagesServerDataSource; #notificationService?: UmbNotificationContext; #initResolver?: () => void; #initialized = false; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; this.#searchDataSource = new UmbLogSearchesServerDataSource(this.#host); this.#messagesDataSource = new UmbLogMessagesServerDataSource(this.#host); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/index.ts index 518a5e18af..944990c6d9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/index.ts @@ -1,16 +1,14 @@ -import { +import type { DirectionModel, - LogLevelCountsModel, + LogLevelCountsReponseModel, LogLevelModel, - PagedLoggerModel, - PagedLogMessageModel, - PagedLogTemplateModel, - PagedSavedLogSearchModel, - SavedLogSearchModel, -} from '@umbraco-cms/backend-api'; -import type { DataSourceResponse } from '@umbraco-cms/models'; - - + PagedLoggerResponseModel, + PagedLogMessageResponseModel, + PagedLogTemplateResponseModel, + PagedSavedLogSearchResponseModel, + SavedLogSearchResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; export interface LogSearchDataSource { getAllSavedSearches({ @@ -19,25 +17,31 @@ export interface LogSearchDataSource { }: { skip?: number; take?: number; - }): Promise>; - getSavedSearchByName({ name }: { name: string }): Promise>; + }): Promise>; + getSavedSearchByName({ name }: { name: string }): Promise>; deleteSavedSearchByName({ name }: { name: string }): Promise>; postLogViewerSavedSearch({ requestBody, }: { - requestBody?: SavedLogSearchModel; + requestBody?: SavedLogSearchResponseModel; }): Promise>; } export interface LogMessagesDataSource { - getLogViewerLevel({ skip, take }: { skip?: number; take?: number }): Promise>; + getLogViewerLevel({ + skip, + take, + }: { + skip?: number; + take?: number; + }): Promise>; getLogViewerLevelCount({ startDate, endDate, }: { startDate?: string; endDate?: string; - }): Promise>; + }): Promise>; getLogViewerLogs({ skip, take = 100, @@ -54,7 +58,7 @@ export interface LogMessagesDataSource { logLevel?: Array; startDate?: string; endDate?: string; - }): Promise>; + }): Promise>; getLogViewerMessageTemplate({ skip, take = 100, @@ -65,5 +69,5 @@ export interface LogMessagesDataSource { take?: number; startDate?: string; endDate?: string; - }): Promise>; + }): Promise>; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/log-viewer.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/log-viewer.server.data.ts index ebdf1264e5..660ab50056 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/log-viewer.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/repository/sources/log-viewer.server.data.ts @@ -1,7 +1,12 @@ import { LogMessagesDataSource, LogSearchDataSource } from '.'; -import { DirectionModel, LogLevelModel, LogViewerResource, SavedLogSearchModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { + DirectionModel, + LogLevelModel, + LogViewerResource, + SavedLogSearchResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the log saved searches @@ -10,14 +15,14 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @implements {TemplateDetailDataSource} */ export class UmbLogSearchesServerDataSource implements LogSearchDataSource { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; /** * Creates an instance of UmbLogSearchesServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbLogSearchesServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -49,7 +54,7 @@ export class UmbLogSearchesServerDataSource implements LogSearchDataSource { * @return {*} * @memberof UmbLogSearchesServerDataSource */ - async postLogViewerSavedSearch({ requestBody }: { requestBody?: SavedLogSearchModel }) { + async postLogViewerSavedSearch({ requestBody }: { requestBody?: SavedLogSearchResponseModel }) { return await tryExecuteAndNotify(this.#host, LogViewerResource.postLogViewerSavedSearch({ requestBody })); } /** @@ -63,151 +68,151 @@ export class UmbLogSearchesServerDataSource implements LogSearchDataSource { return await tryExecuteAndNotify(this.#host, LogViewerResource.deleteLogViewerSavedSearchByName({ name })); } } +/** + * A data source for the log messages and levels + * + * @export + * @class UmbLogMessagesServerDataSource + * @implements {LogMessagesDataSource} + */ +export class UmbLogMessagesServerDataSource implements LogMessagesDataSource { + #host: UmbControllerHostElement; + /** - * A data source for the log messages and levels - * - * @export - * @class UmbLogMessagesServerDataSource - * @implements {LogMessagesDataSource} + * Creates an instance of UmbLogMessagesServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbLogMessagesServerDataSource */ - export class UmbLogMessagesServerDataSource implements LogMessagesDataSource { - #host: UmbControllerHostInterface; - - /** - * Creates an instance of UmbLogMessagesServerDataSource. - * @param {UmbControllerHostInterface} host - * @memberof UmbLogMessagesServerDataSource - */ - constructor(host: UmbControllerHostInterface) { - this.#host = host; - } - - /** - * Grabs all the loggers from the server - * - * @param {{ skip?: number; take?: number }} { skip = 0, take = 100 } - * @return {*} - * @memberof UmbLogMessagesServerDataSource - */ - async getLogViewerLevel({ skip = 0, take = 100 }: { skip?: number; take?: number }) { - return await tryExecuteAndNotify(this.#host, LogViewerResource.getLogViewerLevel({ skip, take })); - } - - /** - * Grabs all the number of different log messages from the server - * - * @param {{ skip?: number; take?: number }} { skip = 0, take = 100 } - * @return {*} - * @memberof UmbLogMessagesServerDataSource - */ - async getLogViewerLevelCount({ startDate, endDate }: { startDate?: string; endDate?: string }) { - return await tryExecuteAndNotify( - this.#host, - LogViewerResource.getLogViewerLevelCount({ - startDate, - endDate, - }) - ); - } - /** - * Grabs all the log messages from the server - * - * @param {{ - * skip?: number; - * take?: number; - * orderDirection?: DirectionModel; - * filterExpression?: string; - * logLevel?: Array; - * startDate?: string; - * endDate?: string; - * }} { - * skip = 0, - * take = 100, - * orderDirection, - * filterExpression, - * logLevel, - * startDate, - * endDate, - * } - * @return {*} - * @memberof UmbLogMessagesServerDataSource - */ - async getLogViewerLogs({ - skip = 0, - take = 100, - orderDirection, - filterExpression, - logLevel, - startDate, - endDate, - }: { - skip?: number; - take?: number; - orderDirection?: DirectionModel; - filterExpression?: string; - logLevel?: Array; - startDate?: string; - endDate?: string; - }) { - return await tryExecuteAndNotify( - this.#host, - LogViewerResource.getLogViewerLog({ - skip, - take, - orderDirection, - filterExpression, - logLevel, - startDate, - endDate, - }) - ); - } - /** - * Grabs all the log message templates from the server - * - * @param {{ - * skip?: number; - * take?: number; - * startDate?: string; - * endDate?: string; - * }} { - * skip, - * take = 100, - * startDate, - * endDate, - * } - * @return {*} - * @memberof UmbLogMessagesServerDataSource - */ - async getLogViewerMessageTemplate({ - skip, - take = 100, - startDate, - endDate, - }: { - skip?: number; - take?: number; - startDate?: string; - endDate?: string; - }) { - return await tryExecuteAndNotify( - this.#host, - LogViewerResource.getLogViewerMessageTemplate({ - skip, - take, - startDate, - endDate, - }) - ); - } - - async getLogViewerValidateLogsSize({ startDate, endDate }: { startDate?: string; endDate?: string }) { - return await tryExecuteAndNotify( - this.#host, - LogViewerResource.getLogViewerValidateLogsSize({ - startDate, - endDate, - }) - ); - } + constructor(host: UmbControllerHostElement) { + this.#host = host; } + + /** + * Grabs all the loggers from the server + * + * @param {{ skip?: number; take?: number }} { skip = 0, take = 100 } + * @return {*} + * @memberof UmbLogMessagesServerDataSource + */ + async getLogViewerLevel({ skip = 0, take = 100 }: { skip?: number; take?: number }) { + return await tryExecuteAndNotify(this.#host, LogViewerResource.getLogViewerLevel({ skip, take })); + } + + /** + * Grabs all the number of different log messages from the server + * + * @param {{ skip?: number; take?: number }} { skip = 0, take = 100 } + * @return {*} + * @memberof UmbLogMessagesServerDataSource + */ + async getLogViewerLevelCount({ startDate, endDate }: { startDate?: string; endDate?: string }) { + return await tryExecuteAndNotify( + this.#host, + LogViewerResource.getLogViewerLevelCount({ + startDate, + endDate, + }) + ); + } + /** + * Grabs all the log messages from the server + * + * @param {{ + * skip?: number; + * take?: number; + * orderDirection?: DirectionModel; + * filterExpression?: string; + * logLevel?: Array; + * startDate?: string; + * endDate?: string; + * }} { + * skip = 0, + * take = 100, + * orderDirection, + * filterExpression, + * logLevel, + * startDate, + * endDate, + * } + * @return {*} + * @memberof UmbLogMessagesServerDataSource + */ + async getLogViewerLogs({ + skip = 0, + take = 100, + orderDirection, + filterExpression, + logLevel, + startDate, + endDate, + }: { + skip?: number; + take?: number; + orderDirection?: DirectionModel; + filterExpression?: string; + logLevel?: Array; + startDate?: string; + endDate?: string; + }) { + return await tryExecuteAndNotify( + this.#host, + LogViewerResource.getLogViewerLog({ + skip, + take, + orderDirection, + filterExpression, + logLevel, + startDate, + endDate, + }) + ); + } + /** + * Grabs all the log message templates from the server + * + * @param {{ + * skip?: number; + * take?: number; + * startDate?: string; + * endDate?: string; + * }} { + * skip, + * take = 100, + * startDate, + * endDate, + * } + * @return {*} + * @memberof UmbLogMessagesServerDataSource + */ + async getLogViewerMessageTemplate({ + skip, + take = 100, + startDate, + endDate, + }: { + skip?: number; + take?: number; + startDate?: string; + endDate?: string; + }) { + return await tryExecuteAndNotify( + this.#host, + LogViewerResource.getLogViewerMessageTemplate({ + skip, + take, + startDate, + endDate, + }) + ); + } + + async getLogViewerValidateLogsSize({ startDate, endDate }: { startDate?: string; endDate?: string }) { + return await tryExecuteAndNotify( + this.#host, + LogViewerResource.getLogViewerValidateLogsSize({ + startDate, + endDate, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-date-range-selector.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-date-range-selector.element.ts index cfa465cb79..cab197ce92 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-date-range-selector.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-date-range-selector.element.ts @@ -1,13 +1,12 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, property, queryAll, state } from 'lit/decorators.js'; -import { query } from 'router-slot'; import { LogViewerDateRange, UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, } from '../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-log-viewer-date-range-selector') export class UmbLogViewerDateRangeSelectorElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-level-tag.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-level-tag.element.ts index d0fc55eb86..4bf03dbf85 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-level-tag.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/components/log-viewer-level-tag.element.ts @@ -1,9 +1,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, LitElement } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { InterfaceColor, InterfaceLook } from '@umbraco-ui/uui-base/lib/types'; -import { LogLevelModel } from '@umbraco-cms/backend-api'; +import { LogLevelModel } from '@umbraco-cms/backoffice/backend-api'; interface LevelMapStyles { look?: InterfaceLook; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/logviewer-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/logviewer-root-workspace.element.ts index 8579ccc331..5a009a7deb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/logviewer-root-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/logviewer-root-workspace.element.ts @@ -1,15 +1,15 @@ import './components'; import { map } from 'rxjs'; import { css, html, nothing } from 'lit'; -import { customElement, state, property } from 'lit/decorators.js'; -import { IRoutingInfo } from 'router-slot'; +import { customElement, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css'; -import { repeat } from 'lit-html/directives/repeat.js'; +import { repeat } from 'lit/directives/repeat.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { umbExtensionsRegistry, createExtensionElement } from '@umbraco-cms/extensions-api'; -import { ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/extensions-registry'; -import { UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from '@umbraco-cms/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { umbExtensionsRegistry, createExtensionElement } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from '@umbraco-cms/internal/router'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; //TODO make uui-input accept min and max values @customElement('umb-logviewer-workspace') @@ -37,10 +37,6 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement { align-items: center; } - #router-slot { - height: 100%; - } - uui-tab-group { --uui-tab-divider: var(--uui-color-border); border-left: 1px solid var(--uui-color-border); @@ -55,7 +51,7 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement { private _workspaceViews: Array = []; @state() - private _routes: any[] = []; + private _routes: IRoute[] = []; @state() private _activePath?: string; @@ -84,7 +80,9 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement { this.observe( umbExtensionsRegistry .extensionsOfTypes(['workspaceView']) - .pipe(map((extensions) => extensions.filter((extension) => extension.meta.workspaces.includes(this._alias)))), + .pipe( + map((extensions) => extensions.filter((extension) => extension.conditions.workspaces.includes(this._alias))) + ), (workspaceViews) => { this._workspaceViews = workspaceViews; this._createRoutes(); @@ -106,13 +104,8 @@ export class UmbLogViewerWorkspaceElement extends UmbLitElement { component: () => { return createExtensionElement(view); }, - setup: (component: Promise | HTMLElement, info: IRoutingInfo) => { - // When its using import, we get an element, when using createExtensionElement we get a Promise. - if ((component as any).then) { - (component as any).then((el: any) => (el.manifest = view)); - } else { - (component as any).manifest = view; - } + setup: (component) => { + (component as any).manifest = view; }, }; }); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/manifests.ts index c740c29aa1..1d6ee72173 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer-root/manifests.ts @@ -1,4 +1,8 @@ -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspaceAlias = 'Umb.Workspace.LogviewerRoot'; @@ -20,11 +24,13 @@ const workspaceViews: Array = [ loader: () => import('../views/overview/index'), weight: 300, meta: { - workspaces: [workspaceAlias], label: 'Overview', pathname: 'overview', icon: 'umb:box-alt', }, + conditions: { + workspaces: [workspaceAlias], + }, }, { type: 'workspaceView', @@ -33,11 +39,13 @@ const workspaceViews: Array = [ loader: () => import('../views/search/index'), weight: 200, meta: { - workspaces: [workspaceAlias], label: 'Search', pathname: 'search', icon: 'umb:search', }, + conditions: { + workspaces: [workspaceAlias], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer.context.ts index 93d7896cc6..22a4eeaeeb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/logviewer.context.ts @@ -1,17 +1,23 @@ import { UmbLogViewerRepository } from '../repository/log-viewer.repository'; -import { ArrayState, createObservablePart, DeepState, ObjectState, StringState } from '@umbraco-cms/observable-api'; +import { + BasicState, + ArrayState, + createObservablePart, + DeepState, + ObjectState, + StringState, +} from '@umbraco-cms/backoffice/observable-api'; import { DirectionModel, - LogLevelCountsModel, + LogLevelCountsReponseModel, LogLevelModel, - PagedLoggerModel, - PagedLogMessageModel, - PagedLogTemplateModel, - PagedSavedLogSearchModel, -} from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { BasicState } from 'libs/observable-api/basic-state'; + PagedLoggerResponseModel, + PagedLogMessageResponseModel, + PagedLogTemplateResponseModel, + PagedSavedLogSearchResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; export type PoolingInterval = 0 | 2000 | 5000 | 10000 | 20000 | 30000; export interface PoolingCOnfig { @@ -24,7 +30,7 @@ export interface LogViewerDateRange { } export class UmbLogViewerWorkspaceContext { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #repository: UmbLogViewerRepository; get today() { @@ -50,16 +56,16 @@ export class UmbLogViewerWorkspaceContext { endDate: this.today, }; - #savedSearches = new DeepState(undefined); + #savedSearches = new DeepState(undefined); savedSearches = createObservablePart(this.#savedSearches, (data) => data?.items); - #logCount = new DeepState(null); + #logCount = new DeepState(null); logCount = createObservablePart(this.#logCount, (data) => data); #dateRange = new DeepState(this.defaultDateRange); dateRange = createObservablePart(this.#dateRange, (data) => data); - #loggers = new DeepState(null); + #loggers = new DeepState(null); loggers = createObservablePart(this.#loggers, (data) => data?.items); #canShowLogs = new BasicState(null); @@ -68,13 +74,13 @@ export class UmbLogViewerWorkspaceContext { #filterExpression = new StringState(''); filterExpression = createObservablePart(this.#filterExpression, (data) => data); - #messageTemplates = new DeepState(null); + #messageTemplates = new DeepState(null); messageTemplates = createObservablePart(this.#messageTemplates, (data) => data); #logLevelsFilter = new ArrayState([]); logLevelsFilter = createObservablePart(this.#logLevelsFilter, (data) => data); - #logs = new DeepState(null); + #logs = new DeepState(null); logs = createObservablePart(this.#logs, (data) => data?.items); logsTotal = createObservablePart(this.#logs, (data) => data?.total); @@ -88,7 +94,7 @@ export class UmbLogViewerWorkspaceContext { currentPage = 1; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; this.#repository = new UmbLogViewerRepository(this.#host); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts index 2aeafb27fa..bae9ab55f4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-level-overview.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { LoggerModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { LoggerResponseModel } from '@umbraco-cms/backoffice/backend-api'; //TODO: implement the saved searches pagination when the API total bug is fixed @customElement('umb-log-viewer-log-level-overview') @@ -18,7 +18,7 @@ export class UmbLogViewerLogLevelOverviewElement extends UmbLitElement { } @state() - private _loggers: LoggerModel[] = []; + private _loggers: LoggerResponseModel[] = []; /** * The name of the logger to get the level for. Defaults to 'Global'. * diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-types-chart.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-types-chart.element.ts index 1c7ec7a927..922c84f72b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-types-chart.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-log-types-chart.element.ts @@ -1,9 +1,8 @@ -import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { LogLevelCountsModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { LogLevelCountsReponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-log-viewer-log-types-chart') export class UmbLogViewerLogTypesChartElement extends UmbLitElement { @@ -80,7 +79,7 @@ export class UmbLogViewerLogTypesChartElement extends UmbLitElement { } @state() - private _logLevelCount: LogLevelCountsModel | null = null; + private _logLevelCount: LogLevelCountsReponseModel | null = null; @state() private logLevelCount: [string, number][] = []; @@ -117,6 +116,7 @@ export class UmbLogViewerLogTypesChartElement extends UmbLitElement { }); } + // TODO: Stop using this complex code in render methods, instead changes to _logLevelCount should trigger a state prop containing the keys. And then try to make use of the repeat LIT method: render() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts index 5c9cd6f754..d96280149b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-message-templates-overview.element.ts @@ -2,8 +2,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { PagedLogTemplateModel, SavedLogSearchModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { PagedLogTemplateResponseModel, SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/backend-api'; //TODO: fix pagination bug when API is fixed @customElement('umb-log-viewer-message-templates-overview') @@ -39,7 +39,7 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement { ]; @state() - private _messageTemplates: PagedLogTemplateModel | null = null; + private _messageTemplates: PagedLogTemplateResponseModel | null = null; #logViewerContext?: UmbLogViewerWorkspaceContext; constructor() { @@ -63,7 +63,7 @@ export class UmbLogViewerMessageTemplatesOverviewElement extends UmbLitElement { this.#logViewerContext?.getMessageTemplates(0, take + 10); } - #renderSearchItem = (searchListItem: SavedLogSearchModel) => { + #renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => { return html`
  • { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts index 588e51bd9f..761f06c97b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/components/log-viewer-saved-searches-overview.element.ts @@ -2,8 +2,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { SavedLogSearchModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/backend-api'; //TODO: implement the saved searches pagination when the API total bug is fixed @customElement('umb-log-viewer-saved-searches-overview') @@ -37,7 +37,7 @@ export class UmbLogViewerSavedSearchesOverviewElement extends UmbLitElement { ]; @state() - private _savedSearches: SavedLogSearchModel[] = []; + private _savedSearches: SavedLogSearchResponseModel[] = []; #logViewerContext?: UmbLogViewerWorkspaceContext; constructor() { @@ -60,7 +60,7 @@ export class UmbLogViewerSavedSearchesOverviewElement extends UmbLitElement { this.#logViewerContext?.setFilterExpression(query); } - #renderSearchItem = (searchListItem: SavedLogSearchModel) => { + #renderSearchItem = (searchListItem: SavedLogSearchResponseModel) => { return html`
  • { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/log-overview-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/log-overview-view.element.ts index 38191cf274..d4faca5e18 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/log-overview-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/overview/log-overview-view.element.ts @@ -1,8 +1,8 @@ import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../logviewer.context'; -import { LogLevelCountsModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { LogLevelCountsReponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; //TODO: add a disabled attribute to the show more button when the total number of items is correctly returned from the endpoint @customElement('umb-log-viewer-overview-view') @@ -11,14 +11,14 @@ export class UmbLogViewerOverviewViewElement extends UmbLitElement { css` :host { display: block; + margin: var(--uui-size-layout-1); } #logviewer-layout { - margin: 20px; - height: calc(100vh - 160px); + padding-bottom: var(--uui-size-layout-1); display: grid; grid-template-columns: 7fr 2fr; - grid-template-rows: 1fr 1fr; + grid-template-rows: auto auto; gap: 20px 20px; grid-auto-flow: row; grid-template-areas: @@ -88,7 +88,7 @@ export class UmbLogViewerOverviewViewElement extends UmbLitElement { private _errorCount = 0; @state() - private _logLevelCount: LogLevelCountsModel | null = null; + private _logLevelCount: LogLevelCountsReponseModel | null = null; @state() private _canShowLogs = false; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-log-level-filter-menu.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-log-level-filter-menu.element.ts index dc72dcec91..78c554931e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-log-level-filter-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-log-level-filter-menu.element.ts @@ -4,8 +4,8 @@ import { css, html } from 'lit'; import { customElement, queryAll, state } from 'lit/decorators.js'; import _ from 'lodash'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { LogLevelModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { LogLevelModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-log-viewer-log-level-filter-menu') export class UmbLogViewerLogLevelFilterMenuElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-message.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-message.element.ts index 8bc5edb9c6..6669964aa3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-message.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-message.element.ts @@ -2,8 +2,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, PropertyValueMap } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { LogLevelModel, LogMessagePropertyModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { LogLevelModel, LogMessagePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; //TODO: check how to display EventId field in the message properties @customElement('umb-log-viewer-message') @@ -132,7 +132,7 @@ export class UmbLogViewerMessageElement extends UmbLitElement { renderedMessage = ''; @property({ attribute: false }) - properties: Array = []; + properties: Array = []; @property({ type: Boolean }) open = false; @@ -210,7 +210,7 @@ export class UmbLogViewerMessageElement extends UmbLitElement { private _propertiesWithSearchMenu: Array = ['HttpRequestNumber', 'SourceContext', 'MachineName']; - private _findLogsWithProperty({ name, value }: LogMessagePropertyModel) { + private _findLogsWithProperty({ name, value }: LogMessagePropertyPresentationModel) { let queryString = ''; if (isNaN(+(value ?? ''))) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-messages-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-messages-list.element.ts index 1fc81d55fa..896fedc78c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-messages-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-messages-list.element.ts @@ -3,8 +3,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, query, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DirectionModel, LogMessageModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DirectionModel, LogMessageResponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-log-viewer-messages-list') export class UmbLogViewerMessagesListElement extends UmbLitElement { @@ -56,7 +56,7 @@ export class UmbLogViewerMessagesListElement extends UmbLitElement { private _sortingDirection: DirectionModel = DirectionModel.ASCENDING; @state() - private _logs: LogMessageModel[] = []; + private _logs: LogMessageResponseModel[] = []; @state() private _logsTotal = 0; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-polling-button.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-polling-button.element.ts index 5ee674f1d4..44b19b8cae 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-polling-button.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-polling-button.element.ts @@ -8,7 +8,7 @@ import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN, } from '../../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-log-viewer-polling-button') export class UmbLogViewerPollingButtonElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts index c4ca1a8ffa..32ae06990d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts @@ -3,8 +3,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, query, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context'; -import { SavedLogSearchModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-log-viewer-search-input') export class UmbLogViewerSearchInputElement extends UmbLitElement { @@ -87,7 +87,7 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { private _savedSearchesExpandSymbol!: UUISymbolExpandElement; @state() - private _savedSearches: SavedLogSearchModel[] = []; + private _savedSearches: SavedLogSearchResponseModel[] = []; @state() private _inputQuery = ''; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/log-search-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/log-search-view.element.ts index c9813ae53c..d936195362 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/log-search-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/logviewer/workspace/views/search/log-search-view.element.ts @@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../logviewer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-log-viewer-search-view') export class UmbLogViewerSearchViewElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/menu.manifests.ts index 9147a6a50a..687f7807df 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/menu.manifests.ts @@ -1,4 +1,4 @@ -import { ManifestMenu } from '@umbraco-cms/extensions-registry'; +import { ManifestMenu } from '@umbraco-cms/backoffice/extensions-registry'; const menu: ManifestMenu = { type: 'menu', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/manifests.ts new file mode 100644 index 0000000000..ddaa4babdc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/manifests.ts @@ -0,0 +1,6 @@ +import { manifests as repositoryManifests } from './repository/manifests'; +import { manifests as menuItemManifests } from './menu-item/manifests'; +import { manifests as treeManifests } from './tree/manifests'; +import { manifests as workspaceManifests } from './workspace/manifests'; + +export const manifests = [...repositoryManifests, ...menuItemManifests, ...treeManifests, ...workspaceManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/menu-item/manifests.ts new file mode 100644 index 0000000000..d249eb7e8f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/menu-item/manifests.ts @@ -0,0 +1,19 @@ +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; + +const menuItem: ManifestTypes = { + type: 'menuItem', + kind: 'tree', + alias: 'Umb.MenuItem.RelationTypes', + name: 'Relation Types Menu Item', + weight: 500, + meta: { + treeAlias: 'Umb.Tree.RelationTypes', + label: 'Relation Types', + icon: 'umb:folder', + }, + conditions: { + menus: ['Umb.Menu.Settings'], + }, +}; + +export const manifests = [menuItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/manifests.ts new file mode 100644 index 0000000000..7859009b6f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/manifests.ts @@ -0,0 +1,32 @@ +import { UmbRelationTypeRepository } from '../repository/relation-type.repository'; +import { UmbRelationTypeStore } from './relation-type.store'; +import { UmbRelationTypeTreeStore } from './relation-type.tree.store'; +import { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; + +export const RELATION_TYPE_REPOSITORY_ALIAS = 'Umb.Repository.RelationType'; + +const repository: ManifestRepository = { + type: 'repository', + alias: RELATION_TYPE_REPOSITORY_ALIAS, + name: 'Relation Type Repository', + class: UmbRelationTypeRepository, +}; + +export const RELATION_TYPE_STORE_ALIAS = 'Umb.Store.RelationType'; +export const RELATION_TYPE_TREE_STORE_ALIAS = 'Umb.Store.RelationTypeTree'; + +const store: ManifestStore = { + type: 'store', + alias: RELATION_TYPE_STORE_ALIAS, + name: 'Relation Type Store', + class: UmbRelationTypeStore, +}; + +const treeStore: ManifestTreeStore = { + type: 'treeStore', + alias: RELATION_TYPE_TREE_STORE_ALIAS, + name: 'Relation Type Tree Store', + class: UmbRelationTypeTreeStore, +}; + +export const manifests = [repository, store, treeStore]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.repository.ts new file mode 100644 index 0000000000..52249a2896 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.repository.ts @@ -0,0 +1,206 @@ +import { UmbRelationTypeTreeStore, UMB_RELATION_TYPE_TREE_STORE_CONTEXT_TOKEN } from './relation-type.tree.store'; +import { UmbRelationTypeServerDataSource } from './sources/relation-type.server.data'; +import { UmbRelationTypeStore, UMB_RELATION_TYPE_STORE_CONTEXT_TOKEN } from './relation-type.store'; +import { RelationTypeTreeServerDataSource } from './sources/relation-type.tree.server.data'; +import { RelationTypeTreeDataSource } from './sources'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { + CreateRelationTypeRequestModel, + ProblemDetailsModel, + RelationTypeResponseModel, + UpdateRelationTypeRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; + +export class UmbRelationTypeRepository + implements + UmbTreeRepository, + UmbDetailRepository +{ + #init!: Promise; + + #host: UmbControllerHostElement; + + #treeSource: RelationTypeTreeDataSource; + #treeStore?: UmbRelationTypeTreeStore; + + #detailDataSource: UmbRelationTypeServerDataSource; + #detailStore?: UmbRelationTypeStore; + + #notificationContext?: UmbNotificationContext; + + constructor(host: UmbControllerHostElement) { + this.#host = host; + + // TODO: figure out how spin up get the correct data source + this.#treeSource = new RelationTypeTreeServerDataSource(this.#host); + this.#detailDataSource = new UmbRelationTypeServerDataSource(this.#host); + + this.#init = Promise.all([ + new UmbContextConsumerController(this.#host, UMB_RELATION_TYPE_TREE_STORE_CONTEXT_TOKEN, (instance) => { + this.#treeStore = instance; + }), + + new UmbContextConsumerController(this.#host, UMB_RELATION_TYPE_STORE_CONTEXT_TOKEN, (instance) => { + this.#detailStore = instance; + }), + + new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { + this.#notificationContext = instance; + }), + ]); + } + + // TODO: Trash + // TODO: Move + + async requestRootTreeItems() { + await this.#init; + + const { data, error } = await this.#treeSource.getRootItems(); + + if (data) { + this.#treeStore?.appendItems(data.items); + } + + return { data, error, asObservable: () => this.#treeStore!.rootItems }; + } + + //TODO RelationTypes can't have children. But this method is required by the tree interface. + async requestTreeItemsOf(parentId: string | null) { + const error: ProblemDetailsModel = { title: 'Not implemented' }; + return { data: undefined, error }; + } + + async requestTreeItems(ids: Array) { + if (!ids) throw new Error('Ids are missing'); + await this.#init; + + const { data, error } = await this.#treeSource.getItems(ids); + + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; + } + + async rootTreeItems() { + await this.#init; + return this.#treeStore!.rootItems; + } + + async treeItemsOf(parentId: string | null) { + await this.#init; + return this.#treeStore!.childrenOf(parentId); + } + + async treeItems(ids: Array) { + await this.#init; + return this.#treeStore!.items(ids); + } + + // DETAILS: + + async createScaffold(parentId: string | null) { + await this.#init; + + if (!parentId) { + throw new Error('Parent id is missing'); + } + + return this.#detailDataSource.createScaffold(parentId); + } + + async requestById(id: string) { + await this.#init; + + // TODO: should we show a notification if the id is missing? + // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? + if (!id) { + const error: ProblemDetailsModel = { title: 'Key is missing' }; + return { error }; + } + const { data, error } = await this.#detailDataSource.get(id); + + if (data) { + this.#detailStore?.append(data); + } + + return { data, error }; + } + + async byKey(id: string) { + await this.#init; + return this.#detailStore!.byKey(id); + } + + // Could potentially be general methods: + + async create(template: CreateRelationTypeRequestModel) { + if (!template) throw new Error('Template is missing'); + if (!template.id) throw new Error('Template id is missing'); + + await this.#init; + + const { error } = await this.#detailDataSource.insert(template); + + if (!error) { + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // TODO: Update tree store with the new item? or ask tree to request the new item? + // this.#detailStore?.append(template); + + const notification = { data: { message: `Relation Type created` } }; + this.#notificationContext?.peek('positive', notification); + } + + return { error }; + } + + async save(id: string, item: UpdateRelationTypeRequestModel) { + if (!id) throw new Error('Id is missing'); + if (!item) throw new Error('Relation type is missing'); + + await this.#init; + + const { error } = await this.#detailDataSource.update(id, item); + + if (!error) { + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a template is updated in the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + this.#detailStore?.append(item); + this.#treeStore?.updateItem(id, { name: item.name }); + + const notification = { data: { message: `Relation Type saved` } }; + this.#notificationContext?.peek('positive', notification); + } + + return { error }; + } + + // General: + + async delete(id: string) { + if (!id) throw new Error('Id is missing'); + + await this.#init; + + const { error } = await this.#detailDataSource.delete(id); + + if (!error) { + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server. + // Consider notify a workspace if a template is deleted from the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + + this.#detailStore?.remove([id]); + this.#treeStore?.removeItem(id); + + const notification = { data: { message: `Relation Type deleted` } }; + this.#notificationContext?.peek('positive', notification); + } + + return { error }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.store.ts new file mode 100644 index 0000000000..f8ac1dd072 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.store.ts @@ -0,0 +1,53 @@ +import type { RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +export const UMB_RELATION_TYPE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbRelationTypeStore'); + +/** + * @export + * @class UmbRelationTypeStore + * @extends {UmbStoreBase} + * @description - Data Store for Template Details + */ +export class UmbRelationTypeStore extends UmbStoreBase { + #data = new ArrayState([], (x) => x.id); + + /** + * Creates an instance of UmbRelationTypeStore. + * @param {UmbControllerHostElement} host + * @memberof UmbRelationTypeStore + */ + constructor(host: UmbControllerHostElement) { + super(host, UMB_RELATION_TYPE_STORE_CONTEXT_TOKEN.toString()); + } + + /** + * Append a relation-type to the store + * @param {RelationTypeResponseModel} RelationType + * @memberof UmbRelationTypeStore + */ + append(RelationType: RelationTypeResponseModel) { + this.#data.append([RelationType]); + } + + /** + * Append a relation-type to the store + * @param {id} RelationTypeResponseModel id. + * @memberof UmbRelationTypeStore + */ + byKey(id: RelationTypeResponseModel['id']) { + return this.#data.getObservablePart((x) => x.find((y) => y.id === id)); + } + + /** + * Removes relation-types in the store with the given uniques + * @param {string[]} uniques + * @memberof UmbRelationTypeStore + */ + remove(uniques: Array) { + this.#data.remove(uniques); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.tree.store.ts new file mode 100644 index 0000000000..a8d057765a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/relation-type.tree.store.ts @@ -0,0 +1,25 @@ +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; + +/** + * @export + * @class UmbRelationTypeTreeStore + * @extends {UmbStoreBase} + * @description - Tree Data Store for relation-types + */ +// TODO: consider if tree store could be turned into a general EntityTreeStore class? +export class UmbRelationTypeTreeStore extends UmbEntityTreeStore { + /** + * Creates an instance of UmbRelationTypeTreeStore. + * @param {UmbControllerHostElement} host + * @memberof UmbRelationTypeTreeStore + */ + constructor(host: UmbControllerHostElement) { + super(host, UMB_RELATION_TYPE_TREE_STORE_CONTEXT_TOKEN.toString()); + } +} + +export const UMB_RELATION_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken( + 'UmbRelationTypeTreeStore' +); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/index.ts new file mode 100644 index 0000000000..f8ff932071 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/index.ts @@ -0,0 +1,7 @@ +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; +import { ItemResponseModelBaseModel, PagedEntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +export interface RelationTypeTreeDataSource { + getRootItems(): Promise>; + getItems(ids: Array): Promise>; +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/relation-type.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/relation-type.server.data.ts new file mode 100644 index 0000000000..80ba73c8d4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/relation-type.server.data.ts @@ -0,0 +1,118 @@ +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; +import { + ProblemDetailsModel, + RelationTypeResource, + RelationTypeResponseModel, + CreateRelationTypeRequestModel, + UpdateRelationTypeRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * A data source for the Relation Type that fetches data from the server + * @export + * @class UmbRelationTypeServerDataSource + * @implements {RepositoryDetailDataSource} + */ +export class UmbRelationTypeServerDataSource + implements UmbDataSource +{ + #host: UmbControllerHostElement; + + /** + * Creates an instance of UmbRelationTypeServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbRelationTypeServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + + /** + * Fetches a Relation Type with the given id from the server + * @param {string} id + * @return {*} + * @memberof UmbRelationTypeServerDataSource + */ + async get(id: string) { + if (!id) { + const error: ProblemDetailsModel = { title: 'Key is missing' }; + return { error }; + } + + return tryExecuteAndNotify( + this.#host, + RelationTypeResource.getRelationTypeById({ + id, + }) + ); + } + + /** + * Creates a new Relation Type scaffold + * @param {(string | null)} parentId + * @return {*} + * @memberof UmbRelationTypeServerDataSource + */ + async createScaffold(parentId: string | null) { + const data: RelationTypeResponseModel = {}; + + return { data }; + } + + /** + * Inserts a new Relation Type on the server + * @param {Document} relationType + * @return {*} + * @memberof UmbRelationTypeServerDataSource + */ + async insert(relationType: CreateRelationTypeRequestModel) { + if (!relationType.id) throw new Error('RelationType id is missing'); + + return tryExecuteAndNotify( + this.#host, + RelationTypeResource.postRelationType({ + requestBody: relationType, + }) + ); + } + + /** + * Updates a RelationType on the server + * @param {RelationTypeResponseModel} relationType + * @return {*} + * @memberof UmbRelationTypeServerDataSource + */ + async update(id: string, relationType: UpdateRelationTypeRequestModel) { + if (!id) throw new Error('RelationType id is missing'); + + return tryExecuteAndNotify( + this.#host, + RelationTypeResource.putRelationTypeById({ + id, + requestBody: relationType, + }) + ); + } + + /** + * Deletes a Relation Type on the server + * @param {string} id + * @return {*} + * @memberof UmbRelationTypeServerDataSource + */ + async delete(id: string) { + if (!id) { + const error: ProblemDetailsModel = { title: 'RelationType id is missing' }; + return { error }; + } + + return tryExecuteAndNotify( + this.#host, + RelationTypeResource.deleteRelationTypeById({ + id, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/relation-type.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/relation-type.tree.server.data.ts new file mode 100644 index 0000000000..1dc64b51b5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/repository/sources/relation-type.tree.server.data.ts @@ -0,0 +1,86 @@ +import { RelationTypeTreeDataSource } from '.'; +import { ProblemDetailsModel, RelationTypeResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +/** + * A data source for the RelationType tree that fetches data from the server + * @export + * @class RelationTypeTreeServerDataSource + * @implements {RelationTypeTreeDataSource} + */ +export class RelationTypeTreeServerDataSource implements RelationTypeTreeDataSource { + #host: UmbControllerHostElement; + + // TODO: how do we handle trashed items? + async trashItems(ids: Array) { + if (!ids) { + const error: ProblemDetailsModel = { title: 'RelationType ids is missing' }; + return { error }; + } + + // TODO: use resources when end point is ready: + /* + return tryExecuteAndNotify( + this.#host, + RelationTypeResource.deleteRelationTypeByKey({ + id: ids, + }) + ); + */ + return Promise.resolve({ error: null, data: null }); + } + + async moveItems(ids: Array, destination: string) { + // TODO: use backend cli when available. + return tryExecuteAndNotify( + this.#host, + fetch('/umbraco/management/api/v1/relation-type/move', { + method: 'POST', + body: JSON.stringify({ ids, destination }), + headers: { + 'Content-Type': 'application/json', + }, + }) + ); + } + + /** + * Creates an instance of RelationTypeTreeServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof RelationTypeTreeServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + + /** + * Fetches the root items for the tree from the server + * @return {*} + * @memberof RelationTypeTreeServerDataSource + */ + async getRootItems() { + return tryExecuteAndNotify(this.#host, RelationTypeResource.getTreeRelationTypeRoot({})); + } + + /** + * Fetches the items for the given ids from the server + * @param {Array} ids + * @return {*} + * @memberof RelationTypeTreeServerDataSource + */ + async getItems(ids: Array) { + if (ids) { + const error: ProblemDetailsModel = { title: 'Ids are missing' }; + return { error }; + } + + return tryExecuteAndNotify( + this.#host, + RelationTypeResource.getRelationTypeItem({ + id: ids, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/tree/manifests.ts new file mode 100644 index 0000000000..42dc1f26cf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/tree/manifests.ts @@ -0,0 +1,23 @@ +import { RELATION_TYPE_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; + +const tree: ManifestTree = { + type: 'tree', + alias: 'Umb.Tree.RelationTypes', + name: 'Relation Types Tree', + meta: { + repositoryAlias: RELATION_TYPE_REPOSITORY_ALIAS, + }, +}; + +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.RelationType', + name: 'Relation Type Tree Item', + conditions: { + entityType: 'relation-type', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/manifests.ts new file mode 100644 index 0000000000..0e4adf80b6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/manifests.ts @@ -0,0 +1,68 @@ +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; + +const workspace: ManifestWorkspace = { + type: 'workspace', + alias: 'Umb.Workspace.RelationType', + name: 'Relation Type Workspace', + loader: () => import('./relation-type-workspace.element'), + meta: { + entityType: 'relation-type', + }, +}; + +const workspaceViews: Array = [ + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.RelationType.RelationType', + name: 'Relation Type Workspace RelationType View', + loader: () => import('./views/relation-type/relation-type-workspace-view-relation-type.element'), + weight: 20, + meta: { + label: 'RelationType', + pathname: 'relation-type', + icon: 'umb:info', + }, + conditions: { + workspaces: ['Umb.Workspace.RelationType'], + }, + }, + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.RelationType.Relation', + name: 'Relation Type Workspace Relation View', + loader: () => import('./views/relation/workspace-view-relation-type-relation.element'), + weight: 10, + meta: { + label: 'Relation', + pathname: 'relation', + icon: 'umb:trafic', + }, + conditions: { + workspaces: ['Umb.Workspace.RelationType'], + }, + }, +]; + +const workspaceActions: Array = [ + { + type: 'workspaceAction', + alias: 'Umb.WorkspaceAction.RelationType.Save', + name: 'Save Relation Type Workspace Action', + meta: { + label: 'Save', + look: 'primary', + color: 'positive', + api: UmbSaveWorkspaceAction, + }, + conditions: { + workspaces: ['Umb.Workspace.RelationType'], + }, + }, +]; + +export const manifests = [workspace, ...workspaceViews, ...workspaceActions]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace-edit.element.ts new file mode 100644 index 0000000000..83a9c84e12 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace-edit.element.ts @@ -0,0 +1,93 @@ +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbRelationTypeWorkspaceContext } from './relation-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +/** + * @element umb-relation-type-workspace-edit-element + * @description - Element for displaying a Relation Type Workspace + */ +@customElement('umb-relation-type-workspace-edit-element') +export class UmbRelationTypeWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + + #header { + display: flex; + flex: 1 1 auto; + margin: 0 var(--uui-size-layout-1); + } + + #name { + width: 100%; + flex: 1 1 auto; + align-items: center; + } + + #alias { + padding: 0 var(--uui-size-space-3); + opacity: 0.5; + } + `, + ]; + + #workspaceContext?: UmbRelationTypeWorkspaceContext; + + @state() + private _relationType?: RelationTypeResponseModel; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbRelationTypeWorkspaceContext; + this.#observeRelationType(); + }); + } + + #observeRelationType() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.data, (data) => (this._relationType = data)); + } + + // TODO. find a way where we don't have to do this for all workspaces. + private _handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + render() { + return html` + + + + `; + } +} + +export default UmbRelationTypeWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-relation-type-workspace-edit-element': UmbRelationTypeWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.context.ts new file mode 100644 index 0000000000..81abf8f66f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.context.ts @@ -0,0 +1,79 @@ +import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; +import { UmbRelationTypeRepository } from '../repository/relation-type.repository'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { RelationTypeBaseModel, RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +export class UmbRelationTypeWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface +{ + #data = new ObjectState(undefined); + data = this.#data.asObservable(); + name = this.#data.getObservablePart((data) => data?.name); + id = this.#data.getObservablePart((data) => data?.id); + + constructor(host: UmbControllerHostElement) { + super(host, new UmbRelationTypeRepository(host)); + } + + async load(id: string) { + const { data } = await this.repository.requestById(id); + + if (data) { + this.setIsNew(false); + this.#data.update(data); + } + } + + async createScaffold(parentId: string | null) { + const { data } = await this.repository.createScaffold(parentId); + if (!data) return; + this.setIsNew(true); + this.#data.next(data); + } + + getData() { + return this.#data.getValue(); + } + + getEntityId() { + return this.getData()?.id || ''; + } + + getEntityType() { + return 'relation-type'; + } + + setName(name: string) { + this.#data.update({ name }); + } + + async save() { + if (!this.#data.value) return; + if (!this.#data.value.id) return; + + if (this.isNew) { + await this.repository.create(this.#data.value); + } else { + await this.repository.save(this.#data.value.id, this.#data.value); + } + + // If it went well, then its not new anymore?. + this.setIsNew(false); + } + + update(id: K, value: RelationTypeBaseModel[K]) { + this.#data.next({ ...this.#data.value, [id]: value }); + } + + async delete(id: string) { + await this.repository.delete(id); + } + + public destroy(): void { + this.#data.complete(); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.element.ts new file mode 100644 index 0000000000..eb96b21baf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.element.ts @@ -0,0 +1,61 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbRelationTypeWorkspaceContext } from './relation-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; + +import './relation-type-workspace-edit.element'; + +/** + * @element umb-relation-type-workspace + * @description - Element for displaying a Relation Type Workspace + */ +@customElement('umb-relation-type-workspace') +export class UmbRelationTypeWorkspaceElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + #workspaceContext = new UmbRelationTypeWorkspaceContext(this); + + #routerPath? = ''; + + #element = document.createElement('umb-relation-type-workspace-edit-element'); + #key = ''; + + @state() + _routes: IRoute[] = [ + { + path: 'create/:parentId', + component: () => this.#element, + setup: (_component, info) => { + const parentId = info.match.params.parentId; + this.#workspaceContext.createScaffold(parentId); + }, + }, + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; + + render() { + return html` { + this.#routerPath = event.target.absoluteRouterPath; + }}>`; + } +} + +export default UmbRelationTypeWorkspaceElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-relation-type-workspace': UmbRelationTypeWorkspaceElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.stories.ts new file mode 100644 index 0000000000..34a177e3c3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/relation-type-workspace.stories.ts @@ -0,0 +1,19 @@ +import './relation-type-workspace.element'; + +import { Meta, Story } from '@storybook/web-components'; +import { html } from 'lit'; + +import { ifDefined } from 'lit/directives/if-defined.js'; +import { data } from '../../../../core/mocks/data/relation-type.data'; + +import type { UmbRelationTypeWorkspaceElement } from './relation-type-workspace.element'; + +export default { + title: 'Workspaces/Relation Type', + component: 'umb-relation-type-workspace', + id: 'umb-relation-type-workspace', +} as Meta; + +export const AAAOverview: Story = () => + html` `; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation-type/relation-type-workspace-view-relation-type.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation-type/relation-type-workspace-view-relation-type.element.ts new file mode 100644 index 0000000000..934f15d8f2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation-type/relation-type-workspace-view-relation-type.element.ts @@ -0,0 +1,104 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UUIBooleanInputEvent, UUIRadioGroupElement, UUIRadioGroupEvent, UUIToggleElement } from '@umbraco-ui/uui'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UmbRelationTypeWorkspaceContext } from '../../relation-type-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-relation-type-workspace-view-relation-type') +export class UmbRelationTypeWorkspaceViewRelationTypeElement extends UmbLitElement { + @state() + private _relationType?: RelationTypeResponseModel; + + #workspaceContext?: UmbRelationTypeWorkspaceContext; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbRelationTypeWorkspaceContext; + this._observeRelationType(); + }); + } + + private _observeRelationType() { + if (!this.#workspaceContext) { + return; + } + + this.observe(this.#workspaceContext.data, (relationType) => { + if (!relationType) return; + + this._relationType = relationType; + }); + } + + #handleDirectionChange(event: UUIRadioGroupEvent) { + const target = event.target as UUIRadioGroupElement; + const value = target.value === 'true'; + this.#workspaceContext?.update('isBidirectional', value); + } + + #handleIsDependencyChange(event: UUIBooleanInputEvent) { + const target = event.target as UUIToggleElement; + const value = target.checked; + this.#workspaceContext?.update('isDependency', value); + } + + render() { + return html` + + + + + + + + ${this.#renderParentProperty()} + ${this.#renderChildProperty()} + + + + + `; + } + + #renderParentProperty() { + if (this._relationType?.id) return html`
    ${this._relationType.parentObjectTypeName}
    `; + + return html``; + } + + #renderChildProperty() { + if (this._relationType?.id) return html`
    ${this._relationType.parentObjectTypeName}
    `; + + return html``; + } + + static styles = [ + UUITextStyles, + css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + `, + ]; +} + +export default UmbRelationTypeWorkspaceViewRelationTypeElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-relation-type-workspace-view-relation-type': UmbRelationTypeWorkspaceViewRelationTypeElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation-type/relation-type-workspace-view-relation-type.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation-type/relation-type-workspace-view-relation-type.stories.ts new file mode 100644 index 0000000000..b7a59493e3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation-type/relation-type-workspace-view-relation-type.stories.ts @@ -0,0 +1,27 @@ +import { Meta, Story } from '@storybook/web-components'; +import { html } from 'lit'; + +//import { data } from '../../../../../core/mocks/data/relation-type.data'; + +import type { UmbRelationTypeWorkspaceViewRelationTypeElement } from './relation-type-workspace-view-relation-type.element'; + +import './relation-type-workspace-view-relation-type.element'; +//import { UmbRelationTypeWorkspaceContext } from '../../workspace-relation-type.context'; + +export default { + title: 'Workspaces/Relation Type/Views/RelationType', + component: 'umb-relation-type-workspace-view-relation-type', + id: 'umb-relation-type-workspace-view-relation-type', + decorators: [ + (story) => { + return html`TODO: make use of mocked workspace context??`; + /*html` + ${story()} + `,*/ + }, + ], +} as Meta; + +export const AAAOverview: Story = () => + html` `; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation/workspace-view-relation-type-relation.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation/workspace-view-relation-type-relation.element.ts new file mode 100644 index 0000000000..b8006df518 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation/workspace-view-relation-type-relation.element.ts @@ -0,0 +1,154 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbTableColumn, UmbTableConfig } from '../../../../../shared/components/table'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { RelationResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-workspace-view-relation-type-relation') +export class UmbWorkspaceViewRelationTypeRelationElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + margin: var(--uui-size-layout-1); + } + `, + ]; + + //TODO Use real data + @state() + _relations: Array = MockData; + + private _tableConfig: UmbTableConfig = { + allowSelection: false, + hideIcon: true, + }; + + private _tableColumns: Array = [ + { + name: 'Parent', + alias: 'parent', + }, + { + name: 'Child', + alias: 'child', + }, + { + name: 'Created', + alias: 'created', + }, + { + name: 'Comment', + alias: 'comment', + }, + ]; + + private get _tableItems() { + return this._relations.map((relation) => { + return { + key: relation.parentId + '-' + relation.childId, + data: [ + { + columnAlias: 'parent', + value: relation.parentName, + }, + { + columnAlias: 'child', + value: relation.childName, + }, + { + columnAlias: 'created', + value: relation.createDate, + }, + { + columnAlias: 'comment', + value: relation.comment, + }, + ], + }; + }); + } + + render() { + return html` + + `; + } +} + +const MockData: Array = [ + { + parentId: 1, + parentName: 'Parent 1', + childId: 2, + childName: 'Child 1', + createDate: '2021-01-01', + comment: 'Comment 1', + }, + { + parentId: 1, + parentName: 'Parent 1', + childId: 3, + childName: 'Child 2', + createDate: '2021-01-01', + comment: 'Comment 2', + }, + { + parentId: 1, + parentName: 'Parent 1', + childId: 4, + childName: 'Child 3', + createDate: '2021-01-01', + comment: 'Comment 3', + }, + { + parentId: 1, + parentName: 'Parent 1', + childId: 5, + childName: 'Child 4', + createDate: '2021-01-01', + comment: 'Comment 4', + }, + { + parentId: 1, + parentName: 'Parent 1', + childId: 6, + childName: 'Child 5', + createDate: '2021-01-01', + comment: 'Comment 5', + }, + { + parentId: 1, + parentName: 'Parent 1', + childId: 7, + childName: 'Child 6', + createDate: '2021-01-01', + comment: 'Comment 6', + }, + { + parentId: 1, + parentName: 'Parent 1', + childId: 8, + childName: 'Child 7', + createDate: '2021-01-01', + comment: 'Comment 7', + }, + { + parentId: 1, + parentName: 'Parent 1', + childId: 9, + childName: 'Child 8', + createDate: '2021-01-01', + comment: 'Comment 8', + }, +]; + +export default UmbWorkspaceViewRelationTypeRelationElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-workspace-view-relation-type-relation': UmbWorkspaceViewRelationTypeRelationElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation/workspace-view-relation-type-relation.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation/workspace-view-relation-type-relation.stories.ts new file mode 100644 index 0000000000..486766b227 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/relation-types/workspace/views/relation/workspace-view-relation-type-relation.stories.ts @@ -0,0 +1,27 @@ +import './workspace-view-relation-type-relation.element'; + +import { Meta, Story } from '@storybook/web-components'; +import { html } from 'lit'; + +//import { data } from '../../../../../core/mocks/data/relation-type.data'; +//import { UmbRelationTypeContext } from '../../relation-type.context'; + +import type { UmbWorkspaceViewRelationTypeRelationElement } from './workspace-view-relation-type-relation.element'; + +export default { + title: 'Workspaces/Relation Type/Views/Relation', + component: 'umb-workspace-view-relation-type-relation', + id: 'umb-workspace-view-relation-type-relation', + decorators: [ + (story) => { + return html`TODO: make use of mocked workspace context??`; + /*html` + ${story()} + `,*/ + }, + ], +} as Meta; + +export const AAAOverview: Story = () => + html` `; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/settings/section.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/settings/section.manifests.ts index 90b8cb4a4c..6c45267c2b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/settings/section.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/settings/section.manifests.ts @@ -1,4 +1,5 @@ -import type { ManifestSection, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models'; +import { ManifestSectionSidebarAppMenuKind } from '@umbraco-cms/backoffice/extensions-registry'; +import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry'; const sectionAlias = 'Umb.Section.Settings'; @@ -13,16 +14,19 @@ const section: ManifestSection = { }, }; -const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = { - type: 'menuSectionSidebarApp', +const menuSectionSidebarApp: ManifestSectionSidebarAppMenuKind = { + type: 'sectionSidebarApp', + kind: 'menu', alias: 'Umb.SectionSidebarMenu.Settings', name: 'Settings Section Sidebar Menu', weight: 100, meta: { label: 'Settings', - sections: [sectionAlias], menu: 'Umb.Menu.Settings', }, + conditions: { + sections: [sectionAlias], + }, }; export const manifests = [section, menuSectionSidebarApp]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-selection-actions.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-selection-actions.element.ts index 099877a7b1..a9bc60ac85 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-selection-actions.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-selection-actions.element.ts @@ -3,10 +3,10 @@ import { css, html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { map } from 'rxjs'; import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from './collection.context'; -import type { ManifestEntityBulkAction, MediaDetails } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbExecutedEvent } from '@umbraco-cms/events'; +import type { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbExecutedEvent } from '@umbraco-cms/backoffice/events'; import '../components/entity-bulk-action/entity-bulk-action.element'; @@ -48,7 +48,7 @@ export class UmbCollectionSelectionActionsElement extends UmbLitElement { @state() private _entityBulkActions: Array = []; - private _collectionContext?: UmbCollectionContext; + private _collectionContext?: UmbCollectionContext; private _selection: Array = []; constructor() { @@ -94,7 +94,7 @@ export class UmbCollectionSelectionActionsElement extends UmbLitElement { this.observe( umbExtensionsRegistry.extensionsOfType('entityBulkAction').pipe( map((extensions) => { - return extensions.filter((extension) => extension.meta.entityType === this.entityType); + return extensions.filter((extension) => extension.conditions.entityType === this.entityType); }) ), (bulkActions) => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-toolbar.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-toolbar.element.ts index a3e6fcaa28..270823236a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-toolbar.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection-toolbar.element.ts @@ -4,9 +4,9 @@ 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 type { ManifestCollectionView } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { ManifestCollectionView } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-collection-toolbar') export class UmbCollectionToolbarElement extends UmbLitElement { @@ -74,7 +74,7 @@ export class UmbCollectionToolbarElement extends UmbLitElement { this.observe( umbExtensionsRegistry.extensionsOfType('collectionView').pipe( map((extensions) => { - return extensions.filter((extension) => extension.meta.entityType === 'media'); + return extensions.filter((extension) => extension.conditions.entityType === 'media'); }) ), (layouts) => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts index 7ad8352aa4..9668a51d68 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.context.ts @@ -1,27 +1,23 @@ -import type { ContentTreeItemModel, EntityTreeItemModel } from '@umbraco-cms/backend-api'; -import type { UmbTreeStore } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextToken, UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { ArrayState, UmbObserverController } from '@umbraco-cms/observable-api'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { createExtensionClass } from 'libs/extensions-api/create-extension-class.function'; -import { UmbTreeRepository } from '@umbraco-cms/repository'; +import { Observable } from 'rxjs'; +import type { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextToken, UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { umbExtensionsRegistry, createExtensionClass } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; // TODO: Clean up the need for store as Media has switched to use Repositories(repository). -export class UmbCollectionContext< - DataType extends ContentTreeItemModel, - StoreType extends UmbTreeStore = UmbTreeStore -> { - private _host: UmbControllerHostInterface; +export class UmbCollectionContext { + private _host: UmbControllerHostElement; private _entityType: string | null; - private _entityKey: string | null; + private _entityId: string | null; - #repository?: UmbTreeRepository; + #repository?: UmbTreeRepository; - private _store?: StoreType; - protected _dataObserver?: UmbObserverController; + private _store?: any; + protected _dataObserver?: UmbObserverController; - #data = new ArrayState(>[]); + #data = new ArrayState(>[]); public readonly data = this.#data.asObservable(); #selection = new ArrayState(>[]); @@ -34,18 +30,18 @@ export class UmbCollectionContext< */ constructor( - host: UmbControllerHostInterface, + host: UmbControllerHostElement, entityType: string | null, - entityKey: string | null, + entityId: string | null, storeAlias?: string, repositoryAlias?: string ) { this._entityType = entityType; this._host = host; - this._entityKey = entityKey; + this._entityId = entityId; if (storeAlias) { - new UmbContextConsumerController(this._host, storeAlias, (_instance: StoreType) => { + new UmbContextConsumerController(this._host, storeAlias, (_instance) => { 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. @@ -92,10 +88,10 @@ export class UmbCollectionContext< this._dataObserver?.destroy(); - if (this._entityKey) { + if (this._entityId) { this._dataObserver = new UmbObserverController( this._host, - this._store.getTreeItemChildren(this._entityKey), + this._store.getTreeItemChildren(this._entityId), (nodes) => { if (nodes) { this.#data.next(nodes); @@ -118,12 +114,12 @@ export class UmbCollectionContext< this._dataObserver?.destroy(); - if (this._entityKey) { + if (this._entityId) { // TODO: we should be able to get an observable from this call. either return a observable or a asObservable() method. - const observable = (await this.#repository.requestTreeItemsOf(this._entityKey)).asObservable?.(); + const observable = (await this.#repository.requestTreeItemsOf(this._entityId)).asObservable?.(); if (observable) { - this._dataObserver = new UmbObserverController(this._host, observable, (nodes) => { + this._dataObserver = new UmbObserverController(this._host, observable as Observable, (nodes) => { if (nodes) { this.#data.next(nodes); } @@ -133,7 +129,7 @@ export class UmbCollectionContext< const observable = (await this.#repository.requestRootTreeItems()).asObservable?.(); if (observable) { - this._dataObserver = new UmbObserverController(this._host, observable, (nodes) => { + this._dataObserver = new UmbObserverController(this._host, observable as Observable, (nodes) => { if (nodes) { this.#data.next(nodes); } @@ -160,12 +156,12 @@ export class UmbCollectionContext< this.#selection.next([]); } - public select(key: string) { - this.#selection.appendOne(key); + public select(id: string) { + this.#selection.appendOne(id); } - public deselect(key: string) { - this.#selection.filter((k) => k !== key); + public deselect(id: string) { + this.#selection.filter((k) => k !== id); } // TODO: how can we make sure to call this. @@ -174,6 +170,4 @@ export class UmbCollectionContext< } } -export const UMB_COLLECTION_CONTEXT_TOKEN = new UmbContextToken>( - 'UmbCollectionContext' -); +export const UMB_COLLECTION_CONTEXT_TOKEN = new UmbContextToken>('UmbCollectionContext'); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.element.ts index 313aea4af4..9b883b69bd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/collection.element.ts @@ -5,10 +5,11 @@ import { map } from 'rxjs'; import './collection-selection-actions.element'; import './collection-toolbar.element'; import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from './collection.context'; -import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import type { ManifestCollectionView, MediaDetails } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { UmbObserverController } from '@umbraco-cms/observable-api'; +import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { ManifestCollectionView } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; @customElement('umb-collection') export class UmbCollectionElement extends UmbLitElement { @@ -30,12 +31,12 @@ export class UmbCollectionElement extends UmbLitElement { ]; @state() - private _routes: Array = []; + private _routes: Array = []; @state() private _selection?: Array | null; - private _collectionContext?: UmbCollectionContext; + private _collectionContext?: UmbCollectionContext; private _entityType!: string; @property({ type: String, attribute: 'entity-type' }) @@ -72,7 +73,7 @@ export class UmbCollectionElement extends UmbLitElement { // 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); + return extensions.filter((extension) => extension.conditions.entityType === this._entityType); }) ), (views) => { @@ -95,7 +96,7 @@ export class UmbCollectionElement extends UmbLitElement { this._routes.push({ path: '**', - redirectTo: views?.[0]?.meta.pathName, + redirectTo: views?.[0]?.meta.pathName ?? '/', }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.element.ts index d34573e22e..2c96968191 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.element.ts @@ -1,11 +1,11 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN } from '../../../shared/collection/collection.context'; -import type { ManifestDashboardCollection } from '@umbraco-cms/models'; -import type { FolderTreeItemModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { ManifestDashboardCollection } from '@umbraco-cms/backoffice/extensions-registry'; +import type { FolderTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import '../collection.element'; @@ -25,7 +25,7 @@ export class UmbDashboardCollectionElement extends UmbLitElement { ]; // TODO: Use the right type here: - private _collectionContext?: UmbCollectionContext; + private _collectionContext?: UmbCollectionContext; public manifest!: ManifestDashboardCollection; @@ -36,9 +36,8 @@ export class UmbDashboardCollectionElement extends UmbLitElement { super.connectedCallback(); if (!this._collectionContext) { - const manifestMeta = this.manifest.meta; - const repositoryAlias = manifestMeta.repositoryAlias; - this._entityType = manifestMeta.entityType; + const repositoryAlias = this.manifest.meta.repositoryAlias; + this._entityType = this.manifest.conditions.entityType; this._collectionContext = new UmbCollectionContext(this, this._entityType, null, '', repositoryAlias); this.provideContext(UMB_COLLECTION_CONTEXT_TOKEN, this._collectionContext); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.stories.ts index ae18d8c2c6..7a736b1f28 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/collection/dashboards/dashboard-collection.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbDashboardCollectionElement } from './dashboard-collection.element'; import './dashboard-collection.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-apps.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-apps.element.ts index 0a0375f6d0..8ca23425fd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-apps.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-apps.element.ts @@ -3,7 +3,7 @@ import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; @customElement('umb-backoffice-header-apps') -export class UmbBackofficeHeaderApps extends LitElement { +export class UmbBackofficeHeaderAppsElement extends LitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -22,6 +22,6 @@ export class UmbBackofficeHeaderApps extends LitElement { declare global { interface HTMLElementTagNameMap { - 'umb-backoffice-header-apps': UmbBackofficeHeaderApps; + 'umb-backoffice-header-apps': UmbBackofficeHeaderAppsElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-sections.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-sections.element.ts index 1c696d7216..d4cce136c1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-sections.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header-sections.element.ts @@ -4,11 +4,11 @@ import { customElement, state } from 'lit/decorators.js'; import { when } from 'lit/directives/when.js'; import { UMB_BACKOFFICE_CONTEXT_TOKEN } from './backoffice.context'; import type { UmbBackofficeContext } from './backoffice.context'; -import type { ManifestSection } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-backoffice-header-sections') -export class UmbBackofficeHeaderSections extends UmbLitElement { +export class UmbBackofficeHeaderSectionsElement extends UmbLitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -104,8 +104,7 @@ export class UmbBackofficeHeaderSections extends UmbLitElement { @click="${() => this._handleSectionTabClick(section.alias)}" ?active="${this._currentSectionAlias === section.alias}" href="${`section/${section.meta.pathname}`}" - label="${section.meta.label || section.name}" - > + label="${section.meta.label || section.name}"> ` )} ${this._renderExtraSections()} @@ -146,6 +145,6 @@ export class UmbBackofficeHeaderSections extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-backoffice-header-sections': UmbBackofficeHeaderSections; + 'umb-backoffice-header-sections': UmbBackofficeHeaderSectionsElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header.element.ts index eeb2541ecd..37437f0fd9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-header.element.ts @@ -1,5 +1,5 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import {css, CSSResultGroup, html, LitElement, unsafeCSS} from 'lit'; +import { css, CSSResultGroup, html, LitElement, unsafeCSS } from 'lit'; import { customElement } from 'lit/decorators.js'; import logoImg from '/umbraco_logomark_white.svg'; @@ -7,7 +7,7 @@ import './backoffice-header-sections.element'; import './backoffice-header-apps.element'; @customElement('umb-backoffice-header') -export class UmbBackofficeHeader extends LitElement { +export class UmbBackofficeHeaderElement extends LitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -57,6 +57,6 @@ export class UmbBackofficeHeader extends LitElement { declare global { interface HTMLElementTagNameMap { - 'umb-backoffice-header': UmbBackofficeHeader; + 'umb-backoffice-header': UmbBackofficeHeaderElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts index 2ef3862bf0..59ab21030a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-main.element.ts @@ -2,33 +2,30 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { state } from 'lit/decorators.js'; +import { UmbSectionElement } from '../section/section.element'; import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section/section.context'; import { UmbBackofficeContext, UMB_BACKOFFICE_CONTEXT_TOKEN } from './backoffice.context'; -import type { UmbRouterSlotChangeEvent } from '@umbraco-cms/router'; -import type { ManifestSection } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { createExtensionElementOrFallback } from '@umbraco-cms/extensions-api'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import type { UmbRouterSlotChangeEvent } from '@umbraco-cms/internal/router'; +import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { createExtensionElementOrFallback } from '@umbraco-cms/backoffice/extensions-api'; @defineElement('umb-backoffice-main') -export class UmbBackofficeMain extends UmbLitElement { +export class UmbBackofficeMainElement extends UmbLitElement { static styles = [ UUITextStyles, css` :host { background-color: var(--uui-color-background); display: block; - width: 100%; - height: 100%; - overflow: hidden; - } - router-slot { - height: 100%; + height: calc(100% - 60px); // 60 => top header height } `, ]; @state() - private _routes: Array = []; + private _routes: Array = []; @state() private _sections: Array = []; @@ -67,6 +64,9 @@ export class UmbBackofficeMain extends UmbLitElement { return { path: this._routePrefix + section.meta.pathname, component: () => createExtensionElementOrFallback(section, 'umb-section'), + setup: (component) => { + (component as UmbSectionElement).manifest = section; + }, }; }); @@ -100,6 +100,6 @@ export class UmbBackofficeMain extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-backoffice-main': UmbBackofficeMain; + 'umb-backoffice-main': UmbBackofficeMainElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts index dd257e3841..41d378c181 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-modal-container.element.ts @@ -2,11 +2,11 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { UmbModalHandler, UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalHandler, UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-backoffice-modal-container') -export class UmbBackofficeModalContainer extends UmbLitElement { +export class UmbBackofficeModalContainerElement extends UmbLitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -49,6 +49,6 @@ export class UmbBackofficeModalContainer extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-backoffice-modal-container': UmbBackofficeModalContainer; + 'umb-backoffice-modal-container': UmbBackofficeModalContainerElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts index eb5268301e..c4e8891ea5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice-notification-container.element.ts @@ -6,11 +6,11 @@ import { UmbNotificationHandler, UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN, -} from '@umbraco-cms/notification'; -import { UmbLitElement } from '@umbraco-cms/element'; +} from '@umbraco-cms/backoffice/notification'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-backoffice-notification-container') -export class UmbBackofficeNotificationContainer extends UmbLitElement { +export class UmbBackofficeNotificationContainerElement extends UmbLitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -65,6 +65,6 @@ export class UmbBackofficeNotificationContainer extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-backoffice-notification-container': UmbBackofficeNotificationContainer; + 'umb-backoffice-notification-container': UmbBackofficeNotificationContainerElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice.context.ts index f6a6ce4c24..9a5d46fcc1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/backoffice-frame/backoffice.context.ts @@ -1,6 +1,6 @@ -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { StringState } from '@umbraco-cms/observable-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { StringState } from '@umbraco-cms/backoffice/observable-api'; export class UmbBackofficeContext { #activeSectionAlias = new StringState(undefined); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.element.ts index 66406ae01c..b8a2cdc685 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.element.ts @@ -15,7 +15,7 @@ import { customElement, property, state } from 'lit/decorators.js'; * @extends {UmbLitElement} */ @customElement('umb-body-layout') -export class UmbBodyLayout extends LitElement { +export class UmbBodyLayoutElement extends LitElement { static styles = [ UUITextStyles, css` @@ -32,7 +32,7 @@ export class UmbBodyLayout extends LitElement { align-items: center; justify-content: space-between; width: 100%; - height: 70px; + height: var(--umb-header-layout-height); background-color: var(--uui-color-surface); border-bottom: 1px solid var(--uui-color-border); box-sizing: border-box; @@ -136,6 +136,6 @@ export class UmbBodyLayout extends LitElement { declare global { interface HTMLElementTagNameMap { - 'umb-body-layout': UmbBodyLayout; + 'umb-body-layout': UmbBodyLayoutElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.stories.ts index 087ae4c959..c64a31e715 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/body-layout/body-layout.stories.ts @@ -1,22 +1,21 @@ import { Meta, StoryObj } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import './body-layout.element'; -import type { UmbBodyLayout } from './body-layout.element'; +import type { UmbBodyLayoutElement } from './body-layout.element'; -const meta: Meta = { - title: 'Components/Workspace Layout', - component: 'umb-body-layout' +const meta: Meta = { + title: 'Components/Workspace Layout', + component: 'umb-body-layout', }; - -export default meta; -type Story = StoryObj; -export const Overview: Story = { - render: () => html` - +export default meta; +type Story = StoryObj; + +export const Overview: Story = { + render: () => html`
    Header slot
    Main slot
    Footer slot
    -
    ` +
    `, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/button-with-dropdown/button-with-dropdown.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/button-with-dropdown/button-with-dropdown.stories.ts index d42a021c21..f9b2f79643 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/button-with-dropdown/button-with-dropdown.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/button-with-dropdown/button-with-dropdown.stories.ts @@ -1,6 +1,5 @@ - import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { UmbButtonWithDropdownElement } from './button-with-dropdown.element'; export default { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.element.ts index 074fa1a193..99833cbcce 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.element.ts @@ -8,7 +8,7 @@ import { customElement } from 'lit/decorators.js'; * */ @customElement('uui-code-block') -export class UUICodeBlock extends LitElement { +export class UUICodeBlockElement extends LitElement { static styles = [ UUITextStyles, css` @@ -54,6 +54,6 @@ export class UUICodeBlock extends LitElement { declare global { interface HTMLElementTagNameMap { - 'uui-code-block': UUICodeBlock; + 'uui-code-block': UUICodeBlockElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.stories.ts index 533a46b28e..f3f2d6ca24 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-block/code-block.stories.ts @@ -1,26 +1,21 @@ import { Meta, StoryObj } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import './code-block.element'; -import type { UUICodeBlock } from './code-block.element'; +import type { UUICodeBlockElement } from './code-block.element'; -const meta: Meta = { - title: 'Components/Code Block', - component: 'uui-code-block' +const meta: Meta = { + title: 'Components/Code Block', + component: 'uui-code-block', }; - + export default meta; -type Story = StoryObj; - +type Story = StoryObj; + export const Overview: Story = { - args: { - } + args: {}, }; export const WithCode: Story = { - decorators: [], - render: () => html` - - // Lets write some javascript - alert("Hello World"); - ` -}; \ No newline at end of file + decorators: [], + render: () => html` // Lets write some javascript alert("Hello World"); `, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.controller.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.controller.ts new file mode 100644 index 0000000000..525e4442ef --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.controller.ts @@ -0,0 +1,370 @@ +import * as monaco from 'monaco-editor'; +import { + CodeEditorConstructorOptions, + CodeEditorSearchOptions, + CodeEditorTheme, + UmbCodeEditorCursorPosition, + UmbCodeEditorCursorPositionChangedEvent, + UmbCodeEditorCursorSelectionChangedEvent, + UmbCodeEditorHost, + UmbCodeEditorRange, + UmbCodeEditorSelection, +} from './code-editor.model'; +import themes from './themes'; +import { UmbChangeEvent, UmbInputEvent } from '@umbraco-cms/backoffice/events'; + +//TODO - consider firing change event on blur + +/** + * This is a wrapper class for the [monaco editor](https://microsoft.github.io/monaco-editor). It exposes some of the monaco editor API. It also handles the creation of the monaco editor. + * It allows access to the entire monaco editor object through `monacoEditor` property, but mind the fact that editor might be swapped in the future for a different library, so use on your own responsibility. + * Through the UmbCodeEditorHost interface it can be used in a custom element. + * By using monaco library directly you can access the entire monaco API along with code completions, actions etc. This class creates some level of abstraction over the monaco editor. It only provides basic functionality, that should be enough for most of the use cases and should be possible to implement with any code editor library. + * + * Current issues: [shadow DOM related issues](https://github.com/microsoft/monaco-editor/labels/editor-shadow-dom) #3217 currently fixed by a hack , [razor syntax highlight](https://github.com/microsoft/monaco-editor/issues/1997) + * + * + * @export + * @class UmbCodeEditor + */ +export class UmbCodeEditorController { + #host: UmbCodeEditorHost; + #editor?: monaco.editor.IStandaloneCodeEditor; + /** + * The monaco editor object. This is the actual monaco editor object. It is exposed for advanced usage, but mind the fact that editor might be swapped in the future for a different library, so use on your own responsibility. For more information see [monaco editor API](https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneCodeEditor.html). + * + * @readonly + * @memberof UmbCodeEditor + */ + get monacoEditor() { + return this.#editor; + } + + #options: CodeEditorConstructorOptions = {}; + /** + * The options used to create the editor. + * + * @readonly + * @type {CodeEditorConstructorOptions} + * @memberof UmbCodeEditor + */ + get options(): CodeEditorConstructorOptions { + return this.#options; + } + + #defaultMonacoOptions: monaco.editor.IStandaloneEditorConstructionOptions = { + automaticLayout: true, + scrollBeyondLastLine: false, + scrollbar: { + verticalScrollbarSize: 5, + }, + // disable this, as it does not work with shadow dom properly. + colorDecorators: false, + }; + + #position: UmbCodeEditorCursorPosition | null = null; + /** + * Provides the current position of the cursor. + * + * @readonly + * @memberof UmbCodeEditor + */ + get position() { + return this.#position; + } + #secondaryPositions: UmbCodeEditorCursorPosition[] = []; + /** + * Provides positions of all the secondary cursors. + * + * @readonly + * @memberof UmbCodeEditor + */ + get secondaryPositions() { + return this.#secondaryPositions; + } + + /** + * Provides the current value of the editor. + * + * @memberof UmbCodeEditor + */ + get value() { + if (!this.#editor) return ''; + const value = this.#editor.getValue(); + return value; + } + + set value(newValue: string) { + if (!this.#editor) throw new Error('Editor object not found'); + + const oldValue = this.value; + if (newValue !== oldValue) { + this.#editor.setValue(newValue); + } + } + /** + * Provides the current model of the editor. For advanced usage. Bare in mind that in case of the monaco library being swapped in the future, this might not be available. For more information see [monaco editor model API](https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.ITextModel.html). + * + * @readonly + * @memberof UmbCodeEditor + */ + get monacoModel() { + if (!this.#editor) return null; + return this.#editor.getModel(); + } + /** + * Creates an instance of UmbCodeEditor. You should instantiate this class through the `UmbCodeEditorHost` interface and that should happen when inside DOM nodes of the host container are available, otherwise the editor will not be able to initialize, for example in lit `firstUpdated` lifecycle hook. It will make host emit change and input events when the value of the editor changes. + * @param {UmbCodeEditorHost} host + * @param {CodeEditorConstructorOptions} [options] + * @memberof UmbCodeEditor + */ + constructor(host: UmbCodeEditorHost, options?: CodeEditorConstructorOptions) { + this.#options = { ...options }; + this.#host = host; + this.#registerThemes(); + this.#createEditor(options); + } + + #registerThemes() { + Object.entries(themes).forEach(([name, theme]) => { + this.#defineTheme(name, theme); + }); + } + + #defineTheme(name: string, theme: monaco.editor.IStandaloneThemeData) { + monaco.editor.defineTheme(name, theme); + } + + #initiateEvents() { + this.#editor?.onDidChangeModelContent(() => { + this.#host.code = this.value ?? ''; + this.#host.dispatchEvent(new UmbInputEvent()); + }); + + this.#editor?.onDidChangeModel(() => { + this.#host.dispatchEvent(new UmbChangeEvent()); + }); + this.#editor?.onDidChangeCursorPosition((e) => { + this.#position = e.position; + this.#secondaryPositions = e.secondaryPositions; + }); + } + + #mapOptions(options: CodeEditorConstructorOptions): monaco.editor.IStandaloneEditorConstructionOptions { + const hasLineNumbers = Object.prototype.hasOwnProperty.call(options, 'lineNumbers'); + const hasMinimap = Object.prototype.hasOwnProperty.call(options, 'minimap'); + const hasLightbulb = Object.prototype.hasOwnProperty.call(options, 'lightbulb'); + + return { + ...options, + lineNumbers: hasLineNumbers ? (options.lineNumbers ? 'on' : 'off') : undefined, + minimap: hasMinimap ? (options.minimap ? { enabled: true } : { enabled: false }) : undefined, + lightbulb: hasLightbulb ? (options.lightbulb ? { enabled: true } : { enabled: false }) : undefined, + }; + } + /** + * Updates the options of the editor. This is useful for updating the options after the editor has been created. + * + * @param {CodeEditorConstructorOptions} newOptions + * @memberof UmbCodeEditor + */ + updateOptions(newOptions: CodeEditorConstructorOptions) { + if (!this.#editor) throw new Error('Editor object not found'); + this.#options = { ...this.#options, ...newOptions }; + this.#editor.updateOptions(this.#mapOptions(newOptions)); + } + + #createEditor(options: CodeEditorConstructorOptions = {}) { + if (!this.#host.container) throw new Error('Container not found'); + if (this.#host.container.hasChildNodes()) throw new Error('Editor container should be empty'); + + const mergedOptions = { ...this.#defaultMonacoOptions, ...this.#mapOptions(options) }; + + this.#editor = monaco.editor.create(this.#host.container, { + ...mergedOptions, + value: this.#host.code ?? '', + language: this.#host.language, + theme: this.#host.theme, + readOnly: this.#host.readonly, + ariaLabel: this.#host.label, + }); + this.#initiateEvents(); + } + /** + * Provides the current selections of the editor. + * + * @return {*} {UmbCodeEditorSelection[]} + * @memberof UmbCodeEditor + */ + getSelections(): UmbCodeEditorSelection[] { + if (!this.#editor) return []; + return this.#editor.getSelections() ?? []; + } + /** + * Provides the current positions of the cursor or multiple cursors. + * + * @return {*} {(UmbCodeEditorCursorPosition | null)} + * @memberof UmbCodeEditor + */ + getPositions(): UmbCodeEditorCursorPosition | null { + if (!this.#editor) return null; + return this.#editor.getPosition(); + } + /** + * Inserts text at the current cursor position or multiple cursor positions. + * + * @param {string} text + * @memberof UmbCodeEditor + */ + insert(text: string) { + if (!this.#editor) throw new Error('Editor object not found'); + const selections = this.#editor.getSelections() ?? []; + if (selections?.length > 0) { + this.#editor.executeEdits( + null, + selections.map((selection) => ({ range: selection, text })) + ); + } + } + /** + * Looks for a string or matching strings in the editor and returns the ranges of the found strings. Can use regex, case sensitive and more. If you want regex set the isRegex to true in the options. + * + * @param {string} searchString + * @param {CodeEditorSearchOptions} [searchOptions={}] + * @return {*} {UmbCodeEditorRange[]} + * @memberof UmbCodeEditor + */ + find( + searchString: string, + searchOptions: CodeEditorSearchOptions = {} + ): UmbCodeEditorRange[] { + if (!this.#editor) throw new Error('Editor object not found'); + const defaultOptions = { + searchOnlyEditableRange: false, + + isRegex: false, + + matchCase: false, + + wordSeparators: null, + + captureMatches: false, + }; + + const { searchOnlyEditableRange, isRegex, matchCase, wordSeparators, captureMatches } = { + ...defaultOptions, + ...searchOptions, + }; + return ( + this.monacoModel + ?.findMatches(searchString, searchOnlyEditableRange, isRegex, matchCase, wordSeparators, captureMatches) + .map((findMatch) => ({ + startLineNumber: findMatch.range.startLineNumber, + startColumn: findMatch.range.startColumn, + endLineNumber: findMatch.range.endLineNumber, + endColumn: findMatch.range.endColumn, + })) ?? [] + ); + } + /** + * Returns the value of the editor for a given range. + * + * @param {UmbCodeEditorRange} range + * @return {*} {string} + * @memberof UmbCodeEditor + */ + getValueInRange(range: UmbCodeEditorRange): string { + if (!this.#editor) throw new Error('Editor object not found'); + return this.monacoModel?.getValueInRange(range) ?? ''; + } + /** + * Inserts text at a given position. + * + * @param {string} text + * @param {UmbCodeEditorCursorPosition} position + * @memberof UmbCodeEditor + */ + insertAtPosition(text: string, position: UmbCodeEditorCursorPosition) { + if (!this.#editor) throw new Error('Editor object not found'); + this.#editor.executeEdits(null, [ + { + range: { + startLineNumber: position.lineNumber, + startColumn: position.column, + endLineNumber: position.lineNumber, + endColumn: position.column, + }, + text, + }, + ]); + } + /** + * Selects a range of text in the editor. + * + * @param {UmbCodeEditorRange} range + * @memberof UmbCodeEditor + */ + select(range: UmbCodeEditorRange) { + if (!this.#editor) throw new Error('Editor object not found'); + this.#editor.setSelection(range); + } + /** + * Changes the theme of the editor. + * + * @template T + * @param {(CodeEditorTheme | T)} theme + * @memberof UmbCodeEditor + */ + setTheme(theme: CodeEditorTheme | T) { + if (!this.#editor) throw new Error('Editor object not found'); + monaco.editor.setTheme(theme); + } + /** + * Runs callback on change of model content. (for example when typing) + * + * @param {() => void} callback + * @memberof UmbCodeEditor + */ + onChangeModelContent(callback: () => void) { + if (!this.#editor) throw new Error('Editor object not found'); + this.#editor.onDidChangeModelContent(() => { + callback(); + }); + } + /** + * Runs callback on change of model (when the entire model is replaced ) + * + * @param {() => void} callback + * @memberof UmbCodeEditor + */ + onDidChangeModel(callback: () => void) { + if (!this.#editor) throw new Error('Editor object not found'); + this.#editor.onDidChangeModel(() => { + callback(); + }); + } + /** + * Runs callback on change of cursor position. Gives as parameter the new position. + * + * @param {((e: UmbCodeEditorCursorPositionChangedEvent | undefined) => void)} callback + * @memberof UmbCodeEditor + */ + onDidChangeCursorPosition(callback: (e: UmbCodeEditorCursorPositionChangedEvent | undefined) => void) { + if (!this.#editor) throw new Error('Editor object not found'); + this.#editor.onDidChangeCursorPosition((event) => { + callback(event); + }); + } + /** + * Runs callback on change of cursor selection. Gives as parameter the new selection. + * + * @param {((e: UmbCodeEditorCursorSelectionChangedEvent | undefined) => void)} callback + * @memberof UmbCodeEditor + */ + onDidChangeCursorSelection(callback: (e: UmbCodeEditorCursorSelectionChangedEvent | undefined) => void) { + if (!this.#editor) throw new Error('Editor object not found'); + this.#editor.onDidChangeCursorSelection((event) => { + callback(event); + }); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.element.ts new file mode 100644 index 0000000000..876d94e08f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.element.ts @@ -0,0 +1,172 @@ +import { css, html, PropertyValues } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { createRef, Ref, ref } from 'lit/directives/ref.js'; +import { UMB_THEME_CONTEXT_TOKEN } from '../../../themes/theme.context'; +import { UmbCodeEditorController } from './code-editor.controller'; +import { CodeEditorLanguage, CodeEditorTheme, UmbCodeEditorHost } from './code-editor.model'; +import { monacoEditorStyles, monacoJumpingCursorHack } from './styles'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +/** + * A custom element that renders a code editor. Code editor is based on the Monaco Editor library. + * The element will listen to the theme context and update the theme accordingly. + * Parts of the monaco Api is exposed through the `editor` property. You can access the monaco editor instance through `editor.monacoEditor`. + * + * @element umb-code-editor + * + * @export + * @class UmbCodeEditorElement + * @extends {UmbLitElement} + * @implements {UmbCodeEditorHost} + * @fires input - Fired when the value of the editor changes. + * @fires change - Fired when the entire model of editor is replaced. + */ +@customElement('umb-code-editor') +export class UmbCodeEditorElement extends UmbLitElement implements UmbCodeEditorHost { + static styles = [ + monacoEditorStyles, + monacoJumpingCursorHack, + css` + :host { + display: block; + } + #editor-container { + width: var(--editor-width); + height: var(--editor-height, 100%); + + --vscode-scrollbar-shadow: #dddddd; + --vscode-scrollbarSlider-background: var(--uui-color-disabled-contrast); + --vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7); + --vscode-scrollbarSlider-activeBackground: rgba(0, 0, 0, 0.6); + } + `, + ]; + + private containerRef: Ref = createRef(); + + get container() { + if (!this.containerRef?.value) throw new Error('Container not found'); + return this.containerRef!.value; + } + + #editor?: UmbCodeEditorController; + + get editor() { + return this.#editor; + } + /** + * Theme of the editor. Default is light. Element will listen to the theme context and update the theme accordingly. + * + * @type {CodeEditorTheme} + * @memberof UmbCodeEditorElement + */ + @property() + theme: CodeEditorTheme = CodeEditorTheme.Light; + /** + * Language of the editor. Default is javascript. + * + * @type {CodeEditorLanguage} + * @memberof UmbCodeEditorElement + */ + @property() + language: CodeEditorLanguage = 'javascript'; + /** + * Label of the editor. Default is 'Code Editor'. + * + * @memberof UmbCodeEditorElement + */ + @property() + label = 'Code Editor'; + + //TODO - this should be called a value + #code = ''; + /** + * Value of the editor. Default is empty string. + * + * @readonly + * @memberof UmbCodeEditorElement + */ + @property() + get code() { + return this.#code; + } + + set code(value: string) { + const oldValue = this.#code; + this.#code = value; + if (this.#editor) { + this.#editor.value = value; + } + this.requestUpdate('code', oldValue); + } + /** + * Whether the editor is readonly. Default is false. + * + * @memberof UmbCodeEditorElement + */ + @property({ type: Boolean, attribute: 'readonly' }) + readonly = false; + + constructor() { + super(); + this.consumeContext(UMB_THEME_CONTEXT_TOKEN, (instance) => { + instance.theme.subscribe((themeAlias) => { + this.theme = themeAlias ? this.#translateTheme(themeAlias) : CodeEditorTheme.Light; + }); + }); + } + + firstUpdated() { + this.#editor = new UmbCodeEditorController(this); + } + + protected updated(_changedProperties: PropertyValues): void { + if (_changedProperties.has('theme') || _changedProperties.has('language')) { + this.#editor?.updateOptions({ + theme: this.theme, + language: this.language, + }); + } + } + + #translateTheme(theme: string) { + switch (theme) { + case 'umb-light-theme': + return CodeEditorTheme.Light; + case 'umb-dark-theme': + return CodeEditorTheme.Dark; + case 'umb-high-contrast-theme': + return CodeEditorTheme.HighContrastLight; + default: + return CodeEditorTheme.Light; + } + } + /** + * Inserts text at the current cursor position. + * + * @param {string} text + * @memberof UmbCodeEditorElement + */ + insert(text: string) { + this.#editor?.insert(text); + } + /** + * Finds all occurrence of the given string or matches the given regular expression. + * + * @param {string} text + * @return {*} + * @memberof UmbCodeEditorElement + */ + find(text: string) { + return this.#editor?.find(text); + } + + render() { + return html`
    `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-code-editor': UmbCodeEditorElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.model.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.model.ts new file mode 100644 index 0000000000..e093a81084 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.model.ts @@ -0,0 +1,229 @@ +export type CodeEditorLanguage = 'razor' | 'typescript' | 'javascript' | 'css' | 'markdown' | 'json' | 'html'; + +export enum CodeEditorTheme { + Light = 'umb-light', + Dark = 'umb-dark', + HighContrastLight = 'umb-hc-light', + HighContrastDark = 'umb-hc-dark', +} + +export interface UmbCodeEditorHost extends HTMLElement { + container: HTMLElement; + language: CodeEditorLanguage; + theme: CodeEditorTheme; + code: string; + readonly: boolean; + label: string; +} + +export interface UmbCodeEditorCursorPosition { + column: number; + lineNumber: number; +} + +export interface UmbCodeEditorRange { + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; +} + +export interface UmbCodeEditorSelection { + startLineNumber: number; + startColumn: number; + endLineNumber: number; + endColumn: number; + positionColumn: number; + positionLineNumber: number; + selectionStartColumn: number; + selectionStartLineNumber: number; +} + +export interface UmbCodeEditorCursorPositionChangedEvent { + position: UmbCodeEditorCursorPosition; + secondaryPositions: UmbCodeEditorCursorPosition[]; +} + +export interface UmbCodeEditorCursorSelectionChangedEvent { + selection: UmbCodeEditorSelection; + secondarySelections: UmbCodeEditorSelection[]; +} + +export interface CodeEditorConstructorOptions { + /** + * The initial value of the auto created model in the editor. + */ + value?: string; + /** + * The initial language of the auto created model in the editor. + */ + language?: CodeEditorLanguage; + /** + * Initial theme to be used for rendering. + * The current out-of-the-box available themes are: 'vs' (default), 'vs-dark', 'hc-black', 'hc-light. + * You can create custom themes via `monaco.editor.defineTheme`. + * To switch a theme, use `monaco.editor.setTheme`. + * **NOTE**: The theme might be overwritten if the OS is in high contrast mode, unless `autoDetectHighContrast` is set to false. + */ + theme?: CodeEditorTheme; + /** + * Container element to use for ARIA messages. + * Defaults to document.body. + */ + ariaContainerElement?: HTMLElement; + /** + * The aria label for the editor's textarea (when it is focused). + */ + ariaLabel?: string; + /** + * The `tabindex` property of the editor's textarea + */ + tabIndex?: number; + + /** + * Control the rendering of line numbers. + * Defaults to `true`. + */ + lineNumbers?: boolean; + /** + * Class name to be added to the editor. + */ + extraEditorClassName?: string; + /** + * Should the editor be read only. See also `domReadOnly`. + * Defaults to false. + */ + readOnly?: boolean; + /** + * Control the behavior and rendering of the minimap. + */ + minimap?: boolean; + /** + * Enable that the editor will install a ResizeObserver to check if its container dom node size has changed. + * Defaults to false. + */ + automaticLayout?: boolean; + /** + * Control the wrapping of the editor. + * When `wordWrap` = "off", the lines will never wrap. + * When `wordWrap` = "on", the lines will wrap at the viewport width. + * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. + * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). + * Defaults to "off". + */ + wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; + /** + * Enable detecting links and making them clickable. + * Defaults to true. + */ + links?: boolean; + /** + * Enable inline color decorators and color picker rendering. + */ + colorDecorators?: boolean; + /** + * Controls the max number of color decorators that can be rendered in an editor at once. + */ + colorDecoratorsLimit?: number; + /** + * Enable custom contextmenu. + * Defaults to true. + */ + contextmenu?: boolean; + /** + * The modifier to be used to add multiple cursors with the mouse. + * Defaults to 'alt' + */ + multiCursorModifier?: 'ctrlCmd' | 'alt'; + /** + * Controls the max number of text cursors that can be in an active editor at once. + */ + multiCursorLimit?: number; + /** + * Controls the number of lines in the editor that can be read out by a screen reader + */ + accessibilityPageSize?: number; + /** + * Controls the spacing around the editor. + * @type {{bottom: number; top: number}} + * @memberof CodeEditorConstructorOptions + */ + padding?: { bottom: number; top: number }; + /** + * Controls if the editor should allow to move selections via drag and drop. + * Defaults to false. + */ + dragAndDrop?: boolean; + /** + * Show code lens + * Defaults to true. + */ + codeLens?: boolean; + /** + * Control the behavior and rendering of the code action lightbulb. + */ + lightbulb?: boolean; + /** + * Enable code folding. + * Defaults to true. + */ + folding?: boolean; + /** + * The font family + */ + fontFamily?: string; + /** + * The font weight + */ + fontWeight?: string; + /** + * The font size + */ + fontSize?: number; + /** + * The line height + */ + lineHeight?: number; + /** + * The letter spacing + */ + letterSpacing?: number; +} + +export interface CodeEditorSearchOptions { + /** + * Limit the searching to only search inside the editable range of the model. + * + * @type {boolean} + * @memberof CodeEditorSearchOptions + */ + searchOnlyEditableRange: boolean; + /** + * Used to indicate that searchString is a regular expression. + * + * @type {boolean} + * @memberof CodeEditorSearchOptions + */ + isRegex: boolean; + /** + * Force the matching to match lower/upper case exactly. + * + * @type {boolean} + * @memberof CodeEditorSearchOptions + */ + matchCase: boolean; + /** + * Force the matching to match entire words only. Pass null otherwise. + * + * @type {string} + * @memberof CodeEditorSearchOptions + */ + wordSeparators: string | null; + /** + * The result will contain the captured groups. + * + * @type {boolean} + * @memberof CodeEditorSearchOptions + */ + captureMatches: boolean; +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.stories.ts new file mode 100644 index 0000000000..e8d7805abe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/code-editor.stories.ts @@ -0,0 +1,232 @@ +import { Meta, StoryObj } from '@storybook/web-components'; +import { html } from 'lit'; +import { UmbCodeEditorElement } from './code-editor.element'; +import { CodeEditorLanguage, CodeEditorTheme } from './code-editor.model'; + +const meta: Meta = { + title: 'Components/Code Editor', + component: 'umb-code-editor', + decorators: [(story) => html`
    ${story()}
    `], + parameters: { layout: 'fullscreen' }, + argTypes: { + theme: { + control: 'select', + options: [ + CodeEditorTheme.Dark, + CodeEditorTheme.Light, + CodeEditorTheme.HighContrastLight, + CodeEditorTheme.HighContrastLight, + ], + }, + }, +}; + +const codeSnippets: Record = { + javascript: `// Returns "banana" + ('b' + 'a' + + 'a' + 'a').toLowerCase();`, + css: `:host { + display: flex; + background-color: var(--uui-color-background); + width: 100%; + height: 100%; + flex-direction: column; + } + + #header { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + height: 70px; + background-color: var(--uui-color-surface); + border-bottom: 1px solid var(--uui-color-border); + box-sizing: border-box; + } + + #headline { + display: block; + margin: 0 var(--uui-size-layout-1); + } + + #tabs { + margin-left: auto; + }`, + html: ` + + + Page Title + + + +

    This is a Heading

    +

    This is a paragraph.

    + + + `, + razor: `@using Umbraco.Extensions + @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage + @{ + if (Model?.Areas.Any() != true) { return; } + } + +
    + @foreach (var area in Model.Areas) + { + @await Html.GetBlockGridItemAreaHtmlAsync(area) + } +
    `, + markdown: ` + You will like those projects! + + --- + + # h1 Heading 8-) + ## h2 Heading + ### h3 Heading + #### h4 Heading + ##### h5 Heading + ###### h6 Heading + + + ## Horizontal Rules + + ___ + + --- + + *** + + + ## Typographic replacements + + Enable typographer option to see result. + + (c) (C) (r) (R) (tm) (TM) (p) (P) +- + + test.. test... test..... test?..... test!.... + + !!!!!! ???? ,, -- --- + + "Smartypants, double quotes" and 'single quotes'`, + typescript: `import { UmbTemplateRepository } from '../repository/template.repository'; + import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; + import { createObservablePart, DeepState } from '@umbraco-cms/observable-api'; + import { TemplateModel } from '@umbraco-cms/backend-api'; + import { UmbControllerHostElement } from '@umbraco-cms/controller'; + + export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext { + #data = new DeepState(undefined); + data = this.#data.asObservable(); + name = createObservablePart(this.#data, (data) => data?.name); + content = createObservablePart(this.#data, (data) => data?.content); + + constructor(host: UmbControllerHostElement) { + super(host, new UmbTemplateRepository(host)); + } + + getData() { + return this.#data.getValue(); + } + + setName(value: string) { + this.#data.next({ ...this.#data.value, $type: this.#data.value?.$type || '', name: value }); + } + + setContent(value: string) { + this.#data.next({ ...this.#data.value, $type: this.#data.value?.$type || '', content: value }); + } + + async load(entityId: string) { + const { data } = await this.repository.requestByKey(entityId); + if (data) { + this.setIsNew(false); + this.#data.next(data); + } + } + + async createScaffold(parentId: string | null) { + const { data } = await this.repository.createScaffold(parentId); + if (!data) return; + this.setIsNew(true); + this.#data.next(data); + } + }`, + json: `{ + "compilerOptions": { + "module": "esnext", + "target": "esnext", + "lib": ["es2020", "dom", "dom.iterable"], + "declaration": true, + "emitDeclarationOnly": true, + "noEmitOnError": true, + "outDir": "./types", + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "forceConsistentCasingInFileNames": true, + "useDefineForClassFields": false, + "skipLibCheck": true, + "resolveJsonModule": true, + "baseUrl": ".", + "paths": { + "@umbraco-cms/css": ["libs/css/custom-properties.css"], + "@umbraco-cms/modal": ["src/core/modal"], + "@umbraco-cms/models": ["libs/models"], + "@umbraco-cms/backend-api": ["libs/backend-api"], + "@umbraco-cms/context-api": ["libs/context-api"], + "@umbraco-cms/controller": ["libs/controller"], + "@umbraco-cms/element": ["libs/element"], + "@umbraco-cms/extensions-api": ["libs/extensions-api"], + "@umbraco-cms/extensions-registry": ["libs/extensions-registry"], + "@umbraco-cms/notification": ["libs/notification"], + "@umbraco-cms/observable-api": ["libs/observable-api"], + "@umbraco-cms/events": ["libs/events"], + "@umbraco-cms/entity-action": ["libs/entity-action"], + "@umbraco-cms/workspace": ["libs/workspace"], + "@umbraco-cms/utils": ["libs/utils"], + "@umbraco-cms/router": ["libs/router"], + "@umbraco-cms/test-utils": ["libs/test-utils"], + "@umbraco-cms/repository": ["libs/repository"], + "@umbraco-cms/resources": ["libs/resources"], + "@umbraco-cms/store": ["libs/store"], + "@umbraco-cms/components/*": ["src/backoffice/components/*"], + "@umbraco-cms/sections/*": ["src/backoffice/sections/*"] + } + }, + "include": ["src/**/*.ts", "apps/**/*.ts", "libs/**/*.ts", "e2e/**/*.ts"], + "references": [ + { + "path": "./tsconfig.node.json" + } + ] + }`, +}; + +export default meta; +type Story = StoryObj; + +const [Javascript, Css, Html, Razor, Markdown, Typescript, Json]: Story[] = Object.keys(codeSnippets).map( + (language) => { + return { + args: { + language: language as CodeEditorLanguage, + code: codeSnippets[language as CodeEditorLanguage], + }, + }; + } +); + +const Themes: Story = { + args: { + language: 'javascript', + code: codeSnippets.javascript, + theme: CodeEditorTheme.Dark, + }, +}; + +export { Javascript, Css, Html, Razor, Markdown, Typescript, Json, Themes }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/index.ts new file mode 100644 index 0000000000..36b9c2e5c2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/index.ts @@ -0,0 +1,8 @@ +import * as initializeWorkers from './languageWorkers'; +import { UmbCodeEditorElement } from './code-editor.element'; +import { UmbCodeEditorController } from './code-editor.controller'; +import { monacoEditorStyles } from './styles'; + +export default UmbCodeEditorElement; + +export { initializeWorkers, UmbCodeEditorController as UmbCodeEditor, UmbCodeEditorElement, monacoEditorStyles }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/languageWorkers.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/languageWorkers.ts new file mode 100644 index 0000000000..8fd766ec2e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/languageWorkers.ts @@ -0,0 +1,33 @@ +//eslint-disable-next-line +import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'; +//eslint-disable-next-line +import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'; +//eslint-disable-next-line +import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'; +//eslint-disable-next-line +import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'; +//eslint-disable-next-line +import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'; + +export const initializeWorkers = () => { + self.MonacoEnvironment = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + getWorker(_: any, label: string) { + if (label === 'json') { + return new jsonWorker(); + } + if (label === 'css' || label === 'scss' || label === 'less') { + return new cssWorker(); + } + if (label === 'html' || label === 'handlebars' || label === 'razor') { + return new htmlWorker(); + } + if (label === 'typescript' || label === 'javascript') { + return new tsWorker(); + } + return new editorWorker(); + }, + }; +}; + +initializeWorkers(); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/styles.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/styles.ts new file mode 100644 index 0000000000..00f7a55e4d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/styles.ts @@ -0,0 +1,14 @@ +import { css, unsafeCSS } from 'lit'; +import styles from 'monaco-editor/min/vs/editor/editor.main.css?inline'; + +export const monacoEditorStyles = css` + ${unsafeCSS(styles)} +`; + +export const monacoJumpingCursorHack = css` + /* a hacky workaround this issue: https://github.com/microsoft/monaco-editor/issues/3217 + should probably be removed when the issue is fixed */ + .view-lines { + font-feature-settings: revert !important; + } +`; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.dark.theme.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.dark.theme.ts new file mode 100644 index 0000000000..cb746a8db7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.dark.theme.ts @@ -0,0 +1,10 @@ +import * as monaco from 'monaco-editor'; + +export const UmbCodeEditorThemeDark: monaco.editor.IStandaloneThemeData = { + base: 'vs-dark', + inherit: true, // can also be false to completely replace the builtin rules + rules: [], + colors: { + 'editor.background': '#21262e', + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.hc-dark.theme.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.hc-dark.theme.ts new file mode 100644 index 0000000000..6e5083021f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.hc-dark.theme.ts @@ -0,0 +1,8 @@ +import * as monaco from 'monaco-editor'; + +export const UmbCodeEditorThemeHighContrastDark: monaco.editor.IStandaloneThemeData = { + base: 'vs-dark', + inherit: true, // can also be false to completely replace the builtin rules + rules: [], + colors: {}, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.hc-light.theme.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.hc-light.theme.ts new file mode 100644 index 0000000000..f783ff22ab --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.hc-light.theme.ts @@ -0,0 +1,8 @@ +import * as monaco from 'monaco-editor'; + +export const UmbCodeEditorThemeHighContrastLight: monaco.editor.IStandaloneThemeData = { + base: 'vs', + inherit: true, // can also be false to completely replace the builtin rules + rules: [], + colors: {}, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.light.theme.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.light.theme.ts new file mode 100644 index 0000000000..1c5c98cbb3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/code-editor.light.theme.ts @@ -0,0 +1,8 @@ +import * as monaco from 'monaco-editor'; + +export const UmbCodeEditorThemeLight: monaco.editor.IStandaloneThemeData = { + base: 'vs', + inherit: true, // can also be false to completely replace the builtin rules + rules: [], + colors: {}, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/index.ts new file mode 100644 index 0000000000..89c7798708 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/code-editor/themes/index.ts @@ -0,0 +1,24 @@ +import * as monaco from 'monaco-editor'; +import { CodeEditorTheme } from '../code-editor.model'; +import { UmbCodeEditorThemeHighContrastLight } from './code-editor.hc-light.theme'; +import { UmbCodeEditorThemeHighContrastDark } from './code-editor.hc-dark.theme'; +import { UmbCodeEditorThemeLight } from './code-editor.light.theme'; +import { UmbCodeEditorThemeDark } from './code-editor.dark.theme'; +/** + * 4 themes for the code editor. + * + * @type {*} */ +const themes: Record = { + 'umb-dark': UmbCodeEditorThemeDark, + 'umb-light': UmbCodeEditorThemeLight, + 'umb-hc-light': UmbCodeEditorThemeHighContrastLight, + 'umb-hc-dark': UmbCodeEditorThemeHighContrastDark, +}; +export { + UmbCodeEditorThemeDark, + UmbCodeEditorThemeLight, + UmbCodeEditorThemeHighContrastLight, + UmbCodeEditorThemeHighContrastDark, + themes, +}; +export default themes; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts index f790057ecf..33f35f8f52 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/debug.element.ts @@ -1,16 +1,20 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing, TemplateResult } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UMB_CONTEXT_DEBUGGER_MODAL_TOKEN } from './modals/debug'; -import { UmbContextDebugRequest } from '@umbraco-cms/context-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; + +import { contextData, DebugContextData, DebugContextItemData, UmbContextDebugRequest } from '@umbraco-cms/backoffice/context-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbModalContext, UMB_CONTEXT_DEBUGGER_MODAL, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; @customElement('umb-debug') -export class UmbDebug extends UmbLitElement { +export class UmbDebugElement extends UmbLitElement { static styles = [ UUITextStyles, css` + :host { + float: right; + } + #container { display: block; font-family: monospace; @@ -54,13 +58,13 @@ export class UmbDebug extends UmbLitElement { ]; @property({ reflect: true, type: Boolean }) - enabled = false; + visible = false; @property({ reflect: true, type: Boolean }) dialog = false; - @property() - contexts = new Map(); + @state() + contextData = Array(); @state() private _debugPaneOpen = false; @@ -85,13 +89,16 @@ export class UmbDebug extends UmbLitElement { // to the root of which then uses the callback prop // of the this event tha has been raised to assign the contexts // back to this property of the WebComponent - this.contexts = contexts; + + // Massage the data into a simplier array of objects + // From a function in the context-api ' + this.contextData = contextData(contexts); }) ); } render() { - if (this.enabled) { + if (this.visible) { return this.dialog ? this._renderDialog() : this._renderPanel(); } else { return nothing; @@ -103,7 +110,7 @@ export class UmbDebug extends UmbLitElement { } private _openDialog() { - this._modalContext?.open(UMB_CONTEXT_DEBUGGER_MODAL_TOKEN, { + this._modalContext?.open(UMB_CONTEXT_DEBUGGER_MODAL, { content: html`${this._renderContextAliases()}`, }); } @@ -132,40 +139,39 @@ export class UmbDebug extends UmbLitElement {
  • `; } - + private _renderContextAliases() { const contextsTemplates: TemplateResult[] = []; - for (const [alias, instance] of this.contexts) { + this.contextData.forEach((contextData) => { contextsTemplates.push( html`
  • - Context: ${alias} - (${typeof instance}) + Context: ${contextData.alias} + (${contextData.type})
      - ${this._renderInstance(instance)} + ${this._renderInstance(contextData.data)}
  • ` ); - } + }); return contextsTemplates; } - private _renderInstance(instance: any) { + private _renderInstance(instance: DebugContextItemData) { const instanceTemplates: TemplateResult[] = []; - - // TODO: WB - Maybe make this a switch statement? - if (typeof instance === 'function') { + + if(instance.type === 'function'){ return instanceTemplates.push(html`
  • Callable Function
  • `); - } else if (typeof instance === 'object') { - const methodNames = this.getClassMethodNames(instance); - if (methodNames.length) { + } + else if(instance.type === 'object'){ + if(instance.methods?.length){ instanceTemplates.push( html`
  • Methods
      - ${methodNames.map((methodName) => html`
    • ${methodName}
    • `)} + ${instance.methods?.map((methodName) => html`
    • ${methodName}
    • `)}
  • ` @@ -173,19 +179,13 @@ export class UmbDebug extends UmbLitElement { } const props: TemplateResult[] = []; - - for (const key in instance) { - if (key.startsWith('_')) { - continue; - } - - const value = instance[key]; - if (typeof value === 'string') { - props.push(html`
  • ${key} = ${value}
  • `); + instance.properties?.forEach((property) => { + if (property.type === 'string') { + props.push(html`
  • ${property.key} = ${property.value}
  • `); } else { - props.push(html`
  • ${key} (${typeof value})
  • `); + props.push(html`
  • ${property.key} (${property.type})
  • `); } - } + }); instanceTemplates.push(html`
  • @@ -195,33 +195,17 @@ export class UmbDebug extends UmbLitElement {
  • `); - } else { - instanceTemplates.push(html`
  • Context is a primitive with value: ${instance}
  • `); + } + else if(instance.type === 'primitive'){ + instanceTemplates.push(html`
  • Context is a primitive with value: ${instance.value}
  • `); } return instanceTemplates; } - - private getClassMethodNames(klass: any) { - const isGetter = (x: any, name: string): boolean => !!(Object.getOwnPropertyDescriptor(x, name) || {}).get; - const isFunction = (x: any, name: string): boolean => typeof x[name] === 'function'; - const deepFunctions = (x: any): any => - x !== Object.prototype && - Object.getOwnPropertyNames(x) - .filter((name) => isGetter(x, name) || isFunction(x, name)) - .concat(deepFunctions(Object.getPrototypeOf(x)) || []); - const distinctDeepFunctions = (klass: any) => Array.from(new Set(deepFunctions(klass))); - - const allMethods = - typeof klass.prototype === 'undefined' - ? distinctDeepFunctions(klass) - : Object.getOwnPropertyNames(klass.prototype); - return allMethods.filter((name: any) => name !== 'constructor' && !name.startsWith('_')); - } } declare global { interface HTMLElementTagNameMap { - 'umb-debug': UmbDebug; + 'umb-debug': UmbDebugElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/manifests.ts index 2b82b6cb72..fd0b85cdf1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/modals/debug/debug-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/modals/debug/debug-modal.element.ts index 841bc6c32b..74e5ade59c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/modals/debug/debug-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/modals/debug/debug-modal.element.ts @@ -1,8 +1,8 @@ import { css, html } from 'lit'; import { customElement } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css'; -import { UmbContextDebuggerModalData } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { UmbContextDebuggerModalData } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; @customElement('umb-context-debugger-modal') export default class UmbContextDebuggerModalElement extends UmbModalBaseElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/modals/debug/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/modals/debug/index.ts deleted file mode 100644 index 2bf39440e8..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/debug/modals/debug/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { TemplateResult } from 'lit'; -import { UmbModalToken } from '@umbraco-cms/modal'; - -export interface UmbContextDebuggerModalData { - content: TemplateResult | string; -} - -export const UMB_CONTEXT_DEBUGGER_MODAL_TOKEN = new UmbModalToken( - 'Umb.Modal.ContextDebugger', - { - type: 'sidebar', - size: 'small', - } -); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.element.ts similarity index 99% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.element.ts index 916ce79310..fb3a7bfcd4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.element.ts @@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, LitElement, svg } from 'lit'; import { customElement, property, query, queryAssignedElements, state } from 'lit/decorators.js'; import { clamp } from 'lodash-es'; -import { UmbDonutSliceElement } from './donut-slice'; +import { UmbDonutSliceElement } from './donut-slice.element'; export interface Circle { color: string; @@ -180,8 +180,6 @@ export class UmbDonutChartElement extends LitElement { this.#printCircles(); } - - } #calculatePercentage(partialValue: number) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.stories.ts index 72529b5b1e..94a935efb6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-chart.stories.ts @@ -1,8 +1,8 @@ -import './donut-slice'; -import './donut-chart'; +import './donut-slice.element'; +import './donut-chart.element'; import { Meta } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; export default { title: 'Components/Donut chart', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-slice.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-slice.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-slice.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/donut-slice.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/index.ts index 218f52b18f..b01b77e83f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/donut-chart/index.ts @@ -1,2 +1,2 @@ -export * from './donut-chart'; -export * from './donut-slice'; +export * from './donut-chart.element'; +export * from './donut-slice.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/dropdown/dropdown.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/dropdown/dropdown.element.ts index 20a72a57d9..c2164ab66b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/dropdown/dropdown.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/dropdown/dropdown.element.ts @@ -1,7 +1,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; // TODO: maybe move this to UI Library. @customElement('umb-dropdown') diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/empty-state/empty-state.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/empty-state/empty-state.stories.ts index 5784914c4e..ddcd24e6fc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/empty-state/empty-state.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/empty-state/empty-state.stories.ts @@ -1,26 +1,27 @@ import { Meta, StoryObj } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import './empty-state.element'; import type { UmbEmptyStateElement } from './empty-state.element'; const meta: Meta = { - title: 'Components/Empty State', - component: 'umb-empty-state', - render: (args) => html` - There are no items to be found`, + title: 'Components/Empty State', + component: 'umb-empty-state', + render: (args) => html` There are no items to be found`, }; - + export default meta; type Story = StoryObj; export const Overview: Story = { - args: { - size: 'large', - } + args: { + size: 'large', + }, }; export const Small: Story = { - args: { - size: 'small', - } -}; \ No newline at end of file + args: { + size: 'small', + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts index 920b3b91f5..3ea2640821 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action-list.element.ts @@ -1,9 +1,9 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { map } from 'rxjs'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models'; +import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; @customElement('umb-entity-action-list') class UmbEntityActionListElement extends UmbLitElement { @@ -32,7 +32,7 @@ class UmbEntityActionListElement extends UmbLitElement { this.observe( umbExtensionsRegistry.extensionsOfType('entityAction').pipe( map((extensions) => { - return extensions.filter((extension) => extension.meta.entityType === this.entityType); + return extensions.filter((extension) => extension.conditions.entityType === this.entityType); }) ), (actions) => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts index fb8da88a95..3ef6ad3819 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-action/entity-action.element.ts @@ -2,9 +2,9 @@ import { html, nothing } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { UUIMenuItemEvent } from '@umbraco-ui/uui'; -import { UmbExecutedEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { ManifestEntityAction } from '@umbraco-cms/extensions-registry'; +import { UmbExecutedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; @customElement('umb-entity-action') class UmbEntityActionElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-bulk-action/entity-bulk-action.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-bulk-action/entity-bulk-action.element.ts index 01b150f737..f21156c02c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-bulk-action/entity-bulk-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/entity-bulk-action/entity-bulk-action.element.ts @@ -1,10 +1,10 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; -import { UmbEntityBulkAction } from '@umbraco-cms/entity-action'; -import { UmbExecutedEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { ManifestEntityBulkAction } from '@umbraco-cms/extensions-registry'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UmbEntityBulkAction } from '@umbraco-cms/backoffice/entity-action'; +import { UmbExecutedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extensions-registry'; @customElement('umb-entity-bulk-action') class UmbEntityBulkActionElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.element.ts index eec5648e04..d690fb3091 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.element.ts @@ -4,8 +4,12 @@ import type { TemplateResult } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { map } from 'rxjs'; import { repeat } from 'lit/directives/repeat.js'; -import { createExtensionElement, isManifestElementableType, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { + createExtensionElement, + isManifestElementableType, + umbExtensionsRegistry, +} from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; export type InitializedExtension = { alias: string; weight: number; component: HTMLElement | null }; @@ -34,12 +38,23 @@ export class UmbExtensionSlotElement extends UmbLitElement { @property({ type: Object, attribute: false }) public filter: (manifest: any) => boolean = () => true; + private _props?: Record = {}; + @property({ type: Object, attribute: false }) + get props() { + return this._props; + } + set props(newVal) { + this._props = newVal; + // TODO: we could optimize this so we only re-set the updated props. + this.#assignPropsToAllComponents(); + } + @property({ type: String, attribute: 'default-element' }) public defaultElement = ''; @property() - public renderMethod: (manifest: InitializedExtension) => TemplateResult<1 | 2> | HTMLElement | null = (manifest) => - manifest.component; + public renderMethod: (extension: InitializedExtension) => TemplateResult<1 | 2> | HTMLElement | null = (extension) => + extension.component; connectedCallback(): void { super.connectedCallback(); @@ -71,16 +86,19 @@ export class UmbExtensionSlotElement extends UmbLitElement { if (isManifestElementableType(extension)) { component = await createExtensionElement(extension); - } else { + } else if (this.defaultElement) { component = document.createElement(this.defaultElement); + } else { + // TODO: Lets make an console.error in this case? } if (component) { + this.#assignProps(component); (component as any).manifest = extension; extensionObject.component = component; // sort: // TODO: Make sure its right to have highest last? - this._extensions.sort((a, b) => a.weight - b.weight); + this._extensions.sort((a, b) => b.weight - a.weight); } else { // Remove cause we could not get the component, so we will get rid of this. //this._extensions.splice(this._extensions.indexOf(extensionObject), 1); @@ -93,6 +111,18 @@ export class UmbExtensionSlotElement extends UmbLitElement { ); } + #assignPropsToAllComponents() { + this._extensions.forEach((ext) => this.#assignProps(ext.component)); + } + + #assignProps = (component: HTMLElement | null) => { + if (!component || !this._props) return; + + Object.keys(this._props).forEach((key) => { + (component as any)[key] = this._props?.[key]; + }); + }; + render() { // TODO: check if we can use repeat directly. return repeat( diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.test.ts index b9d6afd8ba..a61451b20b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/extension-slot/extension-slot.test.ts @@ -1,9 +1,9 @@ import { customElement } from 'lit/decorators.js'; import { expect, fixture, html } from '@open-wc/testing'; import { InitializedExtension, UmbExtensionSlotElement } from './extension-slot.element'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestDashboard } from '@umbraco-cms/extensions-registry'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestDashboard } from '@umbraco-cms/backoffice/extensions-registry'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; @customElement('test-extension-slot-manifest-element') class MyExtensionSlotManifestElement extends HTMLElement {} @@ -54,9 +54,11 @@ describe('UmbExtensionSlotElement', () => { name: 'unit-test-extension', elementName: 'test-extension-slot-manifest-element', meta: { - sections: ['test'], pathname: 'test/test', }, + conditions: { + sections: ['test'], + }, }); }); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.element.ts index 565142fdeb..fc7cadf0f8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.element.ts @@ -12,7 +12,7 @@ import { customElement, state } from 'lit/decorators.js'; * @extends {UmbLitElement} */ @customElement('umb-footer-layout') -export class UmbFooterLayout extends LitElement { +export class UmbFooterLayoutElement extends LitElement { static styles = [ UUITextStyles, css` @@ -46,6 +46,6 @@ export class UmbFooterLayout extends LitElement { declare global { interface HTMLElementTagNameMap { - 'umb-footer-layout': UmbFooterLayout; + 'umb-footer-layout': UmbFooterLayoutElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.stories.ts index dc5fce7e70..c09a6d7fca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/footer-layout/footer-layout.stories.ts @@ -1,9 +1,9 @@ import './footer-layout.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; -import type { UmbFooterLayout } from './footer-layout.element'; +import type { UmbFooterLayoutElement } from './footer-layout.element'; export default { title: 'Workspaces/Shared/Footer Layout', @@ -11,7 +11,7 @@ export default { id: 'umb-footer-layout', } as Meta; -export const AAAOverview: Story = () => html` +export const AAAOverview: Story = () => html`
    Footer slotActions slot diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app-button.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app-button.element.ts index 2095d825fd..536bbb0424 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app-button.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app-button.element.ts @@ -2,10 +2,24 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; -import { ManifestHeaderApp } from '@umbraco-cms/extensions-registry'; +import { ManifestHeaderAppButtonKind, ManifestKind } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; + +const manifest: ManifestKind = { + type: 'kind', + alias: 'Umb.Kind.Button', + matchKind: 'button', + matchType: 'headerApp', + manifest: { + type: 'headerApp', + kind: 'button', + elementName: 'umb-header-app-button', + }, +}; +umbExtensionsRegistry.register(manifest); @customElement('umb-header-app-button') -export class UmbHeaderAppButton extends LitElement { +export class UmbHeaderAppButtonElement extends LitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -16,21 +30,25 @@ export class UmbHeaderAppButton extends LitElement { `, ]; - public manifest?: ManifestHeaderApp; + public manifest?: ManifestHeaderAppButtonKind; render() { return html` - + `; } } -export default UmbHeaderAppButton; +export default UmbHeaderAppButtonElement; declare global { interface HTMLElementTagNameMap { - 'umb-header-app-button': UmbHeaderAppButton; + 'umb-header-app-button': UmbHeaderAppButtonElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app.stories.ts index 581f8416eb..d9a4cab61c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/header-app/header-app.stories.ts @@ -1,26 +1,27 @@ import { Meta, StoryObj } from '@storybook/web-components'; import './header-app-button.element'; -import type { UmbHeaderAppButton } from './header-app-button.element'; +import type { UmbHeaderAppButtonElement } from './header-app-button.element'; -const meta: Meta = { - title: 'Components/Header App Button', - component: 'umb-header-app-button' +const meta: Meta = { + title: 'Components/Header App Button', + component: 'umb-header-app-button', }; - + export default meta; -type Story = StoryObj; - +type Story = StoryObj; + export const Overview: Story = { - args: { - manifest: { - name: 'Some Manifest', - alias: 'someManifestAlias', - type: 'headerApp', - meta: { - label: 'Some Header', - icon: 'umb:home', - pathname: '/some/path' - } - } - } -}; \ No newline at end of file + args: { + manifest: { + name: 'Some Manifest', + alias: 'someManifestAlias', + type: 'headerApp', + kind: 'button', + meta: { + label: 'Some Header', + icon: 'umb:home', + href: '/some/path', + }, + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-item.element.ts index 1db73bb340..9202a44398 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-item.element.ts @@ -1,7 +1,7 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-history-item') export class UmbHistoryItemElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.element.ts index c89a0f39d5..8e1a1b78de 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.element.ts @@ -1,7 +1,7 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-history-list') export class UmbHistoryListElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.stories.ts index fdc13cc6e0..5537f44735 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/history/history-list.stories.ts @@ -2,7 +2,7 @@ import './history-list.element'; import './history-item.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbHistoryListElement } from './history-list.element'; import type { UmbHistoryItemElement } from './history-item.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts index 04c03284f7..78b453c6cb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/index.ts @@ -21,29 +21,42 @@ import './input-checkbox-list/input-checkbox-list.element'; import './input-color-picker/input-color-picker.element'; import './input-culture-select/input-culture-select.element'; import './input-document-picker/input-document-picker.element'; +import './input-document-type-picker/input-document-type-picker.element'; import './input-eye-dropper/input-eye-dropper.element'; import './input-language-picker/input-language-picker.element'; import './input-media-picker/input-media-picker.element'; import './input-multi-url-picker/input-multi-url-picker.element'; import './input-slider/input-slider.element'; import './input-toggle/input-toggle.element'; +import './input-upload-field/input-upload-field.element'; +import './input-template-picker/input-template-picker.element'; import './property-type-based-property/property-type-based-property.element'; import './ref-property-editor-ui/ref-property-editor-ui.element'; import './section/section-main/section-main.element'; import './section/section-sidebar/section-sidebar.element'; import './section/section.element'; + import './table/table.element'; + import './tree/tree.element'; +import './tree/entity-tree-item/entity-tree-item.element'; +import './tree/tree-menu-item/tree-menu-item.element'; + +import './menu/menu-item-base/menu-item-base.element'; + import './variantable-property/variantable-property.element'; import './workspace/workspace-action-menu/workspace-action-menu.element'; +import './header-app/header-app-button.element'; + import './history/history-list.element'; import './history/history-item.element'; import './workspace/workspace-action/workspace-action.element'; -import './workspace/workspace-content/workspace-content.element'; import './workspace/workspace-layout/workspace-layout.element'; - import './workspace/workspace-footer-layout/workspace-footer-layout.element'; +import './template-card/template-card.element'; +import './code-editor'; + export const manifests = [...debugManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.element.ts index 9555158e76..e70a5fc6b4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.element.ts @@ -4,7 +4,7 @@ import { customElement, property } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { repeat } from 'lit/directives/repeat.js'; import { UUIBooleanInputEvent } from '@umbraco-ui/uui'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-input-checkbox-list') export class UmbInputCheckboxListElement extends FormControlMixin(UmbLitElement) { @@ -20,6 +20,7 @@ export class UmbInputCheckboxListElement extends FormControlMixin(UmbLitElement) /** * List of items. */ + // TODO: Could this use a type that we export to ensure TS failure, or hook this up with a type coming from backend? @property() public list: Array<{ key: string; checked: boolean; value: string }> = []; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.stories.ts index d3ed1de046..cee98bed08 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-checkbox-list/input-checkbox-list.stories.ts @@ -3,26 +3,26 @@ import './input-checkbox-list.element'; import type { UmbInputCheckboxListElement } from './input-checkbox-list.element'; const meta: Meta = { - title: 'Components/Inputs/Checkbox List', - component: 'umb-input-checkbox-list' + title: 'Components/Inputs/Checkbox List', + component: 'umb-input-checkbox-list', }; - + export default meta; type Story = StoryObj; - + export const Overview: Story = { - args: { - list: [ - { - key: "isAwesome", - value: "Umbraco is awesome?", - checked: true - }, - { - key: "attendingCodeGarden", - value: "Attending CodeGarden?", - checked: false - }, - ] - } -}; \ No newline at end of file + args: { + list: [ + { + key: 'isAwesome', + value: 'Umbraco is awesome?', + checked: true, + }, + { + key: 'attendingCodeGarden', + value: 'Attending CodeGarden?', + checked: false, + }, + ], + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.element.ts index 3764f7ac75..4125f2e8a2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.element.ts @@ -3,13 +3,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UUIColorSwatchesEvent } from '@umbraco-ui/uui'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { SwatchDetails } from '@umbraco-cms/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { SwatchDetails } from '@umbraco-cms/backoffice/models'; /* * This wraps the UUI library uui-color-swatches component * @element umb-input-color-picker -*/ + */ @customElement('umb-input-color-picker') export class UmbInputColorPickerElement extends FormControlMixin(UmbLitElement) { static styles = [UUITextStyles]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.test.ts index 1cc62c08c9..437f318e7f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-color-picker/input-color-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInputColorPickerElement } from './input-color-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbInputColorPickerElement', () => { let element: UmbInputColorPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-culture-select/input-culture-select.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-culture-select/input-culture-select.element.ts index bdcf53b259..847c14bcb7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-culture-select/input-culture-select.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-culture-select/input-culture-select.element.ts @@ -2,13 +2,13 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { repeat } from 'lit/directives/repeat.js'; import { UUIComboboxElement, UUIComboboxEvent } from '@umbraco-ui/uui'; import { UmbCultureRepository } from '../../../settings/cultures/repository/culture.repository'; -import { UmbChangeEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { CultureModel } from '@umbraco-cms/backend-api'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { CultureReponseModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-input-culture-select') export class UmbInputCultureSelectElement extends FormControlMixin(UmbLitElement) { @@ -33,7 +33,7 @@ export class UmbInputCultureSelectElement extends FormControlMixin(UmbLitElement readonly = false; @state() - private _cultures: CultureModel[] = []; + private _cultures: CultureReponseModel[] = []; @state() private _search = ''; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.element.ts index b7a16996bc..d87623d464 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.element.ts @@ -1,16 +1,19 @@ 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 { ifDefined } from 'lit/directives/if-defined.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from '../../../documents/documents/repository/document.tree.store'; import type { UmbDocumentTreeStore } from '../../../documents/documents/repository/document.tree.store'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../modals/confirm'; -import { UMB_DOCUMENT_PICKER_MODAL_TOKEN } from '../../../documents/documents/modals/document-picker'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DocumentTreeItemModel, FolderTreeItemModel } from '@umbraco-cms/backend-api'; -import type { UmbObserverController } from '@umbraco-cms/observable-api'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, + UMB_DOCUMENT_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DocumentTreeItemResponseModel, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; @customElement('umb-input-document-picker') export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElement) { @@ -58,30 +61,30 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen @property({ type: String, attribute: 'min-message' }) maxMessage = 'This field exceeds the allowed amount of items'; - // TODO: do we need both selectedKeys and value? If we just use value we follow the same pattern as native form controls. - private _selectedKeys: Array = []; - public get selectedKeys(): Array { - return this._selectedKeys; + // TODO: do we need both selectedIds and value? If we just use value we follow the same pattern as native form controls. + private _selectedIds: Array = []; + public get selectedIds(): Array { + return this._selectedIds; } - public set selectedKeys(keys: Array) { - this._selectedKeys = keys; - super.value = keys.join(','); + public set selectedIds(ids: Array) { + this._selectedIds = ids; + super.value = ids.join(','); this._observePickedDocuments(); } @property() - public set value(keysString: string) { - if (keysString !== this._value) { - this.selectedKeys = keysString.split(/[ ,]+/); + public set value(idsString: string) { + if (idsString !== this._value) { + this.selectedIds = idsString.split(/[ ,]+/); } } @state() - private _items?: Array; + private _items?: Array; private _modalContext?: UmbModalContext; private _documentStore?: UmbDocumentTreeStore; - private _pickedItemsObserver?: UmbObserverController; + private _pickedItemsObserver?: UmbObserverController; constructor() { super(); @@ -89,12 +92,12 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen this.addValidator( 'rangeUnderflow', () => this.minMessage, - () => !!this.min && this._selectedKeys.length < this.min + () => !!this.min && this._selectedIds.length < this.min ); this.addValidator( 'rangeOverflow', () => this.maxMessage, - () => !!this.max && this._selectedKeys.length > this.max + () => !!this.max && this._selectedIds.length > this.max ); this.consumeContext(UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN, (instance) => { @@ -116,16 +119,16 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen if (!this._documentStore) return; // TODO: consider changing this to the list data endpoint when it is available - this._pickedItemsObserver = this.observe(this._documentStore.items(this._selectedKeys), (items) => { + this._pickedItemsObserver = this.observe(this._documentStore.items(this._selectedIds), (items) => { this._items = items; }); } private _openPicker() { - // We send a shallow copy(good enough as its just an array of keys) of our this._selectedKeys, as we don't want the modal to manipulate our data: - const modalHandler = this._modalContext?.open(UMB_DOCUMENT_PICKER_MODAL_TOKEN, { + // We send a shallow copy(good enough as its just an array of ids) of our this._selectedIds, as we don't want the modal to manipulate our data: + const modalHandler = this._modalContext?.open(UMB_DOCUMENT_PICKER_MODAL, { multiple: this.max === 1 ? false : true, - selection: [...this._selectedKeys], + selection: [...this._selectedIds], }); modalHandler?.onSubmit().then(({ selection }: any) => { @@ -133,8 +136,8 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen }); } - private async _removeItem(item: FolderTreeItemModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + private async _removeItem(item: EntityTreeItemResponseModel) { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { color: 'danger', headline: `Remove ${item.name}?`, content: 'Are you sure you want to remove this item', @@ -142,12 +145,12 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen }); await modalHandler?.onSubmit(); - const newSelection = this._selectedKeys.filter((value) => value !== item.key); + const newSelection = this._selectedIds.filter((value) => value !== item.id); this._setSelection(newSelection); } private _setSelection(newSelection: Array) { - this.selectedKeys = newSelection; + this.selectedIds = newSelection; this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true })); } @@ -158,12 +161,12 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen `; } - private _renderItem(item: FolderTreeItemModel) { + private _renderItem(item: EntityTreeItemResponseModel) { // TODO: remove when we have a way to handle trashed items - const tempItem = item as FolderTreeItemModel & { isTrashed: boolean }; + const tempItem = item as EntityTreeItemResponseModel & { isTrashed: boolean }; return html` - + ${tempItem.isTrashed ? html` Trashed ` : nothing} this._removeItem(item)} label="Remove document ${item.name}">Remove diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.test.ts index d7f33ff52c..4c20a6ec05 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-picker/input-document-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInputDocumentPickerElement } from './input-document-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbInputDocumentPickerElement', () => { let element: UmbInputDocumentPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-type-picker/input-document-type-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-type-picker/input-document-type-picker.element.ts new file mode 100644 index 0000000000..c3f844b898 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-document-type-picker/input-document-type-picker.element.ts @@ -0,0 +1,141 @@ +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 { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; +import { + UmbDocumentTypeTreeStore, + UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN, +} from '../../../documents/document-types/repository/document-type.tree.store'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, + UMB_DOCUMENT_TYPE_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DocumentTypeResponseModel, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; + +@customElement('umb-input-document-type-picker') +export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitElement) { + static styles = [ + UUITextStyles, + css` + #add-button { + width: 100%; + } + `, + ]; + + // TODO: do we need both selectedIds and value? If we just use value we follow the same pattern as native form controls. + private _selectedIds: Array = []; + public get selectedIds(): Array { + return this._selectedIds; + } + public set selectedIds(ids: Array) { + this._selectedIds = ids; + super.value = ids.join(','); + this._observePickedDocuments(); + } + + @property() + public set value(idsString: string) { + if (idsString !== this._value) { + this.selectedIds = idsString.split(/[ ,]+/); + } + } + + @state() + private _items?: Array; + + private _modalContext?: UmbModalContext; + private _documentTypeStore?: UmbDocumentTypeTreeStore; + private _pickedItemsObserver?: UmbObserverController; + + constructor() { + super(); + this.consumeContext(UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN, (instance) => { + this._documentTypeStore = instance; + this._observePickedDocuments(); + }); + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this._modalContext = instance; + }); + } + + protected getFormElement() { + return undefined; + } + + private _observePickedDocuments() { + this._pickedItemsObserver?.destroy(); + + if (!this._documentTypeStore) return; + + // TODO: consider changing this to the list data endpoint when it is available + this._pickedItemsObserver = this.observe(this._documentTypeStore.items(this._selectedIds), (items) => { + this._items = items; + }); + } + + private _openPicker() { + // We send a shallow copy(good enough as its just an array of ids) of our this._selectedIds, as we don't want the modal to manipulate our data: + const modalHandler = this._modalContext?.open(UMB_DOCUMENT_TYPE_PICKER_MODAL, { + multiple: true, + selection: [...this._selectedIds], + }); + + modalHandler?.onSubmit().then(({ selection }: any) => { + this._setSelection(selection); + }); + } + + private async _removeItem(item: DocumentTypeResponseModel) { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + color: 'danger', + headline: `Remove ${item.name}?`, + content: 'Are you sure you want to remove this item', + confirmLabel: 'Remove', + }); + + await modalHandler?.onSubmit(); + const newSelection = this._selectedIds.filter((value) => value !== item.id); + this._setSelection(newSelection); + } + + private _setSelection(newSelection: Array) { + this.selectedIds = newSelection; + this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true })); + } + + render() { + return html` + ${this._items?.map((item) => this._renderItem(item))} + Add + `; + } + + private _renderItem(item: DocumentTypeResponseModel) { + // TODO: remove when we have a way to handle trashed items + const tempItem = item as DocumentTypeResponseModel & { isTrashed: boolean }; + + return html` + + + ${tempItem.isTrashed ? html` Trashed ` : nothing} + + this._removeItem(item)} label="Remove document ${item.name}">Remove + + + `; + } +} + +export default UmbInputDocumentTypePickerElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-input-document-type-picker': UmbInputDocumentTypePickerElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.element.ts index 75b173a544..73e3de3c2e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.element.ts @@ -3,7 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UUIColorPickerChangeEvent } from '@umbraco-ui/uui'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-input-eye-dropper') export class UmbInputEyeDropperElement extends FormControlMixin(UmbLitElement) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.test.ts index 5f471eea16..78c8726490 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-eye-dropper/input-eye-dropper.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInputEyeDropperElement } from './input-eye-dropper.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbInputEyeDropperElement', () => { let element: UmbInputEyeDropperElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-language-picker/input-language-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-language-picker/input-language-picker.element.ts index c9eb2bd3ca..df04084af4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-language-picker/input-language-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-language-picker/input-language-picker.element.ts @@ -1,16 +1,19 @@ 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 { ifDefined } from 'lit/directives/if-defined.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UmbLanguageRepository } from '../../../settings/languages/repository/language.repository'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../modals/confirm'; -import { UMB_LANGUAGE_PICKER_MODAL_TOKEN } from '../../../settings/languages/modals/language-picker'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbChangeEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { LanguageModel } from '@umbraco-cms/backend-api'; -import type { UmbObserverController } from '@umbraco-cms/observable-api'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, + UMB_LANGUAGE_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; @customElement('umb-input-language-picker') export class UmbInputLanguagePickerElement extends FormControlMixin(UmbLitElement) { @@ -59,31 +62,31 @@ export class UmbInputLanguagePickerElement extends FormControlMixin(UmbLitElemen maxMessage = 'This field exceeds the allowed amount of items'; @property({ type: Object, attribute: false }) - public filter: (language: LanguageModel) => boolean = () => true; + public filter: (language: LanguageResponseModel) => boolean = () => true; private _selectedIsoCodes: Array = []; public get selectedIsoCodes(): Array { return this._selectedIsoCodes; } - public set selectedIsoCodes(keys: Array) { - this._selectedIsoCodes = keys; - super.value = keys.join(','); + public set selectedIsoCodes(isoCodes: Array) { + this._selectedIsoCodes = isoCodes; + super.value = isoCodes.join(','); this._observePickedItems(); } @property() - public set value(keysString: string) { - if (keysString !== this._value) { - this.selectedIsoCodes = keysString.split(/[ ,]+/); + public set value(isoCodesString: string) { + if (isoCodesString !== this._value) { + this.selectedIsoCodes = isoCodesString.split(/[ ,]+/); } } @state() - private _items?: Array; + private _items?: Array; private _modalContext?: UmbModalContext; private _repository = new UmbLanguageRepository(this); - private _pickedItemsObserver?: UmbObserverController; + private _pickedItemsObserver?: UmbObserverController; constructor() { super(); @@ -121,7 +124,7 @@ export class UmbInputLanguagePickerElement extends FormControlMixin(UmbLitElemen } private _openPicker() { - const modalHandler = this._modalContext?.open(UMB_LANGUAGE_PICKER_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_LANGUAGE_PICKER_MODAL, { multiple: this.max === 1 ? false : true, selection: [...this._selectedIsoCodes], filter: this.filter, @@ -132,8 +135,8 @@ export class UmbInputLanguagePickerElement extends FormControlMixin(UmbLitElemen }); } - private _removeItem(item: LanguageModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + private _removeItem(item: LanguageResponseModel) { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { color: 'danger', headline: `Remove ${item.name}?`, content: 'Are you sure you want to remove this item', @@ -165,7 +168,7 @@ export class UmbInputLanguagePickerElement extends FormControlMixin(UmbLitElemen `; } - private _renderItem(item: LanguageModel) { + private _renderItem(item: LanguageResponseModel) { return html` diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-list-base/input-list-base.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-list-base/input-list-base.ts index a1d954be41..2128b126e5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-list-base/input-list-base.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-list-base/input-list-base.ts @@ -1,17 +1,17 @@ import { html } from 'lit'; import { property } from 'lit/decorators.js'; -import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; +import type { UUIModalSidebarSize } from '@umbraco-ui/uui'; import { UmbModalContext, UmbModalToken, UmbModalType, UMB_MODAL_CONTEXT_TOKEN, UmbPickerModalData, -} from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** TODO: Make use of UUI FORM Mixin, to make it easily take part of a form. */ -export class UmbInputListBase extends UmbLitElement { +export class UmbInputListBaseElement extends UmbLitElement { @property({ type: Array }) public value: Array = []; @@ -51,8 +51,8 @@ export class UmbInputListBase extends UmbLitElement { }); } - protected removeFromSelection(key: string) { - this.value = this.value.filter((k) => k !== key); + protected removeFromSelection(id: string) { + this.value = this.value.filter((k) => k !== id); this.selectionUpdated(); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.element.ts index 8778092f1c..f324ca44be 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.element.ts @@ -1,15 +1,18 @@ 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 { ifDefined } from 'lit/directives/if-defined.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UmbMediaRepository } from '../../../media/media/repository/media.repository'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../modals/confirm'; -import { UMB_MEDIA_PICKER_MODAL_TOKEN } from '../../../media/media/modals/media-picker'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { EntityTreeItemModel, FolderTreeItemModel } from '@umbraco-cms/backend-api'; -import type { UmbObserverController } from '@umbraco-cms/observable-api'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, + UMB_MEDIA_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; @customElement('umb-input-media-picker') export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) { @@ -23,7 +26,7 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) } #add-button { text-align: center; - height: 202px; + height: 160px; } uui-icon { @@ -69,29 +72,29 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) @property({ type: String, attribute: 'min-message' }) maxMessage = 'This field exceeds the allowed amount of items'; - // TODO: do we need both selectedKeys and value? If we just use value we follow the same pattern as native form controls. - private _selectedKeys: Array = []; - public get selectedKeys(): Array { - return this._selectedKeys; + // TODO: do we need both selectedIds and value? If we just use value we follow the same pattern as native form controls. + private _selectedIds: Array = []; + public get selectedIds(): Array { + return this._selectedIds; } - public set selectedKeys(keys: Array) { - this._selectedKeys = keys; - super.value = keys.join(','); + public set selectedIds(ids: Array) { + this._selectedIds = ids; + super.value = ids.join(','); this._observePickedMedias(); } @property() - public set value(keysString: string) { - if (keysString !== this._value) { - this.selectedKeys = keysString.split(/[ ,]+/); + public set value(idsString: string) { + if (idsString !== this._value) { + this.selectedIds = idsString.split(/[ ,]+/); } } @state() - private _items?: Array; + private _items?: Array; private _modalContext?: UmbModalContext; - private _pickedItemsObserver?: UmbObserverController; + private _pickedItemsObserver?: UmbObserverController; private _repository = new UmbMediaRepository(this); constructor() { @@ -100,12 +103,12 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) this.addValidator( 'rangeUnderflow', () => this.minMessage, - () => !!this.min && this._selectedKeys.length < this.min + () => !!this.min && this._selectedIds.length < this.min ); this.addValidator( 'rangeOverflow', () => this.maxMessage, - () => !!this.max && this._selectedKeys.length > this.max + () => !!this.max && this._selectedIds.length > this.max ); this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -126,7 +129,7 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) this._pickedItemsObserver?.destroy(); // TODO: consider changing this to the list data endpoint when it is available - const { asObservable } = await this._repository.requestTreeItems(this._selectedKeys); + const { asObservable } = await this._repository.requestTreeItems(this._selectedIds); if (!asObservable) return; @@ -136,10 +139,10 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) } private _openPicker() { - // We send a shallow copy(good enough as its just an array of keys) of our this._selectedKeys, as we don't want the modal to manipulate our data: - const modalHandler = this._modalContext?.open(UMB_MEDIA_PICKER_MODAL_TOKEN, { + // We send a shallow copy(good enough as its just an array of ids) of our this._selectedIds, as we don't want the modal to manipulate our data: + const modalHandler = this._modalContext?.open(UMB_MEDIA_PICKER_MODAL, { multiple: this.max === 1 ? false : true, - selection: [...this._selectedKeys], + selection: [...this._selectedIds], }); modalHandler?.onSubmit().then(({ selection }: any) => { @@ -147,8 +150,8 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) }); } - private _removeItem(item: FolderTreeItemModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + private _removeItem(item: EntityTreeItemResponseModel) { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { color: 'danger', headline: `Remove ${item.name}?`, content: 'Are you sure you want to remove this item', @@ -156,13 +159,13 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) }); modalHandler?.onSubmit().then(() => { - const newSelection = this._selectedKeys.filter((value) => value !== item.key); + const newSelection = this._selectedIds.filter((value) => value !== item.id); this._setSelection(newSelection); }); } private _setSelection(newSelection: Array) { - this.selectedKeys = newSelection; + this.selectedIds = newSelection; this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true })); } @@ -177,14 +180,14 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) `; } - private _renderItem(item: FolderTreeItemModel) { + private _renderItem(item: EntityTreeItemResponseModel) { // TODO: remove when we have a way to handle trashed items - const tempItem = item as FolderTreeItemModel & { isTrashed: boolean }; + const tempItem = item as EntityTreeItemResponseModel & { isTrashed: boolean }; return html` ${tempItem.isTrashed ? html` Trashed ` : nothing} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.test.ts index 29b81bd464..157f18dc4e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-media-picker/input-media-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInputMediaPickerElement } from './input-media-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbInputMediaPickerElement', () => { let element: UmbInputMediaPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-multi-url-picker/input-multi-url-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-multi-url-picker/input-multi-url-picker.element.ts index be778585ad..514effc3f9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-multi-url-picker/input-multi-url-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-multi-url-picker/input-multi-url-picker.element.ts @@ -1,11 +1,16 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, property } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; -import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; -import { UmbLinkPickerLink, UMB_LINK_PICKER_MODAL_TOKEN } from '../../modals/link-picker'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import type { UUIModalSidebarSize } from '@umbraco-ui/uui'; +import type { UmbVariantId } from '../../variants/variant-id.class'; +import { + UmbLinkPickerLink, + UMB_LINK_PICKER_MODAL, + UmbModalRouteRegistrationController, +} from '@umbraco-cms/backoffice/modal'; +import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-input-multi-url-picker @@ -27,6 +32,17 @@ export class UmbInputMultiUrlPickerElement extends FormControlMixin(UmbLitElemen protected getFormElement() { return undefined; } + + @property() + public set alias(value: string | undefined) { + this.myModalRegistration.setUniqueIdentifier('propertyAlias', value); + } + + @property() + public set variantId(value: string | UmbVariantId | undefined) { + this.myModalRegistration.setUniqueIdentifier('variantId', value?.toString()); + } + /** * This is a minimum amount of selected items in this input. * @type {number} @@ -87,7 +103,7 @@ export class UmbInputMultiUrlPickerElement extends FormControlMixin(UmbLitElemen @property({ attribute: false }) set urls(data: Array) { if (!data) return; - this._urls = data; + this._urls = [...data]; // Unfreeze data coming from State, so we can manipulate it. super.value = this._urls.map((x) => x.url).join(','); } @@ -96,7 +112,11 @@ export class UmbInputMultiUrlPickerElement extends FormControlMixin(UmbLitElemen } private _urls: Array = []; - private _modalContext?: UmbModalContext; + + @state() + private _modalRoute?: UmbModalRouteBuilder; + + private myModalRegistration; constructor() { super(); @@ -111,9 +131,56 @@ export class UmbInputMultiUrlPickerElement extends FormControlMixin(UmbLitElemen () => !!this.max && this.urls.length > this.max ); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this._modalContext = instance; - }); + this.myModalRegistration = new UmbModalRouteRegistrationController( + this, + UMB_LINK_PICKER_MODAL, + `:index`, + new Map([ + ['propertyAlias', undefined], + ['variantId', undefined], + ]) + ) + .onSetup((params) => { + // Get index: + const indexParam = params.index; + if (!indexParam) return false; + let index: number | null = parseInt(params.index); + if (Number.isNaN(index)) return false; + + // Use the index to find data: + let data: UmbLinkPickerLink | null = null; + if (index >= 0 && index < this.urls.length) { + data = this._getItemByIndex(index); + } else { + // If not then make a new pick: + index = null; + } + + return { + index: index, + link: { + name: data?.name, + published: data?.published, + queryString: data?.queryString, + target: data?.target, + trashed: data?.trashed, + udi: data?.udi, + url: data?.url, + }, + config: { + hideAnchor: this.hideAnchor, + ignoreUserStartNodes: this.ignoreUserStartNodes, + overlaySize: this.overlaySize || 'small', + }, + }; + }) + .onSubmit((submitData) => { + if (!submitData) return; + this._setSelection(submitData.link, submitData.index); + }) + .observeRouteBuilder((routeBuilder) => { + this._modalRoute = routeBuilder; + }); } private _removeItem(index: number) { @@ -121,9 +188,16 @@ export class UmbInputMultiUrlPickerElement extends FormControlMixin(UmbLitElemen this._dispatchChangeEvent(); } - private _setSelection(selection: UmbLinkPickerLink, index?: number) { - if (index !== undefined && index >= 0) this.urls[index] = selection; - else this.urls.push(selection); + private _getItemByIndex(index: number) { + return this.urls[index]; + } + + private _setSelection(selection: UmbLinkPickerLink, index: number | null) { + if (index !== null && index >= 0) { + this.urls[index] = selection; + } else { + this.urls.push(selection); + } this._dispatchChangeEvent(); } @@ -133,43 +207,24 @@ export class UmbInputMultiUrlPickerElement extends FormControlMixin(UmbLitElemen this.dispatchEvent(new CustomEvent('change', { composed: true, bubbles: true })); } - private _openPicker(data?: UmbLinkPickerLink, index?: number) { - const modalHandler = this._modalContext?.open(UMB_LINK_PICKER_MODAL_TOKEN, { - link: { - name: data?.name, - published: data?.published, - queryString: data?.queryString, - target: data?.target, - trashed: data?.trashed, - udi: data?.udi, - url: data?.url, - }, - config: { - hideAnchor: this.hideAnchor, - ignoreUserStartNodes: this.ignoreUserStartNodes, - overlaySize: this.overlaySize || 'small', - }, - }); - modalHandler?.onSubmit().then((newUrl: UmbLinkPickerLink) => { - if (!newUrl) return; - - this._setSelection(newUrl, index); - }); + // TODO: We should get a href property on uui-ref-node, and not use this method: + private _temporary_onClick_editItem(index: number) { + this.myModalRegistration.open({ index }); } render() { return html`${this.urls?.map((link, index) => this._renderItem(link, index))} - Add`; + Add`; } private _renderItem(link: UmbLinkPickerLink, index: number) { return html` + @open="${() => this._temporary_onClick_editItem(index)}"> - Edit + Edit Remove `; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.element.ts index 8cf1a4ed09..20e021b98c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.element.ts @@ -2,27 +2,22 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; function getNumberOrUndefined(value: string) { - const num = parseInt(value, 10); - return isNaN(num) ? undefined : num; + const num = parseInt(value, 10); + return isNaN(num) ? undefined : num; } @customElement('umb-input-number-range') export class UmbInputNumberRangeElement extends FormControlMixin(UmbLitElement) { - static styles = [ - UUITextStyles, - css` + static styles = [UUITextStyles, css``]; - `, - ]; + @property({ type: String, attribute: 'min-label' }) + minLabel = 'Low value'; - @property({type: String, attribute:'min-label'}) - minLabel = "Low value" - - @property({type: String, attribute:'max-label'}) - maxLabel = "High value" + @property({ type: String, attribute: 'max-label' }) + maxLabel = 'High value'; @state() private _minValue?: number; @@ -30,8 +25,8 @@ export class UmbInputNumberRangeElement extends FormControlMixin(UmbLitElement) public get minValue() { return this._minValue; } - public set minValue(keys: number | undefined) { - this._minValue = keys; + public set minValue(value: number | undefined) { + this._minValue = value; this.updateValue(); } @@ -41,22 +36,22 @@ export class UmbInputNumberRangeElement extends FormControlMixin(UmbLitElement) public get maxValue() { return this._maxValue; } - public set maxValue(keys: number | undefined) { - this._maxValue = keys; + public set maxValue(value: number | undefined) { + this._maxValue = value; this.updateValue(); } private updateValue() { - const newValue = (this._minValue || this._maxValue) ? (this._minValue || '')+','+(this._maxValue || '') : ''; - if(super.value !== newValue) { + const newValue = this._minValue || this._maxValue ? (this._minValue || '') + ',' + (this._maxValue || '') : ''; + if (super.value !== newValue) { super.value = newValue; } } @property() - public set value(keysString: string) { - if(keysString !== this._value) { - const splittedValue = keysString.split(/[ ,]+/); + public set value(valueString: string) { + if (valueString !== this._value) { + const splittedValue = valueString.split(/[ ,]+/); this.minValue = getNumberOrUndefined(splittedValue[0]); this.maxValue = getNumberOrUndefined(splittedValue[1]); } @@ -66,26 +61,29 @@ export class UmbInputNumberRangeElement extends FormControlMixin(UmbLitElement) super(); } - protected getFormElement() { - return this; - } + protected getFormElement() { + return this; + } - private _onMinInput(e:InputEvent) { + private _onMinInput(e: InputEvent) { this.minValue = Number((e.target as HTMLInputElement).value); this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true })); } - private _onMaxInput(e:InputEvent) { + private _onMaxInput(e: InputEvent) { this.maxValue = Number((e.target as HTMLInputElement).value); this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true })); } - - render() { - return html` – `; + return html` + – + `; } - } export default UmbInputNumberRangeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.test.ts index ade9185f53..693933b07c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-number-range/input-number-range.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInputNumberRangeElement } from './input-number-range.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUINumberRangeElement', () => { let element: UmbInputNumberRangeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-radio-button-list/input-radio-button-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-radio-button-list/input-radio-button-list.element.ts index e68110dabc..5d69da7ad4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-radio-button-list/input-radio-button-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-radio-button-list/input-radio-button-list.element.ts @@ -4,7 +4,7 @@ import { customElement, property } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { repeat } from 'lit/directives/repeat.js'; import { UUIBooleanInputEvent } from '@umbraco-ui/uui'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-input-radio-button-list') export class UmbInputRadioButtonListElement extends FormControlMixin(UmbLitElement) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.element.ts index a68fe5ee37..0a81f98e77 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.element.ts @@ -1,13 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbInputListBase } from '../input-list-base/input-list-base'; -import { UMB_SECTION_PICKER_MODAL_TOKEN } from '../../modals/section-picker'; -import type { ManifestSection } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import { UmbInputListBaseElement } from '../input-list-base/input-list-base'; +import { UMB_SECTION_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; @customElement('umb-input-section') -export class UmbInputPickerSectionElement extends UmbInputListBase { +export class UmbInputPickerSectionElement extends UmbInputListBaseElement { static styles = [ UUITextStyles, css` @@ -42,7 +42,7 @@ export class UmbInputPickerSectionElement extends UmbInputListBase { connectedCallback(): void { super.connectedCallback(); - this.pickerToken = UMB_SECTION_PICKER_MODAL_TOKEN; + this.pickerToken = UMB_SECTION_PICKER_MODAL; this._observeSections(); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.test.ts index dc5e319cbb..38973836c1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-section/input-section.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import { UmbPickerSectionElement } from './picker-section.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbPickerSectionElement', () => { // let element: UmbPickerSectionElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-slider/input-slider.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-slider/input-slider.element.ts index 9ffcacdb12..19c468d194 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-slider/input-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-slider/input-slider.element.ts @@ -3,7 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UUISliderEvent } from '@umbraco-ui/uui'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-input-slider') export class UmbInputSliderElement extends FormControlMixin(UmbLitElement) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-template-picker/input-template-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-template-picker/input-template-picker.element.ts new file mode 100644 index 0000000000..aa47ff72d6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-template-picker/input-template-picker.element.ts @@ -0,0 +1,197 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; +import { UmbTemplateCardElement } from '../template-card/template-card.element'; +import { UmbTemplateRepository } from '../../../templating/templates/repository/template.repository'; +import { + UMB_TEMPLATE_PICKER_MODAL, + UMB_TEMPLATE_MODAL, + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { TemplateResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-input-template-picker') +export class UmbInputTemplatePickerElement extends FormControlMixin(UmbLitElement) { + /** + * This is a minimum amount of selected items in this input. + * @type {number} + * @attr + * @default undefined + */ + @property({ type: Number }) + min?: number; + + /** + * Min validation message. + * @type {boolean} + * @attr + * @default + */ + @property({ type: String, attribute: 'min-message' }) + minMessage = 'This field need more items'; + + /** + * This is a maximum amount of selected items in this input. + * @type {number} + * @attr + * @default undefined + */ + @property({ type: Number }) + max?: number; + + /** + * Max validation message. + * @type {boolean} + * @attr + * @default + */ + @property({ type: String, attribute: 'min-message' }) + maxMessage = 'This field exceeds the allowed amount of items'; + + _allowedKeys: Array = []; + @property({ type: Array }) + public get allowedKeys() { + return this._allowedKeys; + } + public set allowedKeys(newKeys: Array) { + this._allowedKeys = newKeys; + this.#observePickedTemplates(); + } + + _defaultKey = ''; + @property({ type: String }) + public get defaultKey(): string { + return this._defaultKey; + } + public set defaultKey(newKey: string) { + this._defaultKey = newKey; + super.value = newKey; + } + + private _modalContext?: UmbModalContext; + private _templateRepository: UmbTemplateRepository = new UmbTemplateRepository(this); + + @state() + _pickedTemplates: TemplateResponseModel[] = []; + + constructor() { + super(); + + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this._modalContext = instance; + }); + } + + async #observePickedTemplates() { + this.observe( + await this._templateRepository.treeItems(this._allowedKeys), + (data) => { + this._pickedTemplates = data; + }, + '_templateRepositoryTreeItems' + ); + } + + protected getFormElement() { + return this; + } + + #changeDefault(e: CustomEvent) { + e.stopPropagation(); + const newKey = (e.target as UmbTemplateCardElement).value as string; + this.defaultKey = newKey; + this.dispatchEvent(new CustomEvent('change-default')); + } + + #openPicker() { + const modalHandler = this._modalContext?.open(UMB_TEMPLATE_PICKER_MODAL, { + multiple: true, + selection: [...this.allowedKeys], + }); + + modalHandler?.onSubmit().then((data) => { + if (!data.selection) return; + this.allowedKeys = data.selection; + this.dispatchEvent(new CustomEvent('change-allowed')); + }); + } + + #removeTemplate(id: string) { + /* + TODO: We need to follow up on this experience. + Could we test if this document type is in use, if so we should have a dialog notifying the user(Dialog, are you sure...) about that we might will break something? + If thats the case, Im not why if a template will be removed from an actual document. + If if its just the option that will go away. + (Comment by Niels) + In current backoffice we just prevent deleting a default when there are other templates. But if its the only one its okay. This is a weird experience, so we should make something that makes more sense. + BTW. its weird cause the damage of removing the default template is equally bad when there is one or more templates. + */ + this.allowedKeys = this.allowedKeys.filter((x) => x !== id); + } + + #openTemplate(e: CustomEvent) { + const id = (e.target as UmbTemplateCardElement).value; + + this._modalContext?.open(UMB_TEMPLATE_MODAL, { + id: id as string, + language: 'razor', + }); + } + + render() { + return html` + ${this._pickedTemplates.map( + (template) => html` + + + + + + ` + )} + Add + `; + } + + static styles = [ + UUITextStyles, + css` + #add-button { + width: 100%; + } + :host { + box-sizing: border-box; + display: flex; + gap: var(--uui-size-space-4); + flex-wrap: wrap; + } + + :host > * { + max-width: 180px; + min-width: 180px; + min-height: 150px; + } + `, + ]; +} + +export default UmbInputTemplatePickerElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-input-template-picker': UmbInputTemplatePickerElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-toggle/input-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-toggle/input-toggle.element.ts index 987749adaa..6142481ef0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-toggle/input-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-toggle/input-toggle.element.ts @@ -3,7 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UUIBooleanInputEvent } from '@umbraco-ui/uui'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-input-toggle') export class UmbInputToggleElement extends FormControlMixin(UmbLitElement) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-upload-field/input-upload-field.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-upload-field/input-upload-field.element.ts new file mode 100644 index 0000000000..a5237a876d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-upload-field/input-upload-field.element.ts @@ -0,0 +1,188 @@ +import { css, html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, query, state } from 'lit/decorators.js'; +import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UUIFileDropzoneElement } from '@umbraco-ui/uui'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; + +@customElement('umb-input-upload-field') +export class UmbInputUploadFieldElement extends FormControlMixin(UmbLitElement) { + static styles = [ + UUITextStyles, + css` + uui-icon { + vertical-align: sub; + margin-right: var(--uui-size-space-4); + } + + uui-symbol-file-thumbnail { + box-sizing: border-box; + min-height: 150px; + padding: var(--uui-size-space-4); + border: 1px solid var(--uui-color-border); + } + + #wrapper { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, auto)); + } + `, + ]; + + private _keys: Array = []; + /** + * @description Keys to the files that belong to this upload field. + * @type {Array} + * @default [] + */ + @property({ type: Array }) + public set keys(fileKeys: Array) { + this._keys = fileKeys; + super.value = this._keys.join(','); + } + public get keys(): Array { + return this._keys; + } + + /** + * @description Allowed file extensions. If left empty, all are allowed. + * @type {Array} + * @default undefined + */ + @property({ type: Array }) + fileExtensions?: Array; + + /** + * @description Allows the user to upload multiple files. + * @type {Boolean} + * @default false + * @attr + */ + @property({ type: Boolean }) + multiple = false; + + @state() + _currentFiles: Blob[] = []; + + @state() + _currentFilesTemp?: Blob[]; + + @state() + extensions?: string[]; + + @query('#dropzone') + private _dropzone?: UUIFileDropzoneElement; + + private _notificationContext?: UmbNotificationContext; + + protected getFormElement() { + return undefined; + } + + constructor() { + super(); + this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { + this._notificationContext = instance; + }); + } + + connectedCallback(): void { + super.connectedCallback(); + this.#setExtensions(); + } + + #setExtensions() { + if (!this.fileExtensions?.length) return; + + this.extensions = this.fileExtensions.map((extension) => { + return `.${extension}`; + }); + } + + #onUpload(e: CustomEvent) { + // UUIFileDropzoneEvent doesnt exist? + + this._currentFilesTemp = e.detail.files; + + if (!this.fileExtensions?.length && this._currentFilesTemp?.length) { + this.#setFiles(this._currentFilesTemp); + return; + } + const validated = this.#validateExtensions(); + this.#setFiles(validated); + } + + #validateExtensions(): Blob[] { + // TODO: Should property editor be able to handle allowed extensions like image/* ? + + const filesValidated: Blob[] = []; + this._currentFilesTemp?.forEach((temp) => { + const type = temp.type.slice(temp.type.lastIndexOf('/') + 1, temp.length); + if (this.fileExtensions?.find((x) => x === type)) filesValidated.push(temp); + else + this._notificationContext?.peek('danger', { + data: { headline: 'File upload', message: `Chosen file type "${type}" is not allowed` }, + }); + }); + + return filesValidated; + } + #setFiles(files: Blob[]) { + this._currentFiles = [...this._currentFiles, ...files]; + + //TODO: set keys when possible, not names + this.keys = this._currentFiles.map((file) => file.name); + this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true })); + } + + #handleBrowse() { + if (!this._dropzone) return; + this._dropzone.browse(); + } + + render() { + return html`${this.#renderFiles()} ${this.#renderDropzone()}`; + } + + #renderDropzone() { + if (!this.multiple && this._currentFiles.length) return nothing; + return html` + + Upload file here + + `; + } + + #renderFiles() { + if (!this._currentFiles?.length) return nothing; + return html`
    + ${this._currentFiles.map((file) => { + return html` + `; + })} +
    + + Remove file(s) + `; + } + + #handleRemove() { + // Remove via endpoint? + this._currentFiles = []; + } +} + +export default UmbInputUploadFieldElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-input-upload-field': UmbInputUploadFieldElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-upload-field/input-upload-field.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-upload-field/input-upload-field.stories.ts new file mode 100644 index 0000000000..02a1fdb44f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-upload-field/input-upload-field.stories.ts @@ -0,0 +1,17 @@ +import { Meta, StoryObj } from '@storybook/web-components'; +import './input-upload-field.element'; +import type { UmbInputUploadFieldElement } from './input-upload-field.element'; + +const meta: Meta = { + title: 'Components/Inputs/Upload Field', + component: 'umb-input-upload-field', +}; + +export default meta; +type Story = StoryObj; + +export const Overview: Story = { + args: { + multiple: false, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.element.ts index bce191a089..c7ecf36862 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.element.ts @@ -1,17 +1,17 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbInputListBase } from '../input-list-base/input-list-base'; +import { UmbInputListBaseElement } from '../input-list-base/input-list-base'; import { UmbUserGroupStore, UMB_USER_GROUP_STORE_CONTEXT_TOKEN, } from '../../../users/user-groups/repository/user-group.store'; -import { UMB_USER_GROUP_PICKER_MODAL_TOKEN } from '../../../users/user-groups/modals/user-group-picker'; -import type { UserGroupEntity } from '@umbraco-cms/models'; +import { UMB_USER_GROUP_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import type { UserGroupEntity } from '@umbraco-cms/backoffice/models'; @customElement('umb-input-user-group') -export class UmbInputPickerUserGroupElement extends UmbInputListBase { +export class UmbInputPickerUserGroupElement extends UmbInputListBaseElement { static styles = [ UUITextStyles, css` @@ -48,7 +48,7 @@ export class UmbInputPickerUserGroupElement extends UmbInputListBase { connectedCallback(): void { super.connectedCallback(); - this.pickerToken = UMB_USER_GROUP_PICKER_MODAL_TOKEN; + this.pickerToken = UMB_USER_GROUP_PICKER_MODAL; this.consumeContext(UMB_USER_GROUP_STORE_CONTEXT_TOKEN, (usersContext) => { this._userGroupStore = usersContext; this._observeUserGroups(); @@ -80,7 +80,7 @@ export class UmbInputPickerUserGroupElement extends UmbInputListBase { ${userGroup.name}
    this.removeFromSelection(userGroup.key)} + @click=${() => this.removeFromSelection(userGroup.id)} label="remove" color="danger">
    diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.test.ts index 20550a4780..d4cf1c0e7e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user-group/input-user-group.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import { UmbPickerUserGroupElement } from './picker-user-group.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbPickerLayoutUserGroupElement', () => { // let element: UmbPickerUserGroupElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.element.ts index b2e077a60d..762edbc5cf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.element.ts @@ -1,13 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing, PropertyValueMap } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbInputListBase } from '../input-list-base/input-list-base'; +import { UmbInputListBaseElement } from '../input-list-base/input-list-base'; import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from '../../../users/users/repository/user.store'; -import { UMB_USER_PICKER_MODAL_TOKEN } from '../../../users/users/modals/user-picker'; -import type { UserEntity } from '@umbraco-cms/models'; +import { UMB_USER_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import type { UserEntity } from '@umbraco-cms/backoffice/models'; @customElement('umb-input-user') -export class UmbPickerUserElement extends UmbInputListBase { +export class UmbPickerUserElement extends UmbInputListBaseElement { static styles = [ UUITextStyles, css` @@ -39,7 +39,7 @@ export class UmbPickerUserElement extends UmbInputListBase { connectedCallback(): void { super.connectedCallback(); - this.pickerToken = UMB_USER_PICKER_MODAL_TOKEN; + this.pickerToken = UMB_USER_PICKER_MODAL; this.consumeContext(UMB_USER_STORE_CONTEXT_TOKEN, (userStore) => { this._userStore = userStore; this._observeUser(); @@ -76,7 +76,7 @@ export class UmbPickerUserElement extends UmbInputListBase {
    ${user.name}
    - this.removeFromSelection(user.key)} label="remove" color="danger"> + this.removeFromSelection(user.id)} label="remove" color="danger">
    ` )} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.test.ts index 483a865475..7d85d80d5f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/input-user/input-user.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import { UmbPickerUserElement } from './picker-user.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbPickerUserElement', () => { // let element: UmbPickerUserElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu-item/menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu-item/menu-item.element.ts deleted file mode 100644 index 22fa6c93c6..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu-item/menu-item.element.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { v4 as uuidv4 } from 'uuid'; -import { css, html } from 'lit'; -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, property } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { ManifestMenuItem } from '@umbraco-cms/models'; - -@customElement('umb-menu-item') -export class UmbMenuItem extends UmbLitElement { - static styles = [UUITextStyles, css``]; - - private _key = uuidv4(); - - @property({ type: Object, attribute: false }) - manifest!: ManifestMenuItem; - - render() { - return html``; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-menu-item': UmbMenuItem; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu-item-base/menu-item-base.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu-item-base/menu-item-base.element.ts new file mode 100644 index 0000000000..ad7cd66ff4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu-item-base/menu-item-base.element.ts @@ -0,0 +1,125 @@ +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/directives/if-defined.js'; +import { map } from 'rxjs'; +import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../../section/section.context'; +import { + UmbSectionSidebarContext, + UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, +} from '../../section/section-sidebar/section-sidebar.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; + +@customElement('umb-menu-item-base') +export class UmbMenuItemBaseElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + private _entityType?: string; + @property({ type: String, attribute: 'entity-type' }) + public get entityType() { + return this._entityType; + } + public set entityType(value: string | undefined) { + this._entityType = value; + this.#observeEntityActions(); + } + + @property({ type: String, attribute: 'icon-name' }) + public iconName = ''; + + @property({ type: String }) + public label = ''; + + @property({ type: Boolean, attribute: 'has-children' }) + public hasChildren = false; + + @state() + private _href?: string; + + @state() + private _hasActions = false; + + #sectionContext?: UmbSectionContext; + #sectionSidebarContext?: UmbSectionSidebarContext; + #actionObserver?: UmbObserverController>; + + constructor() { + super(); + + this.consumeContext(UMB_SECTION_CONTEXT_TOKEN, (sectionContext) => { + this.#sectionContext = sectionContext; + this._observeSection(); + }); + + this.consumeContext(UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, (sectionContext) => { + this.#sectionSidebarContext = sectionContext; + }); + } + + #observeEntityActions() { + if (this.#actionObserver) this.#actionObserver.destroy(); + + this.#actionObserver = this.observe( + umbExtensionsRegistry + .extensionsOfType('entityAction') + .pipe(map((actions) => actions.filter((action) => action.conditions.entityType === this.entityType))), + (actions) => { + this._hasActions = actions.length > 0; + }, + 'entityAction' + ); + } + + private _observeSection() { + if (!this.#sectionContext) return; + + this.observe(this.#sectionContext?.pathname, (pathname) => { + if (!pathname) return; + this._href = this._constructPath(pathname); + }); + } + + // TODO: how do we handle this? + // TODO: use router context + private _constructPath(sectionPathname: string) { + return `section/${sectionPathname}/workspace/${this.entityType}`; + } + + private _openActions() { + if (!this.entityType) throw new Error('Entity type is not defined'); + this.#sectionSidebarContext?.toggleContextMenu(this.entityType, undefined, this.label); + } + + render() { + return html` ${this.#renderIcon()}${this.#renderActions()}`; + } + + #renderIcon() { + return html` `; + } + + #renderActions() { + return html` + ${this._hasActions + ? html` + + + + + + ` + : nothing} + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-menu-item-base': UmbMenuItemBaseElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu-item/menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu-item/menu-item.element.ts new file mode 100644 index 0000000000..0639f05620 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu-item/menu-item.element.ts @@ -0,0 +1,31 @@ +import { html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; + +export interface UmbMenuItemExtensionElement { + manifest: ManifestMenuItem; +} + +@customElement('umb-menu-item') +export class UmbMenuItemElement extends UmbLitElement implements UmbMenuItemExtensionElement { + static styles = [UUITextStyles]; + + @property({ type: Object, attribute: false }) + manifest!: ManifestMenuItem; + + render() { + return html``; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-menu-item': UmbMenuItemElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu.element.ts index 6e5e62bbd6..55679c7bc2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/menu/menu.element.ts @@ -1,10 +1,10 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { ManifestMenu, ManifestMenuItem } from '@umbraco-cms/extensions-registry'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { ManifestMenu, ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import '../menu-item/menu-item.element'; +import './menu-item/menu-item.element'; @customElement('umb-menu') export class UmbMenuElement extends UmbLitElement { @@ -16,7 +16,7 @@ export class UmbMenuElement extends UmbLitElement { render() { return html` items.meta.menus.includes(this.manifest!.alias)} + .filter=${(items: ManifestMenuItem) => items.conditions.menus.includes(this.manifest!.alias)} default-element="umb-menu-item">`; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/property-type-based-property/property-type-based-property.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/property-type-based-property/property-type-based-property.element.ts index 2e26102210..588e861041 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/property-type-based-property/property-type-based-property.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/property-type-based-property/property-type-based-property.element.ts @@ -1,14 +1,19 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbDataTypeRepository } from '../../../settings/data-types/repository/data-type.repository'; import { UmbVariantId } from '../../variants/variant-id.class'; import { UmbDocumentWorkspaceContext } from '../../../documents/documents/workspace/document-workspace.context'; -import type { DataTypeModel, DataTypePropertyModel, PropertyTypeViewModelBaseModel } from '@umbraco-cms/backend-api'; +import type { + DataTypeResponseModel, + DataTypePropertyPresentationModel, + PropertyTypeResponseModelBaseModel, +} from '@umbraco-cms/backoffice/backend-api'; import '../workspace-property/workspace-property.element'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbObserverController } from '@umbraco-cms/observable-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-property-type-based-property') export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { @@ -22,27 +27,27 @@ export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { ]; @property({ type: Object, attribute: false }) - public get property(): PropertyTypeViewModelBaseModel | undefined { + public get property(): PropertyTypeResponseModelBaseModel | undefined { return this._property; } - public set property(value: PropertyTypeViewModelBaseModel | undefined) { + public set property(value: PropertyTypeResponseModelBaseModel | undefined) { const oldProperty = this._property; this._property = value; - if (this._property?.dataTypeKey !== oldProperty?.dataTypeKey) { - this._observeDataType(this._property?.dataTypeKey); + if (this._property?.dataTypeId !== oldProperty?.dataTypeId) { + this._observeDataType(this._property?.dataTypeId); this._observeProperty(); } } - private _property?: PropertyTypeViewModelBaseModel; + private _property?: PropertyTypeResponseModelBaseModel; @state() private _propertyEditorUiAlias?: string; @state() - private _dataTypeData: DataTypePropertyModel[] = []; + private _dataTypeData: DataTypePropertyPresentationModel[] = []; private _dataTypeRepository: UmbDataTypeRepository = new UmbDataTypeRepository(this); - private _dataTypeObserver?: UmbObserverController; + private _dataTypeObserver?: UmbObserverController; @state() private _value?: unknown; @@ -71,8 +76,8 @@ export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { constructor() { super(); - this.consumeContext('umbWorkspaceContext', (workspaceContext: UmbDocumentWorkspaceContext) => { - this._workspaceContext = workspaceContext; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (workspaceContext) => { + this._workspaceContext = workspaceContext as UmbDocumentWorkspaceContext; this._observeProperty(); }); } @@ -90,15 +95,15 @@ export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { ); } - private async _observeDataType(dataTypeKey?: string) { + private async _observeDataType(dataTypeId?: string) { this._dataTypeObserver?.destroy(); - if (dataTypeKey) { + if (dataTypeId) { // Its not technically needed to have await here, this is only to ensure that the data is loaded before we observe it, and thereby only updating the DOM with the latest data. - await this._dataTypeRepository.requestByKey(dataTypeKey); + await this._dataTypeRepository.requestById(dataTypeId); this._dataTypeObserver = this.observe( - await this._dataTypeRepository.byKey(dataTypeKey), + await this._dataTypeRepository.byId(dataTypeId), (dataType) => { - this._dataTypeData = dataType?.data || []; + this._dataTypeData = dataType?.values || []; this._propertyEditorUiAlias = dataType?.propertyEditorUiAlias || undefined; }, 'observeDataType' diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/ref-property-editor-ui/ref-property-editor-ui.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/ref-property-editor-ui/ref-property-editor-ui.stories.ts index 34d8e5365b..cf45fa130e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/ref-property-editor-ui/ref-property-editor-ui.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/ref-property-editor-ui/ref-property-editor-ui.stories.ts @@ -1,44 +1,43 @@ import { Meta, StoryObj } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import './ref-property-editor-ui.element'; import type { UmbRefPropertyEditorUIElement } from './ref-property-editor-ui.element'; const meta: Meta = { - title: 'Components/Ref Property Editor UI', - component: 'umb-ref-property-editor-ui', + title: 'Components/Ref Property Editor UI', + component: 'umb-ref-property-editor-ui', }; - + export default meta; type Story = StoryObj; - + export const Overview: Story = { - args: { - name: "Custom Property Editor UI", - alias: "Umb.PropertyEditorUI.CustomUI", - propertyEditorAlias: "Umbraco.JSON" - } + args: { + name: 'Custom Property Editor UI', + alias: 'Umb.PropertyEditorUI.CustomUI', + propertyEditorAlias: 'Umbraco.JSON', + }, }; - export const WithDetail: Story = { - args: { - name: "Custom Property Editor UI", - alias: "Umb.PropertyEditorUI.CustomUI", - propertyEditorAlias: "Umbraco.JSON", - detail: "With some custom details" - } + args: { + name: 'Custom Property Editor UI', + alias: 'Umb.PropertyEditorUI.CustomUI', + propertyEditorAlias: 'Umbraco.JSON', + detail: 'With some custom details', + }, }; export const WithSlots: Story = { - args: { - name: "Custom Property Editor UI", - alias: "Umb.PropertyEditorUI.CustomUI", - propertyEditorAlias: "Umbraco.JSON", - detail: "With some custom details" - }, + args: { + name: 'Custom Property Editor UI', + alias: 'Umb.PropertyEditorUI.CustomUI', + propertyEditorAlias: 'Umbraco.JSON', + detail: 'With some custom details', + }, render: (args) => html` - @@ -51,5 +50,5 @@ export const WithSlots: Story = {
    - ` -}; \ No newline at end of file + `, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-dashboards/section-dashboards.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-dashboards/section-dashboards.element.ts deleted file mode 100644 index fdd455c893..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-dashboards/section-dashboards.element.ts +++ /dev/null @@ -1,184 +0,0 @@ -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { first, map } from 'rxjs'; -import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section.context'; -import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent, IRoutingInfo } from '@umbraco-cms/router'; -import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import type { ManifestDashboard, ManifestDashboardCollection } from '@umbraco-cms/models'; - -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-section-dashboards') -export class UmbSectionDashboardsElement extends UmbLitElement { - static styles = [ - UUITextStyles, - css` - :host { - display: flex; - flex-direction: column; - height: 100%; - } - - #tabs { - background-color: var(--uui-color-surface); - height: 70px; - border-bottom: 1px solid var(--uui-color-border); - box-sizing: border-box; - } - - #scroll-container { - flex: 1; - position: relative; - } - - #router-slot { - box-sizing: border-box; - display: block; - padding: var(--uui-size-5); - } - - #header { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - min-height: 60px; - box-sizing: border-box; - margin: 0; - padding: 0 var(--uui-size-5); - background-color: var(--uui-color-surface); - border-bottom: 1px solid var(--uui-color-border); - } - `, - ]; - - @state() - private _dashboards?: Array; - - @state() - private _routes: Array = []; - - @state() - private _routerPath?: string; - - @state() - private _activePath?: string; - - private _currentSectionAlias?: string; - private _sectionContext?: UmbSectionContext; - - constructor() { - super(); - - this.consumeContext(UMB_SECTION_CONTEXT_TOKEN, (context) => { - this._sectionContext = context; - this._observeSectionContext(); - }); - } - - private _observeSectionContext() { - if (!this._sectionContext) return; - - this.observe(this._sectionContext.alias.pipe(first()), (alias) => { - this._currentSectionAlias = alias; - this._observeDashboards(); - }); - } - - private _observeDashboards() { - if (!this._currentSectionAlias) return; - - this.observe( - umbExtensionsRegistry - ?.extensionsOfTypes(['dashboard', 'dashboardCollection']) - .pipe( - map((extensions) => - extensions.filter((extension) => extension.meta.sections.includes(this._currentSectionAlias ?? '')) - ) - ), - (dashboards) => { - this._dashboards = dashboards || undefined; - this._createRoutes(); - } - ); - } - - private _createRoutes() { - this._routes = []; - - 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, info: IRoutingInfo) => { - // 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: - if ((component as any).then) { - (component as any).then((el: any) => (el.manifest = dashboard)); - } else { - (component as any).manifest = dashboard; - } - }, - }; - }); - - this._routes.push({ - path: '**', - redirectTo: this._dashboards?.[0]?.meta.pathname, - }); - } - } - - private _renderNavigation() { - return html` - ${this._dashboards && this._dashboards.length > 1 - ? html` - - ${this._dashboards.map( - (dashboard) => html` - - ` - )} - - ` - : this._dashboards?.length === 1 - ? html`` - : nothing} - `; - } - - render() { - return html` - ${this._renderNavigation()} - - { - this._routerPath = event.target.absoluteRouterPath; - }} - @change=${(event: UmbRouterSlotChangeEvent) => { - this._activePath = event.target.localActiveViewPath; - }}> - - `; - } -} - -export default UmbSectionDashboardsElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-section-dashboards': UmbSectionDashboardsElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-dashboards/section-dashboards.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-dashboards/section-dashboards.stories.ts deleted file mode 100644 index 28c3096f16..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-dashboards/section-dashboards.stories.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; -import { manifests } from '../../../../documents/section.manifests'; -import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section.context'; -import type { UmbSectionDashboardsElement } from './section-dashboards.element'; -import type { ManifestSection } from '@umbraco-cms/models'; -import './section-dashboards.element'; - -const contentSectionManifest = manifests.find((m) => m.alias === 'Umb.Section.Content') as ManifestSection; - -export default { - title: 'Sections/Shared/Section Dashboards', - component: 'umb-section-dashboards', - id: 'umb-section-dashboards', - decorators: [ - (story) => - html` - ${story()} - `, - ], -} as Meta; - -export const AAAOverview: Story = () => - html` `; -AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.element.ts index 92fc067235..c9a4b9f487 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.element.ts @@ -11,6 +11,8 @@ export class UmbSectionMainElement extends LitElement { flex: 1 1 auto; height: 100%; } + + main, slot { display: flex; flex-direction: column; @@ -20,7 +22,11 @@ export class UmbSectionMainElement extends LitElement { ]; render() { - return html``; + return html` +
    + +
    + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.stories.ts index 37b6555aa0..8f7ae070a8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-main/section-main.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbSectionMainElement } from './section-main.element'; import './section-main.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts index daf4285728..0da6e7825a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts @@ -1,15 +1,15 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbSectionSidebarContext, UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, } from '../section-sidebar/section-sidebar.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-section-sidebar-context-menu') -export class UmbSectionSidebarContextMenu extends UmbLitElement { +export class UmbSectionSidebarContextMenuElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -120,6 +120,6 @@ export class UmbSectionSidebarContextMenu extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-section-sidebar-context-menu': UmbSectionSidebarContextMenu; + 'umb-section-sidebar-context-menu': UmbSectionSidebarContextMenuElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.element.ts index a3d5197748..67510ed5bf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.element.ts @@ -1,11 +1,29 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { ManifestMenu, ManifestMenuSectionSidebarApp } from '@umbraco-cms/extensions-registry'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { + ManifestKind, + ManifestMenu, + ManifestSectionSidebarAppMenuKind, +} from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; import '../../menu/menu.element'; +// TODO: Move to separate file: +const manifest: ManifestKind = { + type: 'kind', + alias: 'Umb.Kind.Menu', + matchKind: 'menu', + matchType: 'sectionSidebarApp', + manifest: { + type: 'sectionSidebarApp', + elementName: 'umb-section-sidebar-menu', + }, +}; +umbExtensionsRegistry.register(manifest); + @customElement('umb-section-sidebar-menu') export class UmbSectionSidebarMenuElement extends UmbLitElement { static styles = [ @@ -18,14 +36,14 @@ export class UmbSectionSidebarMenuElement extends UmbLitElement { ]; @property() - manifest?: ManifestMenuSectionSidebarApp; + manifest?: ManifestSectionSidebarAppMenuKind; render() { // TODO: link to dashboards when clicking on the menu item header - return html`

    ${this.manifest?.meta.label}

    + return html`

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

    menu.alias === this.manifest!.meta.menu} + .filter=${(menu: ManifestMenu) => menu.alias === this.manifest?.meta?.menu} default-element="umb-menu">`; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.stories.ts index 002ab577eb..797b347e47 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar-menu/section-sidebar-menu.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbSectionSidebarMenuElement } from './section-sidebar-menu.element'; import './section-sidebar-menu.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.context.ts index c926095689..c3a4264b2a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.context.ts @@ -1,11 +1,10 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { StringState } from '@umbraco-cms/observable-api'; -import { BasicState } from 'libs/observable-api/basic-state'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { StringState, BooleanState } from '@umbraco-cms/backoffice/observable-api'; export class UmbSectionSidebarContext { - #host: UmbControllerHostInterface; - #contextMenuIsOpen = new BasicState(false); + #host: UmbControllerHostElement; + #contextMenuIsOpen = new BooleanState(false); contextMenuIsOpen = this.#contextMenuIsOpen.asObservable(); #entityType = new StringState(undefined); @@ -17,17 +16,18 @@ export class UmbSectionSidebarContext { #headline = new StringState(undefined); headline = this.#headline.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } - toggleContextMenu(entityType: string, unique: string, headline: string) { - this.#unique.getValue() === unique ? this.closeContextMenu() : this.openContextMenu(entityType, unique, headline); + toggleContextMenu(entityType: string, unique: string | undefined, headline: string) { + console.log('open for ', entityType, unique, headline); + this.openContextMenu(entityType, unique, headline); } // TODO: we wont get notified about tree item name changes because we don't have a subscription // we need to figure out how we best can handle this when we only know the entity and unique id - openContextMenu(entityType: string, unique: string, headline: string) { + openContextMenu(entityType: string, unique: string | undefined, headline: string) { this.#entityType.next(entityType); this.#unique.next(unique); this.#headline.next(headline); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.element.ts index d388e8bfc2..f16bc17cb6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.element.ts @@ -2,7 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement } from 'lit/decorators.js'; import { UmbSectionSidebarContext, UMB_SECTION_SIDEBAR_CONTEXT_TOKEN } from './section-sidebar.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import '../../tree/context-menu/tree-context-menu.service'; import '../section-sidebar-context-menu/section-sidebar-context-menu.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.stories.ts index 4e6b79e49c..4b8c2a3fdd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-sidebar/section-sidebar.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbSectionSidebarElement } from './section-sidebar.element'; import './section-sidebar.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-views/section-views.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-views/section-views.element.ts index fe8129400f..a75bcc02fc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-views/section-views.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section-views/section-views.element.ts @@ -1,13 +1,16 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; import { map, of } from 'rxjs'; import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section.context'; -import type { ManifestSectionView } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbObserverController } from '@umbraco-cms/observable-api'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; +import type { ManifestDashboard, ManifestSectionView } from '@umbraco-cms/backoffice/extensions-registry'; +import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +// TODO: this might need a new name, since it's both view and dashboard now @customElement('umb-section-views') export class UmbSectionViewsElement extends UmbLitElement { static styles = [ @@ -16,106 +19,172 @@ export class UmbSectionViewsElement extends UmbLitElement { #header { background-color: var(--uui-color-surface); border-bottom: 1px solid var(--uui-color-divider-standalone); + display: flex; + justify-content: space-between; + align-items: center; + height: var(--umb-header-layout-height); + box-sizing: border-box; } - uui-tab-group { + #views { justify-content: flex-end; --uui-tab-divider: var(--uui-color-divider-standalone); } - uui-tab-group uui-tab:first-child { + #views uui-tab:first-child { border-left: 1px solid var(--uui-color-divider-standalone); } `, ]; + @property({ type: String, attribute: 'section-alias' }) + public sectionAlias?: string; + @state() private _views: Array = []; @state() - private _routerFolder = ''; + private _dashboards: Array = []; @state() - private _activeViewPathname?: string; + private _routerPath?: string; + + @state() + private _activePath?: string; + + @state() + private _routes: Array = []; private _sectionContext?: UmbSectionContext; - private _extensionsObserver?: UmbObserverController; + private _extensionsObserver?: UmbObserverController; + private _viewsObserver?: UmbObserverController; + private _dashboardObserver?: UmbObserverController; constructor() { super(); this.consumeContext(UMB_SECTION_CONTEXT_TOKEN, (sectionContext) => { this._sectionContext = sectionContext; - this._observeViews(); - this._observeActiveView(); + this._observeSectionAlias(); }); } - connectedCallback(): void { - super.connectedCallback(); - /* TODO: find a way to construct absolute urls */ - this._routerFolder = window.location.pathname.split('/view')[0]; + async #createRoutes() { + const dashboardRoutes = this._dashboards?.map((manifest) => { + return { + path: 'dashboard/' + manifest.meta.pathname, + component: () => createExtensionElement(manifest), + }; + }); + + const viewRoutes = this._views?.map((manifest) => { + return { + path: 'view/' + manifest.meta.pathname, + component: () => createExtensionElement(manifest), + }; + }); + + const routes = [...dashboardRoutes, ...viewRoutes]; + this._routes = routes?.length > 0 ? [...routes, { path: '**', redirectTo: routes?.[0]?.path }] : []; } - private _observeViews() { + private _observeSectionAlias() { if (!this._sectionContext) return; - this.observe(this._sectionContext.alias, (sectionAlias) => { - this._observeExtensions(sectionAlias); - }, 'viewsObserver') + this.observe( + this._sectionContext.alias, + (sectionAlias) => { + this._observeViews(sectionAlias); + this._observeDashboards(sectionAlias); + }, + 'viewsObserver' + ); } - private _observeExtensions(sectionAlias?: string) { - this._extensionsObserver?.destroy(); - if(sectionAlias) { - this._extensionsObserver = this.observe( - umbExtensionsRegistry?.extensionsOfType('sectionView').pipe( - map((views) => - views - .filter((view) => view.meta.sections.includes(sectionAlias)) - .sort((a, b) => b.meta.weight - a.meta.weight) - ) - ) ?? of([]) - , - (views) => { - this._views = views; - } + + private _observeViews(sectionAlias?: string) { + this._viewsObserver?.destroy(); + if (sectionAlias) { + this._viewsObserver = this.observe( + umbExtensionsRegistry + ?.extensionsOfType('sectionView') + .pipe(map((views) => views.filter((view) => view.conditions.sections.includes(sectionAlias)))) ?? of([]), + (views) => { + this._views = views; + this.#createRoutes(); + } ); } } - private _observeActiveView() { - if(this._sectionContext) { - this.observe(this._sectionContext?.activeViewPathname, (pathname) => { - this._activeViewPathname = pathname; - }, 'activeViewPathnameObserver'); + private _observeDashboards(sectionAlias?: string) { + this._dashboardObserver?.destroy(); + + if (sectionAlias) { + this._dashboardObserver = this.observe( + umbExtensionsRegistry + ?.extensionsOfType('dashboard') + .pipe(map((views) => views.filter((view) => view.conditions.sections.includes(sectionAlias)))) ?? of([]), + (views) => { + this._dashboards = views; + this.#createRoutes(); + } + ); } } render() { - return html` ${this._views.length > 0 ? html` ` : nothing} `; - } - - private _renderViews() { return html` - ${this._views?.length > 0 + ${this._routes.length > 0 ? html` - - ${this._views.map( - (view: ManifestSectionView) => html` - - - ${view.meta.label || view.name} - - ` - )} - + + { + this._routerPath = event.target.absoluteRouterPath; + }} + @change=${(event: UmbRouterSlotChangeEvent) => { + this._activePath = event.target.localActiveViewPath; + }}> + ` : nothing} `; } + + #renderDashboards() { + return html` + + ${this._dashboards.map( + (dashboard) => html` + + ${dashboard.meta.label || dashboard.name} + + ` + )} + + `; + } + + #renderViews() { + return html` + + ${this._views.map( + (view) => html` + + + ${view.meta.label || view.name} + + ` + )} + + `; + } } export default UmbSectionViewsElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.context.ts index b46b979b94..2f90f58eca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.context.ts @@ -1,6 +1,7 @@ -import type { Entity, ManifestSection, ManifestSectionView } from '@umbraco-cms/models'; -import { ObjectState, StringState } from '@umbraco-cms/observable-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; +import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry'; +import type { Entity } from '@umbraco-cms/backoffice/models'; +import { ObjectState, StringState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; export type ActiveTreeItemType = Entity | undefined; @@ -12,20 +13,6 @@ export class UmbSectionContext { public readonly pathname = this.#manifestPathname.asObservable(); public readonly label = this.#manifestLabel.asObservable(); - /* - This was not used anywhere - private _activeTree = new BehaviorSubject(undefined); - public readonly activeTree = this._activeTree.asObservable(); - */ - - // TODO: what is the best context to put this in? - #activeTreeItem = new ObjectState(undefined); - public readonly activeTreeItem = this.#activeTreeItem.asObservable(); - - // TODO: what is the best context to put this in? - #activeViewPathname = new StringState(undefined); - public readonly activeViewPathname = this.#activeViewPathname.asObservable(); - constructor(manifest: ManifestSection) { this.setManifest(manifest); } @@ -35,21 +22,6 @@ export class UmbSectionContext { this.#manifestPathname.next(manifest?.meta?.pathname); this.#manifestLabel.next(manifest ? manifest.meta?.label || manifest.name : undefined); } - - /* - This was not used anywhere - public setActiveTree(tree: ManifestTree) { - this._activeTree.next(tree); - } - */ - - public setActiveTreeItem(item?: ActiveTreeItemType) { - this.#activeTreeItem.next(item); - } - - public setActiveView(view?: ManifestSectionView) { - this.#activeViewPathname.next(view?.meta.pathname); - } } export const UMB_SECTION_CONTEXT_TOKEN = new UmbContextToken('UmbSectionContext'); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.element.ts index 1b211a40b9..2a9b530b68 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/section/section.element.ts @@ -1,18 +1,21 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; +import { customElement, property, state } from 'lit/decorators.js'; import { map } from 'rxjs'; -import type { UmbWorkspaceEntityElement } from '../workspace/workspace-entity-element.interface'; -import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from './section.context'; -import type { UmbRouterSlotChangeEvent, IRoutingInfo } from '@umbraco-cms/router'; -import type { ManifestSectionView, ManifestWorkspace, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models'; -import { umbExtensionsRegistry, createExtensionElement } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { UmbWorkspaceElement } from '../workspace/workspace.element'; +import type { UmbSectionViewsElement } from './section-views/section-views.element'; +import type { ManifestSection, ManifestSectionSidebarApp } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import './section-sidebar-menu/section-sidebar-menu.element'; -import './section-views/section-views.element'; -import '../../../settings/languages/app-language-select/app-language-select.element'; +/** + * @export + * @class UmbSectionElement + * @description - Element hosting sections and section navigation. + */ @customElement('umb-section') export class UmbSectionElement extends UmbLitElement { static styles = [ @@ -24,171 +27,64 @@ export class UmbSectionElement extends UmbLitElement { display: flex; } - #router-slot { - overflow: auto; - height: 100%; - } - h3 { padding: var(--uui-size-4) var(--uui-size-8); } `, ]; - @state() - private _routes?: Array; + @property() + public manifest?: ManifestSection; @state() - private _menus?: Array; + private _routes?: Array; @state() - private _views?: Array; + private _menus?: Array>; - private _workspaces?: Array; - private _sectionContext?: UmbSectionContext; - private _sectionAlias?: string; - - constructor() { - super(); - - this.consumeContext(UMB_SECTION_CONTEXT_TOKEN, (instance) => { - this._sectionContext = instance; - - // TODO: currently they don't corporate, as they overwrite each other... - this._observeMenuItems(); - this._observeSection(); - }); + connectedCallback() { + super.connectedCallback(); + this.#observeSectionSidebarApps(); + this.#createRoutes(); } - private _observeMenuItems() { - if (!this._sectionContext) return; - - this.observe(this._sectionContext?.alias, (alias) => { - this._observeSidebarMenus(alias); - }); - - this.observe(umbExtensionsRegistry.extensionsOfType('workspace'), (workspaceExtensions) => { - this._workspaces = workspaceExtensions; - this._createWorkspaceRoutes(); - }); - } - - private _observeSidebarMenus(sectionAlias?: string) { - if (sectionAlias) { - this.observe( - umbExtensionsRegistry - ?.extensionsOfType('menuSectionSidebarApp') - .pipe(map((manifests) => manifests.filter((manifest) => manifest.meta.sections.includes(sectionAlias)))), - (manifests) => { - this._menus = manifests; - } - ); - } else { - this._menus = []; - } - } - - private _createWorkspaceRoutes() { - if (!this._workspaces) return; - // TODO: find a way to make this reuseable across: - // TODO: Move workspace 'handlers/routes' to the workspace-element. So it becomes local. - const workspaceRoutes = this._workspaces?.map((workspace: ManifestWorkspace) => { - return [ - { - path: `${workspace.meta.entityType}/edit/:key`, - component: () => createExtensionElement(workspace), - setup: (component: Promise, info: IRoutingInfo) => { - component.then((el) => { - el.load(info.match.params.key); - }); - }, - }, - { - path: `${workspace.meta.entityType}/create/root`, - component: () => createExtensionElement(workspace), - setup: (component: Promise) => { - component.then((el) => { - el.create(null); - }); - }, - }, - { - path: `${workspace.meta.entityType}/create/:parentKey`, - component: () => createExtensionElement(workspace), - setup: (component: Promise, info: IRoutingInfo) => { - component.then((el) => { - el.create(info.match.params.parentKey); - }); - }, - }, - { - path: workspace.meta.entityType, - component: () => createExtensionElement(workspace), - }, - ]; - }); + #createRoutes() { + this._routes = []; this._routes = [ { - path: 'dashboard', - component: () => import('./section-dashboards/section-dashboards.element'), + path: 'workspace/:entityType', + component: () => import('../workspace/workspace.element'), + setup: (element, info) => { + (element as UmbWorkspaceElement).entityType = info.match.params.entityType; + }, }, - ...(workspaceRoutes?.flat() || []), { path: '**', - redirectTo: 'dashboard', + component: () => import('../section/section-views/section-views.element'), + setup: (element) => { + (element as UmbSectionViewsElement).sectionAlias = this.manifest?.alias; + }, }, ]; } - private _observeSection() { - if (!this._sectionContext) return; - - this.observe(this._sectionContext.alias, (alias) => { - this._sectionAlias = alias; - this._observeViews(); - }); - } - - private _observeViews() { - this.observe(umbExtensionsRegistry?.extensionsOfType('sectionView'), (views) => { - const sectionViews = views - .filter((view) => { - return this._sectionAlias ? view.meta.sections.includes(this._sectionAlias) : false; - }) - .sort((a, b) => b.meta.weight - a.meta.weight); - if (sectionViews.length > 0) { - this._views = sectionViews; - this._createViewRoutes(); + // TODO: Can this be omitted? or can the same data be used for the extension slot or alike extension presentation? + #observeSectionSidebarApps() { + this.observe( + umbExtensionsRegistry + .extensionsOfType('sectionSidebarApp') + .pipe( + map((manifests) => + manifests.filter((manifest) => manifest.conditions.sections.includes(this.manifest?.alias || '')) + ) + ), + (manifests) => { + this._menus = manifests; } - }); + ); } - private _createViewRoutes() { - this._routes = []; - this._routes = - this._views?.map((view) => { - return { - path: 'view/' + view.meta.pathname, - component: () => createExtensionElement(view), - }; - }) ?? []; - - if (this._views && this._views.length > 0) { - this._routes.push({ - path: '**', - redirectTo: 'view/' + this._views?.[0]?.meta.pathname, - }); - } - } - - private _onRouteChange = (event: UmbRouterSlotChangeEvent) => { - const currentPath = event.target.localActiveViewPath; - const view = this._views?.find((view) => 'view/' + view.meta.pathname === currentPath); - if (!view) return; - this._sectionContext?.setActiveView(view); - }; - render() { return html` ${this._menus && this._menus.length > 0 @@ -197,24 +93,14 @@ export class UmbSectionElement extends UmbLitElement { - items.meta.sections.includes(this._sectionAlias || '')}> - - - items.meta.sections.includes(this._sectionAlias || '')} - default-element="umb-section-sidebar-menu"> + .filter=${(items: ManifestSectionSidebarApp) => + items.conditions.sections.includes(this.manifest?.alias || '')}> ` : nothing} - ${this._views && this._views.length > 0 ? html`` : nothing} ${this._routes && this._routes.length > 0 - ? html`` + ? html`` : nothing} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts index 67a2bfa9b1..0ab0b54030 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.element.ts @@ -1,13 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; -import { css, html, LitElement, nothing } from 'lit'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; -import { when } from 'lit-html/directives/when.js'; +import { css, html, LitElement } from 'lit'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { when } from 'lit/directives/when.js'; import { customElement, property, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; // TODO: move to UI Library - entity actions should NOT be moved to UI Library but stay in an UmbTable element export interface UmbTableItem { - key: string; + id: string; icon?: string; entityType?: string; data: Array; @@ -171,7 +171,7 @@ export class UmbTableElement extends LitElement { private _handleRowCheckboxChange(event: Event, item: UmbTableItem) { const checkboxElement = event.target as HTMLInputElement; - checkboxElement.checked ? this._selectRow(item.key) : this._deselectRow(item.key); + checkboxElement.checked ? this._selectRow(item.id) : this._deselectRow(item.id); } private _handleAllRowsCheckboxChange(event: Event) { @@ -198,7 +198,7 @@ export class UmbTableElement extends LitElement { } private _selectAllRows() { - this.selection = this.items.map((item: UmbTableItem) => item.key); + this.selection = this.items.map((item: UmbTableItem) => item.id); this._selectionMode = true; this.dispatchEvent(new UmbTableSelectedEvent()); } @@ -215,7 +215,7 @@ export class UmbTableElement extends LitElement { ${this._renderHeaderCheckboxCell()} ${this.columns.map((column) => this._renderHeaderCell(column))} - ${repeat(this.items, (item) => item.key, this._renderRow)} + ${repeat(this.items, (item) => item.id, this._renderRow)} `; } @@ -259,9 +259,9 @@ export class UmbTableElement extends LitElement { return html` this._selectRow(item.key)} - @unselected=${() => this._deselectRow(item.key)}> + ?selected=${this._isSelected(item.id)} + @selected=${() => this._selectRow(item.id)} + @unselected=${() => this._deselectRow(item.id)}> ${this._renderRowCheckboxCell(item)} ${this.columns.map((column) => this._renderRowCell(column, item))} `; }; @@ -277,7 +277,7 @@ export class UmbTableElement extends LitElement { label="Select Row" @click=${(e: PointerEvent) => e.stopPropagation()} @change=${(event: Event) => this._handleRowCheckboxChange(event, item)} - ?checked="${this._isSelected(item.key)}"> + ?checked="${this._isSelected(item.id)}"> ` )} `; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.stories.ts index d7ac93c25a..f4da64de01 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/table/table.stories.ts @@ -1,13 +1,13 @@ import { Meta, StoryObj } from '@storybook/web-components'; import './table.element'; import { v4 as uuidv4 } from 'uuid'; -import type { UmbTableElement, UmbTableColumn, UmbTableConfig, UmbTableItem } from './table.element' +import type { UmbTableElement, UmbTableColumn, UmbTableConfig, UmbTableItem } from './table.element'; const meta: Meta = { - title: 'Components/Table', - component: 'umb-table', + title: 'Components/Table', + component: 'umb-table', }; - + export default meta; type Story = StoryObj; @@ -26,7 +26,7 @@ const columns: Array = [ const items: Array = [ { - key: uuidv4(), + id: uuidv4(), icon: 'umb:wand', data: [ { @@ -40,7 +40,7 @@ const items: Array = [ ], }, { - key: uuidv4(), + id: uuidv4(), icon: 'umb:document', data: [ { @@ -54,7 +54,7 @@ const items: Array = [ ], }, { - key: uuidv4(), + id: uuidv4(), icon: 'umb:user', data: [ { @@ -70,35 +70,34 @@ const items: Array = [ ]; export const Overview: Story = { - args: { + args: { items: items, columns: columns, config: { allowSelection: true, hideIcon: false, - } - } + }, + }, }; - export const WithDisallowedSelections: Story = { - args: { + args: { items: items, columns: columns, config: { allowSelection: false, hideIcon: false, - } - } + }, + }, }; export const WithHiddenIcons: Story = { - args: { + args: { items: items, columns: columns, config: { allowSelection: true, hideIcon: true, - } - } -}; \ No newline at end of file + }, + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/template-card/template-card.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/template-card/template-card.element.ts new file mode 100644 index 0000000000..ec7cbf1f29 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/template-card/template-card.element.ts @@ -0,0 +1,170 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +/** + * @element umb-template-card + * @slot actions + * @fires open + * @fires selected + * + * + */ + +@customElement('umb-template-card') +export class UmbTemplateCardElement extends FormControlMixin(UmbLitElement) { + @property({ type: String }) + name = ''; + + @property({ type: Boolean, reflect: true }) + default = false; + + _id = ''; + @property({ type: String }) + public set id(newId: string) { + this._id = newId; + super.value = newId; + } + public get id() { + return this._id; + } + + protected getFormElement() { + return undefined; + } + + #setSelection(e: KeyboardEvent) { + e.preventDefault(); + e.stopPropagation(); + //this.selected = true; + this.dispatchEvent(new CustomEvent('change-default', { bubbles: true, composed: true })); + } + #openTemplate(e: KeyboardEvent) { + e.preventDefault(); + e.stopPropagation(); + this.dispatchEvent(new CustomEvent('open', { bubbles: true, composed: true })); + } + + render() { + return html`
    + + + ${this.default ? '(Default template)' : 'Set default'} + + +
    `; + } + + static styles = [ + UUITextStyles, + css` + :host { + box-sizing: border-box; + display: contents; + position: relative; + + height: 100%; + border: 1px solid red; + margin: auto; + } + + #card { + box-sizing: border-box; + width: 100%; + max-width: 180px; + //width: 200px; + position: relative; + display: flex; + flex-direction: column; + align-items: stretch; + border-radius: var(--uui-border-radius); + border: 1px solid var(--uui-color-divider-emphasis); + background-color: var(--uui-color-background); + padding: var(--uui-size-4); + } + + :host([default]) #card { + border: 1px solid var(--uui-color-selected); + outline: 1px solid var(--uui-color-selected); + } + #card:has(uui-button:hover) { + border: 1px solid var(--uui-color-selected); + } + + #bottom { + margin-top: auto; + } + + slot[name='actions'] { + position: absolute; + top: var(--uui-size-4); + right: var(--uui-size-4); + display: flex; + justify-content: right; + + opacity: 0; + transition: opacity 120ms; + } + + :host(:focus) slot[name='actions'], + :host(:focus-within) slot[name='actions'], + :host(:hover) slot[name='actions'] { + opacity: 1; + } + + #open-part { + border: none; + outline: none; + background: none; + text-align: center; + display: flex; + flex-direction: column; + font-weight: 700; + align-items: center; + cursor: pointer; + flex-grow: 1; + } + + #open-part, + #card { + gap: var(--uui-size-space-2); + } + + #open-part strong { + flex-grow: 1; + display: flex; + align-items: center; + } + + :host([disabled]) #open-part { + pointer-events: none; + } + + #open-part:focus-visible, + #open-part:focus-visible uui-icon, + #open-part:hover, + #open-part:hover uui-icon { + text-decoration: underline; + color: var(--uui-color-interactive-emphasis); + } + + #open-part uui-icon { + font-size: var(--uui-size-20); + color: var(--uui-color-divider-emphasis); + } + `, + ]; +} + +export default UmbTemplateCardElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-template-card': UmbTemplateCardElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/template-card/template-card.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/template-card/template-card.stories.ts new file mode 100644 index 0000000000..464e9bc44b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/template-card/template-card.stories.ts @@ -0,0 +1,40 @@ +import { Meta, StoryObj } from '@storybook/web-components'; +import { html } from 'lit'; +import './template-card.element'; +import type { UmbTemplateCardElement } from './template-card.element'; + +const meta: Meta = { + title: 'Components/Template Card', + component: 'umb-template-card', +}; + +export default meta; +type Story = StoryObj; + +export const Overview: Story = { + args: { + name: 'Template with a name ', + }, +}; + +export const Default: Story = { + args: { + name: 'Just a template', + }, +}; + +export const LongName: Story = { + args: { + name: 'Another template that someone gave a way way too long name without really thinking twice about it', + }, +}; + +export const TemplateCardList: Story = { + render: () => html`
    + + + + +
    `, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu-page.service.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu-page.service.ts index 25bc723a4d..d82eb782bf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu-page.service.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu-page.service.ts @@ -1,13 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, nothing, PropertyValueMap } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DeepState } from '@umbraco-cms/observable-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DeepState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; // TODO: Refactor this, its not a service and the data should be handled by a context api. @customElement('umb-tree-context-menu-page-service') -export class UmbTreeContextMenuPageService extends UmbLitElement { +export class UmbTreeContextMenuPageServiceElement extends UmbLitElement { static styles = [UUITextStyles, css``]; @property({ type: Object }) @@ -64,12 +64,11 @@ export class UmbTreeContextMenuPageService extends UmbLitElement { } } -export const UMB_TREE_CONTEXT_MENU_PAGE_SERVICE_CONTEXT_TOKEN = new UmbContextToken( - 'UmbTreeContextMenuService' -); +export const UMB_TREE_CONTEXT_MENU_PAGE_SERVICE_CONTEXT_TOKEN = + new UmbContextToken('UmbTreeContextMenuService'); declare global { interface HTMLElementTagNameMap { - 'umb-tree-context-menu-page-service': UmbTreeContextMenuPageService; + 'umb-tree-context-menu-page-service': UmbTreeContextMenuPageServiceElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu.service.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu.service.ts index c982250ea0..557c848b9e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu.service.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/context-menu/tree-context-menu.service.ts @@ -1,11 +1,11 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbContextToken } from '@umbraco-cms/context-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-tree-context-menu-service') -export class UmbTreeContextMenuService extends UmbLitElement { +export class UmbTreeContextMenuServiceElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -92,12 +92,12 @@ export class UmbTreeContextMenuService extends UmbLitElement { } } -export const UMB_TREE_CONTEXT_MENU_SERVICE_CONTEXT_TOKEN = new UmbContextToken( +export const UMB_TREE_CONTEXT_MENU_SERVICE_CONTEXT_TOKEN = new UmbContextToken( 'UmbTreeContextMenuService' ); declare global { interface HTMLElementTagNameMap { - 'umb-tree-context-menu-service': UmbTreeContextMenuService; + 'umb-tree-context-menu-service': UmbTreeContextMenuServiceElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/entity-tree-item/entity-tree-item.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/entity-tree-item/entity-tree-item.context.ts new file mode 100644 index 0000000000..62db8e957c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/entity-tree-item/entity-tree-item.context.ts @@ -0,0 +1,10 @@ +import { UmbTreeItemContextBase } from '../tree-item-base/tree-item-base.context'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +// TODO get unique method from an entity repository static method +export class UmbEntityTreeItemContext extends UmbTreeItemContextBase { + constructor(host: UmbControllerHostElement) { + super(host, (x: EntityTreeItemResponseModel) => x.id); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/entity-tree-item/entity-tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/entity-tree-item/entity-tree-item.element.ts new file mode 100644 index 0000000000..11fd1f40f3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/entity-tree-item/entity-tree-item.element.ts @@ -0,0 +1,49 @@ +import { css, html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { UmbEntityTreeItemContext } from './entity-tree-item.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { ManifestKind } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; + +// TODO: Move to separate file: +const manifest: ManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityTreeItem', + matchKind: 'entity', + matchType: 'treeItem', + manifest: { + type: 'treeItem', + elementName: 'umb-entity-tree-item', + }, +}; +umbExtensionsRegistry.register(manifest); + +@customElement('umb-entity-tree-item') +export class UmbEntityTreeItemElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + private _item?: EntityTreeItemResponseModel; + @property({ type: Object, attribute: false }) + public get item() { + return this._item; + } + public set item(value: EntityTreeItemResponseModel | undefined) { + this._item = value; + this.#context.setTreeItem(value); + } + + #context = new UmbEntityTreeItemContext(this); + + render() { + if (!this.item) return nothing; + return html``; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-entity-tree-item': UmbEntityTreeItemElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.context.ts new file mode 100644 index 0000000000..0465630182 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.context.ts @@ -0,0 +1,185 @@ +import { map } from 'rxjs'; +import { + UmbSectionSidebarContext, + UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, +} from '../../section/section-sidebar/section-sidebar.context'; +import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../../section/section.context'; +import { UmbTreeContextBase } from '../tree.context'; +import { UmbTreeItemContext } from '../tree-item.context.interface'; +import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { BooleanState, DeepState, StringState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { + UmbContextConsumerController, + UmbContextProviderController, + UmbContextToken, +} from '@umbraco-cms/backoffice/context-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; + +// add type for unique function +export type UmbTreeItemUniqueFunction = (x: T) => string | null | undefined; + +export class UmbTreeItemContextBase + implements UmbTreeItemContext +{ + public host: UmbControllerHostElement; + public unique?: string; + public type?: string; + + #treeItem = new DeepState(undefined); + treeItem = this.#treeItem.asObservable(); + + #hasChildren = new BooleanState(false); + hasChildren = this.#hasChildren.asObservable(); + + #isLoading = new BooleanState(false); + isLoading = this.#isLoading.asObservable(); + + #isSelectable = new BooleanState(false); + isSelectable = this.#isSelectable.asObservable(); + + #isSelected = new BooleanState(false); + isSelected = this.#isSelected.asObservable(); + + #isActive = new BooleanState(false); + isActive = this.#isActive.asObservable(); + + #hasActions = new BooleanState(false); + hasActions = this.#hasActions.asObservable(); + + #path = new StringState(''); + path = this.#path.asObservable(); + + treeContext?: UmbTreeContextBase; + #sectionContext?: UmbSectionContext; + #sectionSidebarContext?: UmbSectionSidebarContext; + #getUniqueFunction: UmbTreeItemUniqueFunction; + #actionObserver?: UmbObserverController; + + constructor(host: UmbControllerHostElement, getUniqueFunction: UmbTreeItemUniqueFunction) { + this.host = host; + this.#getUniqueFunction = getUniqueFunction; + this.#consumeContexts(); + new UmbContextProviderController(host, UMB_TREE_ITEM_CONTEXT_TOKEN, this); + } + + public setTreeItem(treeItem: T | undefined) { + if (!treeItem) { + this.#treeItem.next(undefined); + return; + } + + const unique = this.#getUniqueFunction(treeItem); + if (!unique) throw new Error('Could not create tree item context, unique key is missing'); + this.unique = unique; + + if (!treeItem.type) throw new Error('Could not create tree item context, tree item type is missing'); + this.type = treeItem.type; + + this.#hasChildren.next(treeItem.hasChildren || false); + this.#observeActions(); + this.#treeItem.next(treeItem); + } + + public async requestChildren() { + if (!this.unique) throw new Error('Could not request children, unique key is missing'); + + // TODO: wait for tree context to be ready + this.#isLoading.next(true); + const response = await this.treeContext!.requestChildrenOf(this.unique); + this.#isLoading.next(false); + return response; + } + + public toggleContextMenu() { + if (!this.getTreeItem() || !this.type || this.unique === undefined) { + throw new Error('Could not request children, tree item is not set'); + } + + this.#sectionSidebarContext?.toggleContextMenu(this.type, this.unique, this.getTreeItem()?.name || ''); + } + + public select() { + if (!this.unique) throw new Error('Could not request children, unique key is missing'); + this.treeContext?.select(this.unique); + } + + public deselect() { + if (!this.unique) throw new Error('Could not request children, unique key is missing'); + this.treeContext?.deselect(this.unique); + } + + #consumeContexts() { + new UmbContextConsumerController(this.host, UMB_SECTION_CONTEXT_TOKEN, (instance) => { + this.#sectionContext = instance; + this.#observeSectionPath(); + }); + + new UmbContextConsumerController(this.host, UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, (instance) => { + this.#sectionSidebarContext = instance; + }); + + new UmbContextConsumerController(this.host, 'umbTreeContext', (treeContext: UmbTreeContextBase) => { + this.treeContext = treeContext; + this.#observeIsSelectable(); + this.#observeIsSelected(); + }); + } + + getTreeItem() { + return this.#treeItem.getValue(); + } + + #observeIsSelectable() { + if (!this.treeContext) return; + new UmbObserverController(this.host, this.treeContext.selectable, (value) => this.#isSelectable.next(value)); + } + + #observeIsSelected() { + if (!this.treeContext) throw new Error('Could not request children, tree context is missing'); + if (!this.unique) throw new Error('Could not request children, unique key is missing'); + + new UmbObserverController( + this.host, + this.treeContext.selection.pipe(map((selection) => selection.includes(this.unique!))), + (isSelected) => { + this.#isSelected.next(isSelected); + } + ); + } + + #observeSectionPath() { + if (!this.#sectionContext) return; + + new UmbObserverController(this.host, this.#sectionContext.pathname, (pathname) => { + if (!pathname) return; + if (!this.type) throw new Error('Cant construct path, entity type is missing'); + if (!this.unique) throw new Error('Cant construct path, unique is missing'); + + const path = this.constructPath(pathname, this.type, this.unique); + this.#path.next(path); + }); + } + + #observeActions() { + if (this.#actionObserver) this.#actionObserver.destroy(); + + this.#actionObserver = new UmbObserverController( + this.host, + umbExtensionsRegistry + .extensionsOfType('entityAction') + .pipe(map((actions) => actions.filter((action) => action.conditions.entityType === this.type))), + (actions) => { + this.#hasActions.next(actions.length > 0); + } + ); + } + + // TODO: use router context + constructPath(pathname: string, entityType: string, unique: string) { + return `section/${pathname}/workspace/${entityType}/edit/${unique}`; + } +} + +export const UMB_TREE_ITEM_CONTEXT_TOKEN = new UmbContextToken('UmbTreeItemContext'); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.element.ts new file mode 100644 index 0000000000..a2b059421c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.element.ts @@ -0,0 +1,168 @@ +import { css, html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbTreeItemContext } from '../tree-item.context.interface'; +import { UMB_TREE_ITEM_CONTEXT_TOKEN } from './tree-item-base.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-tree-item-base') +export class UmbTreeItemBaseElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + @state() + private _item?: TreeItemPresentationModel; + + @state() + private _childItems?: TreeItemPresentationModel[]; + + @state() + private _href?: string; + + @state() + private _isLoading = false; + + @state() + private _isSelectable = false; + + @state() + private _isSelected = false; + + @state() + private _hasActions = false; + + @state() + private _hasChildren = false; + + @state() + private _iconSlotHasChildren = false; + + #treeItemContext?: UmbTreeItemContext; + + constructor() { + super(); + + this.consumeContext(UMB_TREE_ITEM_CONTEXT_TOKEN, (instance) => { + this.#treeItemContext = instance; + if (!this.#treeItemContext) return; + // TODO: investigate if we can make an observe decorator + this.observe(this.#treeItemContext.treeItem, (value) => (this._item = value)); + this.observe(this.#treeItemContext.hasChildren, (value) => (this._hasChildren = value)); + this.observe(this.#treeItemContext.isLoading, (value) => (this._isLoading = value)); + this.observe(this.#treeItemContext.isSelectable, (value) => (this._isSelectable = value)); + this.observe(this.#treeItemContext.isSelected, (value) => (this._isSelected = value)); + this.observe(this.#treeItemContext.hasActions, (value) => (this._hasActions = value)); + this.observe(this.#treeItemContext.path, (value) => (this._href = value)); + }); + } + + connectedCallback(): void { + super.connectedCallback(); + this.addEventListener('selected', this._handleSelectedItem); + this.addEventListener('unselected', this._handleDeselectedItem); + } + + private _handleSelectedItem(event: Event) { + event.stopPropagation(); + this.#treeItemContext?.select(); + } + + private _handleDeselectedItem(event: Event) { + event.stopPropagation(); + this.#treeItemContext?.deselect(); + } + + // TODO: do we want to catch and emit a backoffice event here? + private _onShowChildren() { + if (this._childItems && this._childItems.length > 0) return; + this.#observeChildren(); + } + + async #observeChildren() { + if (!this.#treeItemContext?.requestChildren) return; + + const { asObservable } = await this.#treeItemContext.requestChildren(); + if (!asObservable) return; + + this.observe(asObservable(), (childItems: any) => { + this._childItems = childItems; + }); + } + + private _openActions() { + this.#treeItemContext?.toggleContextMenu(); + } + + render() { + return html` + + ${this.#renderIcon()} ${this.#renderLabel()} ${this.#renderActions()} ${this.#renderChildItems()} + + + `; + } + + #hasNodes = (e: Event) => { + return (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0; + }; + + #renderIcon() { + return html` + { + this._iconSlotHasChildren = this.#hasNodes(e); + }}> + ${this._item?.icon && !this._iconSlotHasChildren + ? html` ` + : nothing} + `; + } + + #renderLabel() { + return html``; + } + + #renderActions() { + return html` + ${this._hasActions + ? html` + + + + + + ` + : nothing} + `; + } + + #renderChildItems() { + return html` + ${this._childItems + ? repeat( + this._childItems, + // TODO: get unique here instead of name. we might be able to get it from the context + (item) => item.name, + (item) => html`` + ) + : ''} + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-tree-item-base': UmbTreeItemBaseElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.stories.ts new file mode 100644 index 0000000000..f81fe83f46 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item-base/tree-item-base.stories.ts @@ -0,0 +1,20 @@ +import { Meta, StoryObj } from '@storybook/web-components'; +import './tree-item-base.element'; +import type { UmbTreeItemBaseElement } from './tree-item-base.element'; + +// TODO: provide tree item context to make this element render properly +const meta: Meta = { + title: 'Components/Tree/Tree Item', + component: 'umb-tree-item', +}; + +export default meta; +type Story = StoryObj; + +export const Overview: Story = { + args: {}, +}; + +export const WithChildren: Story = { + args: {}, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.context.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.context.interface.ts new file mode 100644 index 0000000000..31d877f22e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.context.interface.ts @@ -0,0 +1,35 @@ +import { Observable } from 'rxjs'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ProblemDetailsModel, TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; + +// TODO: temp type. Add paged response type to the repository interface +interface PagedResponse { + total: number; + items: Array; +} + +export interface UmbTreeItemContext { + host: UmbControllerHostElement; + unique?: string; + type?: string; + + treeItem: Observable; + hasChildren: Observable; + isLoading: Observable; + isSelectable: Observable; + isSelected: Observable; + isActive: Observable; + hasActions: Observable; + path: Observable; + + setTreeItem(treeItem: T | undefined): void; + requestChildren(): Promise<{ + data: PagedResponse | undefined; + error: ProblemDetailsModel | undefined; + asObservable?: () => Observable; + }>; + toggleContextMenu(): void; + select(): void; + deselect(): void; + constructPath(pathname: string, entityType: string, unique: string): string; +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.element.ts deleted file mode 100644 index f64476795e..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.element.ts +++ /dev/null @@ -1,272 +0,0 @@ -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 { map, Observable } from 'rxjs'; -import { repeat } from 'lit/directives/repeat.js'; -import { UmbSectionContext, UMB_SECTION_CONTEXT_TOKEN } from '../section/section.context'; -import { - UmbSectionSidebarContext, - UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, -} from '../section/section-sidebar/section-sidebar.context'; -import type { UmbTreeContextBase } from './tree.context'; -import type { Entity } from '@umbraco-cms/models'; -import type { UmbTreeStore } from '@umbraco-cms/store'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; - -@customElement('umb-tree-item') -export class UmbTreeItem extends UmbLitElement { - static styles = [UUITextStyles, css``]; - - @property({ type: String }) - key = ''; - - @property({ type: String }) - parentKey: string | null = null; - - @property({ type: String }) - label = ''; - - @property({ type: String }) - icon = ''; - - private _entityType = ''; - @property({ type: String }) - get entityType() { - return this._entityType; - } - set entityType(newVal) { - const oldVal = this._entityType; - this._entityType = newVal; - this.requestUpdate('entityType', oldVal); - this._observeEntityActions(); - } - - @property({ type: Boolean, attribute: 'has-children' }) - hasChildren = false; - - @state() - private _childItems?: Entity[]; - - @state() - private _href?: string; - - @state() - private _loading = false; - - @state() - private _selectable = false; - - @state() - private _selected = false; - - @state() - private _isActive = false; - - @state() - private _hasActions = false; - - private _treeContext?: UmbTreeContextBase; - private _store?: UmbTreeStore; - private _sectionContext?: UmbSectionContext; - private _sectionSidebarContext?: UmbSectionSidebarContext; - - constructor() { - super(); - - this.consumeContext('umbTreeContext', (treeContext: UmbTreeContextBase) => { - this._treeContext = treeContext; - this._observeSelectable(); - this._observeIsSelected(); - }); - - this.consumeContext('umbStore', (store: UmbTreeStore) => { - this._store = store; - }); - - this.consumeContext(UMB_SECTION_CONTEXT_TOKEN, (sectionContext) => { - this._sectionContext = sectionContext; - this._observeSection(); - this._observeActiveTreeItem(); - }); - - this.consumeContext(UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, (instance) => { - this._sectionSidebarContext = instance; - }); - } - - connectedCallback(): void { - super.connectedCallback(); - - this.addEventListener('selected', this._handleSelectedItem); - this.addEventListener('unselected', this._handleDeselectedItem); - } - - private _handleSelectedItem(event: Event) { - event.stopPropagation(); - this._treeContext?.select(this.key); - } - - private _handleDeselectedItem(event: Event) { - event.stopPropagation(); - this._treeContext?.deselect(this.key); - } - - private _observeSection() { - if (!this._sectionContext) return; - - this.observe(this._sectionContext?.pathname, (pathname) => { - this._href = this._constructPath(pathname || '', this.entityType, this.key); - }); - } - - private _observeSelectable() { - if (!this._treeContext) return; - - this.observe(this._treeContext.selectable, (value) => { - this._selectable = value || false; - }); - } - - private _observeIsSelected() { - if (!this._treeContext) return; - - this.observe(this._treeContext.selection.pipe(map((keys) => keys?.includes(this.key))), (isSelected) => { - this._selected = isSelected || false; - }); - } - - private _observeActiveTreeItem() { - if (!this._sectionContext) return; - - this.observe(this._sectionContext?.activeTreeItem, (treeItem) => { - this._isActive = this.key === treeItem?.key; - }); - } - - private _observeEntityActions() { - // TODO: Stop previous observation, currently we can do this from the UmbElementMixin as its a new subscription when Actions or entityType has changed. - // Solution: store the current observation controller and if it existing then destroy it. - // TODO: as long as a tree consist of one entity type we don't have to observe this every time a new tree item is created. - // Solution: move this to the tree context and observe it once. - this.observe( - umbExtensionsRegistry - .extensionsOfType('entityAction') - .pipe(map((actions) => actions.filter((action) => action.meta.entityType === this._entityType))), - (actions) => { - this._hasActions = actions.length > 0; - } - ); - } - - // TODO: how do we handle this? - private _constructPath(sectionPathname: string, type: string, key: string) { - return type ? `section/${sectionPathname}/${type}/edit/${key}` : undefined; - } - - // TODO: do we want to catch and emit a backoffice event here? - private _onShowChildren() { - if (this._childItems && this._childItems.length > 0) return; - this._observeChildren(); - this._observeRepositoryChildren(); - } - - private async _observeRepositoryChildren() { - if (!this._treeContext?.requestChildrenOf) return; - - // TODO: add loading state - this._treeContext.requestChildrenOf(this.key); - - this.observe(await this._treeContext.childrenOf(this.key), (childItems) => { - this._childItems = childItems as Entity[]; - }); - } - - // TODO: remove when repositories are in place - private _observeChildren() { - if (!this._store?.getTreeItemChildren) return; - - this._loading = true; - - // TODO: we should do something about these types, stop having our own version of Entity. - this.observe(this._store.getTreeItemChildren(this.key) as Observable, (childItems) => { - this._childItems = childItems; - this._loading = false; - }); - } - - private _openActions() { - if (!this._treeContext || !this._sectionContext) return; - - // This is out-commented as it was not used. only kept if someone need this later: - //this._sectionContext?.setActiveTree(this._treeContext?.tree); - - this._sectionContext?.setActiveTreeItem({ - key: this.key, - name: this.label, - icon: this.icon, - type: this.entityType, - hasChildren: this.hasChildren, - parentKey: this.parentKey, - }); - this._sectionSidebarContext?.toggleContextMenu(this.entityType, this.key, this.label); - } - - render() { - return html` - - ${this._renderChildItems()} - - ${this._renderActions()} - - - `; - } - - private _renderChildItems() { - return html` - ${this._childItems - ? repeat( - this._childItems, - (item) => item.key, - (item) => - html`` - ) - : ''} - `; - } - - private _renderActions() { - return html` - ${this._hasActions - ? html` - - - - - - ` - : nothing} - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-tree-item': UmbTreeItem; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.stories.ts deleted file mode 100644 index 5b59cbde3b..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item.stories.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Meta, StoryObj } from '@storybook/web-components'; -import './tree-item.element'; -import type { UmbTreeItem } from './tree-item.element' - -const meta: Meta = { - title: 'Components/Tree/Tree Item', - component: 'umb-tree-item', -}; - -export default meta; -type Story = StoryObj; - -export const Overview: Story = { - args: { - label: 'My Tree Item', - icon: 'umb:home', - hasChildren: false, - } -}; - -export const WithChildren: Story = { - args: { - label: 'My Tree Item', - icon: 'umb:home', - hasChildren: true, - } -}; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item/tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item/tree-item.element.ts new file mode 100644 index 0000000000..8e7efdbcd5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-item/tree-item.element.ts @@ -0,0 +1,30 @@ +import { css, html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { TreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; +import { ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-tree-item') +export class UmbTreeItemElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + @property({ type: Object, attribute: false }) + item?: TreeItemPresentationModel; + + render() { + if (!this.item) return nothing; + return html` manifests.conditions.entityType === this.item?.type} + .props=${{ + item: this.item, + }}>`; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-tree-item': UmbTreeItemElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-menu-item/tree-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-menu-item/tree-menu-item.element.ts new file mode 100644 index 0000000000..7922feb209 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree-menu-item/tree-menu-item.element.ts @@ -0,0 +1,65 @@ +import { html, nothing } from 'lit'; +import { customElement, property, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UUIMenuItemEvent } from '@umbraco-ui/uui'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestKind, ManifestMenuItemTreeKind } from '@umbraco-cms/backoffice/extensions-registry'; + +// TODO: Move to separate file: +const manifest: ManifestKind = { + type: 'kind', + alias: 'Umb.Kind.Tree', + matchKind: 'tree', + matchType: 'menuItem', + manifest: { + type: 'menuItem', + elementName: 'umb-menu-item-tree', + }, +}; +umbExtensionsRegistry.register(manifest); + +@customElement('umb-menu-item-tree') +export class UmbMenuItemTreeElement extends UmbLitElement { + @state() + private _renderTree = false; + + private _onShowChildren(event: UUIMenuItemEvent) { + event.stopPropagation(); + this._renderTree = true; + } + + private _onHideChildren(event: UUIMenuItemEvent) { + event.stopPropagation(); + this._renderTree = false; + } + + @property({ type: Object }) + manifest?: ManifestMenuItemTreeKind; + + // TODO: check if root has children before settings the has-children attribute + // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? + render() { + return this.manifest + ? html` + + ${this._renderTree ? html`` : nothing} + + ` + : ''; + } +} + +export default UmbMenuItemTreeElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-menu-item-tree': UmbMenuItemTreeElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.context.ts index fa0ef9d55c..89020e9acd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.context.ts @@ -1,8 +1,9 @@ import type { Observable } from 'rxjs'; -import { UmbTreeRepository } from '@umbraco-cms/repository'; -import type { ManifestTree } from '@umbraco-cms/models'; -import { DeepState } from '@umbraco-cms/observable-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; +import type { ManifestTree } from '@umbraco-cms/backoffice/extensions-registry'; +import { DeepState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { createExtensionClass, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; export interface UmbTreeContext { tree: ManifestTree; @@ -10,11 +11,11 @@ export interface UmbTreeContext { readonly selection: Observable>; setSelectable(value: boolean): void; setSelection(value: Array): void; - select(key: string): void; + select(id: string): void; } export class UmbTreeContextBase implements UmbTreeContext { - #host: UmbControllerHostInterface; + host: UmbControllerHostElement; public tree: ManifestTree; #selectable = new DeepState(false); @@ -23,15 +24,44 @@ export class UmbTreeContextBase implements UmbTreeContext { #selection = new DeepState(>[]); public readonly selection = this.#selection.asObservable(); - repository!: UmbTreeRepository; + repository?: UmbTreeRepository; - constructor(host: UmbControllerHostInterface, tree: ManifestTree) { - this.#host = host; + #initResolver?: () => void; + #initialized = false; + + #init = new Promise((resolve) => { + this.#initialized ? resolve() : (this.#initResolver = resolve); + }); + + constructor(host: UmbControllerHostElement, tree: ManifestTree) { + this.host = host; this.tree = tree; - if (this.tree.meta.repository) { - // TODO: should be using the right extension and the createExtensionClass method. - this.repository = new this.tree.meta.repository(this.#host) as any; + const repositoryAlias = this.tree.meta.repositoryAlias; + if (!repositoryAlias) throw new Error('Tree must have a repository alias.'); + + new UmbObserverController( + this.host, + umbExtensionsRegistry.getByTypeAndAlias('repository', this.tree.meta.repositoryAlias), + async (repositoryManifest) => { + if (!repositoryManifest) return; + + try { + const result = await createExtensionClass(repositoryManifest, [this.host]); + this.repository = result; + this.#checkIfInitialized(); + } catch (error) { + throw new Error('Could not create repository with alias: ' + repositoryAlias + ''); + } + } + ); + } + + // TODO: find a generic way to do this + #checkIfInitialized() { + if (this.repository) { + this.#initialized = true; + this.#initResolver?.(); } } @@ -44,32 +74,36 @@ export class UmbTreeContextBase implements UmbTreeContext { this.#selection.next(value); } - public select(key: string) { + public select(id: string) { const oldSelection = this.#selection.getValue(); - if (oldSelection.indexOf(key) !== -1) return; + if (oldSelection.indexOf(id) !== -1) return; - const selection = [...oldSelection, key]; + const selection = [...oldSelection, id]; this.#selection.next(selection); } - public deselect(key: string) { + public deselect(id: string) { const selection = this.#selection.getValue(); - this.#selection.next(selection.filter((x) => x !== key)); + this.#selection.next(selection.filter((x) => x !== id)); } public async requestRootItems() { - return this.repository.requestRootTreeItems(); + await this.#init; + return this.repository!.requestRootTreeItems(); } - public async requestChildrenOf(parentKey: string | null) { - return this.repository.requestTreeItemsOf(parentKey); + public async requestChildrenOf(parentId: string | null) { + await this.#init; + return this.repository!.requestTreeItemsOf(parentId); } public async rootItems() { - return this.repository.rootTreeItems(); + await this.#init; + return this.repository!.rootTreeItems(); } - public async childrenOf(parentKey: string | null) { - return this.repository.treeItemsOf(parentKey); + public async childrenOf(parentId: string | null) { + await this.#init; + return this.repository!.treeItemsOf(parentId); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.element.ts index 156ece1717..3466abc60b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/tree/tree.element.ts @@ -1,13 +1,15 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { map } from 'rxjs'; -import { repeat } from 'lit-html/directives/repeat.js'; +import { repeat } from 'lit/directives/repeat.js'; import { UmbTreeContextBase } from './tree.context'; -import type { Entity, ManifestTree } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { ManifestTree } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; -import './tree-item.element'; +import './tree-item/tree-item.element'; +import './tree-item-base/tree-item-base.element'; import './context-menu/tree-context-menu-page.service'; import './context-menu/tree-context-menu.service'; @@ -53,10 +55,7 @@ export class UmbTreeElement extends UmbLitElement { private _tree?: ManifestTree; @state() - private _items: Entity[] = []; - - @state() - private _loading = true; + private _items: EntityTreeItemResponseModel[] = []; private _treeContext?: UmbTreeContextBase; @@ -73,6 +72,7 @@ export class UmbTreeElement extends UmbLitElement { .pipe(map((trees) => trees.find((tree) => tree.alias === this.alias))), async (tree) => { if (this._tree?.alias === tree?.alias) return; + this._tree = tree; this.#provideTreeContext(); } @@ -99,7 +99,7 @@ export class UmbTreeElement extends UmbLitElement { this._treeContext.requestRootItems(); this.observe(await this._treeContext.rootItems(), (rootItems) => { - this._items = rootItems as Entity[]; + this._items = rootItems; }); } @@ -117,15 +117,9 @@ export class UmbTreeElement extends UmbLitElement { return html` ${repeat( this._items, - (item) => item.key, - (item) => - html`` + // TODO: add getUnique to a repository interface + (item, index) => index, + (item) => html`` )} `; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.element.ts index 6baa96b9c7..57391b102a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.element.ts @@ -2,14 +2,14 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbWorkspaceVariantContext, UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN, } from '../workspace/workspace-variant/workspace-variant.context'; import { ActiveVariant } from '../workspace/workspace-context/workspace-split-view-manager.class'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DocumentVariantModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DocumentVariantResponseModel, ContentStateModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-variant-selector') export class UmbVariantSelectorElement extends UmbLitElement { @@ -24,9 +24,11 @@ export class UmbVariantSelectorElement extends UmbLitElement { #variant-selector-toggle { white-space: nowrap; } + #variant-selector-popover { display: block; } + #variant-selector-dropdown { overflow: hidden; z-index: -1; @@ -42,6 +44,95 @@ export class UmbVariantSelectorElement extends UmbLitElement { #variant-close { white-space: nowrap; } + + ul { + list-style-type: none; + padding: 0; + margin: 0; + } + + li { + position: relative; + margin-bottom: 1px; + } + + li:nth-last-of-type(1) { + margin-bottom: 0; + } + + li.selected:before { + background-color: var(--uui-color-current); + border-radius: 0 4px 4px 0; + bottom: 8px; + content: ''; + left: 0; + pointer-events: none; + position: absolute; + top: 8px; + width: 4px; + z-index: 1; + } + + .variant-selector-switch-button { + display: flex; + align-items: center; + border: none; + background: transparent; + color: var(--uui-color-current-contrast); + padding: 6px 20px; + font-weight: bold; + width: 100%; + text-align: left; + font-size: 14px; + cursor: pointer; + border-bottom: 1px solid var(--uui-color-divider-standalone); + font-family: Lato, Helvetica Neue, Helvetica, Arial, sans-serif; + } + + .variant-selector-switch-button:hover { + background: var(--uui-palette-sand); + color: var(--uui-palette-space-cadet-light); + } + + .variant-selector-switch-button i { + font-weight: normal; + } + + .variant-selector-switch-button.add-mode { + position: relative; + color: var(--uui-palette-dusty-grey-dark); + } + + .variant-selector-switch-button.add-mode:after { + border: 2px dashed var(--uui-color-divider-standalone); + bottom: 0; + content: ''; + left: 0; + margin: 2px; + pointer-events: none; + position: absolute; + right: 0; + top: 0; + z-index: 1; + } + + .add-icon { + font-size: 12px; + margin-right: 12px; + } + + .variant-selector-split-view { + position: absolute; + top: 0; + right: 0; + bottom: 1px; + } + + .variant-selector-state { + color: var(--uui-palette-malibu-dimmed); + font-size: 12px; + font-weight: normal; + } `, ]; @@ -50,12 +141,17 @@ export class UmbVariantSelectorElement extends UmbLitElement { alias!: string; @state() - _variants: Array = []; + _variants: Array = []; // TODO: Stop using document context specific ActiveVariant type. @state() _activeVariants: Array = []; + @property() + public get _activeVariantsCultures(): string[] { + return this._activeVariants.map((el) => el.culture ?? '') ?? []; + } + private _variantContext?: UmbWorkspaceVariantContext; @state() @@ -155,7 +251,7 @@ export class UmbVariantSelectorElement extends UmbLitElement { (this._culture ? this._cultureNames.of(this._culture) : '') + (this._segment ? ' — ' + this._segment : ''); } - // TODO. find a way where we don't have to do this for all workspaces. + // TODO: find a way where we don't have to do this for all workspaces. private _handleInput(event: UUIInputEvent) { if (event instanceof UUIInputEvent) { const target = event.composedPath()[0] as UUIInputElement; @@ -178,19 +274,28 @@ export class UmbVariantSelectorElement extends UmbLitElement { this._variantSelectorIsOpen = false; } - private _switchVariant(variant: DocumentVariantModel) { + private _switchVariant(variant: DocumentVariantResponseModel) { this._variantContext?.switchVariant(variant); this._close(); } - private _openSplitView(variant: DocumentVariantModel) { + private _openSplitView(variant: DocumentVariantResponseModel) { this._variantContext?.openSplitView(variant); this._close(); } + private _closeSplitView() { this._variantContext?.closeSplitView(); } + private _isVariantActive(culture: string) { + return this._activeVariantsCultures.includes(culture); + } + + private _isNotPublishedMode(culture: string, state: ContentStateModel) { + return state !== ContentStateModel.PUBLISHED && !this._isVariantActive(culture!); + } + render() { return html` @@ -223,20 +328,37 @@ export class UmbVariantSelectorElement extends UmbLitElement {
    - ${this._variants.map( - (variant) => - html`
      -
    • - - this._switchVariant(variant)}> - ${variant.name} ${variant.culture} ${variant.segment} - +
        + ${this._variants.map( + (variant) => + html` +
      • + - - this._openSplitView(variant)}> Split view -
      • -
      ` - )} + ${this._isVariantActive(variant.culture!) + ? nothing + : html` + this._openSplitView(variant)}> + Split view + + `} +
    • + ` + )} +
    diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.stories.ts index c5f645add3..7aac088b20 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variant-selector/variant-selector.stories.ts @@ -1,17 +1,17 @@ import { Meta, StoryObj } from '@storybook/web-components'; import './variant-selector.element'; -import type { UmbVariantSelectorElement } from './variant-selector.element' +import type { UmbVariantSelectorElement } from './variant-selector.element'; const meta: Meta = { - title: 'Components/Variant Selector', - component: 'umb-variant-selector', + title: 'Components/Variant Selector', + component: 'umb-variant-selector', }; - + export default meta; type Story = StoryObj; export const Overview: Story = { - args: { - alias: 'myAlias' - } -}; \ No newline at end of file + args: { + alias: 'myAlias', + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variantable-property/variantable-property.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variantable-property/variantable-property.element.ts index 35cd55ba18..0ec872fc48 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variantable-property/variantable-property.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/variantable-property/variantable-property.element.ts @@ -3,9 +3,9 @@ import { css, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbVariantId } from '../../variants/variant-id.class'; import { UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN } from '../workspace/workspace-variant/workspace-variant.context'; -import type { PropertyTypeViewModelBaseModel } from '@umbraco-cms/backend-api'; +import type { PropertyTypeResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; import '../workspace-property/workspace-property.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-variantable-property') export class UmbVariantablePropertyElement extends UmbLitElement { @@ -18,12 +18,12 @@ export class UmbVariantablePropertyElement extends UmbLitElement { `, ]; - private _property?: PropertyTypeViewModelBaseModel | undefined; + private _property?: PropertyTypeResponseModelBaseModel | undefined; @property({ type: Object, attribute: false }) - public get property(): PropertyTypeViewModelBaseModel | undefined { + public get property(): PropertyTypeResponseModelBaseModel | undefined { return this._property; } - public set property(property: PropertyTypeViewModelBaseModel | undefined) { + public set property(property: PropertyTypeResponseModelBaseModel | undefined) { this._property = property; this._updatePropertyVariantId(); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.context.ts index 5474e323a9..e069c2a5b5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.context.ts @@ -1,10 +1,15 @@ import { UmbVariantId } from '../../variants/variant-id.class'; import { UmbWorkspaceVariableEntityContextInterface } from '../workspace/workspace-context/workspace-variable-entity-context.interface'; import { UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN } from '../workspace/workspace-variant/workspace-variant.context'; -import type { DataTypeModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ObjectState, StringState, UmbObserverController } from '@umbraco-cms/observable-api'; -import { UmbContextConsumerController, UmbContextProviderController } from '@umbraco-cms/context-api'; +import type { DataTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ClassState, ObjectState, StringState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { + UmbContextConsumerController, + UmbContextProviderController, + UmbContextToken, + UMB_ENTITY_WORKSPACE_CONTEXT, +} from '@umbraco-cms/backoffice/context-api'; // If we get this from the server then we can consider using TypeScripts Partial<> around the model from the Management-API. export type WorkspacePropertyData = { @@ -12,11 +17,11 @@ export type WorkspacePropertyData = { label?: string; description?: string; value?: ValueType | null; - config?: DataTypeModel['data']; // This could potentially then come from hardcoded JS object and not the DataType store. + config?: DataTypeResponseModel['values']; // This could potentially then come from hardcoded JS object and not the DataType store. }; -export class UmbWorkspacePropertyContext { - #host: UmbControllerHostInterface; +export class UmbWorkspacePropertyContext { + #host: UmbControllerHostElement; private _providerController: UmbContextProviderController; @@ -28,25 +33,49 @@ export class UmbWorkspacePropertyContext { public readonly value = this._data.getObservablePart((data) => data.value); public readonly config = this._data.getObservablePart((data) => data.config); - private _variantId?: UmbVariantId; + #workspaceVariantId?: UmbVariantId; + + #variantId = new ClassState(undefined); + public readonly variantId = this.#variantId.asObservable(); private _variantDifference = new StringState(undefined); public readonly variantDifference = this._variantDifference.asObservable(); private _workspaceContext?: UmbWorkspaceVariableEntityContextInterface; + private _workspaceVariantConsumer?: UmbContextConsumerController; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; - // TODO: Figure out how to get the magic string in a better way. - new UmbContextConsumerController( - host, - 'umbWorkspaceContext', - (workspaceContext) => { - this._workspaceContext = workspaceContext; - } - ); + new UmbContextConsumerController(host, UMB_ENTITY_WORKSPACE_CONTEXT, (workspaceContext) => { + this._workspaceContext = workspaceContext as UmbWorkspaceVariableEntityContextInterface; + }); - this._providerController = new UmbContextProviderController(host, 'umbPropertyContext', this); + this._providerController = new UmbContextProviderController(host, UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, this); + + this.variantId.subscribe((propertyVariantId) => { + if (propertyVariantId) { + if (!this._workspaceVariantConsumer) { + this._workspaceVariantConsumer = new UmbContextConsumerController( + this.#host, + UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN, + (workspaceVariantContext) => { + new UmbObserverController(this.#host, workspaceVariantContext.variantId, (workspaceVariantId) => { + this.#workspaceVariantId = workspaceVariantId; + this._generateVariantDifferenceString(); + }); + } + ); + } else { + this._generateVariantDifferenceString(); + } + } + }); + } + + private _generateVariantDifferenceString() { + this._variantDifference.next( + this.#workspaceVariantId ? this.#variantId.getValue()?.toDifferencesString(this.#workspaceVariantId) : '' + ); } public setAlias(alias: WorkspacePropertyData['alias']) { @@ -67,22 +96,17 @@ export class UmbWorkspacePropertyContext { const alias = this._data.getValue().alias; if (alias) { - this._workspaceContext?.setPropertyValue(alias, value, this._variantId); + this._workspaceContext?.setPropertyValue(alias, value, this.#variantId.getValue()); } } public setConfig(config: WorkspacePropertyData['config']) { this._data.update({ config }); } public setVariantId(variantId: UmbVariantId | undefined) { - this._variantId = variantId; - new UmbContextConsumerController(this.#host, UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN, (variantContext) => { - new UmbObserverController(this.#host, variantContext.variantId, (variantId) => { - this._variantDifference.next(variantId ? this._variantId?.toDifferencesString(variantId) : ''); - }); - }); + this.#variantId.next(variantId); } public getVariantId() { - return this._variantId; + return this.#variantId.getValue(); } public resetValue() { @@ -94,3 +118,7 @@ export class UmbWorkspacePropertyContext { this._providerController.destroy(); // This would also be handled by the controller host, but if someone wanted to replace/remove this context without the host being destroyed. Then we have clean up out selfs here. } } + +export const UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN = new UmbContextToken( + 'UmbWorkspacePropertyContext' +); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.element.ts index 634b4a8d7c..b7965d8fe5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.element.ts @@ -1,18 +1,18 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbVariantId } from '../../variants/variant-id.class'; import { UmbWorkspacePropertyContext } from './workspace-property.context'; -import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import type { ManifestPropertyEditorUI, ManifestTypes } from '@umbraco-cms/models'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; import '../../property-actions/shared/property-action-menu/property-action-menu.element'; import '../../../../backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.element'; -import { UmbObserverController } from '@umbraco-cms/observable-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DataTypePropertyModel } from '@umbraco-cms/backend-api'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-workspace-property @@ -114,7 +114,7 @@ export class UmbWorkspacePropertyElement extends UmbLitElement { * @default '' */ @property({ type: Object, attribute: false }) - public set config(value: DataTypePropertyModel[]) { + public set config(value: DataTypePropertyPresentationModel[]) { this._propertyContext.setConfig(value); } @@ -151,10 +151,10 @@ export class UmbWorkspacePropertyElement extends UmbLitElement { private _propertyContext = new UmbWorkspacePropertyContext(this); - private propertyEditorUIObserver?: UmbObserverController; + private propertyEditorUIObserver?: UmbObserverController; private _valueObserver?: UmbObserverController; - private _configObserver?: UmbObserverController; + private _configObserver?: UmbObserverController; constructor() { super(); @@ -211,17 +211,25 @@ export class UmbWorkspacePropertyElement extends UmbLitElement { if (this._element) { this._element.addEventListener('property-value-change', this._onPropertyEditorChange as any as EventListener); - this._valueObserver = this.observe(this._propertyContext.value, (value) => { - this._value = value; - if (this._element) { - this._element.value = value; - } - }); - this._configObserver = this.observe(this._propertyContext.config, (config) => { - if (this._element && config) { - this._element.config = config; - } - }); + this._valueObserver = this.observe( + this._propertyContext.value, + (value) => { + this._value = value; + if (this._element) { + this._element.value = value; + } + }, + '_observePropertyValue' + ); + this._configObserver = this.observe( + this._propertyContext.config, + (config) => { + if (this._element && config) { + this._element.config = config; + } + }, + '_observePropertyConfig' + ); } this.requestUpdate('element', oldValue); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.stories.ts index 9897607990..ffe256bb60 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace-property/workspace-property.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbWorkspacePropertyElement } from './workspace-property.element'; import './workspace-property.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action-menu/workspace-action-menu.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action-menu/workspace-action-menu.element.ts index 1cf0cd994d..a3838dac24 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action-menu/workspace-action-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action-menu/workspace-action-menu.element.ts @@ -1,9 +1,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbWorkspaceEntityContextInterface } from '../workspace-context/workspace-entity-context.interface'; -import { UmbExecutedEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbExecutedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-workspace-action-menu') export class UmbWorkspaceActionMenuElement extends UmbLitElement { @@ -34,10 +34,10 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { @state() private _actionMenuIsOpen = false; - private _workspaceContext?: UmbWorkspaceEntityContextInterface; + private _workspaceContext?: typeof UMB_ENTITY_WORKSPACE_CONTEXT.TYPE; @state() - _entityKey?: string; + _entityId?: string; @state() _entityType?: string; @@ -45,7 +45,7 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { constructor() { super(); - this.consumeContext('umbWorkspaceContext', (context) => { + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (context) => { this._workspaceContext = context; this._observeInfo(); }); @@ -53,7 +53,7 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { private _observeInfo() { if (!this._workspaceContext) return; - this._entityKey = this._workspaceContext.getEntityKey(); + this._entityId = this._workspaceContext.getEntityId(); this._entityType = this._workspaceContext.getEntityType(); } @@ -75,14 +75,14 @@ export class UmbWorkspaceActionMenuElement extends UmbLitElement { } #renderActionsMenu() { - return this._entityKey + return this._entityId ? html`
    diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action/workspace-action.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action/workspace-action.element.ts index 17fea95c41..c06284efee 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action/workspace-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-action/workspace-action.element.ts @@ -2,10 +2,10 @@ import { css, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import type { UUIButtonState } from '@umbraco-ui/uui'; -import { UmbWorkspaceAction } from '@umbraco-cms/workspace'; -import { UmbExecutedEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { ManifestWorkspaceAction } from '@umbraco-cms/models'; +import { UmbWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UmbExecutedEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { ManifestWorkspaceAction } from '@umbraco-cms/backoffice/extensions-registry'; @customElement('umb-workspace-action') export class UmbWorkspaceActionElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/collection/workspace-view-collection.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/collection/workspace-view-collection.element.ts index c171c79007..87a3a06857 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/collection/workspace-view-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/collection/workspace-view-collection.element.ts @@ -1,17 +1,17 @@ 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 { ifDefined } from 'lit/directives/if-defined.js'; import { UmbCollectionContext, UMB_COLLECTION_CONTEXT_TOKEN, } from '../../../../../../shared/collection/collection.context'; import '../../../../../../shared/collection/dashboards/dashboard-collection.element'; -import type { UmbWorkspaceEntityContextInterface } from '../../../workspace-context/workspace-entity-context.interface'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { FolderTreeItemModel } from '@umbraco-cms/backend-api'; -import { ManifestWorkspaceViewCollection } from '@umbraco-cms/extensions-registry'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { FolderTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { ManifestWorkspaceViewCollection } from '@umbraco-cms/backoffice/extensions-registry'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-workspace-view-collection') export class UmbWorkspaceViewCollectionElement extends UmbLitElement { @@ -27,32 +27,31 @@ export class UmbWorkspaceViewCollectionElement extends UmbLitElement { public manifest!: ManifestWorkspaceViewCollection; - private _workspaceContext?: UmbWorkspaceEntityContextInterface; + private _workspaceContext?: typeof UMB_ENTITY_WORKSPACE_CONTEXT.TYPE; // TODO: add type for the collection context. - private _collectionContext?: UmbCollectionContext; + private _collectionContext?: UmbCollectionContext; constructor() { super(); - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext('umbWorkspaceContext', (nodeContext) => { + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (nodeContext) => { this._workspaceContext = nodeContext; this._provideWorkspace(); }); } protected _provideWorkspace() { - const entityKey = this._workspaceContext?.getEntityKey(); + const entityId = this._workspaceContext?.getEntityId(); const entityType = this._workspaceContext?.getEntityType(); - if (entityKey != null && entityType != null) { + if (entityId != null && entityType != null) { const manifestMeta = this.manifest.meta; this._collectionContext = new UmbCollectionContext( this, entityType, - entityKey, + entityId, manifestMeta.storeAlias, manifestMeta.repositoryAlias ); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/edit/workspace-view-content-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/edit/workspace-view-content-edit.element.ts deleted file mode 100644 index 90274f9258..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/edit/workspace-view-content-edit.element.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { css, html } from 'lit'; -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, state } from 'lit/decorators.js'; -import { repeat } from 'lit/directives/repeat.js'; -import type { UmbWorkspaceEntityContextInterface } from '../../../workspace-context/workspace-entity-context.interface'; -import type { ContentProperty, ContentPropertyData, MediaTypeDetails } from '@umbraco-cms/models'; - -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-workspace-view-content-edit') -export class UmbWorkspaceViewContentEditElement extends UmbLitElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - margin: var(--uui-size-layout-1); - } - `, - ]; - - @state() - _properties: ContentProperty[] = []; - - @state() - _data: ContentPropertyData[] = []; - - private _workspaceContext?: UmbWorkspaceEntityContextInterface; - - constructor() { - super(); - - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext>( - 'umbWorkspaceContext', - (workspaceContext) => { - this._workspaceContext = workspaceContext; - this._observeContent(); - } - ); - } - - private _observeContent() { - if (!this._workspaceContext) return; - - /* - TODO: Property-Context: This observer gets all changes, We need to fix this. it should be simpler. - An idea to optimize this would be for this to only care about layout, meaning to property data should be watched here. - As the properties could handle their own data on their own? - - Should use a Observable for example: this._workspaceContext.properties - */ - - /* - // TODO: broken for now, as we need to transfer into the repository way: - this.observe( - this._workspaceContext.data, - (content) => { - // TODO: Should be adapted to new models, maybe a shared 'Content' solution is not the right thing here. - this._properties = content?.properties || []; - console.log('content', content); - - //Maybe we should not give the value(Data), but the umb-property-type-based-property should get the context and observe its own data. - //This would become a more specific Observer therefor better performance?.. Note to self: Debate with Mads how he sees this perspective. - }, - 'observeWorkspaceContextData' - ); - */ - } - - render() { - return html` - - ${repeat( - this._properties, - (property) => property.alias, - (property) => - html` ` - )} - - `; - } -} - -export default UmbWorkspaceViewContentEditElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-workspace-view-content-edit': UmbWorkspaceViewContentEditElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/edit/workspace-view-content-edit.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/edit/workspace-view-content-edit.stories.ts deleted file mode 100644 index 480f424808..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/views/edit/workspace-view-content-edit.stories.ts +++ /dev/null @@ -1,27 +0,0 @@ -import './workspace-view-content-edit.element'; - -import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; - -//import { data } from '../../../../../../core/mocks/data/document.data'; -//import { UmbNodeContext } from '../../node.context'; - -import type { UmbWorkspaceViewContentEditElement } from './workspace-view-content-edit.element'; - -export default { - title: 'Workspaces/Shared/Node/Views/Edit', - component: 'umb-workspace-view-content-edit', - id: 'umb-workspace-view-content-edit', - decorators: [ - (story) => { - return html`TODO: make use of mocked workspace context??`; - /*html` - ${story()} - `,*/ - }, - ], -} as Meta; - -export const AAAOverview: Story = () => - html` `; -AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.element.ts deleted file mode 100644 index 4614ff8618..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.element.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html } from 'lit'; -import { customElement, property, state } from 'lit/decorators.js'; - -import '../workspace-layout/workspace-layout.element'; -import '../../variant-selector/variant-selector.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 { UmbLitElement } from '@umbraco-cms/element'; - -/** - * 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 UmbLitElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - width: 100%; - height: 100%; - } - - #header { - margin: 0 var(--uui-size-layout-1); - flex: 1 1 auto; - } - - #footer { - margin: 0 var(--uui-size-layout-1); - } - `, - ]; - - // TODO: is this used for anything? - @property() - alias!: string; - - // TODO: For variants and split view, we need to be able to repeat, either this element or make this element render multiple `umb-workspace-layout` - - render() { - return html` - - - - - - - - `; - } -} - -export default UmbWorkspaceContentElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-workspace-content': UmbWorkspaceContentElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.stories.ts deleted file mode 100644 index a2c998c743..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-content/workspace-content.stories.ts +++ /dev/null @@ -1,18 +0,0 @@ -import './workspace-content.element'; - -import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; - -import { data } from '../../../../../core/mocks/data/document.data'; - -import type { UmbWorkspaceContentElement } from './workspace-content.element'; - -export default { - title: 'Workspaces/Shared/Node', - component: 'umb-workspace-content', - id: 'umb-workspace-content', -} as Meta; - -export const AAAOverview: Story = () => - html` `; -AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/entity-manager-controller.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/entity-manager-controller.ts index 62c920a95a..9704ce80c2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/entity-manager-controller.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/entity-manager-controller.ts @@ -1,37 +1,37 @@ import { v4 as uuidv4 } from 'uuid'; -import { UmbContextConsumerController, UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextConsumerController, UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; import { UmbNotificationDefaultData, UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN, -} from '@umbraco-cms/notification'; -import { ObjectState, UmbObserverController } from '@umbraco-cms/observable-api'; -import type { EntityTreeItemModel } from '@umbraco-cms/backend-api'; -import { UmbEntityDetailStore } from '@umbraco-cms/store'; +} from '@umbraco-cms/backoffice/notification'; +import { ObjectState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import type { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbEntityDetailStore } from '@umbraco-cms/backoffice/store'; -// Extend entityType base type?, so we are sure to have parentKey? +// Extend entityType base type?, so we are sure to have parentId? // TODO: switch to use EntityDetailItem ? if we can have such type? export class UmbEntityWorkspaceManager< StoreType extends UmbEntityDetailStore, - EntityDetailsType extends EntityTreeItemModel = ReturnType + EntityDetailsType extends EntityTreeItemResponseModel = ReturnType > { private _host; state = new ObjectState(undefined); - protected _storeSubscription?: UmbObserverController; + protected _storeSubscription?: UmbObserverController; private _notificationContext?: UmbNotificationContext; private _store?: StoreType; #isNew = false; private _entityType; - private _entityKey!: string; + private _entityId!: string; private _createAtParentKey?: string | null; - constructor(host: UmbControllerHostInterface, entityType: string, storeToken: UmbContextToken) { + constructor(host: UmbControllerHostElement, entityType: string, storeToken: UmbContextToken) { this._host = host; this._entityType = entityType; @@ -47,7 +47,7 @@ export class UmbEntityWorkspaceManager< } private _observeStore() { - if (!this._store || !this._entityKey) { + if (!this._store || !this._entityId) { return; } @@ -58,7 +58,7 @@ export class UmbEntityWorkspaceManager< this._storeSubscription?.destroy(); this._storeSubscription = new UmbObserverController( this._host, - this._store.getByKey(this._entityKey), + this._store.getByKey(this._entityId), (content) => { if (!content) return; // TODO: Handle nicely if there is no content data. this.state.next(content as any); @@ -71,7 +71,7 @@ export class UmbEntityWorkspaceManager< return this._entityType; }; getEntityKey = (): string => { - return this._entityKey; + return this._entityId; }; getStore = () => { @@ -82,16 +82,16 @@ export class UmbEntityWorkspaceManager< return this.state.getValue(); }; - load = (entityKey: string) => { + load = (entityId: string) => { this.#isNew = false; - this._entityKey = entityKey; + this._entityId = entityId; this._observeStore(); }; - create = (parentKey: string | null) => { + create = (parentId: string | null) => { this.#isNew = true; - this._entityKey = uuidv4(); - this._createAtParentKey = parentKey; + this._entityId = uuidv4(); + this._createAtParentKey = parentId; }; save = (): Promise => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-container-structure-helper.class.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-container-structure-helper.class.ts new file mode 100644 index 0000000000..25b756dfbf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-container-structure-helper.class.ts @@ -0,0 +1,160 @@ +import { UmbDocumentWorkspaceContext } from '../../../../documents/documents/workspace/document-workspace.context'; +import { PropertyContainerTypes } from './workspace-structure-manager.class'; +import { PropertyTypeContainerResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController, UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState, BooleanState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; + +export class UmbWorkspaceContainerStructureHelper { + #host: UmbControllerHostElement; + + #workspaceContext?: UmbDocumentWorkspaceContext; + + private _ownerType?: PropertyContainerTypes = 'Tab'; + private _childType?: PropertyContainerTypes = 'Group'; + private _isRoot = false; + private _ownerName?: string; + private _ownerKey?: string; + + // Containers defined in data might be more than actual containers to display as we merge them by name. + private _ownerContainers: PropertyTypeContainerResponseModelBaseModel[] = []; + + // State containing the merged containers (only one pr. name): + #containers = new ArrayState([], (x) => x.id); + readonly containers = this.#containers.asObservable(); + + #hasProperties = new BooleanState(false); + readonly hasProperties = this.#hasProperties.asObservable(); + + constructor(host: UmbControllerHostElement) { + this.#host = host; + + this.#containers.sortBy((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); + + new UmbContextConsumerController(host, UMB_ENTITY_WORKSPACE_CONTEXT, (context) => { + this.#workspaceContext = context as UmbDocumentWorkspaceContext; + this._observeOwnerContainers(); + }); + } + + public setType(value?: PropertyContainerTypes) { + if (this._ownerType === value) return; + this._ownerType = value; + this._observeOwnerContainers(); + } + public getType() { + return this._ownerType; + } + + public setContainerChildType(value?: PropertyContainerTypes) { + if (this._childType === value) return; + this._childType = value; + this._observeOwnerContainers(); + } + public getContainerChildType() { + return this._childType; + } + + public setName(value?: string) { + if (this._ownerName === value) return; + this._ownerName = value; + this._observeOwnerContainers(); + } + public getName() { + return this._ownerName; + } + + public setIsRoot(value: boolean) { + if (this._isRoot === value) return; + this._isRoot = value; + this._observeOwnerContainers(); + } + public getIsRoot() { + return this._isRoot; + } + + private _observeOwnerContainers() { + if (!this.#workspaceContext) return; + + if (this._isRoot) { + this.#containers.next([]); + // We cannot have root properties currently, therefor we set it to false: + this.#hasProperties.next(false); + this._observeRootContainers(); + } else if (this._ownerName && this._ownerType) { + new UmbObserverController( + this.#host, + this.#workspaceContext.structure.containersByNameAndType(this._ownerName, this._ownerType), + (ownerContainers) => { + this.#containers.next([]); + this._ownerContainers = ownerContainers || []; + if (this._ownerContainers.length > 0) { + this._observeOwnerProperties(); + this._observeChildContainers(); + } + }, + '_observeOwnerContainers' + ); + } + } + + private _observeOwnerProperties() { + if (!this.#workspaceContext) return; + + this._ownerContainers.forEach((container) => { + new UmbObserverController( + this.#host, + this.#workspaceContext!.structure.hasPropertyStructuresOf(container.id!), + (hasProperties) => { + this.#hasProperties.next(hasProperties); + }, + '_observeOwnerHasProperties_' + container.id + ); + }); + } + + private _observeChildContainers() { + if (!this.#workspaceContext || !this._ownerName || !this._childType) return; + + this._ownerContainers.forEach((container) => { + new UmbObserverController( + this.#host, + this.#workspaceContext!.structure.containersOfParentKey(container.id, this._childType!), + this._insertGroupContainers, + '_observeGroupsOf_' + container.id + ); + }); + } + + private _observeRootContainers() { + if (!this.#workspaceContext || !this._isRoot) return; + + new UmbObserverController( + this.#host, + this.#workspaceContext!.structure.rootContainers(this._childType!), + (rootContainers) => { + this.#containers.next([]); + this._insertGroupContainers(rootContainers); + }, + '_observeRootContainers' + ); + } + + private _insertGroupContainers = (groupContainers: PropertyTypeContainerResponseModelBaseModel[]) => { + groupContainers.forEach((group) => { + if (group.name !== null && group.name !== undefined) { + if (!this.#containers.getValue().find((x) => x.name === group.name)) { + this.#containers.appendOne(group); + } + } + }); + }; + + /** Manipulate methods: */ + + async addGroup(ownerKey?: string, sortOrder?: number) { + if (!this.#workspaceContext) return; + + await this.#workspaceContext.structure.createContainer(null, ownerKey, this._childType, sortOrder); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-context.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-context.interface.ts deleted file mode 100644 index c756452a21..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-context.interface.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Observable } from 'rxjs'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; - -export interface UmbWorkspaceContextInterface { - host: UmbControllerHostInterface; - repository: any; // TODO: add type - isNew: Observable; - getIsNew(): boolean; - setIsNew(value: boolean): void; - getEntityType(): string; - getData(): T; - destroy(): void; - // TODO: temp solution to bubble validation errors to the UI - setValidationErrors?(errorMap: any): void; -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-context.ts index 66c5cbab0c..9d6b905264 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-context.ts @@ -1,23 +1,27 @@ -import { UmbContextProviderController } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { DeepState } from '@umbraco-cms/observable-api'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import { UmbContextProviderController, UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { DeepState } from '@umbraco-cms/backoffice/observable-api'; +import type { BaseEntity } from '@umbraco-cms/backoffice/models'; /* TODO: We need to figure out if we like to keep using same alias for all workspace contexts. If so we need to align on a interface that all of these implements. otherwise consumers cant trust the workspace-context. */ -export abstract class UmbWorkspaceContext { - public host: UmbControllerHostInterface; +export abstract class UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface +{ + public host: UmbControllerHostElement; public repository: T; #isNew = new DeepState(false); isNew = this.#isNew.asObservable(); - constructor(host: UmbControllerHostInterface, repository: T) { + constructor(host: UmbControllerHostElement, repository: T) { this.host = host; this.repository = repository; - new UmbContextProviderController(host, 'umbWorkspaceContext', this); + new UmbContextProviderController(host, UMB_ENTITY_WORKSPACE_CONTEXT, this); } getIsNew() { @@ -27,4 +31,10 @@ export abstract class UmbWorkspaceContext { setIsNew(isNew: boolean) { this.#isNew.next(isNew); } + + abstract getEntityId(): string | undefined; // COnsider if this should go away now that we have getUnique() + abstract getEntityType(): string; // TODO: consider of this should be on the repository because a repo is responsible for one entity type + abstract getData(): EntityType | undefined; + abstract save(): Promise; + abstract destroy(): void; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-entity-context.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-entity-context.interface.ts deleted file mode 100644 index cc11f9ff1c..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-entity-context.interface.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Observable } from 'rxjs'; -import type { UmbWorkspaceContextInterface } from './workspace-context.interface'; - -export interface UmbWorkspaceEntityContextInterface extends UmbWorkspaceContextInterface { - getEntityKey(): string | undefined; // COnsider if this should go away now that we have getUnique() - getEntityType(): string; - getData(): T; - save(): Promise; -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-invariantable-entity-context.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-invariantable-entity-context.interface.ts index 85bfff1251..f3034504ab 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-invariantable-entity-context.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-invariantable-entity-context.interface.ts @@ -1,13 +1,13 @@ import type { Observable } from 'rxjs'; -import type { UmbWorkspaceEntityContextInterface } from './workspace-entity-context.interface'; -import type { ValueViewModelBaseModel } from '@umbraco-cms/backend-api'; +import type { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { ValueModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; export interface UmbWorkspaceInvariantableEntityContextInterface - extends UmbWorkspaceEntityContextInterface { + extends UmbEntityWorkspaceContextInterface { getName(): void; setName(name: string): void; - propertyDataByAlias(alias: string): Observable; + propertyDataByAlias(alias: string): Observable; propertyValueByAlias(alias: string): Observable; getPropertyValue(alias: string): void; setPropertyValue(alias: string, value: unknown): void; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-property-structure-helper.class.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-property-structure-helper.class.ts new file mode 100644 index 0000000000..6941cd3daa --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-property-structure-helper.class.ts @@ -0,0 +1,114 @@ +import { UmbDocumentWorkspaceContext } from '../../../../documents/documents/workspace/document-workspace.context'; +import { PropertyContainerTypes } from './workspace-structure-manager.class'; +import { DocumentTypePropertyTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController, UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; + +export class UmbWorkspacePropertyStructureHelper { + #host: UmbControllerHostElement; + + #workspaceContext?: UmbDocumentWorkspaceContext; + + private _containerType?: PropertyContainerTypes; + private _isRoot?: boolean; + private _containerName?: string; + + #propertyStructure = new ArrayState([], (x) => x.id); + readonly propertyStructure = this.#propertyStructure.asObservable(); + + constructor(host: UmbControllerHostElement) { + this.#host = host; + new UmbContextConsumerController(host, UMB_ENTITY_WORKSPACE_CONTEXT, (context) => { + this.#workspaceContext = context as UmbDocumentWorkspaceContext; + this._observeGroupContainers(); + }); + } + + public setContainerType(value?: PropertyContainerTypes) { + if (this._containerType === value) return; + this._containerType = value; + this._observeGroupContainers(); + } + public getContainerType() { + return this._containerType; + } + + public setContainerName(value?: string) { + if (this._containerName === value) return; + this._containerName = value; + this._observeGroupContainers(); + } + public getContainerName() { + return this._containerName; + } + + public setIsRoot(value: boolean) { + if (this._isRoot === value) return; + this._isRoot = value; + this._observeGroupContainers(); + } + public getIsRoot() { + return this._isRoot; + } + + private _observeGroupContainers() { + if (!this.#workspaceContext || !this._containerType) return; + + if (this._isRoot === true) { + this._observePropertyStructureOf(null); + } else if (this._containerName !== undefined) { + new UmbObserverController( + this.#host, + this.#workspaceContext!.structure.containersByNameAndType(this._containerName, this._containerType), + (groupContainers) => { + groupContainers.forEach((group) => this._observePropertyStructureOf(group.id)); + }, + '_observeGroupContainers' + ); + } + } + + private _observePropertyStructureOf(groupId?: string | null) { + if (!this.#workspaceContext || groupId === undefined) return; + + new UmbObserverController( + this.#host, + this.#workspaceContext.structure.propertyStructuresOf(groupId), + (properties) => { + // If this need to be able to remove properties, we need to clean out the ones of this group.id before inserting them: + const _propertyStructure = this.#propertyStructure.getValue().filter((x) => x.containerId !== groupId); + + properties?.forEach((property) => { + if (!_propertyStructure.find((x) => x.alias === property.alias)) { + _propertyStructure.push(property); + } + }); + + if (_propertyStructure.length > 0) { + // TODO: End-point: Missing sort order? + //_propertyStructure = _propertyStructure.sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)); + } + + // Fire update to subscribers: + this.#propertyStructure.next(_propertyStructure); + }, + '_observePropertyStructureOfGroup' + groupId + ); + } + + /** Manipulate methods: */ + + async addProperty(ownerKey?: string, sortOrder?: number) { + if (!this.#workspaceContext) return; + + return await this.#workspaceContext.structure.createProperty(null, ownerKey, sortOrder); + } + + // Takes optional arguments as this is easier for the implementation in the view: + async partialUpdateProperty(propertyKey?: string, partialUpdate?: Partial) { + if (!this.#workspaceContext || !propertyKey || !partialUpdate) return; + + return await this.#workspaceContext.structure.updateProperty(null, propertyKey, partialUpdate); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-property-structure-manager.class.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-property-structure-manager.class.ts deleted file mode 100644 index 96a9c72b21..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-property-structure-manager.class.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { UmbDocumentTypeRepository } from '../../../../documents/document-types/repository/document-type.repository'; -import { - DocumentTypeModel, - DocumentTypePropertyTypeModel, - PropertyTypeContainerViewModelBaseModel, -} from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState, UmbObserverController } from '@umbraco-cms/observable-api'; - -export type PropertyContainerTypes = 'Group' | 'Tab'; - -// TODO: get this type from the repository, or use some generic type. -type T = DocumentTypeModel; - -// TODO: make general interface for NodeTypeRepository, to replace UmbDocumentTypeRepository: -export class UmbWorkspacePropertyStructureManager { - #host: UmbControllerHostInterface; - - #documentTypeRepository: R; - - #documentTypes = new ArrayState([], (x) => x.key); - - #containers = new ArrayState([], (x) => x.key); - - constructor(host: UmbControllerHostInterface, typeRepository: R) { - this.#host = host; - this.#documentTypeRepository = typeRepository; - } - - /** - * loadType will load the node type and all inherited and composed types. - * This will give us all the structure for properties and containers. - */ - public async loadType(key?: string) { - // TODO: I guess it would make sense to clean up, in this case we most likely don't need any of the old document types: - //this.#documentTypes.next([]); - await this._loadType(key); - } - - private async _loadType(key?: string) { - if (!key) return; - - const { data } = await this.#documentTypeRepository.requestByKey(key); - if (!data) return; - - // Load inherited and composed types: - await data?.compositions?.forEach(async (composition) => { - if (composition.key) { - this.loadType(composition.key); - } - }); - - new UmbObserverController(this.#host, await this.#documentTypeRepository.byKey(key), (docType) => { - if (docType) { - this.#documentTypes.appendOne(docType); - this._initDocumentTypeContainers(docType); - this._loadDocumentTypeCompositions(docType); - } - }); - } - - private async _loadDocumentTypeCompositions(documentType: T) { - documentType.compositions?.forEach((composition) => { - this._loadType(composition.key); - }); - } - - private async _initDocumentTypeContainers(documentType: T) { - documentType.containers?.forEach((container) => { - this.#containers.appendOne(container); - }); - } - - hasPropertyStructuresOf(containerKey: string | null) { - return this.#documentTypes.getObservablePart((docTypes) => { - return ( - docTypes.find((docType) => { - return docType.properties?.find((property) => property.containerKey === containerKey); - }) !== undefined - ); - }); - } - rootPropertyStructures() { - return this.propertyStructuresOf(null); - } - propertyStructuresOf(containerKey: string | null) { - return this.#documentTypes.getObservablePart((docTypes) => { - const props: DocumentTypePropertyTypeModel[] = []; - docTypes.forEach((docType) => { - docType.properties?.forEach((property) => { - if (property.containerKey === containerKey) { - props.push(property); - } - }); - }); - return props; - }); - } - - rootContainers(containerType: PropertyContainerTypes) { - return this.#containers.getObservablePart((data) => { - return data.filter((x) => x.parentKey === null && x.type === containerType); - }); - } - - hasRootContainers(containerType: PropertyContainerTypes) { - return this.#containers.getObservablePart((data) => { - return data.filter((x) => x.parentKey === null && x.type === containerType).length > 0; - }); - } - - containersOfParentKey( - parentKey: PropertyTypeContainerViewModelBaseModel['parentKey'], - containerType: PropertyContainerTypes - ) { - return this.#containers.getObservablePart((data) => { - return data.filter((x) => x.parentKey === parentKey && x.type === containerType); - }); - } - - containersByNameAndType(name: string, containerType: PropertyContainerTypes) { - return this.#containers.getObservablePart((data) => { - return data.filter((x) => x.name === name && x.type === containerType); - }); - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-split-view-manager.class.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-split-view-manager.class.ts index d0e38cab9d..3c238c96b0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-split-view-manager.class.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-split-view-manager.class.ts @@ -1,6 +1,6 @@ import { UmbVariantId } from '../../../variants/variant-id.class'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState } from '@umbraco-cms/observable-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; export type ActiveVariant = { index: number; @@ -14,12 +14,12 @@ export type ActiveVariant = { * @description - Class managing the split view state for a workspace context. */ export class UmbWorkspaceSplitViewManager { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #activeVariantsInfo = new ArrayState([], (x) => x.index); public readonly activeVariantsInfo = this.#activeVariantsInfo.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-structure-manager.class.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-structure-manager.class.ts new file mode 100644 index 0000000000..8a7b24dc23 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-structure-manager.class.ts @@ -0,0 +1,310 @@ +import { UmbDocumentTypeRepository } from '../../../../documents/document-types/repository/document-type.repository'; +import { generateGuid } from '@umbraco-cms/backoffice/utils'; +import { + DocumentTypeResponseModel, + DocumentTypePropertyTypeResponseModel, + PropertyTypeContainerResponseModelBaseModel, + ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel, + PropertyTypeResponseModelBaseModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement, UmbControllerInterface } from '@umbraco-cms/backoffice/controller'; +import { + ArrayState, + UmbObserverController, + MappingFunction, + partialUpdateFrozenArray, +} from '@umbraco-cms/backoffice/observable-api'; + +export type PropertyContainerTypes = 'Group' | 'Tab'; + +// TODO: get this type from the repository, or use some generic type. +type T = DocumentTypeResponseModel; + +// TODO: make general interface for NodeTypeRepository, to replace UmbDocumentTypeRepository: +export class UmbWorkspacePropertyStructureManager { + #host: UmbControllerHostElement; + #init!: Promise; + + #documentTypeRepository: R; + + #rootDocumentTypeKey?: string; + #documentTypeObservers = new Array(); + #documentTypes = new ArrayState([], (x) => x.id); + readonly documentTypes = this.#documentTypes.asObservable(); + private readonly _documentTypeContainers = this.#documentTypes.getObservablePart((x) => + x.flatMap((x) => x.containers ?? []) + ); + + #containers = new ArrayState([], (x) => x.id); + + constructor(host: UmbControllerHostElement, typeRepository: R) { + this.#host = host; + this.#documentTypeRepository = typeRepository; + + new UmbObserverController(host, this.documentTypes, (documentTypes) => { + documentTypes.forEach((documentType) => { + // We could cache by docType Key? + // TODO: how do we ensure a container goes away? + + //this._initDocumentTypeContainers(documentType); + this._loadDocumentTypeCompositions(documentType); + }); + }); + new UmbObserverController(host, this._documentTypeContainers, (documentTypeContainers) => { + this.#containers.next(documentTypeContainers); + }); + } + + /** + * loadType will load the node type and all inherited and composed types. + * This will give us all the structure for properties and containers. + */ + public async loadType(id?: string) { + this._reset(); + + this.#rootDocumentTypeKey = id; + + const promiseResult = this._loadType(id); + this.#init = promiseResult; + await this.#init; + return promiseResult; + } + + public async createScaffold(parentId: string) { + this._reset(); + + if (!parentId) return {}; + + const { data } = await this.#documentTypeRepository.createScaffold(parentId); + if (!data) return {}; + + this.#rootDocumentTypeKey = data.id; + + this.#init = this._observeDocumentType(data); + await this.#init; + return { data }; + } + + private async _ensureType(id?: string) { + if (!id) return; + if (this.#documentTypes.getValue().find((x) => x.id === id)) return; + await this._loadType(id); + } + + private async _loadType(id?: string) { + if (!id) return {}; + + const { data } = await this.#documentTypeRepository.requestById(id); + if (!data) return {}; + + await this._observeDocumentType(data); + return { data }; + } + + public async _observeDocumentType( + data: ContentTypeResponseModelBaseDocumentTypePropertyTypeResponseModelDocumentTypePropertyTypeContainerResponseModel + ) { + if (!data.id) return; + + // Load inherited and composed types: + this._loadDocumentTypeCompositions(data); + + this.#documentTypeObservers.push( + new UmbObserverController(this.#host, await this.#documentTypeRepository.byId(data.id), (docType) => { + if (docType) { + // TODO: Handle if there was changes made to the specific document type in this context. + /* + possible easy solutions could be to notify user wether they want to update(Discard the changes to accept the new ones). + */ + this.#documentTypes.appendOne(docType); + } + }) + ); + } + + private async _loadDocumentTypeCompositions(documentType: T) { + documentType.compositions?.forEach((composition) => { + this._ensureType(composition.id); + }); + } + + /* + private async _initDocumentTypeContainers(documentType: T) { + documentType.containers?.forEach((container) => { + this.#containers.appendOne({ ...container, _ownerDocumentTypeKey: documentType.id }); + }); + } + */ + + /** Public methods for consuming structure: */ + + rootDocumentType() { + return this.#documentTypes.getObservablePart((x) => x.find((y) => y.id === this.#rootDocumentTypeKey)); + } + getRootDocumentType() { + return this.#documentTypes.getValue().find((y) => y.id === this.#rootDocumentTypeKey); + } + updateRootDocumentType(entry: T) { + this.#documentTypes.updateOne(this.#rootDocumentTypeKey, entry); + } + + // We could move the actions to another class? + + async createContainer( + documentTypeKey: string | null, + parentId: string | null = null, + type: PropertyContainerTypes = 'Group', + sortOrder?: number + ) { + await this.#init; + documentTypeKey = documentTypeKey ?? this.#rootDocumentTypeKey!; + + const container: PropertyTypeContainerResponseModelBaseModel = { + id: generateGuid(), + parentId: parentId, + name: 'New', + type: type, + sortOrder: sortOrder ?? 0, + }; + + const containers = [...(this.#documentTypes.getValue().find((x) => x.id === documentTypeKey)?.containers ?? [])]; + containers.push(container); + + this.#documentTypes.updateOne(documentTypeKey, { containers }); + + return container; + } + + async removeContainer(documentTypeKey: string | null, containerId: string | null = null) { + await this.#init; + documentTypeKey = documentTypeKey ?? this.#rootDocumentTypeKey!; + + const frozenContainers = this.#documentTypes.getValue().find((x) => x.id === documentTypeKey)?.containers ?? []; + const containers = frozenContainers.filter((x) => x.id !== containerId); + + this.#documentTypes.updateOne(documentTypeKey, { containers }); + } + + async createProperty(documentTypeKey: string | null, containerId: string | null = null, sortOrder?: number) { + await this.#init; + documentTypeKey = documentTypeKey ?? this.#rootDocumentTypeKey!; + + const property: PropertyTypeResponseModelBaseModel = { + id: generateGuid(), + containerId: containerId, + //sortOrder: sortOrder ?? 0, + }; + + const properties = [...(this.#documentTypes.getValue().find((x) => x.id === documentTypeKey)?.properties ?? [])]; + properties.push(property); + + this.#documentTypes.updateOne(documentTypeKey, { properties }); + + return property; + } + + async updateProperty( + documentTypeKey: string | null, + propertyKey: string, + partialUpdate: Partial + ) { + await this.#init; + documentTypeKey = documentTypeKey ?? this.#rootDocumentTypeKey!; + + const frozenProperties = this.#documentTypes.getValue().find((x) => x.id === documentTypeKey)?.properties ?? []; + + const properties = partialUpdateFrozenArray(frozenProperties, partialUpdate, (x) => x.id === propertyKey!); + + this.#documentTypes.updateOne(documentTypeKey, { properties }); + } + + /* + rootDocumentTypeName() { + return this.#documentTypes.getObservablePart((docTypes) => { + const docType = docTypes.find((x) => x.id === this.#rootDocumentTypeKey); + return docType?.name ?? ''; + }); + } + */ + + rootDocumentTypeObservablePart(mappingFunction: MappingFunction) { + return this.#documentTypes.getObservablePart((docTypes) => { + const docType = docTypes.find((x) => x.id === this.#rootDocumentTypeKey); + return docType ? mappingFunction(docType) : undefined; + }); + } + /* + nameOfDocumentType(id: string) { + return this.#documentTypes.getObservablePart((docTypes) => { + const docType = docTypes.find((x) => x.id === id); + return docType?.name ?? ''; + }); + } + */ + + hasPropertyStructuresOf(containerId: string | null) { + return this.#documentTypes.getObservablePart((docTypes) => { + return ( + docTypes.find((docType) => { + return docType.properties?.find((property) => property.containerId === containerId); + }) !== undefined + ); + }); + } + rootPropertyStructures() { + return this.propertyStructuresOf(null); + } + propertyStructuresOf(containerId: string | null) { + return this.#documentTypes.getObservablePart((docTypes) => { + const props: DocumentTypePropertyTypeResponseModel[] = []; + docTypes.forEach((docType) => { + docType.properties?.forEach((property) => { + if (property.containerId === containerId) { + props.push(property); + } + }); + }); + return props; + }); + } + + rootContainers(containerType: PropertyContainerTypes) { + return this.#containers.getObservablePart((data) => { + return data.filter((x) => x.parentId === null && x.type === containerType); + }); + } + + hasRootContainers(containerType: PropertyContainerTypes) { + return this.#containers.getObservablePart((data) => { + return data.filter((x) => x.parentId === null && x.type === containerType).length > 0; + }); + } + + containersOfParentKey( + parentId: PropertyTypeContainerResponseModelBaseModel['parentId'], + containerType: PropertyContainerTypes + ) { + return this.#containers.getObservablePart((data) => { + return data.filter((x) => x.parentId === parentId && x.type === containerType); + }); + } + + // TODO: Maybe this must take parentId into account as well? + containersByNameAndType(name: string, containerType: PropertyContainerTypes) { + return this.#containers.getObservablePart((data) => { + return data.filter((x) => x.name === name && x.type === containerType); + }); + } + + private _reset() { + this.#documentTypeObservers.forEach((observer) => observer.destroy()); + this.#documentTypeObservers = []; + this.#documentTypes.next([]); + this.#containers.next([]); + } + public destroy() { + this._reset(); + this.#documentTypes.complete(); + this.#containers.complete(); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-variable-entity-context.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-variable-entity-context.interface.ts index 7167156eea..b46abfeed7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-variable-entity-context.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-context/workspace-variable-entity-context.interface.ts @@ -1,20 +1,20 @@ import type { Observable } from 'rxjs'; import { UmbVariantId } from '../../../variants/variant-id.class'; -import type { UmbWorkspaceEntityContextInterface } from './workspace-entity-context.interface'; import { UmbWorkspaceSplitViewManager } from './workspace-split-view-manager.class'; -import type { ValueViewModelBaseModel, VariantViewModelBaseModel } from '@umbraco-cms/backend-api'; +import type { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { ValueModelBaseModel, VariantResponseModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; -export interface UmbWorkspaceVariableEntityContextInterface extends UmbWorkspaceEntityContextInterface { - variants: Observable>; +export interface UmbWorkspaceVariableEntityContextInterface extends UmbEntityWorkspaceContextInterface { + variants: Observable>; splitView: UmbWorkspaceSplitViewManager; getName(variantId?: UmbVariantId): void; setName(name: string, variantId?: UmbVariantId): void; - getVariant(variantId: UmbVariantId): VariantViewModelBaseModel | undefined; + getVariant(variantId: UmbVariantId): VariantResponseModelBaseModel | undefined; - propertyDataByAlias(alias: string, variantId?: UmbVariantId): Observable; + propertyDataByAlias(alias: string, variantId?: UmbVariantId): Observable; propertyValueByAlias(alias: string, variantId?: UmbVariantId): Observable; getPropertyValue(alias: string, variantId?: UmbVariantId): void; setPropertyValue(alias: string, value: unknown, variantId?: UmbVariantId): void; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-entity-element.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-entity-element.interface.ts deleted file mode 100644 index f701853c32..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-entity-element.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface UmbWorkspaceEntityElement { - load(key: string): void; - create(parentKey: string | null): void; -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.element.ts index 6af6b320fa..525a5ede25 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.element.ts @@ -1,9 +1,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import type { ManifestWorkspaceAction } from '@umbraco-cms/models'; +import type { ManifestWorkspaceAction } from '@umbraco-cms/backoffice/extensions-registry'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-workspace-footer-layout @@ -16,7 +16,7 @@ import { UmbLitElement } from '@umbraco-cms/element'; */ // TODO: stop naming this something with layout. as its not just an layout. it hooks up with extensions. @customElement('umb-workspace-footer-layout') -export class UmbWorkspaceFooterLayout extends UmbLitElement { +export class UmbWorkspaceFooterLayoutElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -61,7 +61,7 @@ export class UmbWorkspaceFooterLayout extends UmbLitElement { extension.meta.workspaces.includes(this.alias)} + .filter=${(extension: ManifestWorkspaceAction) => extension.conditions.workspaces.includes(this.alias)} default-element="umb-workspace-action"> @@ -71,6 +71,6 @@ export class UmbWorkspaceFooterLayout extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-workspace-footer-layout': UmbWorkspaceFooterLayout; + 'umb-workspace-footer-layout': UmbWorkspaceFooterLayoutElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.stories.ts index b673c8b304..a37b61a21b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-footer-layout/workspace-footer-layout.stories.ts @@ -2,9 +2,9 @@ import '../workspace-layout/workspace-layout.element'; import './workspace-footer-layout.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; -import type { UmbWorkspaceFooterLayout } from './workspace-footer-layout.element'; +import type { UmbWorkspaceFooterLayoutElement } from './workspace-footer-layout.element'; export default { title: 'Workspaces/Shared/Footer Layout', @@ -12,7 +12,7 @@ export default { id: 'umb-workspace-footer-layout', } as Meta; -export const AAAOverview: Story = () => html` +export const AAAOverview: Story = () => html`
    Footer slot
    Actions slot
    `; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts index 8abacffa60..48c6859ea2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.element.ts @@ -4,18 +4,23 @@ import { customElement, property, state } from 'lit/decorators.js'; import { map } from 'rxjs'; import { repeat } from 'lit/directives/repeat.js'; -import type { UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent, IRoutingInfo } from '@umbraco-cms/router'; -import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import type { ManifestWorkspaceView, ManifestWorkspaceViewCollection } from '@umbraco-cms/models'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import type { UmbRouterSlotInitEvent, UmbRouterSlotChangeEvent } from '@umbraco-cms/internal/router'; +import { createExtensionElement, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { + ManifestWorkspaceView, + ManifestWorkspaceViewCollection, +} from '@umbraco-cms/backoffice/extensions-registry'; import '../../body-layout/body-layout.element'; import '../../extension-slot/extension-slot.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-workspace-layout * @description * @slot icon - Slot for icon + * @slot header - Slot for workspace header * @slot name - Slot for name * @slot footer - Slot for workspace footer * @slot actions - Slot for workspace footer actions @@ -26,7 +31,7 @@ import { UmbLitElement } from '@umbraco-cms/element'; */ // TODO: stop naming this something with layout. as its not just an layout. it hooks up with extensions. @customElement('umb-workspace-layout') -export class UmbWorkspaceLayout extends UmbLitElement { +export class UmbWorkspaceLayoutElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -36,6 +41,12 @@ export class UmbWorkspaceLayout extends UmbLitElement { height: 100%; } + #router-slot { + display: flex; + flex-direction: column; + height: 100%; + } + uui-input { width: 100%; } @@ -87,7 +98,7 @@ export class UmbWorkspaceLayout extends UmbLitElement { private _workspaceViews: Array = []; @state() - private _routes?: any[]; + private _routes?: IRoute[]; @state() private _routerPath?: string; @@ -99,7 +110,9 @@ export class UmbWorkspaceLayout extends UmbLitElement { this.observe( umbExtensionsRegistry .extensionsOfTypes(['workspaceView', 'workspaceViewCollection']) - .pipe(map((extensions) => extensions.filter((extension) => extension.meta.workspaces.includes(this.alias)))), + .pipe( + map((extensions) => extensions.filter((extension) => extension.conditions.workspaces.includes(this.alias))) + ), (workspaceViews) => { this._workspaceViews = workspaceViews; this._createRoutes(); @@ -118,16 +131,18 @@ export class UmbWorkspaceLayout extends UmbLitElement { if (view.type === 'workspaceViewCollection') { return import( '../../../../shared/components/workspace/workspace-content/views/collection/workspace-view-collection.element' - ); + ) as unknown as Promise; } return createExtensionElement(view); }, - setup: (component: Promise | HTMLElement, info: IRoutingInfo) => { - // When its using import, we get an element, when using createExtensionElement we get a Promise. - if ((component as any).then) { - (component as any).then((el: any) => (el.manifest = view)); + setup: (component, info) => { + if (component && 'manifest' in component) { + component.manifest = view; } else { - (component as any).manifest = view; + console.group(`[UmbWorkspaceLayout] Failed to setup component for route: ${info.match.route.path}`); + console.log('Matched route', info.match.route); + console.error('Missing property "manifest" on component', component); + console.groupEnd(); } }, }; @@ -209,6 +224,6 @@ export class UmbWorkspaceLayout extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-workspace-layout': UmbWorkspaceLayout; + 'umb-workspace-layout': UmbWorkspaceLayoutElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.stories.ts index b40e13d850..ba84a2855e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-layout/workspace-layout.stories.ts @@ -1,9 +1,9 @@ import './workspace-layout.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; -import type { UmbWorkspaceLayout } from './workspace-layout.element'; +import type { UmbWorkspaceLayoutElement } from './workspace-layout.element'; export default { title: 'Workspaces/Shared/Editor Entity Layout', @@ -11,7 +11,7 @@ export default { id: 'umb-workspace-layout', } as Meta; -export const AAAOverview: Story = () => html` +export const AAAOverview: Story = () => html`
    Icon slot
    Name slot
    Footer slot
    diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.element.ts index 5fc679c887..0363bb948b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.element.ts @@ -11,47 +11,6 @@ import { customElement, property } from 'lit/decorators.js'; */ @customElement('umb-workspace-property-layout') export class UmbWorkspacePropertyLayoutElement extends LitElement { - static styles = [ - UUITextStyles, - css` - :host { - display: grid; - grid-template-columns: 200px auto; - column-gap: var(--uui-size-layout-2); - border-bottom: 1px solid var(--uui-color-divider); - padding: var(--uui-size-space-6) 0; - container-type: inline-size; - } - - :host > div { - grid-column: span 2; - } - - @container (width > 600px) { - :host(:not([orientation='vertical'])) > div { - grid-column: span 1; - } - } - - :host(:last-of-type) { - border-bottom: none; - } - - :host-context(umb-variantable-property:first-of-type) { - padding-top:0; - } - - p { - margin-bottom: 0; - } - #header { - position: sticky; - top: var(--uui-size-space-4); - height: min-content; - } - `, - ]; - /** * Alias. The technical name of the property. * @type {string} @@ -105,6 +64,49 @@ export class UmbWorkspacePropertyLayoutElement extends LitElement {
    `; } + + static styles = [ + UUITextStyles, + css` + :host { + display: grid; + grid-template-columns: 200px auto; + column-gap: var(--uui-size-layout-2); + border-bottom: 1px solid var(--uui-color-divider); + padding: var(--uui-size-layout-1) 0; + container-type: inline-size; + } + + :host > div { + grid-column: span 2; + } + + @container (width > 600px) { + :host(:not([orientation='vertical'])) > div { + grid-column: span 1; + } + } + + :host(:last-of-type) { + border-bottom: none; + } + + :host-context(umb-variantable-property:first-of-type) { + padding-top: 0; + } + + p { + margin-bottom: 0; + } + + #header { + position: sticky; + top: var(--uui-size-space-4); + height: min-content; + z-index: 2; + } + `, + ]; } declare global { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.stories.ts index 8d3e036bd6..acc53311bd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-property-layout/workspace-property-layout.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbWorkspacePropertyLayoutElement } from './workspace-property-layout.element'; import './workspace-property-layout.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.context.ts index 9d2d06494d..0f621391b5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.context.ts @@ -2,15 +2,20 @@ import { UmbDocumentWorkspaceContext } from '../../../../documents/documents/wor import { UmbVariantId } from '../../../variants/variant-id.class'; import { UmbWorkspaceVariableEntityContextInterface } from '../workspace-context/workspace-variable-entity-context.interface'; import { ActiveVariant } from '../workspace-context/workspace-split-view-manager.class'; -import { UmbContextConsumerController, UmbContextProviderController, UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ClassState, NumberState, ObjectState, UmbObserverController } from '@umbraco-cms/observable-api'; -import { DocumentVariantModel } from '@umbraco-cms/backend-api'; +import { + UmbContextConsumerController, + UmbContextProviderController, + UmbContextToken, + UMB_ENTITY_WORKSPACE_CONTEXT, +} from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ClassState, NumberState, ObjectState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { DocumentVariantResponseModel } from '@umbraco-cms/backoffice/backend-api'; //type EntityType = DocumentModel; export class UmbWorkspaceVariantContext { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #workspaceContext?: UmbWorkspaceVariableEntityContextInterface; public getWorkspaceContext() { @@ -20,7 +25,7 @@ export class UmbWorkspaceVariantContext { #index = new NumberState(undefined); index = this.#index.asObservable(); - #currentVariant = new ObjectState(undefined); + #currentVariant = new ObjectState(undefined); currentVariant = this.#currentVariant.asObservable(); name = this.#currentVariant.getObservablePart((x) => x?.name); @@ -32,14 +37,14 @@ export class UmbWorkspaceVariantContext { private _currentVariantObserver?: UmbObserverController; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; new UmbContextProviderController(host, UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN.toString(), this); // How do we ensure this connects to a document workspace context? and not just any other context? (We could start providing workspace contexts twice, under the general name and under a specific name) // TODO: Figure out if this is the best way to consume the context or if it can be strongly typed with an UmbContextToken - new UmbContextConsumerController(host, 'umbWorkspaceContext', (context) => { + new UmbContextConsumerController(host, UMB_ENTITY_WORKSPACE_CONTEXT, (context) => { this.#workspaceContext = context as UmbDocumentWorkspaceContext; this._observeVariant(); }); @@ -49,7 +54,7 @@ export class UmbWorkspaceVariantContext { }); } - public switchVariant(variant: DocumentVariantModel) { + public switchVariant(variant: DocumentVariantResponseModel) { const index = this.#index.value; if (index === undefined) return; this.#workspaceContext?.splitView.switchVariant(index, new UmbVariantId(variant)); @@ -61,7 +66,7 @@ export class UmbWorkspaceVariantContext { this.#workspaceContext?.splitView.closeSplitView(index); } - public openSplitView(variant: DocumentVariantModel) { + public openSplitView(variant: DocumentVariantResponseModel) { this.#workspaceContext?.splitView.openSplitView(new UmbVariantId(variant)); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.element.ts index 1bf14943c6..be15f2a2c5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace-variant/workspace-variant.element.ts @@ -3,11 +3,12 @@ import { css, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import '../workspace-layout/workspace-layout.element'; +import '../../../../shared/components/variant-selector/variant-selector.element.ts'; // Lazy load // TODO: Make this dynamic, use load-extensions method to loop over extensions for this node. import { UmbWorkspaceVariantContext } from './workspace-variant.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace.element.ts new file mode 100644 index 0000000000..739193c890 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/components/workspace/workspace.element.ts @@ -0,0 +1,28 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html, nothing } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { ManifestWorkspace } from '@umbraco-cms/backoffice/extensions-registry'; + +@customElement('umb-workspace') +export class UmbWorkspaceElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + @property({ type: String, attribute: 'entity-type' }) + entityType = ''; + + render() { + if (!this.entityType) nothing; + return html` manifest.meta.entityType === this.entityType}>`; + } +} + +export default UmbWorkspaceElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-workspace': UmbWorkspaceElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/index.ts index f308f04e5b..758856fe7c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/index.ts @@ -1,17 +1,15 @@ import { manifests as componentManifests } from './components'; import { manifests as propertyActionManifests } from './property-actions/manifests'; import { manifests as propertyEditorManifests } from './property-editors/manifests'; -import { manifests as collectionViewManifests } from './collection/views/manifests'; import { manifests as modalManifests } from './modals/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [ ...componentManifests, ...propertyActionManifests, ...propertyEditorManifests, - ...collectionViewManifests, ...modalManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.element.ts index fb8f4cc781..f710783f81 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.element.ts @@ -1,9 +1,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbConfirmModalData, UmbConfirmModalResult } from '.'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbModalHandler } from '@umbraco-cms/modal'; +import { UmbConfirmModalData, UmbConfirmModalResult, UmbModalHandler } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-confirm-modal') export class UmbConfirmModalElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.stories.ts index 8a33def986..790bc96c46 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/confirm/confirm-modal.stories.ts @@ -4,7 +4,7 @@ import { Meta, Story } from '@storybook/web-components'; import { html } from 'lit'; import type { UmbConfirmModalElement } from './confirm-modal.element'; -import type { UmbConfirmModalData } from './'; +import type { UmbConfirmModalData } from '@umbraco-cms/backoffice/modal'; export default { title: 'API/Modals/Layouts/Confirm', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/embedded-media/embedded-media-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/embedded-media/embedded-media-modal.element.ts new file mode 100644 index 0000000000..6f38cc48dc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/embedded-media/embedded-media-modal.element.ts @@ -0,0 +1,277 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, state } from 'lit/decorators.js'; +import { when } from 'lit-html/directives/when.js'; +import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'; +import { + OEmbedResult, + OEmbedStatus, + UmbEmbeddedMediaModalData, + UmbEmbeddedMediaModalResult, + UmbModalHandler, +} from '@umbraco-cms/backoffice/modal'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +interface UmbEmbeddedMediaModalModel { + url?: string; + info?: string; + a11yInfo?: string; + originalWidth: number; + originalHeight: number; + width: number; + height: number; + constrain: boolean; +} + +@customElement('umb-embedded-media-modal') +export class UmbEmbeddedMediaModalElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + h3 { + margin-left: var(--uui-size-space-5); + margin-right: var(--uui-size-space-5); + } + + uui-input { + width: 100%; + --uui-button-border-radius: 0; + } + + .sr-only { + clip: rect(0, 0, 0, 0); + border: 0; + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; + } + + umb-workspace-property-layout:first-child { + padding-top: 0; + } + + umb-workspace-property-layout:last-child { + padding-bottom: 0; + } + + p { + margin-bottom: 0; + } + `, + ]; + + #loading = false; + #embedResult!: OEmbedResult; + + @property({ attribute: false }) + modalHandler?: UmbModalHandler; + + @property({ type: Object }) + data?: UmbEmbeddedMediaModalData; + + #handleConfirm() { + this.modalHandler?.submit({ selection: this.#embedResult }); + } + + #handleCancel() { + this.modalHandler?.reject(); + } + + @state() + private _model: UmbEmbeddedMediaModalModel = { + url: '', + width: 360, + height: 240, + constrain: true, + info: '', + a11yInfo: '', + originalHeight: 240, + originalWidth: 360, + }; + + connectedCallback() { + super.connectedCallback(); + if (this.data?.url) { + Object.assign(this._model, this.data); + this.#getPreview(); + } + } + + async #getPreview() { + this._model.info = ''; + this._model.a11yInfo = ''; + + this.#loading = true; + this.requestUpdate('_model'); + + try { + // TODO => use backend cli when available + const result = await fetch( + umbracoPath('/rteembed?') + + new URLSearchParams({ + url: this._model.url, + width: this._model.width?.toString(), + height: this._model.height?.toString(), + } as { [key: string]: string }) + ); + + this.#embedResult = await result.json(); + + switch (this.#embedResult.oEmbedStatus) { + case 0: + this.#onPreviewFailed('Not supported'); + break; + case 1: + this.#onPreviewFailed('Could not embed media - please ensure the URL is valid'); + break; + case 2: + this._model.info = ''; + this._model.a11yInfo = 'Retrieved URL'; + break; + } + } catch (e) { + this.#onPreviewFailed('Could not embed media - please ensure the URL is valid'); + } + + this.#loading = false; + this.requestUpdate('_model'); + } + + #onPreviewFailed(message: string) { + this._model.info = message; + this._model.a11yInfo = message; + } + + #onUrlChange(e: InputEvent) { + this._model.url = (e.target as HTMLInputElement).value; + this.requestUpdate('_model'); + } + + #onWidthChange(e: InputEvent) { + this._model.width = parseInt((e.target as HTMLInputElement).value, 10); + this.#changeSize('width'); + } + + #onHeightChange(e: InputEvent) { + this._model.height = parseInt((e.target as HTMLInputElement).value, 10); + this.#changeSize('height'); + } + + /** + * Calculates the width or height axis dimension when the other is changed. + * If constrain is false, axis change independently + * @param axis {string} + */ + #changeSize(axis: 'width' | 'height') { + const resize = this._model.originalWidth !== this._model.width || this._model.originalHeight !== this._model.height; + + if (this._model.constrain) { + if (axis === 'width') { + this._model.height = Math.round((this._model.width / this._model.originalWidth) * this._model.height); + } else { + this._model.width = Math.round((this._model.height / this._model.originalHeight) * this._model.width); + } + } + + this._model.originalWidth = this._model.width; + this._model.originalHeight = this._model.height; + + if (this._model.url !== '' && resize) { + this.#getPreview(); + } + } + + #onConstrainChange() { + this._model.constrain = !this._model.constrain; + } + + /** + * If the embed does not support dimensions, or was not requested successfully + * the width, height and constrain controls are disabled + * @returns {boolean} + */ + #dimensionControlsDisabled() { + return !this.#embedResult?.supportsDimensions || this.#embedResult?.oEmbedStatus !== OEmbedStatus.Success; + } + + render() { + return html` + + + +
    + + + +
    +
    + + ${when( + this.#embedResult?.oEmbedStatus === OEmbedStatus.Success || this._model.a11yInfo, + () => html` +
    + ${when(this.#loading, () => html``)} + ${when(this.#embedResult.markup, () => html`${unsafeHTML(this.#embedResult.markup)}`)} + ${when(this._model.info, () => html` `)} + ${when(this._model.a11yInfo, () => html` `)} +
    +
    ` + )} + + + + + + + + + + + + +
    + + Cancel + +
    + `; + } +} + +export default UmbEmbeddedMediaModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-embedded-media-modal': UmbEmbeddedMediaModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/embedded-media/embedded-media-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/embedded-media/embedded-media-modal.stories.ts new file mode 100644 index 0000000000..2638f0142c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/embedded-media/embedded-media-modal.stories.ts @@ -0,0 +1,26 @@ +import '../../components/body-layout/body-layout.element'; +import './embedded-media-modal.element'; + +import { Meta } from '@storybook/web-components'; +import { html } from 'lit'; +import { UmbEmbeddedMediaModalData } from '@umbraco-cms/backoffice/modal'; + +export default { + title: 'API/Modals/Layouts/Embedded Media', + component: 'umb-embedded-media-modal', + id: 'umb-embedded-media-modal', +} as Meta; + +const data: UmbEmbeddedMediaModalData = { + url: 'https://youtu.be/wJNbtYdr-Hg', + width: 360, + height: 240, + constrain: true, +}; + +export const Overview = () => html` + + +`; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/folder/folder-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/folder/folder-modal.element.ts new file mode 100644 index 0000000000..eb9986ff11 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/folder/folder-modal.element.ts @@ -0,0 +1,177 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property, query, state } from 'lit/decorators.js'; +import { UmbFolderModalData, UmbFolderModalResult, UmbModalHandler } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbFolderRepository } from '@umbraco-cms/backoffice/repository'; +import { createExtensionClass, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { FolderReponseModel, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { ManifestBase } from '@umbraco-cms/backoffice/extensions-registry'; + +@customElement('umb-folder-modal') +export class UmbFolderModalElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + #name { + width: 100%; + } + `, + ]; + + @property({ attribute: false }) + modalHandler?: UmbModalHandler; + + private _data?: UmbFolderModalData; + @property({ type: Object, attribute: false }) + public get data() { + return this._data; + } + public set data(value: UmbFolderModalData | undefined) { + this._data = value; + this.#unique = value?.unique || null; + this.#repositoryAlias = value?.repositoryAlias; + this.#observeRepository(); + } + + #repositoryAlias?: string; + #unique: string | null = null; + #repository?: UmbFolderRepository; + #repositoryObserver?: UmbObserverController; + + @state() + _folder?: FolderReponseModel; + + @state() + _headline?: string; + + @state() + _isNew = false; + + #observeRepository() { + this.#repositoryObserver?.destroy(); + if (!this.#repositoryAlias) return; + this.#repositoryObserver = this.observe( + umbExtensionsRegistry.getByTypeAndAlias('repository', this.#repositoryAlias), + async (repositoryManifest) => { + if (!repositoryManifest) return; + + try { + const result = await createExtensionClass(repositoryManifest, [this]); + this.#repository = result; + this.#init(); + } catch (error) { + throw new Error('Could not create repository with alias: ' + this.#repositoryAlias + ''); + } + } + ); + } + + // TODO: so I ended up building a full workspace in the end. We should look into building the real workspace folder editor + // and see if we can use that in this modal instead of this custom logic. + #init() { + if (this.#unique) { + this.#load(); + } else { + this.#create(); + } + } + + async #create() { + if (!this.#repository) throw new Error('Repository is required to create folder'); + const { data } = await this.#repository.createFolderScaffold(this.#unique); + this._folder = data; + this._isNew = true; + } + + async #load() { + if (!this.#unique) throw new Error('Unique is required to load folder'); + if (!this.#repository) throw new Error('Repository is required to create folder'); + const { data } = await this.#repository.requestFolder(this.#unique); + this._folder = data; + this._isNew = false; + } + + @query('#dataTypeFolderForm') + private _formElement?: HTMLFormElement; + + #onCancel() { + this.modalHandler?.reject(); + } + + #submitForm() { + this._formElement?.requestSubmit(); + } + + async #onSubmit(event: SubmitEvent) { + event.preventDefault(); + if (!this._folder) throw new Error('Folder is not initialized correctly'); + if (!this.#repository) throw new Error('Repository is required to create folder'); + + const isValid = this._formElement?.checkValidity(); + if (!isValid) return; + + let error: ProblemDetailsModel | undefined; + + const formData = new FormData(this._formElement); + const folderName = formData.get('name') as string; + + this._folder = { ...this._folder, name: folderName }; + + if (this._isNew) { + const { error: createError } = await this.#repository.createFolder(this._folder); + error = createError; + } else { + if (!this.#unique) throw new Error('Unique is required to update folder'); + const { error: updateError } = await this.#repository.updateFolder(this.#unique, this._folder); + error = updateError; + } + + if (!error) { + this.modalHandler?.submit(); + } + } + + render() { + return html` + + + +
    + + Folder name + + +
    +
    +
    + + + +
    + `; + } +} + +export default UmbFolderModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-folder-modal': UmbFolderModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.element.ts index a7de5856ed..ff0cab31b1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.element.ts @@ -6,8 +6,8 @@ import { customElement, property, state } from 'lit/decorators.js'; import { styleMap } from 'lit/directives/style-map.js'; import icons from '../../../../../public-assets/icons/icons.json'; -import { UmbIconPickerModalData, UmbIconPickerModalResult } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { UmbIconPickerModalData, UmbIconPickerModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; // TODO: Make use of UmbPickerLayoutBase // TODO: to prevent element extension we need to move the Picker logic into a separate class we can reuse across all pickers diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.stories.ts index 2facbfb42a..53ee8a5bdb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.stories.ts @@ -5,7 +5,7 @@ import { Meta, Story } from '@storybook/web-components'; import { html } from 'lit'; import type { UmbIconPickerModalElement } from './icon-picker-modal.element'; -import { UmbIconPickerModalData } from '.'; +import { UmbIconPickerModalData } from '@umbraco-cms/backoffice/modal'; export default { title: 'API/Modals/Layouts/Icon Picker', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.test.ts index 6831f4a0c9..9b226ca627 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/icon-picker/icon-picker-modal.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbIconPickerModalElement } from './icon-picker-modal.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('umb-icon-picker-modal', () => { let element: UmbIconPickerModalElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/link-picker/link-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/link-picker/link-picker-modal.element.ts index 73b31ccc82..7325caf339 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/link-picker/link-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/link-picker/link-picker-modal.element.ts @@ -3,9 +3,14 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, query, state } from 'lit/decorators.js'; import { UUIBooleanInputEvent, UUIInputElement } from '@umbraco-ui/uui'; import { UmbTreeElement } from '../../components/tree/tree.element'; -import { UmbLinkPickerConfig, UmbLinkPickerLink, UmbLinkPickerModalData, UmbLinkPickerModalResult } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; -import { buildUdi, getKeyFromUdi } from '@umbraco-cms/utils'; +import { + UmbLinkPickerConfig, + UmbLinkPickerLink, + UmbLinkPickerModalData, + UmbLinkPickerModalResult, +} from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; +import { buildUdi, getKeyFromUdi } from '@umbraco-cms/backoffice/utils'; @customElement('umb-link-picker-modal') export class UmbLinkPickerModalElement extends UmbModalBaseElement { @@ -46,6 +51,9 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement = [ { @@ -7,6 +7,12 @@ const modals: Array = [ name: 'Confirm Modal', loader: () => import('./confirm/confirm-modal.element'), }, + { + type: 'modal', + alias: 'Umb.Modal.Folder', + name: 'Folder Modal', + loader: () => import('./folder/folder-modal.element'), + }, { type: 'modal', alias: 'Umb.Modal.IconPicker', @@ -31,6 +37,24 @@ const modals: Array = [ name: 'Section Picker Modal', loader: () => import('./section-picker/section-picker-modal.element'), }, + { + type: 'modal', + alias: 'Umb.Modal.TemplatePicker', + name: 'Template Picker Modal', + loader: () => import('./template-picker/template-picker-modal.element'), + }, + { + type: 'modal', + alias: 'Umb.Modal.Template', + name: 'Template Modal', + loader: () => import('./template/template-modal.element'), + }, + { + type: 'modal', + alias: 'Umb.Modal.EmbeddedMedia', + name: 'Embedded Media Modal', + loader: () => import('./embedded-media/embedded-media-modal.element'), + }, ]; export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/property-settings/property-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/property-settings/property-settings-modal.element.ts index 9aa4b3f305..c57165fe42 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/property-settings/property-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/property-settings/property-settings-modal.element.ts @@ -2,14 +2,18 @@ import { UUIBooleanInputEvent, UUIInputEvent, UUISelectEvent } from '@umbraco-ui import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UMB_PROPERTY_EDITOR_UI_PICKER_MODAL_TOKEN } from '../../property-editors/modals/property-editor-ui-picker'; -import { UmbPropertySettingsModalResult } from '.'; -import { UmbModalContext, UmbModalBaseElement, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { ManifestPropertyEditorUI } from '@umbraco-cms/extensions-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_PROPERTY_EDITOR_UI_PICKER_MODAL, + UmbPropertySettingsModalResult, +} from '@umbraco-cms/backoffice/modal'; +import { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; @customElement('umb-property-settings-modal') -export class UmbPropertySettingsModalElement extends UmbModalBaseElement { +export class UmbPropertySettingsModalElement extends UmbModalBaseElement { static styles = [ UUITextStyles, css` @@ -17,11 +21,11 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement('Umb.Modal.SectionPicker', { - type: 'sidebar', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker-modal.element.ts index 6bef6233da..3200aef2b3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker-modal.element.ts @@ -1,9 +1,9 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbModalElementPickerBase } from '@umbraco-cms/modal'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import type { ManifestSection } from '@umbraco-cms/models'; +import { UmbModalElementPickerBase } from '@umbraco-cms/internal/modal'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { ManifestSection } from '@umbraco-cms/backoffice/extensions-registry'; @customElement('umb-section-picker-modal') export class UmbSectionPickerModalElement extends UmbModalElementPickerBase { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker.test.ts index eb7318065a..7ade1e4f09 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/section-picker/section-picker.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import { UmbPickerLayoutSectionElement } from './picker-layout-section.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbPickerLayoutSectionElement', () => { // let element: UmbPickerLayoutSectionElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/template-picker/template-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/template-picker/template-picker-modal.element.ts new file mode 100644 index 0000000000..ef63b2064b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/template-picker/template-picker-modal.element.ts @@ -0,0 +1,105 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbTreeElement } from '../../components/tree/tree.element'; +import { UmbTemplatePickerModalData, UmbTemplatePickerModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; + +//TODO: make a default tree-picker that can be used across multiple pickers +// TODO: make use of UmbPickerLayoutBase +@customElement('umb-template-picker-modal') +export class UmbTemplatePickerModalElement extends UmbModalBaseElement< + UmbTemplatePickerModalData, + UmbTemplatePickerModalResult +> { + @state() + _selection: Array = []; + + @state() + _multiple = true; + + connectedCallback() { + super.connectedCallback(); + this._selection = this.data?.selection ?? []; + this._multiple = this.data?.multiple ?? true; + } + + private _handleSelectionChange(e: CustomEvent) { + e.stopPropagation(); + const element = e.target as UmbTreeElement; + this._selection = this._multiple ? element.selection : [element.selection[element.selection.length - 1]]; + } + + private _submit() { + this.modalHandler?.submit({ selection: this._selection }); + } + + private _close() { + this.modalHandler?.reject(); + } + + // TODO: implement search + // TODO: make umb-tree have a disabled option (string array like selection)? + render() { + return html` + + + +
    + +
    +
    + + +
    +
    + `; + } + + static styles = [ + UUITextStyles, + css` + h3 { + margin-left: var(--uui-size-space-5); + margin-right: var(--uui-size-space-5); + } + + uui-input { + width: 100%; + } + + hr { + border: none; + border-bottom: 1px solid var(--uui-color-divider); + margin: 16px 0; + } + + #content-list { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-3); + } + + .content-item { + cursor: pointer; + } + + .content-item.selected { + background-color: var(--uui-color-selected); + color: var(--uui-color-selected-contrast); + } + `, + ]; +} + +export default UmbTemplatePickerModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-template-picker-modal': UmbTemplatePickerModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/template/template-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/template/template-modal.element.ts new file mode 100644 index 0000000000..f1771e6a34 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/modals/template/template-modal.element.ts @@ -0,0 +1,162 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, query, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { UUIInputEvent } from '@umbraco-ui/uui'; +import { UmbCodeEditor } from '../../components/code-editor'; +import { UmbTemplateModalData, UmbTemplateModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbInputEvent } from '@umbraco-cms/backoffice/events'; +import { TemplateResource, TemplateResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; + +//TODO: make a default tree-picker that can be used across multiple pickers +// TODO: make use of UmbPickerLayoutBase +@customElement('umb-template-modal') +export class UmbTemplateModalElement extends UmbModalBaseElement { + @state() + _id = ''; + + @state() + _template?: TemplateResponseModel; + + @query('umb-code-editor') + _codeEditor?: UmbCodeEditor; + + connectedCallback() { + super.connectedCallback(); + + if (!this.data?.id) return; + + // TODO: use the template workspace instead of a custom modal. This is still to be made available as infinite editors(Modals). + alert('This should be using the Template Workspace instead of a custom build modal.'); + this._id = this.data.id; + this.#getTemplate(); + } + + async #getTemplate() { + const { data } = await tryExecuteAndNotify(this, TemplateResource.getTemplateById({ id: this._id })); + if (!data) return; + + this._template = data; + } + + async #saveTemplate() { + const { error } = await tryExecuteAndNotify( + this, + TemplateResource.putTemplateById({ id: this._id, requestBody: this._template }) + ); + if (!error) { + console.log(`template (${this._id}) saved successfully`); + } + } + + private _submit() { + if (!this._template?.id) return; + + this.#saveTemplate(); + this.modalHandler?.submit({ id: this._template.id }); + } + + private _close() { + this.modalHandler?.reject(); + } + + #codeEditorInput(e: UmbInputEvent) { + e.stopPropagation(); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + this._template.code = this._codeEditor?.code; + } + + #templateNameInput(e: UUIInputEvent) { + if (!this._template) return; + this._template.name = e.target.value as string; + } + + render() { + return html` + +
    + +
    ${this._template?.alias}
    +
    +
    + + +
    + Master template: To be continued +
    + To be continued + To be continued + To be continued +
    +
    + +
    +
    + + +
    +
    + `; + } + + static styles = [ + UUITextStyles, + css` + uui-box { + position: relative; + display: block; + height: 100%; + margin: var(--uui-size-layout-1); + } + + #layout-header { + display: flex; + width: 100%; + align-items: center; + margin: 0 var(--uui-size-layout-1); + } + + #template-name { + align-items: center; + padding: 0 var(--uui-size-space-3); + flex-grow: 1; + } + + umb-code-editor { + position: absolute; /** Umb-code-editor has issues with height, this is the temp solution on this case */ + top: 75px; + left: 0; + bottom: 0; + width: 100%; + } + + #button-group { + display: flex; + justify-content: space-between; + } + + #secondary-group { + display: flex; + gap: var(--uui-size-space-4); + } + `, + ]; +} + +export default UmbTemplateModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-template-modal': UmbTemplateModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.element.ts index 6df5a91cc9..12357bb9e7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.element.ts @@ -1,13 +1,14 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -//import type { UmbPropertyActionMenuContext } from '../shared/property-action-menu/property-action-menu.context'; import { UmbPropertyAction } from '../shared/property-action/property-action.model'; -import type { UmbWorkspacePropertyContext } from '../../components/workspace-property/workspace-property.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { + UmbWorkspacePropertyContext, + UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, +} from '../../components/workspace-property/workspace-property.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-property-action-clear') export class UmbPropertyActionClearElement extends UmbLitElement implements UmbPropertyAction { - @property() value = ''; @@ -23,7 +24,7 @@ export class UmbPropertyActionClearElement extends UmbLitElement implements UmbP this._propertyActionMenuContext = propertyActionsContext; }); */ - this.consumeContext('umbPropertyContext', (propertyContext: UmbWorkspacePropertyContext) => { + this.consumeContext(UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, (propertyContext: UmbWorkspacePropertyContext) => { this._propertyContext = propertyContext; }); } @@ -40,7 +41,7 @@ export class UmbPropertyActionClearElement extends UmbLitElement implements UmbP //this.value = '';// This is though bad as it assumes we are dealing with a string. So wouldn't work as a generalized element. //this.dispatchEvent(new CustomEvent('property-value-change')); // Or you can do this: - this._propertyContext?.resetValue();// This resets value to what the property wants. + this._propertyContext?.resetValue(); // This resets value to what the property wants. } render() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.stories.ts index 7f3b7cf5cb..45bb332668 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/clear/property-action-clear.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyActionClearElement } from './property-action-clear.element'; import './property-action-clear.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.element.ts index 874c535eaf..1e7cc2136b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.element.ts @@ -5,8 +5,8 @@ import { UmbNotificationDefaultData, UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN, -} from '@umbraco-cms/notification'; -import { UmbLitElement } from '@umbraco-cms/element'; +} from '@umbraco-cms/backoffice/notification'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-property-action-copy') export class UmbPropertyActionCopyElement extends UmbLitElement implements UmbPropertyAction { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.stories.ts index 875f26e338..99c7fb230d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/copy/property-action-copy.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyActionCopyElement } from './property-action-copy.element'; import './property-action-copy.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/manifests.ts index 1b5a1b4307..372aa3b2f7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyAction } from '@umbraco-cms/models'; +import type { ManifestPropertyAction } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests: Array = [ { @@ -6,7 +6,7 @@ export const manifests: Array = [ alias: 'Umb.PropertyAction.Copy', name: 'Copy Property Action', loader: () => import('./copy/property-action-copy.element'), - meta: { + conditions: { propertyEditors: ['Umb.PropertyEditorUI.TextBox'], }, }, @@ -15,7 +15,7 @@ export const manifests: Array = [ alias: 'Umb.PropertyAction.Clear', name: 'Clear Property Action', loader: () => import('./clear/property-action-clear.element'), - meta: { + conditions: { propertyEditors: ['Umb.PropertyEditorUI.TextBox'], }, }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.context.ts index 3964a7a5f0..3a8205847f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.context.ts @@ -1,12 +1,12 @@ -import { UmbContextProviderController } from '@umbraco-cms/context-api'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { DeepState } from '@umbraco-cms/observable-api'; +import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { DeepState } from '@umbraco-cms/backoffice/observable-api'; export class UmbPropertyActionMenuContext { #isOpen = new DeepState(false); public readonly isOpen = this.#isOpen.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { new UmbContextProviderController(host, 'umbPropertyActionMenu', this); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.element.ts index 1320ed1f17..ff51de4e4d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action-menu/property-action-menu.element.ts @@ -3,12 +3,12 @@ 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 type { ManifestPropertyAction } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import type { ManifestPropertyAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; import '../property-action/property-action.element'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbObserverController } from '@umbraco-cms/observable-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; @customElement('umb-property-action-menu') export class UmbPropertyActionMenuElement extends UmbLitElement { @@ -26,6 +26,8 @@ export class UmbPropertyActionMenuElement extends UmbLitElement { #popover-trigger { --uui-button-padding-top-factor: 0.5; --uui-button-padding-bottom-factor: 0.1; + --uui-button-height: 18px; + --uui-button-border-radius: 6px; } #dropdown { @@ -78,7 +80,7 @@ export class UmbPropertyActionMenuElement extends UmbLitElement { this._actionsObserver = this.observe( umbExtensionsRegistry.extensionsOfType('propertyAction').pipe( map((propertyActions) => { - return propertyActions.filter((propertyAction) => propertyAction.meta.propertyEditors.includes(alias)); + return propertyActions.filter((propertyAction) => propertyAction.conditions.propertyEditors.includes(alias)); }) ), (manifests) => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action/property-action.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action/property-action.element.ts index 7417cce141..22aa520e24 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action/property-action.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-actions/shared/property-action/property-action.element.ts @@ -2,9 +2,9 @@ import { CSSResultGroup, html, LitElement } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui'; import type { UmbPropertyAction } from './property-action.model'; -import { createExtensionElement } from '@umbraco-cms/extensions-api'; +import { createExtensionElement } from '@umbraco-cms/backoffice/extensions-api'; -import type { ManifestPropertyAction } from '@umbraco-cms/models'; +import type { ManifestPropertyAction } from '@umbraco-cms/backoffice/extensions-registry'; @customElement('umb-property-action') export class UmbPropertyActionElement extends LitElement implements UmbPropertyAction { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-creator/property-creator.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-creator/property-creator.element.ts index dacc3558f0..a925a8299a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-creator/property-creator.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-creator/property-creator.element.ts @@ -1,9 +1,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { UMB_PROPERTY_SETTINGS_MODAL_TOKEN } from '../modals/property-settings'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_PROPERTY_SETTINGS_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-property-creator') export class UmbPropertyCreatorElement extends UmbLitElement { @@ -18,7 +17,7 @@ export class UmbPropertyCreatorElement extends UmbLitElement { } #onAddProperty() { - const modalHandler = this.#modalContext?.open(UMB_PROPERTY_SETTINGS_MODAL_TOKEN); + const modalHandler = this.#modalContext?.open(UMB_PROPERTY_SETTINGS_MODAL); modalHandler?.onSubmit().then((result) => { console.log('result', result); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/manifests.ts index 34fdaa64db..8cfe2dc6ac 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts index c679bfb670..62dfc7906e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts @@ -4,11 +4,14 @@ import { customElement, property, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { groupBy } from 'lodash-es'; import type { UUIInputEvent } from '@umbraco-ui/uui'; -import { UmbPropertyEditorUIPickerModalData, UmbPropertyEditorUIPickerModalResult } from '.'; -import type { UmbModalHandler } from '@umbraco-cms/modal'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { + UmbPropertyEditorUIPickerModalData, + UmbPropertyEditorUIPickerModalResult, +} from '@umbraco-cms/backoffice/modal'; +import type { UmbModalHandler } from '@umbraco-cms/backoffice/modal'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; interface GroupedPropertyEditorUIs { [key: string]: Array; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.stories.ts index 16d9f48b9d..fd6291ef18 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/modals/property-editor-ui-picker/property-editor-ui-picker-modal.stories.ts @@ -1,7 +1,7 @@ import { Meta, Story } from '@storybook/web-components'; import { html } from 'lit'; import type { UmbPropertyEditorUIPickerModalElement } from './property-editor-ui-picker-modal.element'; -import type { UmbPropertyEditorUIPickerModalData } from './'; +import type { UmbPropertyEditorUIPickerModalData } from '@umbraco-cms/backoffice/modal'; import './property-editor-ui-picker-modal.element'; import '../../../components/body-layout/body-layout.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockGrid.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockGrid.ts index d747e31f5f..89409a50fc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockGrid.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockGrid.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockList.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockList.ts index 087516e940..1279075915 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockList.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.BlockList.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.CheckboxList.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.CheckboxList.ts index 8bbc7811d4..74f2587cc0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.CheckboxList.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.CheckboxList.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.EyeDropper.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.EyeDropper.ts index 3654529213..e11be1d20e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.EyeDropper.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.EyeDropper.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.ts index 0dff209166..19260f42aa 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ColorPicker.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ContentPicker.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ContentPicker.ts index 27731b8bf8..a6ab9e054d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ContentPicker.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ContentPicker.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.DateTime.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.DateTime.ts index 824bbd6a2c..6dd6d1464b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.DateTime.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.DateTime.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; // TODO: We won't include momentjs anymore so we need to find a way to handle date formats export const manifest: ManifestPropertyEditorModel = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Decimal.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Decimal.ts index 15e46b6af4..6d71975535 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Decimal.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Decimal.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Dropdown.Flexible.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Dropdown.Flexible.ts index d307758b4d..b2ec1447a0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Dropdown.Flexible.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Dropdown.Flexible.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; // TODO: We won't include momentjs anymore so we need to find a way to handle date formats export const manifest: ManifestPropertyEditorModel = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.EmailAddress.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.EmailAddress.ts index 59c5eef401..be2e059379 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.EmailAddress.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.EmailAddress.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ImageCropper.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ImageCropper.ts index 3df75caa48..b87f751e84 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ImageCropper.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ImageCropper.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Integer.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Integer.ts index 48df3a939b..e7427c16e4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Integer.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Integer.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.JSON.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.JSON.ts index 33a09adbef..02c6e42768 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.JSON.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.JSON.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Label.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Label.ts index 33b212bd28..9de06d4f6f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Label.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Label.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ListView.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ListView.ts index 5ba53b7d7f..44dd1289d9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ListView.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.ListView.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MarkdownEditor.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MarkdownEditor.ts index 30aa9fe60c..1d1b05c01a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MarkdownEditor.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MarkdownEditor.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MediaPicker3.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MediaPicker3.ts index ce6a4d7309..dc5a199a05 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MediaPicker3.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MediaPicker3.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberGroupPicker.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberGroupPicker.ts index 1b01e05396..9f8dce244c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberGroupPicker.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberGroupPicker.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberPicker.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberPicker.ts index eafed1924d..a8aa7aabf3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberPicker.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MemberPicker.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiNodeTreePicker.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiNodeTreePicker.ts index d42f6f20c0..63db74e50e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiNodeTreePicker.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiNodeTreePicker.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiUrlPicker.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiUrlPicker.ts index 30a8bd6248..450be77299 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiUrlPicker.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultiUrlPicker.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultipleTextString.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultipleTextString.ts index 0795164b0a..d237f984db 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultipleTextString.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.MultipleTextString.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.RadioButtonList.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.RadioButtonList.ts index eeaf343770..181d4f3f54 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.RadioButtonList.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.RadioButtonList.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Slider.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Slider.ts index af5791dee8..1346b83738 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Slider.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Tags.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Tags.ts index 2c2ebe7ae8..448a25b87f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Tags.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.Tags.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextArea.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextArea.ts index c03cc34174..c30c8a6ec4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextArea.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextArea.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextBox.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextBox.ts index 6996840f51..131c04254c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextBox.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TextBox.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TinyMCE.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TinyMCE.ts index d1778f6b4e..c2ac9bb0ed 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TinyMCE.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TinyMCE.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TrueFalse.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TrueFalse.ts index 5734f73ea5..f1cd41ddda 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TrueFalse.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.TrueFalse.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; // TODO: We won't include momentjs anymore so we need to find a way to handle date formats export const manifest: ManifestPropertyEditorModel = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UploadField.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UploadField.ts index 541a74a90d..6ce7072583 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UploadField.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UploadField.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; // TODO: We won't include momentjs anymore so we need to find a way to handle date formats export const manifest: ManifestPropertyEditorModel = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UserPicker.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UserPicker.ts index 617e86f9fa..b454c538cc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UserPicker.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/Umbraco.UserPicker.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorModel = { type: 'propertyEditorModel', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/manifests.ts index f311d6ad0a..d86bba6e68 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/models/manifests.ts @@ -30,7 +30,7 @@ import { manifest as userPicker } from './Umbraco.UserPicker'; import { manifest as memberPicker } from './Umbraco.MemberPicker'; import { manifest as memberGroupPicker } from './Umbraco.MemberGroupPicker'; -import type { ManifestPropertyEditorModel } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorModel } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests: Array = [ colorPicker, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.element.ts index ad3c265dbb..c53387f381 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.element.ts @@ -1,12 +1,15 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import type { PropertyEditorConfigDefaultData, PropertyEditorConfigProperty } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import type { + PropertyEditorConfigDefaultData, + PropertyEditorConfigProperty, +} from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; import '../../../components/workspace-property/workspace-property.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-config diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.stories.ts index 46d8606f61..d3457f26bd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/shared/property-editor-config/property-editor-config.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorConfigElement } from './property-editor-config.element'; import './property-editor-config.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/manifests.ts index c336308b08..2dde7a4aae 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.element.ts index b1a5a2de20..6d341fa44d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-block-grid-block-configuration diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.stories.ts index b5abe7e06a..84a24b1a83 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIBlockGridBlockConfigurationElement } from './property-editor-ui-block-grid-block-configuration.element'; import './property-editor-ui-block-grid-block-configuration.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.test.ts index 8a7f376095..3e06b77ca7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/block-configuration/property-editor-ui-block-grid-block-configuration.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIBlockGridBlockConfigurationElement } from './property-editor-ui-block-grid-block-configuration.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIBlockGridBlockConfigurationElement', () => { let element: UmbPropertyEditorUIBlockGridBlockConfigurationElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/manifests.ts index 2482047d12..69af245189 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.element.ts index 4c3af973a9..c47dfb5c34 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-block-grid-group-configuration diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.stories.ts index 6a27630cce..dad33027be 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIBlockGridGroupConfigurationElement } from './property-editor-ui-block-grid-group-configuration.element'; import './property-editor-ui-block-grid-group-configuration.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.test.ts index 6115399f01..303022bb25 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/group-configuration/property-editor-ui-block-grid-group-configuration.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIBlockGridGroupConfigurationElement } from './property-editor-ui-block-grid-group-configuration.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIBlockGridGroupConfigurationElement', () => { let element: UmbPropertyEditorUIBlockGridGroupConfigurationElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/manifests.ts index edd0538abd..39a726a55b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.element.ts index d9e73c661b..419f0f5481 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-block-grid-stylesheet-picker diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.stories.ts index 724705e5c2..e66213c7f6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIBlockGridStylesheetPickerElement } from './property-editor-ui-block-grid-stylesheet-picker.element'; import './property-editor-ui-block-grid-stylesheet-picker.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.test.ts index 3aaf37b700..36dcddf30f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/config/stylesheet-picker/property-editor-ui-block-grid-stylesheet-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIBlockGridStylesheetPickerElement } from './property-editor-ui-block-grid-stylesheet-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIBlockGridStylesheetPickerElement', () => { let element: UmbPropertyEditorUIBlockGridStylesheetPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/manifests.ts index 81f3b6c5b5..25e872cd99 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/manifests.ts @@ -1,7 +1,7 @@ import { manifest as blockConfiguration } from './config/block-configuration/manifests'; import { manifest as groupConfiguration } from './config/group-configuration/manifests'; import { manifest as stylesheetPicker } from './config/stylesheet-picker/manifests'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid-inner-test.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid-inner-test.element.ts index 4142444310..682577eec5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid-inner-test.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid-inner-test.element.ts @@ -1,9 +1,9 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { IRoute, IRoutingInfo } from 'router-slot'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/router'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; /** * @element umb-property-editor-ui-block-grid-inner-test @@ -28,7 +28,7 @@ export class UmbPropertyEditorUIBlockGridInnerTestElement extends UmbLitElement component: () => { return import('./property-editor-ui-block-grid-inner-test.element'); }, - setup: (component: Promise | HTMLElement, info: IRoutingInfo) => { + setup: (component, info) => { console.log('block route inner', info); if (component instanceof HTMLElement) { (component as any).name = 'inner-1'; @@ -41,7 +41,7 @@ export class UmbPropertyEditorUIBlockGridInnerTestElement extends UmbLitElement component: () => { return import('./property-editor-ui-block-grid-inner-test.element'); }, - setup: (component: Promise | HTMLElement, info: IRoutingInfo) => { + setup: (component, info) => { console.log('block route inner', info); if (component instanceof HTMLElement) { (component as any).name = 'inner-2'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.element.ts index 88074e0bb5..774bdc20b0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.element.ts @@ -1,12 +1,13 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { IRoute, IRoutingInfo } from 'router-slot'; -import { UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN } from '../../../../shared/components/workspace/workspace-variant/workspace-variant.context'; import { UmbVariantId } from '../../../../shared/variants/variant-id.class'; -import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/router'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN } from '../../../../shared/components/workspace/workspace-variant/workspace-variant.context'; +import { UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN } from '../../../../shared/components/workspace-property/workspace-property.context'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import type { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/internal/router'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-block-grid @@ -38,10 +39,9 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement constructor() { super(); - this.consumeContext(UMB_WORKSPACE_VARIANT_CONTEXT_TOKEN, (context) => { - this._variantContext = context; - this.observe(this._variantContext?.variantId, (variantId) => { - this._variantId = variantId; + this.consumeContext(UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, (context) => { + this.observe(context?.variantId, (propertyVariantId) => { + this._variantId = propertyVariantId; this.setupRoutes(); }); }); @@ -52,11 +52,11 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement if (this._variantId !== undefined) { this._routes = [ { - path: this._variantId.toString() + '/modal-1', + path: 'modal-1', component: () => { return import('./property-editor-ui-block-grid-inner-test.element'); }, - setup: (component: Promise | HTMLElement, info: IRoutingInfo) => { + setup: (component, info) => { console.log('block route', info); if (component instanceof HTMLElement) { (component as any).name = 'block-grid-1'; @@ -64,12 +64,12 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement }, }, { - path: this._variantId.toString() + '/modal-2', + path: 'modal-2', //pathMatch: 'full', component: () => { return import('./property-editor-ui-block-grid-inner-test.element'); }, - setup: (component: Promise | HTMLElement, info: IRoutingInfo) => { + setup: (component, info) => { console.log('block route', info); if (component instanceof HTMLElement) { (component as any).name = 'block-grid-2'; @@ -88,17 +88,16 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement + href="${this._routerPath + '/'}modal-1" + .active=${this._routerPath + '/' + 'modal-1' === this._activePath}> + href="${this._routerPath + '/'}modal-2" + .active=${this._routerPath + '/' + 'modal-2' === this._activePath}> - { @@ -107,7 +106,7 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement @change=${(event: UmbRouterSlotChangeEvent) => { this._activePath = event.target.localActiveViewPath; }}> - + ` : 'loading...'; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.stories.ts index 227722a7ca..2e2536347b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIBlockGridElement } from './property-editor-ui-block-grid.element'; import './property-editor-ui-block-grid.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.test.ts index d7eb2f0d21..370f9431e2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-grid/property-editor-ui-block-grid.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIBlockGridElement } from './property-editor-ui-block-grid.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIBlockGridElement', () => { let element: UmbPropertyEditorUIBlockGridElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/manifests.ts index c0485380d6..1b7aec8f59 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.element.ts index f08fd1694d..6c207dd808 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-block-list-block-configuration diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.stories.ts index 4d2f85052e..d4e2142c6b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIBlockListBlockConfigurationElement } from './property-editor-ui-block-list-block-configuration.element'; import './property-editor-ui-block-list-block-configuration.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.test.ts index bf617f111b..52ebebdceb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/config/block-configuration/property-editor-ui-block-list-block-configuration.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIBlockListBlockConfigurationElement } from './property-editor-ui-block-list-block-configuration.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIBlockListBlockConfigurationElement', () => { let element: UmbPropertyEditorUIBlockListBlockConfigurationElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/manifests.ts index 49401f720f..89098d9278 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/manifests.ts @@ -1,5 +1,5 @@ import { manifest as blockConfiguration } from './config/block-configuration/manifests'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.element.ts index 50d78729d4..8fc617b7f7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-block-list diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.stories.ts index c04c90de3a..93b3d74e03 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIBlockListElement } from './property-editor-ui-block-list.element'; import './property-editor-ui-block-list.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.test.ts index ac39d3aefa..29094233f0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/block-list/property-editor-ui-block-list.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIBlockListElement } from './property-editor-ui-block-list.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIBlockListElement', () => { let element: UmbPropertyEditorUIBlockListElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/manifests.ts index a54858705e..63f39b2faf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.element.ts index c46d39e441..b161988d4d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.element.ts @@ -2,9 +2,9 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { UmbInputCheckboxListElement } from '../../../components/input-checkbox-list/input-checkbox-list.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-property-editor-ui-checkbox-list @@ -23,7 +23,7 @@ export class UmbPropertyEditorUICheckboxListElement extends UmbLitElement implem } @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const listData = config.find((x) => x.alias === 'items'); if (!listData) return; @@ -54,7 +54,7 @@ export class UmbPropertyEditorUICheckboxListElement extends UmbLitElement implem render() { return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.stories.ts index e47e8c68c2..123de52638 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUICheckboxListElement } from './property-editor-ui-checkbox-list.element'; import './property-editor-ui-checkbox-list.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.test.ts index 629e446eb2..727175c5fe 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/checkbox-list/property-editor-ui-checkbox-list.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUICheckboxListElement } from './property-editor-ui-checkbox-list.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUICheckboxListElement', () => { let element: UmbPropertyEditorUICheckboxListElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/manifests.ts index fc4ed9741b..c394e03ab4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.element.ts index f1ea228ed3..41ef8e31a9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-collection-view-bulk-action-permissions diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.stories.ts index 89bdedf1d2..c8d47e30af 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUICollectionViewBulkActionPermissionsElement } from './property-editor-ui-collection-view-bulk-action-permissions.element'; import './property-editor-ui-collection-view-bulk-action-permissions.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.test.ts index 7b568d9a96..969df9f36b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/bulk-action-permissions/property-editor-ui-collection-view-bulk-action-permissions.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUICollectionViewBulkActionPermissionsElement } from './property-editor-ui-collection-view-bulk-action-permissions.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUICollectionViewBulkActionPermissionsElement', () => { let element: UmbPropertyEditorUICollectionViewBulkActionPermissionsElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/manifests.ts index 203797145f..de5267f373 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts index e5483e4fe0..2789e8147a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-collection-view-column-configuration diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.stories.ts index e570b2d3fb..440113392e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUICollectionViewColumnConfigurationElement } from './property-editor-ui-collection-view-column-configuration.element'; import './property-editor-ui-collection-view-column-configuration.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.test.ts index 71bd8e3fc7..bf93111b0f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/column-configuration/property-editor-ui-collection-view-column-configuration.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUICollectionViewColumnConfigurationElement } from './property-editor-ui-collection-view-column-configuration.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUICollectionViewColumnConfigurationElement', () => { let element: UmbPropertyEditorUICollectionViewColumnConfigurationElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/manifests.ts index baf233401e..ffbfd84df3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.element.ts index 90febd1e3f..6576df1792 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-collection-view-layout-configuration diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.stories.ts index e0b72a1299..745c9c6fa8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUICollectionViewLayoutConfigurationElement } from './property-editor-ui-collection-view-layout-configuration.element'; import './property-editor-ui-collection-view-layout-configuration.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.test.ts index f6f8ac82fc..0c2095d0df 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/layout-configuration/property-editor-ui-collection-view-layout-configuration.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUICollectionViewLayoutConfigurationElement } from './property-editor-ui-collection-view-layout-configuration.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUICollectionViewLayoutConfigurationElement', () => { let element: UmbPropertyEditorUICollectionViewLayoutConfigurationElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/manifests.ts index a8d2f0956f..66ca4cb66d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.element.ts index 6ea8a17e1c..5622a5457d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-collection-view-order-by diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.stories.ts index f4117b8581..f599980509 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUICollectionViewOrderByElement } from './property-editor-ui-collection-view-order-by.element'; import './property-editor-ui-collection-view-order-by.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.test.ts index d2f7d4e3ec..2fd6fa348b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/config/order-by/property-editor-ui-collection-view-order-by.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUICollectionViewOrderByElement } from './property-editor-ui-collection-view-order-by.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUICollectionViewOrderByElement', () => { let element: UmbPropertyEditorUICollectionViewOrderByElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/manifests.ts index e99665523e..f1d618ef05 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/manifests.ts @@ -2,7 +2,7 @@ import { manifest as bulkActionPermissions } from './config/bulk-action-permissi import { manifest as columnConfiguration } from './config/column-configuration/manifests'; import { manifest as layoutConfiguration } from './config/layout-configuration/manifests'; import { manifest as orderBy } from './config/order-by/manifests'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.element.ts index 02d402ff81..9899891891 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-collection-view diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.stories.ts index 7b052f9d15..69e743a8ab 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUICollectionViewElement } from './property-editor-ui-collection-view.element'; import './property-editor-ui-collection-view.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.test.ts index f5c64912b1..4bbefb1018 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/collection-view/property-editor-ui-collection-view.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUICollectionViewElement } from './property-editor-ui-collection-view.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUICollectionViewElement', () => { let element: UmbPropertyEditorUICollectionViewElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/manifests.ts index cc0fead291..cf80433f40 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.element.ts index eb68421589..7c9be4925f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.element.ts @@ -2,10 +2,10 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { UUIColorSwatchesEvent } from '@umbraco-ui/uui'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DataTypePropertyModel } from '@umbraco-cms/backend-api'; -import type { SwatchDetails } from '@umbraco-cms/models'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; +import type { SwatchDetails } from '@umbraco-cms/backoffice/models'; /** * @element umb-property-editor-ui-color-picker @@ -24,7 +24,7 @@ export class UmbPropertyEditorUIColorPickerElement extends UmbLitElement impleme private _swatches: SwatchDetails[] = []; @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const useLabel = config.find((x) => x.alias === 'useLabel'); if (useLabel) this._showLabels = useLabel.value; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.stories.ts index bc99333127..64f562c20c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIColorPickerElement } from './property-editor-ui-color-picker.element'; import './property-editor-ui-color-picker.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.test.ts index d902de2888..2d896f684d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/color-picker/property-editor-ui-color-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIColorPickerElement } from './property-editor-ui-color-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIColorPickerElement', () => { let element: UmbPropertyEditorUIColorPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/manifests.ts index 0a4b96eb04..97353810f3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', @@ -21,7 +21,8 @@ export const manifest: ManifestPropertyEditorUI = { { alias: 'offsetTime', label: 'Offset time', - description: 'When enabled the time displayed will be offset with the servers timezone, this is useful for scenarios like scheduled publishing when an editor is in a different timezone than the hosted server', + description: + 'When enabled the time displayed will be offset with the servers timezone, this is useful for scenarios like scheduled publishing when an editor is in a different timezone than the hosted server', propertyEditorUI: 'Umb.PropertyEditorUI.Toggle', }, ], @@ -32,8 +33,8 @@ export const manifest: ManifestPropertyEditorUI = { }, { alias: 'offsetTime', - value: false - } + value: false, + }, ], }, }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts index 07ad88691f..7b4eb5472d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts @@ -3,9 +3,9 @@ import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { InputType } from '@umbraco-ui/uui'; import { UmbPropertyValueChangeEvent } from '../..'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { PropertyEditorConfigDefaultData } from '@umbraco-cms/extensions-registry'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { PropertyEditorConfigDefaultData } from '@umbraco-cms/backoffice/extensions-registry'; /** * @element umb-property-editor-ui-date-picker diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts index b3f5beae7e..4d7638d61c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIDatePickerElement } from './property-editor-ui-date-picker.element'; import './property-editor-ui-date-picker.element'; @@ -12,19 +12,20 @@ export default { config: [ { alias: 'format', - value: 'YYYY-MM-DD HH:mm:ss' - } - ] - } + value: 'YYYY-MM-DD HH:mm:ss', + }, + ], + }, } as Meta; -const Template: Story = ({config, value}) => html``; +const Template: Story = ({ config, value }) => + html``; export const Overview = Template.bind({}); export const WithDateValue = Template.bind({}); WithDateValue.args = { - value: '2021-01-24 15:20' + value: '2021-01-24 15:20', }; export const WithFormat = Template.bind({}); @@ -32,9 +33,9 @@ WithFormat.args = { config: [ { alias: 'format', - value: 'dd/MM/yyyy HH:mm:ss' - } - ] + value: 'dd/MM/yyyy HH:mm:ss', + }, + ], }; export const TimeOnly = Template.bind({}); @@ -42,9 +43,9 @@ TimeOnly.args = { config: [ { alias: 'format', - value: 'HH:mm:ss' - } - ] + value: 'HH:mm:ss', + }, + ], }; export const DateOnly = Template.bind({}); @@ -52,7 +53,7 @@ DateOnly.args = { config: [ { alias: 'format', - value: 'dd/MM/yyyy' - } - ] -}; \ No newline at end of file + value: 'dd/MM/yyyy', + }, + ], +}; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts index 91f298f819..11a4002b8f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UUIInputElement } from '@umbraco-ui/uui'; import { UmbPropertyEditorUIDatePickerElement } from './property-editor-ui-date-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIDatePickerElement', () => { let element: UmbPropertyEditorUIDatePickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/manifests.ts index ac9902c752..2a8e59cc62 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', @@ -28,7 +28,7 @@ export const manifest: ManifestPropertyEditorUI = { alias: 'ignoreUserStartNodes', label: 'Ignore User Start Nodes', description: 'Selecting this option allows a user to choose nodes that they normally dont have access to', - propertyEditorUI: 'Umb.PropertyEditorUI.Boolean', + propertyEditorUI: 'Umb.PropertyEditorUI.Toggle', }, ], }, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/property-editor-ui-document-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/property-editor-ui-document-picker.element.ts index 1247db88b2..d2e02efa43 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/property-editor-ui-document-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/document-picker/property-editor-ui-document-picker.element.ts @@ -1,10 +1,10 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import type { UmbInputDocumentPickerElement } from '../../../components/input-document-picker/input-document-picker.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import '../../../components/input-document-picker/input-document-picker.element'; -import type { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; @customElement('umb-property-editor-ui-document-picker') export class UmbPropertyEditorUIContentPickerElement extends UmbLitElement implements UmbPropertyEditorElement { @@ -19,7 +19,7 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbLitElement imple } @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const validationLimit = config.find((x) => x.alias === 'validationLimit'); this._limitMin = (validationLimit?.value as any).min; @@ -32,7 +32,7 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbLitElement imple private _limitMax?: number; private _onChange(event: CustomEvent) { - this.value = (event.target as UmbInputDocumentPickerElement).selectedKeys; + this.value = (event.target as UmbInputDocumentPickerElement).selectedIds; this.dispatchEvent(new CustomEvent('property-value-change')); } @@ -41,7 +41,7 @@ export class UmbPropertyEditorUIContentPickerElement extends UmbLitElement imple return html` Add { let element: UmbPropertyEditorUIDropdownElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/manifests.ts index 3ff87259c9..7b2af8dd74 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.element.ts index 96bb3ccbd2..a24e470c38 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.element.ts @@ -2,9 +2,9 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { UUIColorPickerChangeEvent } from '@umbraco-ui/uui'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-property-editor-ui-eye-dropper @@ -23,7 +23,7 @@ export class UmbPropertyEditorUIEyeDropperElement extends UmbLitElement implemen private _swatches: string[] = []; @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const showAlpha = config.find((x) => x.alias === 'showAlpha'); if (showAlpha) this._opacity = showAlpha.value; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.stories.ts index 1bf169f897..6bc8746807 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIEyeDropperElement } from './property-editor-ui-eye-dropper.element'; import './property-editor-ui-eye-dropper.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.test.ts index 6e3092dfb5..0d0b82596a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/eye-dropper/property-editor-ui-eye-dropper.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIEyeDropperElement } from './property-editor-ui-eye-dropper.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIEyeDropperElement', () => { let element: UmbPropertyEditorUIEyeDropperElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/manifests.ts index 4458bc6653..dd37fbdff9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts index 8e75f956cd..aebdeeb989 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts @@ -1,10 +1,9 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UMB_ICON_PICKER_MODAL_TOKEN } from '../../../modals/icon-picker'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_ICON_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-icon-picker @@ -29,7 +28,7 @@ export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement implemen } private _openModal() { - this._modalContext?.open(UMB_ICON_PICKER_MODAL_TOKEN); + this._modalContext?.open(UMB_ICON_PICKER_MODAL); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.stories.ts index 37beb48855..3c5d0856f7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbIconPickerModalElement } from '../../../../shared/modals/icon-picker/icon-picker-modal.element'; import type { UmbPropertyEditorUIIconPickerElement } from './property-editor-ui-icon-picker.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.test.ts index fb580afdf9..63917404d6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/icon-picker/property-editor-ui-icon-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIIconPickerElement } from './property-editor-ui-icon-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIIconPickerElement', () => { let element: UmbPropertyEditorUIIconPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/manifests.ts index 28cbf872f2..23bd170925 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.element.ts index 99fd3118d1..c11b93d848 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-image-cropper diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.stories.ts index c73186ac2f..2f75d4945a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIImageCropperElement } from './property-editor-ui-image-cropper.element'; import './property-editor-ui-image-cropper.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.test.ts index 8341e78af0..c5574bfdad 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-cropper/property-editor-ui-image-cropper.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIImageCropperElement } from './property-editor-ui-image-cropper.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIImageCropperElement', () => { let element: UmbPropertyEditorUIImageCropperElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/manifests.ts index c0e2103653..3f99787b12 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.element.ts index c8c84bb914..d6cc3592b4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-image-crops-configuration diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.stories.ts index e9f75ddc91..811330e122 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIImageCropsConfigurationElement } from './property-editor-ui-image-crops-configuration.element'; import './property-editor-ui-image-crops-configuration.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.test.ts index 2c9a89a769..5fb5a759ca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/image-crops-configuration/property-editor-ui-image-crops-configuration.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIImageCropsConfigurationElement } from './property-editor-ui-image-crops-configuration.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIImageCropsConfigurationElement', () => { let element: UmbPropertyEditorUIImageCropsConfigurationElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/manifests.ts index 7c3f1ca069..c855adaf18 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.element.ts index e06e10061f..5cc1faa69e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-label diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.stories.ts index 862aa36bd2..77beeb6727 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUILabelElement } from './property-editor-ui-label.element'; import './property-editor-ui-label.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.test.ts index 9687836ee9..e5f813c4c9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/label/property-editor-ui-label.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUILabelElement } from './property-editor-ui-label.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUILabelElement', () => { let element: UmbPropertyEditorUILabelElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/manifests.ts index 73a7dcd5d8..e8aed7a381 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/manifests.ts @@ -32,7 +32,7 @@ import { manifests as numbers } from './number/manifests'; import { manifest as userPicker } from './user-picker/manifests'; import { manifest as memberPicker } from './member-picker/manifests'; import { manifest as memberGroupPicker } from './member-group-picker/manifests'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests: Array = [ colorPicker, diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/manifests.ts index b3f1e12abb..3a0d06fe1b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.element.ts index 24c6a83027..d403592382 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-markdown-editor diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.stories.ts index 33ba0d5203..0e7ada92e4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIMarkdownEditorElement } from './property-editor-ui-markdown-editor.element'; import './property-editor-ui-markdown-editor.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.test.ts index 93ec2d48e0..f712b6336f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/markdown-editor/property-editor-ui-markdown-editor.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIMarkdownEditorElement } from './property-editor-ui-markdown-editor.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIMarkdownEditorElement', () => { let element: UmbPropertyEditorUIMarkdownEditorElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/manifests.ts index 4dfb987f95..3a4efe133b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/property-editor-ui-media-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/property-editor-ui-media-picker.element.ts index a4228b08eb..fe81fe9792 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/property-editor-ui-media-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/media-picker/property-editor-ui-media-picker.element.ts @@ -1,9 +1,9 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbInputMediaPickerElement } from '../../../../../backoffice/shared/components/input-media-picker/input-media-picker.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-property-editor-ui-media-picker @@ -21,7 +21,7 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme } @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const validationLimit = config.find((x) => x.alias === 'validationLimit'); if (!validationLimit) return; @@ -35,7 +35,7 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme private _limitMax?: number; private _onChange(event: CustomEvent) { - this.value = (event.target as UmbInputMediaPickerElement).selectedKeys; + this.value = (event.target as UmbInputMediaPickerElement).selectedIds; this.dispatchEvent(new CustomEvent('property-value-change')); } @@ -43,7 +43,7 @@ export class UmbPropertyEditorUIMediaPickerElement extends UmbLitElement impleme return html` Add { let element: UmbPropertyEditorUIMediaPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/manifests.ts index 2d3d7d41ae..de05d10269 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.element.ts index b26690d1ad..770289b8fe 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-member-group-picker diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.stories.ts index 8d437fdf32..abdf596558 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIMemberGroupPickerElement } from './property-editor-ui-member-group-picker.element'; import './property-editor-ui-member-group-picker.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.test.ts index c4b6d508f8..f1e7944b14 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-group-picker/property-editor-ui-member-group-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIMemberGroupPickerElement } from './property-editor-ui-member-group-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIMemberGroupPickerElement', () => { let element: UmbPropertyEditorUIMemberGroupPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/manifests.ts index 644fef49fb..b4e3e79f64 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.element.ts index d1cc234e13..8c5c2b5038 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-member-picker diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.stories.ts index be840c23ed..a2da67c5d5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIMemberPickerElement } from './property-editor-ui-member-picker.element'; import './property-editor-ui-member-picker.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.test.ts index 40843b34df..15a4447c59 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/member-picker/property-editor-ui-member-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIMemberPickerElement } from './property-editor-ui-member-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIMemberPickerElement', () => { let element: UmbPropertyEditorUIMemberPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/manifests.ts index 90c48e605f..03235d693e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/property-editor-ui-multi-url-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/property-editor-ui-multi-url-picker.element.ts index 1d74448439..e4111187c0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/property-editor-ui-multi-url-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multi-url-picker/property-editor-ui-multi-url-picker.element.ts @@ -1,17 +1,17 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; -import { UUIModalSidebarSize } from '@umbraco-ui/uui-modal-sidebar'; +import type { UUIModalSidebarSize } from '@umbraco-ui/uui'; import { UmbInputMultiUrlPickerElement } from '../../../../shared/components/input-multi-url-picker/input-multi-url-picker.element'; -import { UmbLinkPickerLink } from '../../../../shared/modals/link-picker'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN } from '../../../../shared/components/workspace-property/workspace-property.context'; +import { UmbLinkPickerLink } from '@umbraco-cms/backoffice/modal'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-multi-url-picker */ - @customElement('umb-property-editor-ui-multi-url-picker') export class UmbPropertyEditorUIMultiUrlPickerElement extends UmbLitElement implements UmbPropertyEditorElement { static styles = [UUITextStyles]; @@ -20,7 +20,7 @@ export class UmbPropertyEditorUIMultiUrlPickerElement extends UmbLitElement impl value: UmbLinkPickerLink[] = []; @property({ type: Array, attribute: false }) - public set config(config: DataTypePropertyModel[]) { + public set config(config: DataTypePropertyPresentationModel[]) { const overlaySize = config.find((x) => x.alias === 'overlaySize'); if (overlaySize) this._overlaySize = overlaySize.value; @@ -51,6 +51,25 @@ export class UmbPropertyEditorUIMultiUrlPickerElement extends UmbLitElement impl @state() private _minNumber?: number; + @state() + private _alias?: string; + + @state() + private _propertyVariantId?: string; + + constructor() { + super(); + + this.consumeContext(UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, (context) => { + this.observe(context.alias, (alias) => { + this._alias = alias; + }); + this.observe(context.variantId, (variantId) => { + this._propertyVariantId = variantId?.toString() || 'invariant'; + }); + }); + } + private _onChange(event: CustomEvent) { this.value = (event.target as UmbInputMultiUrlPickerElement).urls; this.dispatchEvent(new CustomEvent('property-value-change')); @@ -58,6 +77,8 @@ export class UmbPropertyEditorUIMultiUrlPickerElement extends UmbLitElement impl render() { return html` { let element: UmbPropertyEditorUIMultiUrlPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string-item/input-multiple-text-string-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string-item/input-multiple-text-string-item.element.ts index 2c187b7e19..cbc21787b0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string-item/input-multiple-text-string-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string-item/input-multiple-text-string-item.element.ts @@ -4,10 +4,9 @@ import { customElement, property, query } from 'lit/decorators.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import { UUIInputEvent } from '@umbraco-ui/uui-input'; import { UUIInputElement } from '@umbraco-ui/uui'; -import { UMB_CONFIRM_MODAL_TOKEN } from '../../../../modals/confirm'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbChangeEvent, UmbInputEvent, UmbDeleteEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UmbChangeEvent, UmbInputEvent, UmbDeleteEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-input-multiple-text-string-item @@ -66,7 +65,7 @@ export class UmbInputMultipleTextStringItemElement extends FormControlMixin(UmbL } #onDelete() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL_TOKEN, { + const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: `Delete ${this.value || 'item'}`, content: 'Are you sure you want to delete this item?', color: 'danger', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string/input-multiple-text-string.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string/input-multiple-text-string.element.ts index 510eeb2bec..f0dc741e85 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string/input-multiple-text-string.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/input-multiple-text-string/input-multiple-text-string.element.ts @@ -4,8 +4,8 @@ import { customElement, property, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins'; import UmbInputMultipleTextStringItemElement from '../input-multiple-text-string-item/input-multiple-text-string-item.element'; -import { UmbInputEvent, UmbChangeEvent, UmbDeleteEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbInputEvent, UmbChangeEvent, UmbDeleteEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; export type MultipleTextStringValue = Array; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/manifests.ts index 1016429ab5..0101236a9f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.element.ts index 2634afeb01..6f8dc64a1f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.element.ts @@ -1,13 +1,13 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UmbPropertyValueChangeEvent } from '../..'; import UmbInputMultipleTextStringElement, { MultipleTextStringValue, } from './input-multiple-text-string/input-multiple-text-string.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbChangeEvent } from '@umbraco-cms/events'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/events'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; export type MultipleTextStringConfigData = Array<{ alias: 'minNumber' | 'maxNumber'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.stories.ts index 39f2b28be8..455f61bcea 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIMultipleTextStringElement } from './property-editor-ui-multiple-text-string.element'; import './property-editor-ui-multiple-text-string.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.test.ts index 9edad0b89e..bc30bc903f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/multiple-text-string/property-editor-ui-multiple-text-string.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIMultipleTextStringElement } from './property-editor-ui-multiple-text-string.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIMultipleTextStringElement', () => { let element: UmbPropertyEditorUIMultipleTextStringElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/manifests.ts index 4c739b3240..4d109a2241 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.element.ts index 4f110af285..731cc6c56a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.element.ts @@ -2,8 +2,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import type { UmbInputNumberRangeElement } from '../../../../shared/components/input-number-range/input-number-range.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import '../../../../shared/components/input-number-range/input-number-range.element'; type ValueType = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.stories.ts index b3b0027c60..e562fe2603 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUINumberRangeElement } from './property-editor-ui-number-range.element'; import './property-editor-ui-number-range.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.test.ts index b6bfe9d109..55f1baafd9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number-range/property-editor-ui-number-range.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUINumberRangeElement } from './property-editor-ui-number-range.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUINumberRangeElement', () => { let element: UmbPropertyEditorUINumberRangeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/manifests.ts index 131f7368fb..a83887074b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; // TODO: we don't really want this config value to be changed from the UI. We need a way to handle hidden config properties. const allowDecimalsConfig = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.element.ts index f1bab95b1b..3a8e51db01 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.element.ts @@ -1,8 +1,8 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-property-editor-ui-number') export class UmbPropertyEditorUINumberElement extends UmbLitElement implements UmbPropertyEditorElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.stories.ts index be74c018be..0bb4c88e3b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/number/property-editor-ui-number.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUINumberElement } from './property-editor-ui-number.element'; import './property-editor-ui-number.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/manifests.ts index f4cf3a8fcc..a832559cbf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.element.ts index 90ac01ce2e..01ada182d8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-order-direction diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.stories.ts index ecf903f68d..2db7f21592 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIOrderDirectionElement } from './property-editor-ui-order-direction.element'; import './property-editor-ui-order-direction.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.test.ts index 174822b370..83cedc5faf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/order-direction/property-editor-ui-order-direction.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIOrderDirectionElement } from './property-editor-ui-order-direction.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIOrderDirectionElement', () => { let element: UmbPropertyEditorUIOrderDirectionElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/manifests.ts index 2baef91ae5..d322ad843a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.element.ts index b660d0424c..562f5ca98b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-overlay-size diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.stories.ts index 4ae4156e8e..5a428f985c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIOverlaySizeElement } from './property-editor-ui-overlay-size.element'; import './property-editor-ui-overlay-size.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.test.ts index 512b133194..31993aef82 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/overlay-size/property-editor-ui-overlay-size.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIOverlaySizeElement } from './property-editor-ui-overlay-size.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIOverlaySizeElement', () => { let element: UmbPropertyEditorUIOverlaySizeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/manifests.ts index 6570654940..fd0b64ae8c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.element.ts index da082889df..2860ec351a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.element.ts @@ -3,9 +3,9 @@ import { customElement, property, state } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import '../../../components/input-radio-button-list/input-radio-button-list.element'; import type { UmbInputRadioButtonListElement } from '../../../components/input-radio-button-list/input-radio-button-list.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-property-editor-ui-radio-button-list @@ -24,7 +24,7 @@ export class UmbPropertyEditorUIRadioButtonListElement extends UmbLitElement imp } @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const listData = config.find((x) => x.alias === 'items'); if (!listData) return; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.stories.ts index 731d38eeab..67d1fde28d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIRadioButtonListElement } from './property-editor-ui-radio-button-list.element'; import './property-editor-ui-radio-button-list.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.test.ts index 0a89713c8c..9eb632c187 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/radio-button-list/property-editor-ui-radio-button-list.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIRadioButtonListElement } from './property-editor-ui-radio-button-list.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIRadioButtonListElement', () => { let element: UmbPropertyEditorUIRadioButtonListElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/manifests.ts index f2cfe7d534..b7b5d264e8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.element.ts index 6e81051161..1e9e8d1fc0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.element.ts @@ -2,9 +2,9 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import UmbInputSliderElement from '../../../../shared/components/input-slider/input-slider.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-property-editor-ui-slider @@ -38,7 +38,7 @@ export class UmbPropertyEditorUISliderElement extends UmbLitElement implements U _max?: number; @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const enableRange = config.find((x) => x.alias === 'enableRange'); if (enableRange) this._enableRange = enableRange.value as boolean; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.stories.ts index 2c409547b9..3a1276d23f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUISliderElement } from './property-editor-ui-slider.element'; import './property-editor-ui-slider.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.test.ts index 0e308a015a..e4f5ebc5af 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/slider/property-editor-ui-slider.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUISliderElement } from './property-editor-ui-slider.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUISliderElement', () => { let element: UmbPropertyEditorUISliderElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/manifests.ts index dbcc66558b..1aac162bc4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.element.ts index 16804c091c..5c6952088a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-tags-storage-type diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.stories.ts index 77f2d144f8..2dde067661 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITagsStorageTypeElement } from './property-editor-ui-tags-storage-type.element'; import './property-editor-ui-tags-storage-type.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.test.ts index 1de85497c5..b37a82f97f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/config/storage-type/property-editor-ui-tags-storage-type.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUITagsStorageTypeElement } from './property-editor-ui-tags-storage-type.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUITagsStorageTypeElement', () => { let element: UmbPropertyEditorUITagsStorageTypeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/manifests.ts index d826098369..b6998e0016 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/manifests.ts @@ -1,5 +1,5 @@ import { manifest as storageType } from './config/storage-type/manifests'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.element.ts index 61aaf420ba..3d1595083e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-tags diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.stories.ts index 2e81b69e8a..de47fda75b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITagsElement } from './property-editor-ui-tags.element'; import './property-editor-ui-tags.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.test.ts index ad0bbe21e9..42ca8bd847 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tags/property-editor-ui-tags.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUITagsElement } from './property-editor-ui-tags.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUITagsElement', () => { let element: UmbPropertyEditorUITagsElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/manifests.ts index 44fcc4e718..9aba31efb2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; // TODO: we don't really want this config value to be changed from the UI. We need a way to handle hidden config properties. const inputTypeConfig = { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.element.ts index 4ed5e651b0..bd108a43f4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.element.ts @@ -1,8 +1,8 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-property-editor-ui-text-box') export class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.stories.ts index a636a73f31..f0ac712382 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/text-box/property-editor-ui-text-box.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITextBoxElement } from './property-editor-ui-text-box.element'; import './property-editor-ui-text-box.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/manifests.ts index 337454010b..b4c4c6204d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.element.ts index de39bfcbd7..f39539b6a9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.element.ts @@ -2,9 +2,12 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; import { UUITextareaElement } from '@umbraco-ui/uui'; -import type { UmbWorkspacePropertyContext } from '../../../../shared/components/workspace-property/workspace-property.context'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { + UmbWorkspacePropertyContext, + UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, +} from '../../../../shared/components/workspace-property/workspace-property.context'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-property-editor-ui-textarea') export class UmbPropertyEditorUITextareaElement extends UmbLitElement implements UmbPropertyEditorElement { @@ -28,7 +31,7 @@ export class UmbPropertyEditorUITextareaElement extends UmbLitElement implements constructor() { super(); - this.consumeContext('umbPropertyContext', (instance: UmbWorkspacePropertyContext) => { + this.consumeContext(UMB_WORKSPACE_PROPERTY_CONTEXT_TOKEN, (instance: UmbWorkspacePropertyContext) => { this.propertyContext = instance; }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.stories.ts index 49cfb72302..389abbb0fe 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/textarea/property-editor-ui-textarea.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITextareaElement } from './property-editor-ui-textarea.element'; import './property-editor-ui-textarea.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/manifests.ts index 5363e9faec..2ce258ed7b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.element.ts index 82fa2edbd1..edcb9a17f0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-tiny-mce-configuration diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.stories.ts index 447be2a933..7d3ea279e8 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITinyMceConfigurationElement } from './property-editor-ui-tiny-mce-configuration.element'; import './property-editor-ui-tiny-mce-configuration.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.test.ts index 142ce9b535..25c0e4d6df 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/config/configuration/property-editor-ui-tiny-mce-configuration.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUITinyMceConfigurationElement } from './property-editor-ui-tiny-mce-configuration.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUITinyMceConfigurationElement', () => { let element: UmbPropertyEditorUITinyMceConfigurationElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/manifests.ts index 1c570b0cb8..1386dbae77 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/manifests.ts @@ -1,5 +1,5 @@ import { manifest as configuration } from './config/configuration/manifests'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.element.ts index dc3e18e17f..82382969ee 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-tiny-mce diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.stories.ts index 3dc06cef73..9de6efe4eb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITinyMceElement } from './property-editor-ui-tiny-mce.element'; import './property-editor-ui-tiny-mce.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.test.ts index 966c0db902..e6ad7abce6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tiny-mce/property-editor-ui-tiny-mce.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUITinyMceElement } from './property-editor-ui-tiny-mce.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUITinyMceElement', () => { let element: UmbPropertyEditorUITinyMceElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/manifests.ts index 0dc321a694..c753b44041 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.element.ts index 7c942602c3..1b7128c789 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.element.ts @@ -2,9 +2,9 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbInputToggleElement } from '../../../components/input-toggle/input-toggle.element'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DataTypePropertyModel } from '@umbraco-cms/backend-api'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-property-editor-ui-toggle @@ -26,7 +26,7 @@ export class UmbPropertyEditorUIToggleElement extends UmbLitElement implements U _showLabels?: boolean; @property({ type: Array, attribute: false }) - public set config(config: Array) { + public set config(config: Array) { const defaultValue = config.find((x) => x.alias === 'default'); if (defaultValue) this.value = defaultValue.value as boolean; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.stories.ts index 4720a23399..27b2a4a29f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIToggleElement } from './property-editor-ui-toggle.element'; import './property-editor-ui-toggle.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.test.ts index a46277d546..0df0a2b6d4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/toggle/property-editor-ui-toggle.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIToggleElement } from './property-editor-ui-toggle.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIToggleElement', () => { let element: UmbPropertyEditorUIToggleElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/manifests.ts index 0d1206a872..22a9b853b2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.element.ts index 5975246ffe..39e0f4aba0 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-tree-picker-start-node diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.stories.ts index 3cec8808f8..514000a8ea 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITreePickerStartNodeElement } from './property-editor-ui-tree-picker-start-node.element'; import './property-editor-ui-tree-picker-start-node.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.test.ts index 461ae27a2f..722f09ac07 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/config/start-node/property-editor-ui-tree-picker-start-node.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUITreePickerStartNodeElement } from './property-editor-ui-tree-picker-start-node.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUITreePickerStartNodeElement', () => { let element: UmbPropertyEditorUITreePickerStartNodeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/manifests.ts index 0743c08937..9b585b3a59 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/manifests.ts @@ -1,5 +1,5 @@ import { manifest as startNode } from './config/start-node/manifests'; -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.element.ts index dc03722e39..94f3e28c9d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-tree-picker diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.stories.ts index ef4f2ef961..cfc9ef64b2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUITreePickerElement } from './property-editor-ui-tree-picker.element'; import './property-editor-ui-tree-picker.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.test.ts index 1550ae7b02..46117fb197 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/tree-picker/property-editor-ui-tree-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUITreePickerElement } from './property-editor-ui-tree-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUITreePickerElement', () => { let element: UmbPropertyEditorUITreePickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/manifests.ts index 558ae359e8..941229b65a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.element.ts index aae5553516..56afaf29ca 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.element.ts @@ -1,8 +1,10 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { customElement, property, state } from 'lit/decorators.js'; +import { UmbInputUploadFieldElement } from '../../../../shared/components/input-upload-field/input-upload-field.element'; +import type { DataTypePropertyPresentationModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-upload-field @@ -15,10 +17,30 @@ export class UmbPropertyEditorUIUploadFieldElement extends UmbLitElement impleme value = ''; @property({ type: Array, attribute: false }) - public config = []; + public set config(config: Array) { + const fileExtensions = config.find((x) => x.alias === 'fileExtensions'); + if (fileExtensions) this._fileExtensions = fileExtensions.value; + + const multiple = config.find((x) => x.alias === 'multiple'); + if (multiple) this._multiple = multiple.value; + } + + @state() + private _fileExtensions?: Array; + + @state() + private _multiple?: boolean; + + private _onChange(event: CustomEvent) { + this.value = (event.target as unknown as UmbInputUploadFieldElement).value as string; + this.dispatchEvent(new CustomEvent('property-value-change')); + } render() { - return html`
    umb-property-editor-ui-upload-field
    `; + return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.stories.ts index ba5426d78b..7729437b01 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIUploadFieldElement } from './property-editor-ui-upload-field.element'; import './property-editor-ui-upload-field.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.test.ts index 05c26b8ca5..a430089aec 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/upload-field/property-editor-ui-upload-field.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIUploadFieldElement } from './property-editor-ui-upload-field.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIUploadFieldElement', () => { let element: UmbPropertyEditorUIUploadFieldElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/manifests.ts index 5ea5535cfa..f3dc215dfd 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.element.ts index 28b123ef1e..0a24a724b4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-user-picker diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.stories.ts index 503373fd41..b57a2e47f4 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIUserPickerElement } from './property-editor-ui-user-picker.element'; import './property-editor-ui-user-picker.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.test.ts index 26abdd82aa..d9c269599c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/user-picker/property-editor-ui-user-picker.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIUserPickerElement } from './property-editor-ui-user-picker.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIUserPickerElement', () => { let element: UmbPropertyEditorUIUserPickerElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/manifests.ts index d39e979da2..b7bf15bcb7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestPropertyEditorUI } from '@umbraco-cms/models'; +import type { ManifestPropertyEditorUI } from '@umbraco-cms/backoffice/extensions-registry'; export const manifest: ManifestPropertyEditorUI = { type: 'propertyEditorUI', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.element.ts index b9e0a781e1..351777767a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, property } from 'lit/decorators.js'; -import { UmbPropertyEditorElement } from '@umbraco-cms/property-editor'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbPropertyEditorElement } from '@umbraco-cms/backoffice/property-editor'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-property-editor-ui-value-type diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.stories.ts index e2883ab499..f0ec7b357f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbPropertyEditorUIValueTypeElement } from './property-editor-ui-value-type.element'; import './property-editor-ui-value-type.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.test.ts index 3e5d5bc3ae..4f79194650 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/value-type/property-editor-ui-value-type.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbPropertyEditorUIValueTypeElement } from './property-editor-ui-value-type.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbPropertyEditorUIValueTypeElement', () => { let element: UmbPropertyEditorUIValueTypeElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/file-system-tree-item/file-system-tree-item.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/file-system-tree-item/file-system-tree-item.context.ts new file mode 100644 index 0000000000..670d5d6be4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/file-system-tree-item/file-system-tree-item.context.ts @@ -0,0 +1,15 @@ +import { UmbTreeItemContextBase } from '../../../shared/components/tree/tree-item-base/tree-item-base.context'; +import { urlFriendlyPathFromServerFilePath } from '../../utils'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; + +// TODO get unique method from an entity repository static method +export class UmbFileSystemTreeItemContext extends UmbTreeItemContextBase { + constructor(host: UmbControllerHostElement) { + super(host, (x: FileSystemTreeItemPresentationModel) => x.path); + } + + constructPath(pathname: string, entityType: string, path: string) { + return `section/${pathname}/workspace/${entityType}/edit/${urlFriendlyPathFromServerFilePath(path)}`; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/file-system-tree-item/file-system-tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/file-system-tree-item/file-system-tree-item.element.ts new file mode 100644 index 0000000000..1d18dc610a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/file-system-tree-item/file-system-tree-item.element.ts @@ -0,0 +1,49 @@ +import { css, html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, property } from 'lit/decorators.js'; +import { UmbFileSystemTreeItemContext } from './file-system-tree-item.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { ManifestKind } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; + +// TODO: Move to separate file: +const manifest: ManifestKind = { + type: 'kind', + alias: 'Umb.Kind.FileSystemTreeItem', + matchKind: 'fileSystem', + matchType: 'treeItem', + manifest: { + type: 'treeItem', + elementName: 'umb-file-system-tree-item', + }, +}; +umbExtensionsRegistry.register(manifest); + +@customElement('umb-file-system-tree-item') +export class UmbFileSystemTreeItemElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + private _item?: FileSystemTreeItemPresentationModel; + @property({ type: Object, attribute: false }) + public get item() { + return this._item; + } + public set item(value: FileSystemTreeItemPresentationModel | undefined) { + this._item = value; + this.#context.setTreeItem(value); + } + + #context = new UmbFileSystemTreeItemContext(this); + + render() { + if (!this.item) return nothing; + return html``; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-file-system-tree-item': UmbFileSystemTreeItemElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/index.ts new file mode 100644 index 0000000000..23987fc391 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/components/index.ts @@ -0,0 +1 @@ +import './file-system-tree-item/file-system-tree-item.element'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/index.ts index a869c8a5fb..27ba7af32b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/index.ts @@ -1,9 +1,12 @@ import { manifests as menuManifests } from './menu.manifests'; import { manifests as templateManifests } from './templates/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { manifests as stylesheetManifests } from './stylesheets/manifests'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -export const manifests = [...menuManifests, ...templateManifests]; +import './components'; + +export const manifests = [...menuManifests, ...templateManifests, ...stylesheetManifests]; const registerExtensions = (manifests: Array) => { manifests.forEach((manifest) => umbExtensionsRegistry.register(manifest)); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/menu.manifests.ts index 700ff9b7be..f27e9289be 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/menu.manifests.ts @@ -1,4 +1,4 @@ -import { ManifestMenuSectionSidebarApp, ManifestMenu } from '@umbraco-cms/extensions-registry'; +import { ManifestMenu, ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; const menu: ManifestMenu = { type: 'menu', @@ -9,16 +9,19 @@ const menu: ManifestMenu = { }, }; -const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = { - type: 'menuSectionSidebarApp', +const menuSectionSidebarApp: ManifestTypes = { + type: 'sectionSidebarApp', + kind: 'menu', alias: 'Umb.SectionSidebarMenu.Templating', name: 'Templating Section Sidebar Menu', weight: 100, meta: { label: 'Templating', - sections: ['Umb.Section.Settings'], menu: 'Umb.Menu.Templating', }, + conditions: { + sections: ['Umb.Section.Settings'], + }, }; export const manifests = [menu, menuSectionSidebarApp]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/index.ts new file mode 100644 index 0000000000..7d6c362f01 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/index.ts @@ -0,0 +1,8 @@ +import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; + +// TODO: temp until we have a proper stylesheet model +export interface StylesheetDetails extends FileSystemTreeItemPresentationModel { + content: string; +} + +export const STYLESHEET_ENTITY_TYPE = 'stylesheet'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/manifests.ts new file mode 100644 index 0000000000..ddaa4babdc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/manifests.ts @@ -0,0 +1,6 @@ +import { manifests as repositoryManifests } from './repository/manifests'; +import { manifests as menuItemManifests } from './menu-item/manifests'; +import { manifests as treeManifests } from './tree/manifests'; +import { manifests as workspaceManifests } from './workspace/manifests'; + +export const manifests = [...repositoryManifests, ...menuItemManifests, ...treeManifests, ...workspaceManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/menu-item/manifests.ts new file mode 100644 index 0000000000..c6ee826fc0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/menu-item/manifests.ts @@ -0,0 +1,20 @@ +import { STYLESHEET_TREE_ALIAS } from '../tree/manifests'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; + +const menuItem: ManifestTypes = { + type: 'menuItem', + kind: 'tree', + alias: 'Umb.MenuItem.Stylesheets', + name: 'Stylesheets Menu Item', + weight: 400, + meta: { + label: 'Stylesheets', + icon: 'umb:folder', + treeAlias: STYLESHEET_TREE_ALIAS, + }, + conditions: { + menus: ['Umb.Menu.Templating'], + }, +}; + +export const manifests = [menuItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/manifests.ts new file mode 100644 index 0000000000..a47e28ae46 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/manifests.ts @@ -0,0 +1,24 @@ +import { UmbStylesheetRepository } from './stylesheet.repository'; +import { UmbStylesheetTreeStore } from './stylesheet.tree.store'; +import { ManifestRepository, ManifestTreeStore } from '@umbraco-cms/backoffice/extensions-registry'; + +export const STYLESHEET_REPOSITORY_ALIAS = 'Umb.Repository.Stylesheet'; + +const repository: ManifestRepository = { + type: 'repository', + alias: STYLESHEET_REPOSITORY_ALIAS, + name: 'Stylesheet Repository', + class: UmbStylesheetRepository, +}; + +export const STYLESHEET_STORE_ALIAS = 'Umb.Store.Stylesheet'; +export const STYLESHEET_TREE_STORE_ALIAS = 'Umb.Store.StylesheetTree'; + +const treeStore: ManifestTreeStore = { + type: 'treeStore', + alias: STYLESHEET_TREE_STORE_ALIAS, + name: 'Stylesheet Tree Store', + class: UmbStylesheetTreeStore, +}; + +export const manifests = [treeStore, repository]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/sources/stylesheet.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/sources/stylesheet.server.data.ts new file mode 100644 index 0000000000..6ce1917236 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/sources/stylesheet.server.data.ts @@ -0,0 +1,47 @@ +import { StylesheetDetails } from '../..'; +import { DataSourceResponse, UmbDataSource } from '@umbraco-cms/backoffice/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +/** + * A data source for the Stylesheet that fetches data from the server + * @export + * @class UmbStylesheetServerDataSource + * @implements {UmbStylesheetServerDataSource} + */ +export class UmbStylesheetServerDataSource implements UmbDataSource { + #host: UmbControllerHostElement; + + /** + * Creates an instance of UmbStylesheetServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbStylesheetServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + createScaffold(parentId: string | null): Promise> { + throw new Error('Method not implemented.'); + } + + /** + * Fetches a Stylesheet with the given path from the server + * @param {string} path + * @return {*} + * @memberof UmbStylesheetServerDataSource + */ + async get(path: string) { + if (!path) throw new Error('Path is missing'); + console.log('GET STYLESHEET WITH PATH', path); + return { data: undefined, error: undefined }; + } + + insert(data: StylesheetDetails): Promise> { + throw new Error('Method not implemented.'); + } + update(path: string, data: StylesheetDetails): Promise> { + throw new Error('Method not implemented.'); + } + delete(path: string): Promise { + throw new Error('Method not implemented.'); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/sources/stylesheet.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/sources/stylesheet.tree.server.data.ts new file mode 100644 index 0000000000..5b7674f6df --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/sources/stylesheet.tree.server.data.ts @@ -0,0 +1,68 @@ +import { + FileSystemTreeItemPresentationModel, + PagedFileSystemTreeItemPresentationModel, + StylesheetResource, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; + +/** + * A data source for the Stylesheet tree that fetches data from the server + * @export + * @class UmbStylesheetTreeServerDataSource + * @implements {UmbTreeDataSource} + */ +export class UmbStylesheetTreeServerDataSource + implements UmbTreeDataSource +{ + #host: UmbControllerHostElement; + + /** + * Creates an instance of UmbStylesheetTreeServerDataSource. + * @param {UmbControllerHostElement} host + * @memberof UmbStylesheetTreeServerDataSource + */ + constructor(host: UmbControllerHostElement) { + this.#host = host; + } + + /** + * Fetches the stylesheet tree root items from the server + * @return {*} + * @memberof UmbStylesheetTreeServerDataSource + */ + async getRootItems() { + return tryExecuteAndNotify(this.#host, StylesheetResource.getTreeStylesheetRoot({})); + } + + /** + * Fetches the children of a given stylesheet path from the server + * @param {(string | undefined)} path + * @return {*} + * @memberof UmbStylesheetTreeServerDataSource + */ + async getChildrenOf(path: string | undefined) { + return tryExecuteAndNotify( + this.#host, + StylesheetResource.getTreeStylesheetChildren({ + path, + }) + ); + } + + /** + * Fetches stylesheet items from the server + * @param {(string | undefined)} path + * @return {*} + * @memberof UmbStylesheetTreeServerDataSource + */ + async getItems(path: Array) { + return tryExecuteAndNotify( + this.#host, + StylesheetResource.getStylesheetItem({ + path, + }) + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/stylesheet.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/stylesheet.repository.ts new file mode 100644 index 0000000000..fd73a0cda1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/stylesheet.repository.ts @@ -0,0 +1,110 @@ +import { UmbStylesheetTreeStore, UMB_STYLESHEET_TREE_STORE_CONTEXT_TOKEN } from './stylesheet.tree.store'; +import { UmbStylesheetTreeServerDataSource } from './sources/stylesheet.tree.server.data'; +import { UmbStylesheetServerDataSource } from './sources/stylesheet.server.data'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; +import { + FileSystemTreeItemPresentationModel, + PagedFileSystemTreeItemPresentationModel, +} from '@umbraco-cms/backoffice/backend-api'; + +export class UmbStylesheetRepository + implements UmbTreeRepository +{ + #host; + #dataSource; + #treeDataSource; + #treeStore?: UmbStylesheetTreeStore; + #notificationContext?: UmbNotificationContext; + #initResolver?: () => void; + #initialized = false; + + constructor(host: UmbControllerHostElement) { + this.#host = host; + + // TODO: figure out how spin up get the correct data source + this.#dataSource = new UmbStylesheetServerDataSource(this.#host); + this.#treeDataSource = new UmbStylesheetTreeServerDataSource(this.#host); + + new UmbContextConsumerController(this.#host, UMB_STYLESHEET_TREE_STORE_CONTEXT_TOKEN, (instance) => { + this.#treeStore = instance; + this.#checkIfInitialized(); + }); + + new UmbContextConsumerController(this.#host, UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { + this.#notificationContext = instance; + this.#checkIfInitialized(); + }); + } + + #init = new Promise((resolve) => { + this.#initialized ? resolve() : (this.#initResolver = resolve); + }); + + #checkIfInitialized() { + if (this.#treeStore && this.#notificationContext) { + this.#initialized = true; + this.#initResolver?.(); + } + } + + async requestRootTreeItems() { + await this.#init; + + const { data, error } = await this.#treeDataSource.getRootItems(); + + if (data) { + this.#treeStore?.appendItems(data.items); + } + + return { data, error }; + } + + async requestTreeItemsOf(path: string | null) { + if (!path) throw new Error('Cannot request tree item with missing path'); + + await this.#init; + + const { data, error } = await this.#treeDataSource.getChildrenOf(path); + + if (data) { + this.#treeStore!.appendItems(data.items); + } + + return { data, error, asObservable: () => this.#treeStore!.childrenOf(path) }; + } + + async requestTreeItems(paths: Array) { + if (!paths) throw new Error('Paths are missing'); + await this.#init; + const { data, error } = await this.#treeDataSource.getItems(paths); + return { data, error }; + } + + async rootTreeItems() { + await this.#init; + return this.#treeStore!.rootItems; + } + + async treeItemsOf(parentPath: string | null) { + if (!parentPath) throw new Error('Parent Path is missing'); + await this.#init; + return this.#treeStore!.childrenOf(parentPath); + } + + async treeItems(paths: Array) { + if (!paths) throw new Error('Paths are missing'); + await this.#init; + return this.#treeStore!.items(paths); + } + + // DETAILS + async requestByPath(path: string) { + if (!path) throw new Error('Path is missing'); + await this.#init; + const { data, error } = await this.#dataSource.get(path); + return { data, error }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/stylesheet.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/stylesheet.tree.store.ts new file mode 100644 index 0000000000..317f94c2b4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/repository/stylesheet.tree.store.ts @@ -0,0 +1,24 @@ +import { UmbFileSystemTreeStore } from '@umbraco-cms/backoffice/store'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; + +/** + * @export + * @class UmbStylesheetTreeStore + * @extends {UmbEntityTreeStore} + * @description - Tree Data Store for Stylesheets + */ +export class UmbStylesheetTreeStore extends UmbFileSystemTreeStore { + /** + * Creates an instance of UmbStylesheetTreeStore. + * @param {UmbControllerHostElement} host + * @memberof UmbStylesheetTreeStore + */ + constructor(host: UmbControllerHostElement) { + super(host, UMB_STYLESHEET_TREE_STORE_CONTEXT_TOKEN.toString()); + } +} + +export const UMB_STYLESHEET_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken( + 'UmbStylesheetTreeStore' +); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/tree/manifests.ts new file mode 100644 index 0000000000..c93536bd70 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/tree/manifests.ts @@ -0,0 +1,27 @@ +import { STYLESHEET_ENTITY_TYPE } from '..'; +import { STYLESHEET_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; + +export const STYLESHEET_TREE_ALIAS = 'Umb.Tree.Stylesheet'; + +const tree: ManifestTree = { + type: 'tree', + alias: STYLESHEET_TREE_ALIAS, + name: 'Stylesheet Tree', + weight: 10, + meta: { + repositoryAlias: STYLESHEET_REPOSITORY_ALIAS, + }, +}; + +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'fileSystem', + alias: 'Umb.TreeItem.Stylesheet', + name: 'Stylesheet Tree Item', + conditions: { + entityType: STYLESHEET_ENTITY_TYPE, + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/manifests.ts new file mode 100644 index 0000000000..ad0675cf06 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/manifests.ts @@ -0,0 +1,20 @@ +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; + +const workspace: ManifestWorkspace = { + type: 'workspace', + alias: 'Umb.Workspace.StyleSheet', + name: 'Stylesheet Workspace', + loader: () => import('./stylesheet-workspace.element'), + meta: { + entityType: 'stylesheet', + }, +}; + +const workspaceViews: Array = []; +const workspaceActions: Array = []; + +export const manifests = [workspace, ...workspaceViews, ...workspaceActions]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace-edit.element.ts new file mode 100644 index 0000000000..69c89804e5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace-edit.element.ts @@ -0,0 +1,29 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; + +@customElement('umb-stylesheet-workspace-edit') +export class UmbStylesheetWorkspaceEditElement extends LitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + `, + ]; + + render() { + return html` Stylesheet workspace `; + } +} + +export default UmbStylesheetWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-stylesheet-workspace-edit': UmbStylesheetWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.context.ts new file mode 100644 index 0000000000..a973a00a4b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.context.ts @@ -0,0 +1,42 @@ +import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; +import { UmbStylesheetRepository } from '../repository/stylesheet.repository'; +import { StylesheetDetails } from '..'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; + +export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext { + #data = new ObjectState(undefined); + data = this.#data.asObservable(); + + constructor(host: UmbControllerHostElement) { + super(host, new UmbStylesheetRepository(host)); + } + + getEntityType(): string { + return 'stylesheet'; + } + + getData() { + return this.#data.getValue(); + } + + getEntityId() { + return this.getData()?.path || ''; + } + + async load(path: string) { + const { data } = await this.repository.requestByPath(path); + if (data) { + this.setIsNew(false); + this.#data.update(data); + } + } + + public async save() { + throw new Error('Save method not implemented.'); + } + + public destroy(): void { + this.#data.complete(); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.element.ts new file mode 100644 index 0000000000..0d9d3487c1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.element.ts @@ -0,0 +1,50 @@ +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { serverFilePathFromUrlFriendlyPath } from '../../utils'; +import { UmbStylesheetWorkspaceEditElement } from './stylesheet-workspace-edit.element'; +import { UmbStylesheetWorkspaceContext } from './stylesheet-workspace.context'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-stylesheet-workspace') +export class UmbStylesheetWorkspaceElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + width: 100%; + height: 100%; + } + `, + ]; + + #workspaceContext = new UmbStylesheetWorkspaceContext(this); + #element = new UmbStylesheetWorkspaceEditElement(); + + @state() + _routes: IRoute[] = [ + { + path: 'edit/:path', + component: () => this.#element, + setup: (_component, info) => { + const path = info.match.params.path; + const serverPath = serverFilePathFromUrlFriendlyPath(path); + this.#workspaceContext.load(serverPath); + }, + }, + ]; + + render() { + return html` `; + } +} + +export default UmbStylesheetWorkspaceElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-stylesheet-workspace': UmbStylesheetWorkspaceElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.stories.ts new file mode 100644 index 0000000000..9642c1b6bb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/stylesheets/workspace/stylesheet-workspace.stories.ts @@ -0,0 +1,16 @@ +import './stylesheet-workspace.element'; + +import { Meta, Story } from '@storybook/web-components'; +import { html } from 'lit'; + +import type { UmbStylesheetWorkspaceElement } from './stylesheet-workspace.element'; + +export default { + title: 'Workspaces/Stylesheet', + component: 'umb-stylesheet-workspace', + id: 'umb-stylesheet-workspace', +} as Meta; + +export const AAAOverview: Story = () => + html` `; +AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/create/create.action.ts index eb5c1bca61..97067b0fc3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/create/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/create/create.action.ts @@ -1,8 +1,8 @@ -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export class UmbCreateEntityAction }> extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/manifests.ts index eead35cbed..a85363c686 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/entity-actions/manifests.ts @@ -1,7 +1,7 @@ import { TEMPLATE_REPOSITORY_ALIAS } from '../repository/manifests'; import { UmbCreateEntityAction } from './create/create.action'; -import { UmbDeleteEntityAction } from '@umbraco-cms/entity-action'; -import { ManifestEntityAction } from 'libs/extensions-registry/entity-action.models'; +import { ManifestEntityAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { UmbDeleteEntityAction } from '@umbraco-cms/backoffice/entity-action'; const entityActions: Array = [ { @@ -9,24 +9,28 @@ const entityActions: Array = [ alias: 'Umb.EntityAction.Template.Create', name: 'Create Template Entity Action', meta: { - entityType: 'template', icon: 'umb:add', label: 'Create', api: UmbCreateEntityAction, repositoryAlias: TEMPLATE_REPOSITORY_ALIAS, }, + conditions: { + entityType: 'template', + }, }, { type: 'entityAction', alias: 'Umb.EntityAction.Template.Delete', name: 'Delete Template Entity Action', meta: { - entityType: 'template', icon: 'umb:trash', label: 'Delete', api: UmbDeleteEntityAction, repositoryAlias: TEMPLATE_REPOSITORY_ALIAS, }, + conditions: { + entityType: 'template', + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/menu-item/manifests.ts index 1f84068f1d..c97219a775 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/menu-item/manifests.ts @@ -1,15 +1,18 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -const menuItem: ManifestMenuItem = { +const menuItem: ManifestTypes = { type: 'menuItem', + kind: 'tree', alias: 'Umb.MenuItem.Templates', name: 'Templates Menu Item', weight: 40, - loader: () => import('./templates-menu-item.element'), meta: { label: 'Templates', icon: 'umb:folder', entityType: 'template', + treeAlias: 'Umb.Tree.Templates', + }, + conditions: { menus: ['Umb.Menu.Templating'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/menu-item/templates-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/menu-item/templates-menu-item.element.ts deleted file mode 100644 index d9b9600990..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/menu-item/templates-menu-item.element.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { html, nothing } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; - -@customElement('umb-templates-menu-item') -export class UmbTemplatesMenuItemElement extends UmbLitElement { - @state() - private _renderTree = false; - - private _onShowChildren() { - this._renderTree = true; - } - - private _onHideChildren() { - this._renderTree = false; - } - - // TODO: check if root has children before settings the has-children attribute - // TODO: how do we want to cache the tree? (do we want to rerender every time the user opens the tree)? - // TODO: can we make this reusable? - render() { - return html` - ${this._renderTree ? html`` : nothing} - `; - } -} - -export default UmbTemplatesMenuItemElement; - -declare global { - interface HTMLElementTagNameMap { - 'umb-templates-menu-item': UmbTemplatesMenuItemElement; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/manifests.ts index ba3295e7e1..2ff152e430 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbTemplateRepository } from '../repository/template.repository'; import { UmbTemplateTreeStore } from './template.tree.store'; import { UmbTemplateStore } from './template.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const TEMPLATE_REPOSITORY_ALIAS = 'Umb.Repository.Template'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/index.ts index 35c6f99794..934e2e05ed 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/index.ts @@ -1,8 +1,8 @@ -import type { DataSourceResponse } from '@umbraco-cms/models'; -import type { EntityTreeItemModel, PagedEntityTreeItemModel } from '@umbraco-cms/backend-api'; +import type { DataSourceResponse } from '@umbraco-cms/backoffice/repository'; +import type { ItemResponseModelBaseModel, PagedEntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; export interface TemplateTreeDataSource { - getRootItems(): Promise>; - getChildrenOf(parentKey: string): Promise>; - getItems(key: Array): Promise>; + getRootItems(): Promise>; + getChildrenOf(parentId: string): Promise>; + getItems(ids: Array): Promise>; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.detail.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.detail.server.data.ts index 0d6f39e347..5fdffe4c7e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.detail.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.detail.server.data.ts @@ -1,16 +1,13 @@ import { v4 as uuid } from 'uuid'; -import { ProblemDetailsModel, TemplateModel, TemplateResource } from '@umbraco-cms/backend-api'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; -import type { DataSourceResponse } from '@umbraco-cms/models'; - -export interface TemplateDetailDataSource { - createScaffold(): Promise>; - get(key: string): Promise>; - insert(template: TemplateModel): Promise; - update(template: TemplateModel): Promise; - delete(key: string): Promise; -} +import { + TemplateResponseModel, + TemplateResource, + CreateTemplateRequestModel, + UpdateTemplateRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import type { UmbDataSource } from '@umbraco-cms/backoffice/repository'; /** * A data source for the Template detail that fetches data from the server @@ -18,39 +15,41 @@ export interface TemplateDetailDataSource { * @class UmbTemplateDetailServerDataSource * @implements {TemplateDetailDataSource} */ -export class UmbTemplateDetailServerDataSource implements TemplateDetailDataSource { - #host: UmbControllerHostInterface; +export class UmbTemplateDetailServerDataSource + implements UmbDataSource +{ + #host: UmbControllerHostElement; /** * Creates an instance of UmbTemplateDetailServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbTemplateDetailServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** - * Fetches a Template with the given key from the server - * @param {string} key + * Fetches a Template with the given id from the server + * @param {string} id * @return {*} * @memberof UmbTemplateDetailServerDataSource */ - get(key: string) { - return tryExecuteAndNotify(this.#host, TemplateResource.getTemplateByKey({ key })); + get(id: string) { + return tryExecuteAndNotify(this.#host, TemplateResource.getTemplateById({ id })); } /** * Creates a new Template scaffold - * @param {(string | null)} parentKey + * @param {(string | null)} parentId * @return {*} * @memberof UmbTemplateDetailServerDataSource */ async createScaffold() { const error = undefined; - const data: TemplateModel = { + const data: TemplateResponseModel = { $type: '', - key: uuid(), + id: uuid(), name: '', alias: '', content: '', @@ -77,13 +76,13 @@ export class UmbTemplateDetailServerDataSource implements TemplateDetailDataSour * @return {*} * @memberof UmbTemplateDetailServerDataSource */ - async insert(template: TemplateModel) { - const payload = { requestBody: template }; - // TODO: fix type mismatch + async insert(template: CreateTemplateRequestModel) { + if (!template) throw new Error('Template is missing'); + return tryExecuteAndNotify( this.#host, - tryExecuteAndNotify(this.#host, TemplateResource.postTemplate(payload)) as any - ) as any; + tryExecuteAndNotify(this.#host, TemplateResource.postTemplate({ requestBody: template })) + ); } /** @@ -92,28 +91,20 @@ export class UmbTemplateDetailServerDataSource implements TemplateDetailDataSour * @return {*} * @memberof UmbTemplateDetailServerDataSource */ - async update(template: TemplateModel) { - if (!template.key) { - const error: ProblemDetailsModel = { title: 'Template key is missing' }; - return { error }; - } - - const payload = { key: template.key, requestBody: template }; - return tryExecuteAndNotify(this.#host, TemplateResource.putTemplateByKey(payload)); + async update(id: string, template: UpdateTemplateRequestModel) { + if (!id) throw new Error('Id is missing'); + if (!template) throw new Error('Template is missing'); + return tryExecuteAndNotify(this.#host, TemplateResource.putTemplateById({ id, requestBody: template })); } /** * Deletes a Template on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbTemplateDetailServerDataSource */ - async delete(key: string) { - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - - return await tryExecuteAndNotify(this.#host, TemplateResource.deleteTemplateByKey({ key })); + async delete(id: string) { + if (!id) throw new Error('Id is missing'); + return await tryExecuteAndNotify(this.#host, TemplateResource.deleteTemplateById({ id })); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.tree.server.data.ts index 4d1bfedb2b..ed7be4b8d9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/sources/template.tree.server.data.ts @@ -1,7 +1,7 @@ import { TemplateTreeDataSource } from '.'; -import { ProblemDetailsModel, TemplateResource } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { ProblemDetailsModel, TemplateResource } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Template tree that fetches data from the server @@ -10,14 +10,14 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @implements {TemplateTreeDataSource} */ export class TemplateTreeServerDataSource implements TemplateTreeDataSource { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; /** * Creates an instance of TemplateTreeServerDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof TemplateTreeServerDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -31,41 +31,41 @@ export class TemplateTreeServerDataSource implements TemplateTreeDataSource { } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} * @memberof TemplateTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + async getChildrenOf(parentId: string | null) { + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, TemplateResource.getTreeTemplateChildren({ - parentKey, + parentId, }) ); } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} id * @return {*} * @memberof TemplateTreeServerDataSource */ - async getItems(keys: Array) { - if (!keys) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; + async getItems(ids: Array) { + if (!ids) { + const error: ProblemDetailsModel = { title: 'Ids are missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - TemplateResource.getTreeTemplateItem({ - key: keys, + TemplateResource.getTemplateItem({ + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.repository.ts index 3c8cf551b1..0ec0c4baa7 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.repository.ts @@ -2,16 +2,24 @@ import { UmbTemplateDetailServerDataSource } from './sources/template.detail.ser import { TemplateTreeServerDataSource } from './sources/template.tree.server.data'; import { UmbTemplateStore, UMB_TEMPLATE_STORE_CONTEXT_TOKEN } from './template.store'; import { UmbTemplateTreeStore, UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN } from './template.tree.store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { ProblemDetailsModel, TemplateModel } from '@umbraco-cms/backend-api'; -import { UmbDetailRepository } from 'libs/repository/detail-repository.interface'; -import { UmbTreeRepository } from 'libs/repository/tree-repository.interface'; +import type { UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { + CreateTemplateRequestModel, + ProblemDetailsModel, + TemplateResponseModel, + UpdateTemplateRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; -export class UmbTemplateRepository implements UmbTreeRepository, UmbDetailRepository { +export class UmbTemplateRepository + implements + UmbTreeRepository, + UmbDetailRepository +{ #init; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; #treeDataSource: TemplateTreeServerDataSource; #detailDataSource: UmbTemplateDetailServerDataSource; @@ -21,7 +29,7 @@ export class UmbTemplateRepository implements UmbTreeRepository, UmbDetailReposi #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source @@ -57,34 +65,34 @@ export class UmbTemplateRepository implements UmbTreeRepository, UmbDetailReposi return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeDataSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeDataSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeDataSource.getItems(keys); + const { data, error } = await this.#treeDataSource.getItems(ids); - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -92,39 +100,39 @@ export class UmbTemplateRepository implements UmbTreeRepository, UmbDetailReposi return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS: - async createScaffold(parentKey: string | null) { + async createScaffold(parentId: string | null) { await this.#init; - if (!parentKey) { - throw new Error('Parent key is missing'); + if (!parentId) { + throw new Error('Parent id is missing'); } - // TODO: add parent key to create scaffold + // TODO: add parent id to create scaffold return this.#detailDataSource.createScaffold(); } - async requestByKey(key: string) { + async requestById(id: string) { await this.#init; - // TODO: should we show a notification if the key is missing? + // TODO: should we show a notification if the id is missing? // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - const { data, error } = await this.#detailDataSource.get(key); + const { data, error } = await this.#detailDataSource.get(id); if (data) { this.#store?.append(data); @@ -135,10 +143,10 @@ export class UmbTemplateRepository implements UmbTreeRepository, UmbDetailReposi // Could potentially be general methods: - async create(template: TemplateModel) { + async create(template: TemplateResponseModel) { await this.#init; - if (!template || !template.key) { + if (!template || !template.id) { throw new Error('Template is missing'); } @@ -157,40 +165,39 @@ export class UmbTemplateRepository implements UmbTreeRepository, UmbDetailReposi return { error }; } - async save(template: TemplateModel) { + async save(id: string, template: UpdateTemplateRequestModel) { + if (!id) throw new Error('Id is missing'); + if (!template) throw new Error('Template is missing'); + await this.#init; - if (!template || !template.key) { - throw new Error('Template is missing'); - } - - const { error } = await this.#detailDataSource.update(template); + const { error } = await this.#detailDataSource.update(id, template); if (!error) { const notification = { data: { message: `Template saved` } }; this.#notificationContext?.peek('positive', notification); - } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - // Consider notify a workspace if a template is updated in the store while someone is editing it. - this.#store?.append(template); - this.#treeStore?.updateItem(template.key, { name: template.name }); - // TODO: would be nice to align the stores on methods/methodNames. + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a template is updated in the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + //this.#store?.append(template); + this.#treeStore?.updateItem(id, template); + } return { error }; } // General: - async delete(key: string) { + async delete(id: string) { await this.#init; - if (!key) { - throw new Error('Template key is missing'); + if (!id) { + throw new Error('Template id is missing'); } - const { error } = await this.#detailDataSource.delete(key); + const { error } = await this.#detailDataSource.delete(id); if (!error) { const notification = { data: { message: `Template deleted` } }; @@ -200,8 +207,8 @@ export class UmbTemplateRepository implements UmbTreeRepository, UmbDetailReposi // TODO: we currently don't use the detail store for anything. // Consider to look up the data before fetching from the server. // Consider notify a workspace if a template is deleted from the store while someone is editing it. - this.#store?.remove([key]); - this.#treeStore?.removeItem(key); + this.#store?.remove([id]); + this.#treeStore?.removeItem(id); // TODO: would be nice to align the stores on methods/methodNames. return { error }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.store.ts index 0051164f79..edebf64d61 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.store.ts @@ -1,8 +1,8 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import type { TemplateModel } from '@umbraco-cms/backend-api'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import type { TemplateResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export @@ -11,14 +11,14 @@ import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; * @description - Data Store for Templates */ export class UmbTemplateStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); /** * Creates an instance of UmbTemplateStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbTemplateStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_TEMPLATE_STORE_CONTEXT_TOKEN.toString()); } @@ -27,7 +27,7 @@ export class UmbTemplateStore extends UmbStoreBase { * @param {Template} template * @memberof UmbTemplateStore */ - append(template: TemplateModel) { + append(template: TemplateResponseModel) { this.#data.append([template]); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.tree.store.ts index 448bde7b44..d243c300f9 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/repository/template.tree.store.ts @@ -1,10 +1,8 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; -export const UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken( - 'UmbTemplateTreeStore' -); +export const UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbTemplateTreeStore'); /** * @export @@ -12,13 +10,13 @@ export const UMB_TEMPLATE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken = [ meta: { look: 'primary', color: 'positive', - workspaces: ['Umb.Workspace.Template'], label: 'Save', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Template'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts index 16886f30de..d4f7541846 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/templates/workspace/template-workspace.context.ts @@ -1,19 +1,27 @@ import { UmbTemplateRepository } from '../repository/template.repository'; import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { createObservablePart, DeepState } from '@umbraco-cms/observable-api'; -import { TemplateModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { createObservablePart, DeepState } from '@umbraco-cms/backoffice/observable-api'; +import { TemplateResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; -export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext { - #data = new DeepState(undefined); +export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext { + #data = new DeepState(undefined); data = this.#data.asObservable(); name = createObservablePart(this.#data, (data) => data?.name); content = createObservablePart(this.#data, (data) => data?.content); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbTemplateRepository(host)); } + getEntityType(): string { + return 'template'; + } + + getEntityId() { + return this.getData()?.id || ''; + } + getData() { return this.#data.getValue(); } @@ -26,18 +34,26 @@ export class UmbTemplateWorkspaceContext extends UmbWorkspaceContext - - + + + Insert "My hovercraft is full of eels" + + + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/templating/utils.ts b/src/Umbraco.Web.UI.Client/src/backoffice/templating/utils.ts new file mode 100644 index 0000000000..80214bb7fd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/templating/utils.ts @@ -0,0 +1,5 @@ +// TODO: we can try and make pretty urls if we want to +export const urlFriendlyPathFromServerFilePath = (path: string) => encodeURIComponent(path).replace('.', '-'); + +// TODO: we can try and make pretty urls if we want to +export const serverFilePathFromUrlFriendlyPath = (unique: string) => decodeURIComponent(unique.replace('-', '.')); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/themes/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/themes/manifests.ts index be1f5ad5f7..994b6e8b58 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/themes/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/themes/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestTheme } from '@umbraco-cms/models'; +import type { ManifestTheme } from '@umbraco-cms/backoffice/extensions-registry'; export const themes: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/themes/theme.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/themes/theme.context.ts index 5e246bc46e..959c8f19ef 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/themes/theme.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/themes/theme.context.ts @@ -1,24 +1,24 @@ import { map } from 'rxjs'; import { manifests } from './manifests'; -import { UmbContextProviderController, UmbContextToken } from '@umbraco-cms/context-api'; -import { StringState, UmbObserverController } from '@umbraco-cms/observable-api'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ManifestTheme } from '@umbraco-cms/extensions-registry'; +import { UmbContextProviderController, UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { StringState, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ManifestTheme } from '@umbraco-cms/backoffice/extensions-registry'; const LOCAL_STORAGE_KEY = 'umb-theme-alias'; export class UmbThemeContext { - private _host: UmbControllerHostInterface; + private _host: UmbControllerHostElement; #theme = new StringState('umb-light-theme'); public readonly theme = this.#theme.asObservable(); - private themeSubscription?: UmbObserverController; + private themeSubscription?: UmbObserverController; - #styleElement: HTMLLinkElement| HTMLStyleElement | null = null; + #styleElement: HTMLLinkElement | HTMLStyleElement | null = null; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this._host = host; new UmbContextProviderController(host, UMB_THEME_CONTEXT_TOKEN, this); @@ -43,25 +43,21 @@ export class UmbThemeContext { async (themes) => { this.#styleElement?.remove(); if (themes.length > 0) { - if(themes[0].loader) { - - const styleEl = this.#styleElement = document.createElement('style'); + if (themes[0].loader) { + const styleEl = (this.#styleElement = document.createElement('style')); styleEl.setAttribute('type', 'text/css'); document.head.appendChild(styleEl); const result = await themes[0].loader(); // Checking that this is still our styleElement, it has not been replaced with another theme in between. - if(styleEl === this.#styleElement) { + if (styleEl === this.#styleElement) { (styleEl as any).appendChild(document.createTextNode(result)); } - } else if (themes[0].css) { - this.#styleElement = document.createElement('link'); this.#styleElement.setAttribute('rel', 'stylesheet'); this.#styleElement.setAttribute('href', themes[0].css); document.head.appendChild(this.#styleElement); - } } else { localStorage.removeItem(LOCAL_STORAGE_KEY); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dashboards/dictionary/dashboard-translation-dictionary.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dashboards/dictionary/dashboard-translation-dictionary.element.ts index 38b5625580..031192d45b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dashboards/dictionary/dashboard-translation-dictionary.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dashboards/dictionary/dashboard-translation-dictionary.element.ts @@ -1,17 +1,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { when } from 'lit-html/directives/when.js'; +import { when } from 'lit/directives/when.js'; import { UmbTableConfig, UmbTableColumn, UmbTableItem } from '../../../../backoffice/shared/components/table'; import { UmbDictionaryRepository } from '../../dictionary/repository/dictionary.repository'; -import { - UmbCreateDictionaryModalResult, - UMB_CREATE_DICTIONARY_MODAL_TOKEN, -} from '../../dictionary/entity-actions/create/'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DictionaryOverviewModel, LanguageModel } from '@umbraco-cms/backend-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DictionaryOverviewResponseModel, LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CREATE_DICTIONARY_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-dashboard-translation-dictionary') export class UmbDashboardTranslationDictionaryElement extends UmbLitElement { @@ -22,6 +18,7 @@ export class UmbDashboardTranslationDictionaryElement extends UmbLitElement { display: flex; flex-direction: column; height: 100%; + margin: var(--uui-size-layout-1); } #dictionary-top-bar { @@ -50,7 +47,7 @@ export class UmbDashboardTranslationDictionaryElement extends UmbLitElement { @state() private _tableItemsFiltered: Array = []; - #dictionaryItems: DictionaryOverviewModel[] = []; + #dictionaryItems: DictionaryOverviewResponseModel[] = []; #repo!: UmbDictionaryRepository; @@ -60,7 +57,7 @@ export class UmbDashboardTranslationDictionaryElement extends UmbLitElement { #tableColumns: Array = []; - #languages: Array = []; + #languages: Array = []; constructor() { super(); @@ -112,14 +109,14 @@ export class UmbDashboardTranslationDictionaryElement extends UmbLitElement { #setTableItems() { this.#tableItems = this.#dictionaryItems.map((dictionary) => { - // key is name to allow filtering on the displayed value + // id is set to name to allow filtering on the displayed value const tableItem: UmbTableItem = { - key: dictionary.name ?? '', + id: dictionary.name ?? '', icon: 'umb:book-alt', data: [ { columnAlias: 'name', - value: html` + value: html` ${dictionary.name} `, }, @@ -151,24 +148,24 @@ export class UmbDashboardTranslationDictionaryElement extends UmbLitElement { #filter(e: { target: HTMLInputElement }) { this._tableItemsFiltered = e.target.value - ? this.#tableItems.filter((t) => t.key.includes(e.target.value)) + ? this.#tableItems.filter((t) => t.id.includes(e.target.value)) : this.#tableItems; } async #create() { // TODO: what to do if modal service is not available? if (!this.#modalContext) return; + if (!this.#repo) return; - const modalHandler = this.#modalContext?.open(UMB_CREATE_DICTIONARY_MODAL_TOKEN, { unique: null }); + const modalHandler = this.#modalContext?.open(UMB_CREATE_DICTIONARY_MODAL, { unique: null }); // TODO: get type from modal result const { name } = await modalHandler.onSubmit(); if (!name) return; - const result = await this.#repo?.create({ $type: '', name, parentKey: null, translations: [], key: '' }); - + const { data } = await this.#repo.createScaffold(null); + console.log(data); // TODO => get location header to route to new item - console.log(result); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create-dictionary-modal-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create-dictionary-modal-layout.element.ts index 4b462e515f..6756740c65 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create-dictionary-modal-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create-dictionary-modal-layout.element.ts @@ -1,12 +1,12 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, query } from 'lit/decorators.js'; -import { when } from 'lit-html/directives/when.js'; -import { UmbCreateDictionaryModalData, UmbCreateDictionaryModalResult } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { when } from 'lit/directives/when.js'; +import { UmbCreateDictionaryModalData, UmbCreateDictionaryModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; @customElement('umb-create-dictionary-modal') -export class UmbCreateDictionaryModalLayoutElement extends UmbModalBaseElement< +export class UmbCreateDictionaryModalElement extends UmbModalBaseElement< UmbCreateDictionaryModalData, UmbCreateDictionaryModalResult > { @@ -71,10 +71,10 @@ export class UmbCreateDictionaryModalLayoutElement extends UmbModalBaseElement< } } -export default UmbCreateDictionaryModalLayoutElement; +export default UmbCreateDictionaryModalElement; declare global { interface HTMLElementTagNameMap { - 'umb-create-dictionary-modal': UmbCreateDictionaryModalLayoutElement; + 'umb-create-dictionary-modal': UmbCreateDictionaryModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create.action.ts index 2de1ddc2e9..34bb2459bf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/create/create.action.ts @@ -4,11 +4,10 @@ import { UmbSectionSidebarContext, UMB_SECTION_SIDEBAR_CONTEXT_TOKEN, } from '../../../../../backoffice/shared/components/section/section-sidebar/section-sidebar.context'; -import { UMB_CREATE_DICTIONARY_MODAL_TOKEN } from '.'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CREATE_DICTIONARY_MODAL } from '@umbraco-cms/backoffice/modal'; // TODO: temp import import './create-dictionary-modal-layout.element'; @@ -20,7 +19,7 @@ export default class UmbCreateDictionaryEntityAction extends UmbEntityActionBase #sectionSidebarContext!: UmbSectionSidebarContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -35,10 +34,11 @@ export default class UmbCreateDictionaryEntityAction extends UmbEntityActionBase async execute() { // TODO: what to do if modal service is not available? if (!this.#modalContext) return; + if (!this.repository) return; // TODO: how can we get the current entity detail in the modal? Passing the observable // feels a bit hacky. Works, but hacky. - const modalHandler = this.#modalContext?.open(UMB_CREATE_DICTIONARY_MODAL_TOKEN, { + const modalHandler = this.#modalContext?.open(UMB_CREATE_DICTIONARY_MODAL, { unique: this.unique, parentName: this.#sectionSidebarContext.headline, }); @@ -47,15 +47,9 @@ export default class UmbCreateDictionaryEntityAction extends UmbEntityActionBase const { name } = await modalHandler.onSubmit(); if (!name) return; - const result = await this.repository?.create({ - $type: '', - name, - parentKey: this.unique, - translations: [], - key: '', - }); + const { data } = await this.repository.createScaffold(this.unique, name); // TODO => get location header to route to new item - console.log(result); + console.log(data); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export-dictionary-modal-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export-dictionary-modal.element.ts similarity index 80% rename from src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export-dictionary-modal-layout.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export-dictionary-modal.element.ts index bce5dc282a..9f746ae2e1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export-dictionary-modal-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export-dictionary-modal.element.ts @@ -1,11 +1,11 @@ import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, query } from 'lit/decorators.js'; -import { UmbExportDictionaryModalData, UmbExportDictionaryModalResult } from '.'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { UmbExportDictionaryModalData, UmbExportDictionaryModalResult } from '@umbraco-cms/backoffice/modal'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; -@customElement('umb-export-dictionary-modal-layout') -export class UmbExportDictionaryModalLayoutElement extends UmbModalBaseElement< +@customElement('umb-export-dictionary-modal') +export class UmbExportDictionaryModalElement extends UmbModalBaseElement< UmbExportDictionaryModalData, UmbExportDictionaryModalResult > { @@ -49,10 +49,10 @@ export class UmbExportDictionaryModalLayoutElement extends UmbModalBaseElement< } } -export default UmbExportDictionaryModalLayoutElement; +export default UmbExportDictionaryModalElement; declare global { interface HTMLElementTagNameMap { - 'umb-export-dictionary-modal-layout': UmbExportDictionaryModalLayoutElement; + 'umb-export-dictionary-modal': UmbExportDictionaryModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export.action.ts index de6d5bcc4c..5505ad4ced 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/export/export.action.ts @@ -1,19 +1,18 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { UmbDictionaryRepository } from '../../repository/dictionary.repository'; -import { UMB_EXPORT_DICTIONARY_MODAL_TOKEN } from '.'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_EXPORT_DICTIONARY_MODAL } from '@umbraco-cms/backoffice/modal'; -import './export-dictionary-modal-layout.element'; +import './export-dictionary-modal.element'; export default class UmbExportDictionaryEntityAction extends UmbEntityActionBase { static styles = [UUITextStyles]; #modalContext?: UmbModalContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -25,7 +24,7 @@ export default class UmbExportDictionaryEntityAction extends UmbEntityActionBase // TODO: what to do if modal service is not available? if (!this.#modalContext) return; - const modalHandler = this.#modalContext?.open(UMB_EXPORT_DICTIONARY_MODAL_TOKEN, { unique: this.unique }); + const modalHandler = this.#modalContext?.open(UMB_EXPORT_DICTIONARY_MODAL, { unique: this.unique }); // TODO: get type from modal result const { includeChildren } = await modalHandler.onSubmit(); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import-dictionary-modal-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import-dictionary-modal.element.ts similarity index 71% rename from src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import-dictionary-modal-layout.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import-dictionary-modal.element.ts index b178a42ac3..f92fc6a94b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import-dictionary-modal-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import-dictionary-modal.element.ts @@ -1,16 +1,16 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, query, state } from 'lit/decorators.js'; -import { when } from 'lit-html/directives/when.js'; +import { when } from 'lit/directives/when.js'; import { repeat } from 'lit/directives/repeat.js'; import { UmbTreeElement } from '../../../../shared/components/tree/tree.element'; import { UmbDictionaryRepository } from '../../repository/dictionary.repository'; -import { UmbImportDictionaryModalData, UmbImportDictionaryModalResult } from '.'; -import { DictionaryUploadModel } from '@umbraco-cms/backend-api'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; +import { UmbImportDictionaryModalData, UmbImportDictionaryModalResult } from '@umbraco-cms/backoffice/modal'; +import { DictionaryItemResponseModel, ImportDictionaryRequestModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; -@customElement('umb-import-dictionary-modal-layout') -export class UmbImportDictionaryModalLayoutElement extends UmbModalBaseElement< +@customElement('umb-import-dictionary-modal') +export class UmbImportDictionaryModalLayout extends UmbModalBaseElement< UmbImportDictionaryModalData, UmbImportDictionaryModalResult > { @@ -27,7 +27,7 @@ export class UmbImportDictionaryModalLayoutElement extends UmbModalBaseElement< private _form!: HTMLFormElement; @state() - private _uploadedDictionary?: DictionaryUploadModel; + private _uploadedDictionaryTempId?: string; @state() private _showUploadView = true; @@ -44,11 +44,11 @@ export class UmbImportDictionaryModalLayoutElement extends UmbModalBaseElement< #detailRepo = new UmbDictionaryRepository(this); async #importDictionary() { - if (!this._uploadedDictionary?.fileName) return; + if (!this._uploadedDictionaryTempId) return; this.modalHandler?.submit({ - fileName: this._uploadedDictionary.fileName, - parentKey: this._selection[0], + temporaryFileId: this._uploadedDictionaryTempId, + parentId: this._selection[0], }); } @@ -66,11 +66,21 @@ export class UmbImportDictionaryModalLayoutElement extends UmbModalBaseElement< if (!this._form.checkValidity()) return; const formData = new FormData(this._form); - const { data } = await this.#detailRepo.upload(formData); - this._uploadedDictionary = data; + const uploadData: ImportDictionaryRequestModel = { + temporaryFileId: formData.get('file')?.toString() ?? '', + }; - if (!this._uploadedDictionary) { + // TODO: fix this upload experience. We need to update our form so it gets temporary file id from the server: + const { data } = await this.#detailRepo.upload(uploadData); + + if (!data) return; + + this._uploadedDictionaryTempId = data; + // TODO: We need to find another way to gather the data of the uploaded dictionary, to represent the dictionaryItems? See further below. + //this._uploadedDictionary = data; + + if (!this._uploadedDictionaryTempId) { this._showErrorView = true; this._showImportView = false; return; @@ -113,6 +123,8 @@ export class UmbImportDictionaryModalLayoutElement extends UmbModalBaseElement< /// TODO => Tree view needs isolation and single-select option #renderImportView() { + //TODO: gather this data in some other way, we cannot use the feedback from the server anymore. can we use info about the file directly? or is a change to the end point required? + /* if (!this._uploadedDictionary?.dictionaryItems) return; return html` @@ -140,6 +152,7 @@ export class UmbImportDictionaryModalLayoutElement extends UmbModalBaseElement< look="primary" @click=${this.#importDictionary}> `; + */ } // TODO => Determine what to display when dictionary import/upload fails @@ -156,10 +169,10 @@ export class UmbImportDictionaryModalLayoutElement extends UmbModalBaseElement< } } -export default UmbImportDictionaryModalLayoutElement; +export default UmbImportDictionaryModalLayout; declare global { interface HTMLElementTagNameMap { - 'umb-import-dictionary-modal-layout': UmbImportDictionaryModalLayoutElement; + 'umb-import-dictionary-modal': UmbImportDictionaryModalLayout; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import.action.ts index b8d5d411b2..2ab539bca3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/import/import.action.ts @@ -1,19 +1,18 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { UmbDictionaryRepository } from '../../repository/dictionary.repository'; -import { UMB_IMPORT_DICTIONARY_MODAL_TOKEN } from '.'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_IMPORT_DICTIONARY_MODAL } from '@umbraco-cms/backoffice/modal'; -import './import-dictionary-modal-layout.element'; +import './import-dictionary-modal.element'; export default class UmbImportDictionaryEntityAction extends UmbEntityActionBase { static styles = [UUITextStyles]; #modalContext?: UmbModalContext; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { @@ -25,13 +24,13 @@ export default class UmbImportDictionaryEntityAction extends UmbEntityActionBase // TODO: what to do if modal service is not available? if (!this.#modalContext) return; - const modalHandler = this.#modalContext?.open(UMB_IMPORT_DICTIONARY_MODAL_TOKEN, { unique: this.unique }); + const modalHandler = this.#modalContext?.open(UMB_IMPORT_DICTIONARY_MODAL, { unique: this.unique }); // TODO: get type from modal result - const { fileName, parentKey } = await modalHandler.onSubmit(); - if (!fileName) return; + const { temporaryFileId, parentId } = await modalHandler.onSubmit(); + if (!temporaryFileId) return; - const result = await this.repository?.import(fileName, parentKey); + const result = await this.repository?.import(temporaryFileId, parentId); // TODO => get location header to route to new item console.log(result); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/manifests.ts index 7e75f56e94..fc79433c06 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/manifests.ts @@ -3,8 +3,8 @@ import UmbReloadDictionaryEntityAction from './reload.action'; import UmbImportDictionaryEntityAction from './import/import.action'; import UmbExportDictionaryEntityAction from './export/export.action'; import UmbCreateDictionaryEntityAction from './create/create.action'; -import { UmbDeleteEntityAction, UmbMoveEntityAction } from '@umbraco-cms/entity-action'; -import type { ManifestEntityAction, ManifestModal } from '@umbraco-cms/models'; +import { UmbDeleteEntityAction, UmbMoveEntityAction } from '@umbraco-cms/backoffice/entity-action'; +import type { ManifestEntityAction, ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const entityType = 'dictionary-item'; const repositoryAlias = DICTIONARY_REPOSITORY_ALIAS; @@ -16,12 +16,14 @@ const entityActions: Array = [ name: 'Create Dictionary Entity Action', weight: 600, meta: { - entityType, icon: 'umb:add', label: 'Create', repositoryAlias, api: UmbCreateDictionaryEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -29,12 +31,14 @@ const entityActions: Array = [ name: 'Move Dictionary Entity Action', weight: 500, meta: { - entityType, icon: 'umb:enter', label: 'Move', repositoryAlias, api: UmbMoveEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -42,12 +46,14 @@ const entityActions: Array = [ name: 'Export Dictionary Entity Action', weight: 400, meta: { - entityType, icon: 'umb:download-alt', label: 'Export', repositoryAlias, api: UmbExportDictionaryEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -55,12 +61,14 @@ const entityActions: Array = [ name: 'Import Dictionary Entity Action', weight: 300, meta: { - entityType, icon: 'umb:page-up', label: 'Import', repositoryAlias, api: UmbImportDictionaryEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -68,12 +76,14 @@ const entityActions: Array = [ name: 'Reload Dictionary Entity Action', weight: 200, meta: { - entityType, icon: 'umb:refresh', label: 'Reload', repositoryAlias, api: UmbReloadDictionaryEntityAction, }, + conditions: { + entityType, + }, }, { type: 'entityAction', @@ -81,12 +91,14 @@ const entityActions: Array = [ name: 'Delete Dictionary Entity Action', weight: 100, meta: { - entityType, icon: 'umb:trash', label: 'Delete', repositoryAlias, api: UmbDeleteEntityAction, }, + conditions: { + entityType, + }, }, ]; @@ -101,13 +113,13 @@ const modals: Array = [ type: 'modal', alias: 'Umb.Modal.ExportDictionary', name: 'Export Dictionary Modal', - loader: () => import('./export/export-dictionary-modal-layout.element'), + loader: () => import('./export/export-dictionary-modal.element'), }, { type: 'modal', alias: 'Umb.Modal.ImportDictionary', name: 'Import Dictionary Modal', - loader: () => import('./import/import-dictionary-modal-layout.element'), + loader: () => import('./import/import-dictionary-modal.element'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/reload.action.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/reload.action.ts index dd31434f25..ac91ad2bfe 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/reload.action.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/entity-actions/reload.action.ts @@ -1,12 +1,12 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { UmbDictionaryRepository } from '../repository/dictionary.repository'; -import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export default class UmbReloadDictionaryEntityAction extends UmbEntityActionBase { static styles = [UUITextStyles]; - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/dictionary-menu-item.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/dictionary-menu-item.element.ts index 98dffdf557..e12c1f7865 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/dictionary-menu-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/dictionary-menu-item.element.ts @@ -1,6 +1,6 @@ import { html } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-dictionary-menu-item') export class UmbDictionaryMenuItemElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/manifests.ts index c62856cc82..842e3c5993 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu-item/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestMenuItem } from '@umbraco-cms/models'; +import type { ManifestMenuItem } from '@umbraco-cms/backoffice/extensions-registry'; const menuItem: ManifestMenuItem = { type: 'menuItem', @@ -10,6 +10,8 @@ const menuItem: ManifestMenuItem = { label: 'Dictionary', icon: 'umb:book-alt', entityType: 'dictionary-item', + }, + conditions: { menus: ['Umb.Menu.Dictionary'], }, }; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu.manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu.manifests.ts index de5891031c..cf0ebc94cc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu.manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/menu.manifests.ts @@ -1,4 +1,4 @@ -import { ManifestMenu } from '@umbraco-cms/extensions-registry'; +import { ManifestMenu } from '@umbraco-cms/backoffice/extensions-registry'; const menu: ManifestMenu = { type: 'menu', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.repository.ts index 2618c22ffd..0ce6e7db0f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.repository.ts @@ -1,20 +1,33 @@ -import { DictionaryTreeServerDataSource } from './sources/dictionary.tree.server.data'; -import { UmbDictionaryTreeStore, UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN } from './dictionary.tree.store'; -import { UmbDictionaryDetailServerDataSource } from './sources/dictionary.detail.server.data'; import { UmbDictionaryStore, UMB_DICTIONARY_STORE_CONTEXT_TOKEN } from './dictionary.store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbContextConsumerController } from '@umbraco-cms/context-api'; -import { RepositoryTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/repository'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/notification'; -import type { DictionaryDetails } from '@umbraco-cms/models'; +import { UmbDictionaryDetailServerDataSource } from './sources/dictionary.detail.server.data'; +import { UmbDictionaryTreeStore, UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN } from './dictionary.tree.store'; +import { DictionaryTreeServerDataSource } from './sources/dictionary.tree.server.data'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; +import { UmbTreeDataSource, UmbDetailRepository, UmbTreeRepository } from '@umbraco-cms/backoffice/repository'; +import { + CreateDictionaryItemRequestModel, + DictionaryOverviewResponseModel, + ImportDictionaryRequestModel, + ProblemDetailsModel, + UpdateDictionaryItemRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; -export class UmbDictionaryRepository implements UmbTreeRepository, UmbDetailRepository { +export class UmbDictionaryRepository + implements + UmbTreeRepository, + UmbDetailRepository< + CreateDictionaryItemRequestModel, + UpdateDictionaryItemRequestModel, + DictionaryOverviewResponseModel + > +{ #init!: Promise; - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - #treeSource: RepositoryTreeDataSource; + #treeSource: UmbTreeDataSource; #treeStore?: UmbDictionaryTreeStore; #detailSource: UmbDictionaryDetailServerDataSource; @@ -22,7 +35,7 @@ export class UmbDictionaryRepository implements UmbTreeRepository, UmbDetailRepo #notificationContext?: UmbNotificationContext; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; // TODO: figure out how spin up get the correct data source @@ -56,34 +69,34 @@ export class UmbDictionaryRepository implements UmbTreeRepository, UmbDetailRepo return { data, error, asObservable: () => this.#treeStore!.rootItems }; } - async requestTreeItemsOf(parentKey: string | null) { + async requestTreeItemsOf(parentId: string | null) { await this.#init; - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getChildrenOf(parentKey); + const { data, error } = await this.#treeSource.getChildrenOf(parentId); if (data) { this.#treeStore?.appendItems(data.items); } - return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentKey) }; + return { data, error, asObservable: () => this.#treeStore!.childrenOf(parentId) }; } - async requestTreeItems(keys: Array) { + async requestTreeItems(ids: Array) { await this.#init; - if (!keys) { + if (!ids) { const error: ProblemDetailsModel = { title: 'Keys are missing' }; return { data: undefined, error }; } - const { data, error } = await this.#treeSource.getItems(keys); + const { data, error } = await this.#treeSource.getItems(ids); - return { data, error, asObservable: () => this.#treeStore!.items(keys) }; + return { data, error, asObservable: () => this.#treeStore!.items(ids) }; } async rootTreeItems() { @@ -91,39 +104,29 @@ export class UmbDictionaryRepository implements UmbTreeRepository, UmbDetailRepo return this.#treeStore!.rootItems; } - async treeItemsOf(parentKey: string | null) { + async treeItemsOf(parentId: string | null) { await this.#init; - return this.#treeStore!.childrenOf(parentKey); + return this.#treeStore!.childrenOf(parentId); } - async treeItems(keys: Array) { + async treeItems(ids: Array) { await this.#init; - return this.#treeStore!.items(keys); + return this.#treeStore!.items(ids); } // DETAILS - async createScaffold(parentKey: string | null) { + async createScaffold(parentId: string | null, name?: string) { + if (parentId === undefined) throw new Error('Parent id is missing'); await this.#init; - - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; - return { data: undefined, error }; - } - - return this.#detailSource.createScaffold(parentKey); + return this.#detailSource.createScaffold(parentId, name); } - async requestByKey(key: string) { + async requestById(id: string) { + if (!id) throw new Error('Id is missing'); await this.#init; - // TODO: should we show a notification if the key is missing? - // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!key) { - const error: ProblemDetailsModel = { title: 'Key is missing' }; - return { error }; - } - const { data, error } = await this.#detailSource.get(key); + const { data, error } = await this.#detailSource.get(id); if (data) { this.#detailStore?.append(data); @@ -136,39 +139,35 @@ export class UmbDictionaryRepository implements UmbTreeRepository, UmbDetailRepo return this.#detailSource.list(skip, take); } - async delete(key: string) { + async delete(id: string) { await this.#init; - return this.#detailSource.delete(key); + return this.#detailSource.delete(id); } - async save(dictionary: DictionaryDetails) { + async save(id: string, updatedDictionary: UpdateDictionaryItemRequestModel) { + if (!id) throw new Error('Id is missing'); + if (!updatedDictionary) throw new Error('Dictionary is missing'); + await this.#init; - // TODO: should we show a notification if the dictionary is missing? - // Investigate what is best for Acceptance testing, cause in that perspective a thrown error might be the best choice? - if (!dictionary || !dictionary.key) { - const error: ProblemDetailsModel = { title: 'Dictionary is missing' }; - return { error }; - } - - const { error } = await this.#detailSource.update(dictionary); + const { error } = await this.#detailSource.update(id, updatedDictionary); if (!error) { - const notification = { data: { message: `Dictionary '${dictionary.name}' saved` } }; + // TODO: we currently don't use the detail store for anything. + // Consider to look up the data before fetching from the server + // Consider notify a workspace if a dictionary is updated in the store while someone is editing it. + // TODO: would be nice to align the stores on methods/methodNames. + //this.#detailStore?.append(dictionary); + this.#treeStore?.updateItem(id, { name: updatedDictionary.name }); + + const notification = { data: { message: `Dictionary '${updatedDictionary.name}' saved` } }; this.#notificationContext?.peek('positive', notification); } - // TODO: we currently don't use the detail store for anything. - // Consider to look up the data before fetching from the server - // Consider notify a workspace if a dictionary is updated in the store while someone is editing it. - this.#detailStore?.append(dictionary); - this.#treeStore?.updateItem(dictionary.key, { name: dictionary.name }); - // TODO: would be nice to align the stores on methods/methodNames. - return { error }; } - async create(detail: DictionaryDetails) { + async create(detail: CreateDictionaryItemRequestModel) { await this.#init; if (!detail.name) { @@ -186,29 +185,29 @@ export class UmbDictionaryRepository implements UmbTreeRepository, UmbDetailRepo return { data, error }; } - async export(key: string, includeChildren = false) { + async export(id: string, includeChildren = false) { await this.#init; - if (!key) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - return this.#detailSource.export(key, includeChildren); + return this.#detailSource.export(id, includeChildren); } - async import(fileName: string, parentKey?: string) { + async import(temporaryFileId: string, parentId?: string) { await this.#init; - if (!fileName) { + if (!temporaryFileId) { const error: ProblemDetailsModel = { title: 'File is missing' }; return { error }; } - return this.#detailSource.import(fileName, parentKey); + return this.#detailSource.import(temporaryFileId, parentId); } - async upload(formData: FormData) { + async upload(formData: ImportDictionaryRequestModel) { await this.#init; if (!formData) { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.store.ts index bf72879c7e..c4b62e7c82 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.store.ts @@ -1,8 +1,8 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import type { DictionaryDetails } from '@umbraco-cms/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { DictionaryItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; /** * @export @@ -11,13 +11,13 @@ import type { DictionaryDetails } from '@umbraco-cms/models'; * @description - Data Store for Dictionary */ export class UmbDictionaryStore extends UmbStoreBase { - #data = new ArrayState([], (x) => x.key); + #data = new ArrayState([], (x) => x.id); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DICTIONARY_STORE_CONTEXT_TOKEN.toString()); } - append(dictionary: DictionaryDetails) { + append(dictionary: DictionaryItemResponseModel) { this.#data.append([dictionary]); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.tree.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.tree.store.ts index 743235f01b..3c60cabe70 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.tree.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/dictionary.tree.store.ts @@ -1,20 +1,20 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbTreeStoreBase } from '@umbraco-cms/store'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityTreeStore } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export * @class UmbDictionaryTreeStore - * @extends {UmbTreeStoreBase} + * @extends {UmbEntityTreeStore} * @description - Tree Data Store for Dictionary */ -export class UmbDictionaryTreeStore extends UmbTreeStoreBase { +export class UmbDictionaryTreeStore extends UmbEntityTreeStore { /** * Creates an instance of UmbDictionaryTreeStore. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof UmbDictionaryTreeStore */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_DICTIONARY_TREE_STORE_CONTEXT_TOKEN.toString()); } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/manifests.ts index 0309458660..012668b989 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/manifests.ts @@ -1,8 +1,7 @@ import { UmbDictionaryRepository } from '../repository/dictionary.repository'; import { UmbDictionaryTreeStore } from './dictionary.tree.store'; import { UmbDictionaryStore } from './dictionary.store'; -import { ManifestRepository } from 'libs/extensions-registry/repository.models'; -import { ManifestStore, ManifestTreeStore } from '@umbraco-cms/extensions-registry'; +import { ManifestStore, ManifestTreeStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const DICTIONARY_REPOSITORY_ALIAS = 'Umb.Repository.Dictionary'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.detail.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.detail.server.data.ts index 8606fa42fe..3479db2d77 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.detail.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.detail.server.data.ts @@ -1,13 +1,16 @@ -import { DictionaryDetailDataSource } from './dictionary.details.server.data.interface'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { v4 as uuidv4 } from 'uuid'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import { - DictionaryItemCreateModel, + CreateDictionaryItemRequestModel, + DictionaryItemResponseModel, DictionaryResource, + ImportDictionaryRequestModel, LanguageResource, ProblemDetailsModel, -} from '@umbraco-cms/backend-api'; -import type { DictionaryDetails } from '@umbraco-cms/models'; + UpdateDictionaryItemRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbDataSource } from '@umbraco-cms/backoffice/repository'; /** * @description - A data source for the Dictionary detail that fetches data from the server @@ -15,36 +18,41 @@ import type { DictionaryDetails } from '@umbraco-cms/models'; * @class UmbDictionaryDetailServerDataSource * @implements {DictionaryDetailDataSource} */ -export class UmbDictionaryDetailServerDataSource implements DictionaryDetailDataSource { - #host: UmbControllerHostInterface; +export class UmbDictionaryDetailServerDataSource + implements + UmbDataSource +{ + #host: UmbControllerHostElement; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } /** * @description - Creates a new Dictionary scaffold - * @param {string} parentKey + * @param {string} parentId * @return {*} * @memberof UmbDictionaryDetailServerDataSource */ - async createScaffold(parentKey: string) { - const data: DictionaryDetails = { - name: '', - parentKey, - } as DictionaryDetails; + async createScaffold(parentId?: string | null, name?: string) { + const data = { + id: uuidv4(), + parentId, + name, + translations: [], + }; return { data }; } /** - * @description - Fetches a Dictionary with the given key from the server - * @param {string} key + * @description - Fetches a Dictionary with the given id from the server + * @param {string} id * @return {*} * @memberof UmbDictionaryDetailServerDataSource */ - get(key: string) { - return tryExecuteAndNotify(this.#host, DictionaryResource.getDictionaryByKey({ key })) as any; + get(id: string) { + return tryExecuteAndNotify(this.#host, DictionaryResource.getDictionaryById({ id })); } /** @@ -63,14 +71,12 @@ export class UmbDictionaryDetailServerDataSource implements DictionaryDetailData * @return {*} * @memberof UmbDictionaryDetailServerDataSource */ - async update(dictionary: DictionaryDetails) { - if (!dictionary.key) { - const error: ProblemDetailsModel = { title: 'Dictionary key is missing' }; - return { error }; - } + async update(id: string, dictionary: UpdateDictionaryItemRequestModel) { + if (!id) throw new Error('Id is missing'); + if (!dictionary) throw new Error('Dictionary is missing'); - const payload = { key: dictionary.key, requestBody: dictionary }; - return tryExecuteAndNotify(this.#host, DictionaryResource.putDictionaryByKey(payload)); + const payload = { id, requestBody: dictionary }; + return tryExecuteAndNotify(this.#host, DictionaryResource.putDictionaryById(payload)); } /** @@ -79,56 +85,50 @@ export class UmbDictionaryDetailServerDataSource implements DictionaryDetailData * @return {*} * @memberof UmbDictionaryDetailServerDataSource */ - async insert(data: DictionaryDetails) { - const requestBody: DictionaryItemCreateModel = { - parentKey: data.parentKey, - name: data.name, - }; - - // TODO: fix type mismatch: - return tryExecuteAndNotify(this.#host, DictionaryResource.postDictionary({ requestBody })) as any; + async insert(data: CreateDictionaryItemRequestModel) { + return tryExecuteAndNotify(this.#host, DictionaryResource.postDictionary({ requestBody: data })); } /** * @description - Deletes a Dictionary on the server - * @param {string} key + * @param {string} id * @return {*} * @memberof UmbDictionaryDetailServerDataSource */ - async delete(key: string) { - if (!key) { + async delete(id: string) { + if (!id) { const error: ProblemDetailsModel = { title: 'Key is missing' }; return { error }; } - return await tryExecuteAndNotify(this.#host, DictionaryResource.deleteDictionaryByKey({ key })); + return await tryExecuteAndNotify(this.#host, DictionaryResource.deleteDictionaryById({ id })); } /** * @description - Import a dictionary - * @param {string} fileName - * @param {string?} parentKey + * @param {string} temporaryFileId + * @param {string?} parentId * @returns {*} * @memberof UmbDictionaryDetailServerDataSource */ - async import(fileName: string, parentKey?: string) { - // TODO => parentKey will be a guid param once #13786 is merged and API regenerated + async import(temporaryFileId: string, parentId?: string) { + // TODO => parentId will be a guid param once #13786 is merged and API regenerated return await tryExecuteAndNotify( this.#host, - DictionaryResource.postDictionaryImport({ requestBody: { fileName, parentKey } }) + DictionaryResource.postDictionaryImport({ requestBody: { temporaryFileId, parentId } }) ); } /** * @description - Upload a Dictionary - * @param {FormData} formData + * @param {ImportDictionaryRequestModel} formData * @return {*} * @memberof UmbDictionaryDetailServerDataSource */ - async upload(formData: FormData) { + async upload(formData: ImportDictionaryRequestModel) { return await tryExecuteAndNotify( this.#host, - DictionaryResource.postDictionaryUpload({ + DictionaryResource.postDictionaryImport({ requestBody: formData, }) ); @@ -136,13 +136,13 @@ export class UmbDictionaryDetailServerDataSource implements DictionaryDetailData /** * @description - Export a Dictionary, optionally including child items. - * @param {string} key + * @param {string} id * @param {boolean} includeChildren * @return {*} * @memberof UmbDictionaryDetailServerDataSource */ - async export(key: string, includeChildren: boolean) { - return await tryExecuteAndNotify(this.#host, DictionaryResource.getDictionaryByKeyExport({ key, includeChildren })); + async export(id: string, includeChildren: boolean) { + return await tryExecuteAndNotify(this.#host, DictionaryResource.getDictionaryByIdExport({ id, includeChildren })); } async getLanguages() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.details.server.data.interface.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.details.server.data.interface.ts deleted file mode 100644 index 238702d0bc..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.details.server.data.interface.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - DictionaryItemModel, - DictionaryUploadModel, - PagedDictionaryOverviewModel, - PagedLanguageModel, -} from '@umbraco-cms/backend-api'; -import type { DataSourceResponse, DictionaryDetails } from '@umbraco-cms/models'; - -export interface DictionaryDetailDataSource { - createScaffold(parentKey: string): Promise>; - list(skip?: number, take?: number): Promise>; - get(key: string): Promise>; - insert(data: DictionaryDetails): Promise; - update(dictionary: DictionaryItemModel): Promise; - delete(key: string): Promise; - export(key: string, includeChildren: boolean): Promise>; - import(fileName: string, parentKey?: string): Promise>; - upload(formData: FormData): Promise>; - // TODO - temp only - getLanguages(): Promise>; -} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.tree.server.data.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.tree.server.data.ts index faacf9512b..a24572eb9f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.tree.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/repository/sources/dictionary.tree.server.data.ts @@ -1,7 +1,7 @@ -import { DictionaryResource, ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { RepositoryTreeDataSource } from '@umbraco-cms/repository'; -import { tryExecuteAndNotify } from '@umbraco-cms/resources'; +import { DictionaryResource, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbTreeDataSource } from '@umbraco-cms/backoffice/repository'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * A data source for the Dictionary tree that fetches data from the server @@ -9,15 +9,15 @@ import { tryExecuteAndNotify } from '@umbraco-cms/resources'; * @class DictionaryTreeServerDataSource * @implements {DictionaryTreeDataSource} */ -export class DictionaryTreeServerDataSource implements RepositoryTreeDataSource { - #host: UmbControllerHostInterface; +export class DictionaryTreeServerDataSource implements UmbTreeDataSource { + #host: UmbControllerHostElement; /** * Creates an instance of DictionaryTreeDataSource. - * @param {UmbControllerHostInterface} host + * @param {UmbControllerHostElement} host * @memberof DictionaryTreeDataSource */ - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; } @@ -31,41 +31,41 @@ export class DictionaryTreeServerDataSource implements RepositoryTreeDataSource } /** - * Fetches the children of a given parent key from the server - * @param {(string | null)} parentKey + * Fetches the children of a given parent id from the server + * @param {(string | null)} parentId * @return {*} * @memberof DictionaryTreeServerDataSource */ - async getChildrenOf(parentKey: string | null) { - if (!parentKey) { - const error: ProblemDetailsModel = { title: 'Parent key is missing' }; + async getChildrenOf(parentId: string | null) { + if (!parentId) { + const error: ProblemDetailsModel = { title: 'Parent id is missing' }; return { error }; } return tryExecuteAndNotify( this.#host, DictionaryResource.getTreeDictionaryChildren({ - parentKey, + parentId, }) ); } /** - * Fetches the items for the given keys from the server - * @param {Array} keys + * Fetches the items for the given ids from the server + * @param {Array} ids * @return {*} * @memberof DictionaryTreeServerDataSource */ - async getItems(keys: Array) { - if (!keys || keys.length === 0) { - const error: ProblemDetailsModel = { title: 'Keys are missing' }; + async getItems(ids: Array) { + if (!ids || ids.length === 0) { + const error: ProblemDetailsModel = { title: 'Ids are missing' }; return { error }; } return tryExecuteAndNotify( this.#host, - DictionaryResource.getTreeDictionaryItem({ - key: keys, + DictionaryResource.getDictionaryItem({ + id: ids, }) ); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/tree/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/tree/manifests.ts index 2d1129154a..dcfeba9411 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/tree/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/tree/manifests.ts @@ -1,13 +1,23 @@ -import { UmbDictionaryRepository } from '../repository/dictionary.repository'; -import type { ManifestTree } from '@umbraco-cms/models'; +import { DICTIONARY_REPOSITORY_ALIAS } from '../repository/manifests'; +import type { ManifestTree, ManifestTreeItem } from '@umbraco-cms/backoffice/extensions-registry'; const tree: ManifestTree = { type: 'tree', alias: 'Umb.Tree.Dictionary', name: 'Dictionary Tree', meta: { - repository: UmbDictionaryRepository, + repositoryAlias: DICTIONARY_REPOSITORY_ALIAS, }, }; -export const manifests = [tree]; +const treeItem: ManifestTreeItem = { + type: 'treeItem', + kind: 'entity', + alias: 'Umb.TreeItem.DictionaryItem', + name: 'Dictionary Item Tree Item', + conditions: { + entityType: 'dictionary-item', + }, +}; + +export const manifests = [tree, treeItem]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace-edit.element.ts new file mode 100644 index 0000000000..0cf2947ecb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace-edit.element.ts @@ -0,0 +1,76 @@ +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { css, html } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbDictionaryWorkspaceContext } from './dictionary-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-dictionary-workspace-edit') +export class UmbDictionaryWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + #header { + display: flex; + padding: 0 var(--uui-size-layout-1); + gap: var(--uui-size-space-4); + width: 100%; + } + uui-input { + width: 100%; + } + `, + ]; + + @state() + private _name?: string | null = ''; + + #workspaceContext?: UmbDictionaryWorkspaceContext; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbDictionaryWorkspaceContext; + this.#observeName(); + }); + } + + #observeName() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.name, (name) => (this._name = name)); + } + + // TODO. find a way where we don't have to do this for all workspaces. + #handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + render() { + return html` + + + + `; + } +} + +export default UmbDictionaryWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-dictionary-workspace-edit': UmbDictionaryWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.context.ts index 9ee60311ee..2d2eb3039d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.context.ts @@ -1,21 +1,21 @@ import { UmbDictionaryRepository } from '../repository/dictionary.repository'; import { UmbWorkspaceContext } from '../../../../backoffice/shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../../backoffice/shared/components/workspace/workspace-context/workspace-entity-context.interface'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ObjectState } from '@umbraco-cms/observable-api'; -import type { DictionaryDetails } from '@umbraco-cms/models'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { DictionaryItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; -type EntityType = DictionaryDetails; -export class UmbWorkspaceDictionaryContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface +export class UmbDictionaryWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { - #data = new ObjectState(undefined); + #data = new ObjectState(undefined); data = this.#data.asObservable(); + name = this.#data.getObservablePart((data) => data?.name); dictionary = this.#data.getObservablePart((data) => data); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbDictionaryRepository(host)); } @@ -23,8 +23,8 @@ export class UmbWorkspaceDictionaryContext return this.#data.getValue(); } - getEntityKey() { - return this.getData()?.key || ''; + getEntityId() { + return this.getData()?.id || ''; } getEntityType() { @@ -55,24 +55,27 @@ export class UmbWorkspaceDictionaryContext this.#data.next({ ...this.#data.value, translations: updatedValue }); } - async load(entityKey: string) { - const { data } = await this.repository.requestByKey(entityKey); + async load(entityId: string) { + const { data } = await this.repository.requestById(entityId); if (data) { this.setIsNew(false); this.#data.next(data); } } - async createScaffold(parentKey: string | null) { - const { data } = await this.repository.createScaffold(parentKey); + async createScaffold(parentId: string | null) { + const { data } = await this.repository.createScaffold(parentId); if (!data) return; this.setIsNew(true); - this.#data.next(data); + // TODO: This is a hack to get around the fact that the data is not typed correctly. + // Create and response models are different. We need to look into this. + this.#data.next(data as unknown as DictionaryItemResponseModel); } async save() { if (!this.#data.value) return; - await this.repository.save(this.#data.value); + if (!this.#data.value.id) return; + await this.repository.save(this.#data.value.id, this.#data.value); this.setIsNew(false); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.element.ts index 8bc48e4d75..68d93ba9c5 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.element.ts @@ -1,75 +1,32 @@ -import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, html } from 'lit'; +import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbWorkspaceEntityElement } from '../../../../backoffice/shared/components/workspace/workspace-entity-element.interface'; -import { UmbWorkspaceDictionaryContext } from './dictionary-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbDictionaryWorkspaceContext } from './dictionary-workspace.context'; +import { UmbDictionaryWorkspaceEditElement } from './dictionary-workspace-edit.element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-dictionary-workspace') -export class UmbWorkspaceDictionaryElement extends UmbLitElement implements UmbWorkspaceEntityElement { - static styles = [ - UUITextStyles, - css` - #header { - display: flex; - padding: 0 var(--uui-size-space-6); - gap: var(--uui-size-space-4); - width: 100%; - } - uui-input { - width: 100%; - } - `, +export class UmbWorkspaceDictionaryElement extends UmbLitElement { + static styles = [UUITextStyles]; + + #workspaceContext = new UmbDictionaryWorkspaceContext(this); + #element = new UmbDictionaryWorkspaceEditElement(); + + @state() + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, ]; - @state() - _unique?: string; - - public load(entityKey: string) { - this.#workspaceContext.load(entityKey); - this._unique = entityKey; - } - - public create(parentKey: string | null) { - this.#workspaceContext.createScaffold(parentKey); - } - - @state() - private _name?: string | null = ''; - - #workspaceContext = new UmbWorkspaceDictionaryContext(this); - - async connectedCallback() { - super.connectedCallback(); - - this.observe(this.#workspaceContext.name, (name) => { - this._name = name; - }); - } - - // TODO. find a way where we don't have to do this for all workspaces. - #handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this.#workspaceContext?.setName(target.value); - } - } - } - render() { - return html` - - - - `; + return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.stories.ts index 71a1059e42..b38f37a57d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/dictionary-workspace.stories.ts @@ -1,6 +1,7 @@ import './dictionary-workspace.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { data } from '../../../../core/mocks/data/dictionary.data'; import type { UmbWorkspaceDictionaryElement } from './dictionary-workspace.element'; @@ -11,6 +12,6 @@ export default { } as Meta; export const AAAOverview: Story = () => - html` `; + html` `; AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/manifests.ts index 38d81ac4bb..0b91eb6fec 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/manifests.ts @@ -1,6 +1,10 @@ import { DICTIONARY_REPOSITORY_ALIAS } from '../repository/manifests'; -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspaceAlias = 'Umb.Workspace.Dictionary'; @@ -22,11 +26,13 @@ const workspaceViews: Array = [ loader: () => import('./views/edit/workspace-view-dictionary-edit.element'), weight: 100, meta: { - workspaces: [workspaceAlias], label: 'Edit', pathname: 'edit', icon: 'edit', }, + conditions: { + workspaces: [workspaceAlias], + }, }, ]; @@ -37,12 +43,14 @@ const workspaceActions: Array = [ name: 'Save Dictionary Workspace Action', weight: 90, meta: { - workspaces: ['Umb.Workspace.Dictionary'], label: 'Save', look: 'primary', color: 'positive', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.Dictionary'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.element.ts index 7ca550a636..d232ccd027 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.element.ts @@ -2,12 +2,13 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import { UUITextareaElement, UUITextareaEvent } from '@umbraco-ui/uui'; -import { UmbWorkspaceDictionaryContext } from '../../dictionary-workspace.context'; +import { UmbDictionaryWorkspaceContext } from '../../dictionary-workspace.context'; import { UmbDictionaryRepository } from '../../../repository/dictionary.repository'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DictionaryItemModel, LanguageModel } from '@umbraco-cms/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DictionaryItemResponseModel, LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-workspace-view-dictionary-edit') export class UmbWorkspaceViewDictionaryEditElement extends UmbLitElement { @@ -22,14 +23,14 @@ export class UmbWorkspaceViewDictionaryEditElement extends UmbLitElement { ]; @state() - private _dictionary?: DictionaryItemModel; + private _dictionary?: DictionaryItemResponseModel; #repo!: UmbDictionaryRepository; @state() - private _languages: Array = []; + private _languages: Array = []; - #workspaceContext!: UmbWorkspaceDictionaryContext; + #workspaceContext!: UmbDictionaryWorkspaceContext; async connectedCallback() { super.connectedCallback(); @@ -37,8 +38,8 @@ export class UmbWorkspaceViewDictionaryEditElement extends UmbLitElement { this.#repo = new UmbDictionaryRepository(this); this._languages = await this.#repo.getLanguages(); - this.consumeContext('umbWorkspaceContext', (_instance) => { - this.#workspaceContext = _instance; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (_instance) => { + this.#workspaceContext = _instance as UmbDictionaryWorkspaceContext; this.#observeDictionary(); }); } @@ -49,7 +50,7 @@ export class UmbWorkspaceViewDictionaryEditElement extends UmbLitElement { }); } - #renderTranslation(language: LanguageModel) { + #renderTranslation(language: LanguageResponseModel) { if (!language.isoCode) return; const translation = this._dictionary?.translations?.find((x) => x.isoCode === language.isoCode); @@ -68,7 +69,7 @@ export class UmbWorkspaceViewDictionaryEditElement extends UmbLitElement { if (e instanceof UUITextareaEvent) { const target = e.composedPath()[0] as UUITextareaElement; const translation = target.value.toString(); - const isoCode = target.getAttribute('name')!; + const isoCode = target.getAttribute('name')!; this.#workspaceContext.setPropertyValue(isoCode, translation); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.stories.ts index 806bd714e5..f2afe0facf 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/dictionary/workspace/views/edit/workspace-view-dictionary-edit.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; //import { data } from '../../../../../core/mocks/data/dictionary.data'; import type { UmbWorkspaceViewDictionaryEditElement } from './workspace-view-dictionary-edit.element'; import './workspace-view-dictionary-edit.element'; @@ -15,11 +15,11 @@ export default { /*html` ${story()} `,*/ - } + }, ], } as Meta; export const AAAOverview: Story = () => html` `; - + AAAOverview.storyName = 'Overview'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/index.ts index 7712683eb5..9d5a22448b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/index.ts @@ -1,7 +1,7 @@ import { manifests as translationSectionManifests } from './section.manifest'; import { manifests as dictionaryManifests } from './dictionary/manifests'; -import type { ManifestTypes } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; export const manifests = [...translationSectionManifests, ...dictionaryManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/translation/section.manifest.ts b/src/Umbraco.Web.UI.Client/src/backoffice/translation/section.manifest.ts index aeaee59e29..290a8ab517 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/translation/section.manifest.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/translation/section.manifest.ts @@ -1,4 +1,4 @@ -import type { ManifestDashboard, ManifestSection, ManifestMenuSectionSidebarApp } from '@umbraco-cms/models'; +import type { ManifestDashboard, ManifestSection, ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; const sectionAlias = 'Umb.Section.Translation'; @@ -13,16 +13,19 @@ const section: ManifestSection = { }, }; -const menuSectionSidebarApp: ManifestMenuSectionSidebarApp = { - type: 'menuSectionSidebarApp', +const menuSectionSidebarApp: ManifestTypes = { + type: 'sectionSidebarApp', + kind: 'menu', alias: 'Umb.SidebarMenu.Dictionary', name: 'Dictionary Sidebar Menu', weight: 100, meta: { label: 'Dictionary', - sections: [sectionAlias], menu: 'Umb.Menu.Dictionary', }, + conditions: { + sections: [sectionAlias], + }, }; const dashboards: Array = [ @@ -34,9 +37,11 @@ const dashboards: Array = [ loader: () => import('./dashboards/dictionary/dashboard-translation-dictionary.element'), meta: { label: 'Dictionary overview', - sections: [sectionAlias], pathname: '', }, + conditions: { + sections: [sectionAlias], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-header-app.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-header-app.element.ts index 974928025b..7cf07e767f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-header-app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-header-app.element.ts @@ -2,13 +2,12 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbCurrentUserStore, UMB_CURRENT_USER_STORE_CONTEXT_TOKEN } from './current-user.store'; -import { UMB_CURRENT_USER_MODAL_TOKEN } from './modals/current-user'; -import type { UserDetails } from '@umbraco-cms/models'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CURRENT_USER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-current-user-header-app') -export class UmbCurrentUserHeaderApp extends UmbLitElement { +export class UmbCurrentUserHeaderAppElement extends UmbLitElement { static styles: CSSResultGroup = [ UUITextStyles, css` @@ -47,7 +46,7 @@ export class UmbCurrentUserHeaderApp extends UmbLitElement { } private _handleUserClick() { - this._modalContext?.open(UMB_CURRENT_USER_MODAL_TOKEN); + this._modalContext?.open(UMB_CURRENT_USER_MODAL); } render() { @@ -59,10 +58,10 @@ export class UmbCurrentUserHeaderApp extends UmbLitElement { } } -export default UmbCurrentUserHeaderApp; +export default UmbCurrentUserHeaderAppElement; declare global { interface HTMLElementTagNameMap { - 'umb-current-user-header-app': UmbCurrentUserHeaderApp; + 'umb-current-user-header-app': UmbCurrentUserHeaderAppElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-history.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-history.store.ts index f16efb7640..2a5df8b61f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-history.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user-history.store.ts @@ -1,5 +1,5 @@ -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { DeepState } from '@umbraco-cms/observable-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { DeepState } from '@umbraco-cms/backoffice/observable-api'; export type UmbModelType = 'dialog' | 'sidebar'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user.store.ts index 024bf6b78c..70556528f1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/current-user.store.ts @@ -1,8 +1,8 @@ import { umbUsersData } from '../../../core/mocks/data/users.data'; -import { umbracoPath } from '@umbraco-cms/utils'; -import type { UserDetails } from '@umbraco-cms/models'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ObjectState } from '@umbraco-cms/observable-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ObjectState } from '@umbraco-cms/backoffice/observable-api'; export const UMB_CURRENT_USER_STORE_CONTEXT_TOKEN = new UmbContextToken('UmbCurrentUserStore'); @@ -31,4 +31,3 @@ export class UmbCurrentUserStore { return currentUser ? currentUser.userGroups.includes(adminUserGroupKey) : false; } } - diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/manifests.ts index f805aad559..2db8a84064 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/manifests.ts @@ -1,23 +1,14 @@ import { manifests as modalManifests } from './modals/manifests'; -import type { ManifestHeaderApp, ManifestUserDashboard } from '@umbraco-cms/models'; +import { manifests as userProfileAppsManifests } from './user-profile-apps/manifests'; +import type { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; -export const userDashboards: Array = [ - { - type: 'userDashboard', - alias: 'Umb.UserDashboard.Themes', - name: 'Themes User Dashboard', - loader: () => import('./user-dashboard-themes.element'), - weight: 1, - }, -]; - -export const headerApps: Array = [ +export const headerApps: Array = [ { type: 'headerApp', alias: 'Umb.HeaderApp.CurrentUser', name: 'Current User', loader: () => import('./current-user-header-app.element'), - weight: 1000, + weight: 0, meta: { label: 'TODO: how should we enable this to not be set.', icon: 'TODO: how should we enable this to not be set.', @@ -26,4 +17,4 @@ export const headerApps: Array = [ }, ]; -export const manifests = [...userDashboards, ...headerApps, ...modalManifests]; +export const manifests = [...headerApps, ...modalManifests, ...userProfileAppsManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/change-password/change-password-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/change-password/change-password-modal.element.ts index 2440cb743a..f5fc28ad43 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/change-password/change-password-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/change-password/change-password-modal.element.ts @@ -1,9 +1,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { css, CSSResultGroup, html, nothing } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { UmbChangePasswordModalData } from '.'; -import { UmbModalHandler } from '@umbraco-cms/modal'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalHandler, UmbChangePasswordModalData } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-change-password-modal') export class UmbChangePasswordModalElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/change-password/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/change-password/index.ts deleted file mode 100644 index 6a3504c607..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/change-password/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; - -export interface UmbChangePasswordModalData { - requireOldPassword: boolean; -} - -export const UMB_CHANGE_PASSWORD_MODAL_TOKEN = new UmbModalToken( - 'Umb.Modal.ChangePassword', - { - type: 'dialog', - } -); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/current-user/current-user-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/current-user/current-user-modal.element.ts index e64252a10d..862d2e5823 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/current-user/current-user-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/current-user/current-user-modal.element.ts @@ -1,16 +1,10 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; -import { css, CSSResultGroup, html, nothing } from 'lit'; +import { css, CSSResultGroup, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { - UmbCurrentUserHistoryStore, - UmbCurrentUserHistoryItem, - UMB_CURRENT_USER_HISTORY_STORE_CONTEXT_TOKEN, -} from '../../current-user-history.store'; import { UmbCurrentUserStore, UMB_CURRENT_USER_STORE_CONTEXT_TOKEN } from '../../current-user.store'; -import { UMB_CHANGE_PASSWORD_MODAL_TOKEN } from '../change-password'; -import { UmbModalHandler, UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import type { UserDetails } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbModalHandler } from '@umbraco-cms/backoffice/modal'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-current-user-modal') export class UmbCurrentUserModalElement extends UmbLitElement { @@ -37,43 +31,11 @@ export class UmbCurrentUserModalElement extends UmbLitElement { flex-direction: column; gap: var(--uui-size-space-3); } - #recent-history { + #userProfileApps { display: flex; flex-direction: column; gap: var(--uui-size-space-3); } - #recent-history-items { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-4); - } - .history-item { - display: grid; - grid-template-columns: 32px 1fr; - grid-template-rows: 1fr; - color: var(--uui-color-interactive); - text-decoration: none; - } - .history-item uui-icon { - margin-top: var(--uui-size-space-1); - } - .history-item:hover { - color: var(--uui-color-interactive-emphasis); - } - .history-item > div { - color: inherit; - text-decoration: none; - display: flex; - flex-direction: column; - line-height: 1.4em; - } - .history-item > div > span { - font-size: var(--uui-size-4); - opacity: 0.5; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } `, ]; @@ -83,30 +45,16 @@ export class UmbCurrentUserModalElement extends UmbLitElement { @state() private _currentUser?: UserDetails; - @state() - private _history: Array = []; - - private _modalContext?: UmbModalContext; private _currentUserStore?: UmbCurrentUserStore; - private _currentUserHistoryStore?: UmbCurrentUserHistoryStore; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this._modalContext = instance; - }); - this.consumeContext(UMB_CURRENT_USER_STORE_CONTEXT_TOKEN, (instance) => { this._currentUserStore = instance; this._observeCurrentUser(); }); - this.consumeContext(UMB_CURRENT_USER_HISTORY_STORE_CONTEXT_TOKEN, (instance) => { - this._currentUserHistoryStore = instance; - this._observeHistory(); - }); - this._observeCurrentUser(); } @@ -117,55 +65,11 @@ export class UmbCurrentUserModalElement extends UmbLitElement { this._currentUser = currentUser; }); } - private async _observeHistory() { - if (this._currentUserHistoryStore) { - this.observe(this._currentUserHistoryStore.latestHistory, (history) => { - this._history = history; - }); - } - } private _close() { this.modalHandler?.submit(); } - private _edit() { - if (!this._currentUser) return; - - history.pushState(null, '', '/section/users/view/users/user/' + this._currentUser.key); //TODO Change to a tag with href and make dynamic - this._close(); - } - - private _changePassword() { - if (!this._modalContext) return; - - this._modalContext.open(UMB_CHANGE_PASSWORD_MODAL_TOKEN, { - requireOldPassword: this._currentUserStore?.isAdmin || false, - }); - } - - private _renderHistoryItem(item: UmbCurrentUserHistoryItem) { - return html` - - -
    - ${Array.isArray(item.label) ? item.label[0] : item.label} - - ${Array.isArray(item.label) - ? item.label.map((label, index) => { - if (index === 0) return; - return html` - ${label} - ${index !== item.label.length - 1 ? html`${'>'}` : nothing} - `; - }) - : nothing} - -
    -
    - `; - } - private _logout() { this._currentUserStore?.logout(); } @@ -174,24 +78,7 @@ export class UmbCurrentUserModalElement extends UmbLitElement { return html`
    - - Your profile - Edit - Change password - - - External login providers - - -
    - -
    - - Recent History -
    - ${this._history.reverse().map((item) => html` ${this._renderHistoryItem(item)} `)} -
    -
    +
    Close diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/current-user/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/current-user/index.ts deleted file mode 100644 index 978eeb535c..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/current-user/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; - -export const UMB_CURRENT_USER_MODAL_TOKEN = new UmbModalToken('Umb.Modal.CurrentUser', { - type: 'sidebar', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/manifests.ts index 68cc073e78..2e65cb97df 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/manifests.ts new file mode 100644 index 0000000000..1a035797ab --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/manifests.ts @@ -0,0 +1,49 @@ +import { ManifestUserProfileApp } from '@umbraco-cms/backoffice/extensions-registry'; + +export const userProfileApps: Array = [ + { + type: 'userProfileApp', + alias: 'Umb.UserProfileApp.profile', + name: 'Profile User Profile App', + loader: () => import('./user-profile-app-profile.element'), + weight: 900, + meta: { + label: 'Profile User Profile App', + pathname: 'profile', + }, + }, + { + type: 'userProfileApp', + alias: 'Umb.UserProfileApp.ExternalLoginProviders', + name: 'External Login Providers User Profile App', + loader: () => import('./user-profile-app-external-login-providers.element'), + weight: 800, + meta: { + label: 'External Login Providers User Profile App', + pathname: 'externalLoginProviders', + }, + }, + { + type: 'userProfileApp', + alias: 'Umb.UserProfileApp.Themes', + name: 'Themes User Profile App', + loader: () => import('./user-profile-app-themes.element'), + weight: 200, + meta: { + label: 'Themes User Profile App', + pathname: 'themes', + }, + }, + { + type: 'userProfileApp', + alias: 'Umb.UserProfileApp.History', + name: 'History User Profile App', + loader: () => import('./user-profile-app-history.element'), + weight: 100, + meta: { + label: 'History User Profile App', + pathname: 'history', + }, + }, +]; +export const manifests = [...userProfileApps]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-external-login-providers.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-external-login-providers.element.ts new file mode 100644 index 0000000000..9ebcc291a5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-external-login-providers.element.ts @@ -0,0 +1,26 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-user-profile-app-external-login-providers') +export class UmbUserProfileAppExternalLoginProvidersElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + render() { + return html` + + External login providers + + + `; + } +} + +export default UmbUserProfileAppExternalLoginProvidersElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-profile-app-external-login-providers': UmbUserProfileAppExternalLoginProvidersElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-history.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-history.element.ts new file mode 100644 index 0000000000..ffdd50ace4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-history.element.ts @@ -0,0 +1,118 @@ +import { css, html, nothing } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { + UmbCurrentUserHistoryItem, + UmbCurrentUserHistoryStore, + UMB_CURRENT_USER_HISTORY_STORE_CONTEXT_TOKEN, +} from '../current-user-history.store'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-user-profile-app-history') +export class UmbUserProfileAppHistoryElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + #recent-history { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-3); + } + #recent-history-items { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); + } + .history-item { + display: grid; + grid-template-columns: 32px 1fr; + grid-template-rows: 1fr; + color: var(--uui-color-interactive); + text-decoration: none; + } + .history-item uui-icon { + margin-top: var(--uui-size-space-1); + } + .history-item:hover { + color: var(--uui-color-interactive-emphasis); + } + .history-item > div { + color: inherit; + text-decoration: none; + display: flex; + flex-direction: column; + line-height: 1.4em; + } + .history-item > div > span { + font-size: var(--uui-size-4); + opacity: 0.5; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + `, + ]; + + @state() + private _history: Array = []; + + #currentUserHistoryStore?: UmbCurrentUserHistoryStore; + + constructor() { + super(); + + this.consumeContext(UMB_CURRENT_USER_HISTORY_STORE_CONTEXT_TOKEN, (instance) => { + this.#currentUserHistoryStore = instance; + this.#observeHistory(); + }); + } + + #observeHistory() { + if (this.#currentUserHistoryStore) { + this.observe(this.#currentUserHistoryStore.latestHistory, (history) => { + this._history = history; + }); + } + } + + render() { + return html` + + Recent History +
    + ${this._history.reverse().map((item) => html` ${this.#renderHistoryItem(item)} `)} +
    +
    + `; + } + + #renderHistoryItem(item: UmbCurrentUserHistoryItem) { + return html` + + +
    + ${Array.isArray(item.label) ? item.label[0] : item.label} + + ${Array.isArray(item.label) + ? item.label.map((label, index) => { + if (index === 0) return; + return html` + ${label} + ${index !== item.label.length - 1 ? html`${'>'}` : nothing} + `; + }) + : nothing} + +
    +
    + `; + } +} + +export default UmbUserProfileAppHistoryElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-dashboard-test': UmbUserProfileAppHistoryElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-profile.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-profile.element.ts new file mode 100644 index 0000000000..840b280c6a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-profile.element.ts @@ -0,0 +1,73 @@ +import { css, html } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbCurrentUserStore, UMB_CURRENT_USER_STORE_CONTEXT_TOKEN } from '../current-user.store'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbModalContext, UMB_CHANGE_PASSWORD_MODAL, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; + +@customElement('umb-user-profile-app-profile') +export class UmbUserProfileAppProfileElement extends UmbLitElement { + static styles = [UUITextStyles, css``]; + + @state() + private _currentUser?: UserDetails; + + private _modalContext?: UmbModalContext; + private _currentUserStore?: UmbCurrentUserStore; + + constructor() { + super(); + + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this._modalContext = instance; + }); + + this.consumeContext(UMB_CURRENT_USER_STORE_CONTEXT_TOKEN, (instance) => { + this._currentUserStore = instance; + this._observeCurrentUser(); + }); + + this._observeCurrentUser(); + } + + private async _observeCurrentUser() { + if (!this._currentUserStore) return; + + this.observe(this._currentUserStore.currentUser, (currentUser) => { + this._currentUser = currentUser; + }); + } + + private _edit() { + if (!this._currentUser) return; + + history.pushState(null, '', 'section/users/view/users/user/' + this._currentUser.id); //TODO Change to a tag with href and make dynamic + //TODO Implement modal routing for the current-user-modal, so that the modal closes when navigating to the edit profile page + } + private _changePassword() { + if (!this._modalContext) return; + + this._modalContext.open(UMB_CHANGE_PASSWORD_MODAL, { + requireOldPassword: this._currentUserStore?.isAdmin || false, + }); + } + + render() { + return html` + + Your profile + Edit + Change password + + `; + } +} + +export default UmbUserProfileAppProfileElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-profile-app-profile': UmbUserProfileAppProfileElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-dashboard-themes.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-themes.element.ts similarity index 71% rename from src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-dashboard-themes.element.ts rename to src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-themes.element.ts index 84ce43e311..b6bc69938f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-dashboard-themes.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/current-user/user-profile-apps/user-profile-app-themes.element.ts @@ -2,13 +2,13 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { UUISelectEvent } from '@umbraco-ui/uui'; -import { UmbThemeContext, UMB_THEME_CONTEXT_TOKEN } from '../../themes/theme.context'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTheme } from '@umbraco-cms/extensions-registry'; +import { UmbThemeContext, UMB_THEME_CONTEXT_TOKEN } from '../../../themes/theme.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTheme } from '@umbraco-cms/backoffice/extensions-registry'; -@customElement('umb-user-dashboard-test') -export class UmbUserDashboardTestElement extends UmbLitElement { +@customElement('umb-user-profile-app-themes') +export class UmbUserProfileAppThemesElement extends UmbLitElement { static styles = [ UUITextStyles, css` @@ -47,7 +47,7 @@ export class UmbUserDashboardTestElement extends UmbLitElement { }); } - private _handleThemeChange(event: UUISelectEvent) { + #handleThemeChange(event: UUISelectEvent) { if (!this.#themeService) return; const theme = event.target.value.toString(); @@ -55,7 +55,7 @@ export class UmbUserDashboardTestElement extends UmbLitElement { this.#themeService.setThemeByAlias(theme); } - get options() { + get #options() { return this._themes.map((t) => ({ name: t.name, value: t.alias, selected: t.alias === this._themeAlias })); } @@ -64,17 +64,17 @@ export class UmbUserDashboardTestElement extends UmbLitElement { Select Theme + .options=${this.#options}> `; } } -export default UmbUserDashboardTestElement; +export default UmbUserProfileAppThemesElement; declare global { interface HTMLElementTagNameMap { - 'umb-user-dashboard-test': UmbUserDashboardTestElement; + 'umb-user-profile-app-themes': UmbUserProfileAppThemesElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/index.ts index 03d81407b4..dfabd9ec4c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/index.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/index.ts @@ -3,8 +3,8 @@ import { manifests as userManifests } from './users/manifests'; import { manifests as userSectionManifests } from './user-section/manifests'; import { manifests as currentUserManifests } from './current-user/manifests'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { ManifestTypes } from '@umbraco-cms/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { ManifestTypes } from '@umbraco-cms/backoffice/extensions-registry'; export const manifests = [...userGroupManifests, ...userManifests, ...userSectionManifests, ...currentUserManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/manifests.ts index afd2fe55b9..9849287724 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/index.ts deleted file mode 100644 index b56c013f03..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { UserDetails } from '@umbraco-cms/models'; -import { UmbModalToken, UmbPickerModalData } from '@umbraco-cms/modal'; - -export const UMB_USER_GROUP_PICKER_MODAL_TOKEN = new UmbModalToken>( - 'Umb.Modal.UserGroupPicker', - { - type: 'sidebar', - size: 'small', - } -); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts index 05332be801..3a06069852 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.element.ts @@ -2,8 +2,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbUserGroupStore, UMB_USER_GROUP_STORE_CONTEXT_TOKEN } from '../../repository/user-group.store'; -import { UmbModalElementPickerBase } from '@umbraco-cms/modal'; -import type { UserGroupDetails } from '@umbraco-cms/models'; +import { UmbModalElementPickerBase } from '@umbraco-cms/internal/modal'; +import type { UserGroupDetails } from '@umbraco-cms/backoffice/models'; @customElement('umb-user-group-picker-modal') export class UmbUserGroupPickerModalElement extends UmbModalElementPickerBase { @@ -81,9 +81,9 @@ export class UmbUserGroupPickerModalElement extends UmbModalElementPickerBase html`
    this.handleSelection(item.key)} - @keydown=${(e: KeyboardEvent) => this._handleKeydown(e, item.key)} - class=${this.isSelected(item.key) ? 'item selected' : 'item'}> + @click=${() => this.handleSelection(item.id)} + @keydown=${(e: KeyboardEvent) => this._handleKeydown(e, item.id)} + class=${this.isSelected(item.id) ? 'item selected' : 'item'}> ${item.name}
    diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.test.ts index b24ed8ff39..0ca037bc6c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/modals/user-group-picker/user-group-picker-modal.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import { UmbPickerLayoutUserGroupElement } from './picker-layout-user-group.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbPickerLayoutUserGroupElement', () => { // let element: UmbPickerLayoutUserGroupElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/manifests.ts index bf2a3e442c..7de2e86b25 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/manifests.ts @@ -1,6 +1,6 @@ import { UmbUserGroupRepository } from '../repository/user-group.repository'; import { UmbUserGroupStore } from './user-group.store'; -import type { ManifestStore, ManifestRepository } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const USER_GROUP_REPOSITORY_ALIAS = 'Umb.Repository.UserGroup'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.repository.ts index 33e825330d..7e4eac48ec 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.repository.ts @@ -1,10 +1,10 @@ -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; // TODO: implement export class UmbUserGroupRepository { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; console.log(this.#host); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.store.ts index 950acae2df..64197bb05b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/repository/user-group.store.ts @@ -1,8 +1,8 @@ -import type { UserGroupDetails } from '@umbraco-cms/models'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { ArrayState } from '@umbraco-cms/observable-api'; -import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/store'; +import type { UserGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/backoffice/store'; // TODO: get rid of this type addition & { ... }: //export type UmbUserGroupStoreItemType = UserGroupDetails & { users?: Array }; @@ -16,26 +16,21 @@ export const UMB_USER_GROUP_STORE_CONTEXT_TOKEN = new UmbContextToken { - - - #groups = new ArrayState([], x => x.key); + #groups = new ArrayState([], (x) => x.id); public groups = this.#groups.asObservable(); - - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_USER_GROUP_STORE_CONTEXT_TOKEN.toString()); } - - - getScaffold(entityType: string, parentKey: string | null) { + getScaffold(entityType: string, parentId: string | null) { return { - key: '', + id: '', name: '', icon: '', type: 'user-group', hasChildren: false, - parentKey: '', + parentId: '', sections: [], permissions: [], users: [], @@ -54,27 +49,27 @@ export class UmbUserGroupStore extends UmbStoreBase implements UmbEntityDetailSt return this.groups; } - getByKey(key: string) { + getByKey(id: string) { // TODO: use Fetcher API. // TODO: only fetch if the data type is not in the store? - fetch(`/umbraco/backoffice/user-groups/details/${key}`) + fetch(`/umbraco/backoffice/user-groups/details/${id}`) .then((res) => res.json()) .then((data) => { this.#groups.append([data]); }); - return this.#groups.getObservablePart((userGroups) => userGroups.find(userGroup => userGroup.key === key)); + return this.#groups.getObservablePart((userGroups) => userGroups.find((userGroup) => userGroup.id === id)); } - getByKeys(keys: Array) { - const params = keys.map((key) => `key=${key}`).join('&'); + getByKeys(ids: Array) { + const params = ids.map((id) => `id=${id}`).join('&'); fetch(`/umbraco/backoffice/user-groups/getByKeys?${params}`) .then((res) => res.json()) .then((data) => { this.#groups.append(data); }); - return this.#groups.getObservablePart((items) => items.filter(node => keys.includes(node.key))); + return this.#groups.getObservablePart((items) => items.filter((node) => ids.includes(node.id))); } async save(userGroups: Array) { @@ -83,7 +78,7 @@ export class UmbUserGroupStore extends UmbStoreBase implements UmbEntityDetailSt // TODO: implement so user group store updates the users, but these needs to save as well..? /* if (this._userStore && userGroup.users) { - await this._userStore.updateUserGroup(userGroup.users, userGroup.key); + await this._userStore.updateUserGroup(userGroup.users, userGroup.id); } */ diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/actions/workspace-action-user-group-save.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/actions/workspace-action-user-group-save.element.ts index 3977037d08..79a76bc2fb 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/actions/workspace-action-user-group-save.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/actions/workspace-action-user-group-save.element.ts @@ -2,8 +2,9 @@ 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 { UmbWorkspaceUserContext } from '../../../users/workspace/user-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbUserWorkspaceContext } from '../../../users/workspace/user-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-workspace-action-user-group-save') export class UmbWorkspaceActionUserGroupSaveElement extends UmbLitElement { @@ -12,14 +13,13 @@ export class UmbWorkspaceActionUserGroupSaveElement extends UmbLitElement { @state() private _saveButtonState?: UUIButtonState; - private _workspaceContext?: UmbWorkspaceUserContext; + private _workspaceContext?: UmbUserWorkspaceContext; constructor() { super(); - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext('umbWorkspaceContext', (instance) => { - this._workspaceContext = instance; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this._workspaceContext = instance as UmbUserWorkspaceContext; }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/manifests.ts index 15267e8e6d..29a5252340 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/manifests.ts @@ -1,4 +1,8 @@ -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace-edit.element.ts new file mode 100644 index 0000000000..a997c5133a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace-edit.element.ts @@ -0,0 +1,372 @@ +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { UUITextStyles } from '@umbraco-ui/uui-css'; +import { css, html, nothing } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; +import { UmbUserStore } from '../../users/repository/user.store'; +import { UmbUserGroupWorkspaceContext } from './user-group-workspace.context'; +import type { UserGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +import '../../../shared/components/input-user/input-user.element'; +import '../../../shared/components/input-section/input-section.element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; + +@customElement('umb-user-group-workspace-edit') +export class UmbUserGroupWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + height: 100%; + } + + #main { + display: grid; + grid-template-columns: 1fr 350px; + gap: var(--uui-size-layout-1); + padding: var(--uui-size-layout-1); + } + #left-column { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); + } + #right-column > uui-box > div { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-2); + } + hr { + border: none; + border-bottom: 1px solid var(--uui-color-divider); + width: 100%; + } + uui-input { + width: 100%; + } + .faded-text { + color: var(--uui-color-text-alt); + font-size: 0.8rem; + } + #default-permissions { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); + } + .default-permission { + display: flex; + align-items: center; + gap: var(--uui-size-space-4); + padding: var(--uui-size-space-2); + } + .default-permission:not(:last-child) { + border-bottom: 1px solid var(--uui-color-divider); + } + .permission-info { + display: flex; + flex-direction: column; + } + `, + ]; + + defaultPermissions: Array<{ + name: string; + permissions: Array<{ name: string; description: string; value: boolean }>; + }> = [ + { + name: 'Administration', + permissions: [ + { + name: 'Culture and Hostnames', + description: 'Allow access to assign culture and hostnames', + value: false, + }, + { + name: 'Restrict Public Access', + description: 'Allow access to set and change access restrictions for a node', + value: false, + }, + { + name: 'Rollback', + description: 'Allow access to roll back a node to a previous state', + value: false, + }, + ], + }, + { + name: 'Content', + permissions: [ + { + name: 'Browse Node', + description: 'Allow access to view a node', + value: false, + }, + { + name: 'Create Content Template', + description: 'Allow access to create a Content Template', + value: false, + }, + { + name: 'Delete', + description: 'Allow access to delete nodes', + value: false, + }, + { + name: 'Create', + description: 'Allow access to create nodes', + value: false, + }, + { + name: 'Publish', + description: 'Allow access to publish nodes', + value: false, + }, + { + name: 'Permissions', + description: 'Allow access to change permissions for a node', + value: false, + }, + { + name: 'Send To Publish', + description: 'Allow access to send a node for approval before publishing', + value: false, + }, + { + name: 'Unpublish', + description: 'Allow access to unpublish a node', + value: false, + }, + { + name: 'Update', + description: 'Allow access to save a node', + value: false, + }, + { + name: 'Full restore', + description: 'Allow the user to restore items', + value: false, + }, + { + name: 'Partial restore', + description: 'Allow the user to partial restore items', + value: false, + }, + { + name: 'Queue for transfer', + description: 'Allow the user to queue item(s)', + value: false, + }, + ], + }, + { + name: 'Structure', + permissions: [ + { + name: 'Copy', + description: 'Allow access to copy a node', + value: false, + }, + { + name: 'Move', + description: 'Allow access to move a node', + value: false, + }, + { + name: 'Sort', + description: 'Allow access to change the sort order for nodes', + value: false, + }, + ], + }, + ]; + + private _userStore?: UmbUserStore; + + #workspaceContext?: UmbUserGroupWorkspaceContext; + + @state() + private _userGroup?: UserGroupDetails; + + @state() + private _userKeys?: Array; + + constructor() { + super(); + + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbUserGroupWorkspaceContext; + this.observeUserGroup(); + }); + } + + observeUserGroup() { + if (!this.#workspaceContext) return; + this.observe(this.#workspaceContext.data, (userGroup) => (this._userGroup = userGroup as any)); + } + + private _observeUsers() { + if (!this._userStore) return; + + // 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) => { + // TODO: handle if there is no users. + if (!this._userKeys && users.length > 0) { + const entityId = this.#workspaceContext?.getEntityId(); + if (!entityId) return; + this._userKeys = users.filter((user) => user.userGroups.includes(entityId)).map((user) => user.id); + //this._updateProperty('users', this._userKeys); + // TODO: make a method on the UmbWorkspaceUserGroupContext: + //this._workspaceContext.setUsers(); + } + }); + } + + private _updateUserKeys(userKeys: Array) { + this._userKeys = userKeys; + // TODO: make a method on the UmbWorkspaceUserGroupContext: + //this._workspaceContext.setUsers(); + } + + private _updatePermission(permission: { name: string; description: string; value: boolean }) { + if (!this.#workspaceContext) return; + + const checkValue = this._checkPermission(permission); + //const selectedPermissions = this._workspaceContext.getData().permissions; + // TODO: make a method on the UmbWorkspaceUserGroupContext: + //const selectedPermissions = this._workspaceContext.getPermissions(); + + /* + let newPermissions = []; + if (checkValue === false) { + newPermissions = [...selectedPermissions, permission.name]; + } else { + newPermissions = selectedPermissions.filter((p) => p !== permission.name); + } + */ + + //this._updateProperty('permissions', newPermissions); + // TODO: make a method on the UmbWorkspaceUserGroupContext: + //this._workspaceContext.setPermissions(); + } + + private _checkPermission(permission: { name: string; description: string; value: boolean }) { + if (!this.#workspaceContext) return false; + + //return this._workspaceContext.getPermissions().includes(permission.name); + return false; + } + + private _updateSections(value: string[]) { + console.log('To be done'); + //this._workspaceContext.setSections(value); + } + + private renderLeftColumn() { + if (!this._userGroup) return nothing; + + return html` +
    Assign access
    + + this._updateSections(e.target.value)}> + + + + + + + + + + + + + + + +
    + + +
    Default Permissions
    +
    + ${repeat( + this.defaultPermissions, + (defaultPermission) => html` +
    + ${defaultPermission.name} + ${repeat( + defaultPermission.permissions, + (permission) => html` +
    + this._updatePermission(permission)}> +
    + ${permission.name} + ${permission.description} +
    +
    + ` + )} +
    + ` + )} +
    +
    + + +
    Granular permissions
    +
    `; + } + + private renderRightColumn() { + return html` +
    Users
    + this._updateUserKeys((e.target as any).value)} + .value=${this._userKeys || []}> +
    `; + } + + // TODO: find a way where we don't have to do this for all Workspaces. + private _handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.setName(target.value); + } + } + } + + render() { + if (!this._userGroup) return nothing; + + return html` + + +
    +
    ${this.renderLeftColumn()}
    +
    ${this.renderRightColumn()}
    +
    +
    + `; + } +} + +export default UmbUserGroupWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-group-workspace-edit': UmbUserGroupWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.context.ts index bdf1d7f7ac..19a5fe183b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.context.ts @@ -1,14 +1,14 @@ import { UmbEntityWorkspaceManager } from '../../../shared/components/workspace/workspace-context/entity-manager-controller'; import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; import { UMB_USER_GROUP_STORE_CONTEXT_TOKEN } from '../repository/user-group.store'; import { UmbUserGroupRepository } from '../repository/user-group.repository'; -import type { UserGroupDetails } from '@umbraco-cms/models'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { UserGroupDetails } from '@umbraco-cms/backoffice/models'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; -export class UmbWorkspaceUserGroupContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface +export class UmbUserGroupWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { #manager = new UmbEntityWorkspaceManager( this.host, @@ -19,7 +19,7 @@ export class UmbWorkspaceUserGroupContext public readonly data = this.#manager.state.asObservable(); public readonly name = this.#manager.state.getObservablePart((state) => state?.name); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbUserGroupRepository(host)); } @@ -28,7 +28,7 @@ export class UmbWorkspaceUserGroupContext } getEntityType = this.#manager.getEntityType; getUnique = this.#manager.getEntityKey; - getEntityKey = this.#manager.getEntityKey; + getEntityId = this.#manager.getEntityKey; getStore = this.#manager.getStore; getData = this.#manager.getData as any; // TODO: fix type mismatch, but this will be done when we move to repositories. load = this.#manager.load; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.element.ts index 733034d8a4..e27f918e93 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.element.ts @@ -1,223 +1,27 @@ -import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; import { UUITextStyles } from '@umbraco-ui/uui-css'; -import { css, html, nothing } from 'lit'; +import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { repeat } from 'lit/directives/repeat.js'; -import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from '../../users/repository/user.store'; -import { UmbWorkspaceEntityElement } from '../../../shared/components/workspace/workspace-entity-element.interface'; -import { UmbWorkspaceUserGroupContext } from './user-group-workspace.context'; -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; -import type { ManifestWorkspaceAction, UserGroupDetails } from '@umbraco-cms/models'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; - -import '../../../shared/components/input-user/input-user.element'; -import '../../../shared/components/input-section/input-section.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbUserGroupWorkspaceContext } from './user-group-workspace.context'; +import { UmbUserGroupWorkspaceEditElement } from './user-group-workspace-edit.element'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { ManifestWorkspaceAction } from '@umbraco-cms/backoffice/extensions-registry'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; @customElement('umb-user-group-workspace') -export class UmbUserGroupWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - height: 100%; - } +export class UmbUserGroupWorkspaceElement extends UmbLitElement { + static styles = [UUITextStyles]; - #main { - display: grid; - grid-template-columns: 1fr 350px; - gap: var(--uui-size-space-6); - padding: var(--uui-size-space-6); - } - #left-column { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-4); - } - #right-column > uui-box > div { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-2); - } - hr { - border: none; - border-bottom: 1px solid var(--uui-color-divider); - width: 100%; - } - uui-input { - width: 100%; - } - .faded-text { - color: var(--uui-color-text-alt); - font-size: 0.8rem; - } - #default-permissions { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-4); - } - .default-permission { - display: flex; - align-items: center; - gap: var(--uui-size-space-4); - padding: var(--uui-size-space-2); - } - .default-permission:not(:last-child) { - border-bottom: 1px solid var(--uui-color-divider); - } - .permission-info { - display: flex; - flex-direction: column; - } - `, - ]; - - defaultPermissions: Array<{ - name: string; - permissions: Array<{ name: string; description: string; value: boolean }>; - }> = [ - { - name: 'Administration', - permissions: [ - { - name: 'Culture and Hostnames', - description: 'Allow access to assign culture and hostnames', - value: false, - }, - { - name: 'Restrict Public Access', - description: 'Allow access to set and change access restrictions for a node', - value: false, - }, - { - name: 'Rollback', - description: 'Allow access to roll back a node to a previous state', - value: false, - }, - ], - }, - { - name: 'Content', - permissions: [ - { - name: 'Browse Node', - description: 'Allow access to view a node', - value: false, - }, - { - name: 'Create Content Template', - description: 'Allow access to create a Content Template', - value: false, - }, - { - name: 'Delete', - description: 'Allow access to delete nodes', - value: false, - }, - { - name: 'Create', - description: 'Allow access to create nodes', - value: false, - }, - { - name: 'Publish', - description: 'Allow access to publish nodes', - value: false, - }, - { - name: 'Permissions', - description: 'Allow access to change permissions for a node', - value: false, - }, - { - name: 'Send To Publish', - description: 'Allow access to send a node for approval before publishing', - value: false, - }, - { - name: 'Unpublish', - description: 'Allow access to unpublish a node', - value: false, - }, - { - name: 'Update', - description: 'Allow access to save a node', - value: false, - }, - { - name: 'Full restore', - description: 'Allow the user to restore items', - value: false, - }, - { - name: 'Partial restore', - description: 'Allow the user to partial restore items', - value: false, - }, - { - name: 'Queue for transfer', - description: 'Allow the user to queue item(s)', - value: false, - }, - ], - }, - { - name: 'Structure', - permissions: [ - { - name: 'Copy', - description: 'Allow access to copy a node', - value: false, - }, - { - name: 'Move', - description: 'Allow access to move a node', - value: false, - }, - { - name: 'Sort', - description: 'Allow access to change the sort order for nodes', - value: false, - }, - ], - }, - ]; - - private _userStore?: UmbUserStore; - - private _workspaceContext: UmbWorkspaceUserGroupContext = new UmbWorkspaceUserGroupContext(this); - - @state() - private _userGroup?: UserGroupDetails; - - @state() - private _userKeys?: Array; + #workspaceContext = new UmbUserGroupWorkspaceContext(this); + #element = new UmbUserGroupWorkspaceEditElement(); constructor() { super(); - this._registerWorkspaceActions(); - - this.consumeContext(UMB_USER_STORE_CONTEXT_TOKEN, (instance) => { - this._userStore = instance; - this._observeUsers(); - }); - - this.observe(this._workspaceContext.data, (userGroup) => { - // TODO: Fix type mismatch - this._userGroup = userGroup as any; - }); - } - - public load(entityKey: string) { - this._workspaceContext.load(entityKey); - } - - public create(parentKey: string | null) { - this._workspaceContext.create(parentKey); } + // TODO: move this to a manifest file private _registerWorkspaceActions() { const manifests: Array = [ { @@ -225,12 +29,14 @@ export class UmbUserGroupWorkspaceElement extends UmbLitElement implements UmbWo alias: 'Umb.WorkspaceAction.UserGroup.Save', name: 'Save User Group Workspace Action', meta: { - workspaces: ['Umb.Workspace.UserGroup'], label: 'Save', look: 'primary', color: 'positive', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.UserGroup'], + }, }, ]; @@ -240,159 +46,20 @@ export class UmbUserGroupWorkspaceElement extends UmbLitElement implements UmbWo }); } - private _observeUsers() { - if (!this._userStore) return; - - // 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) => { - // TODO: handle if there is no users. - if (!this._userKeys && users.length > 0) { - const entityKey = this._workspaceContext.getEntityKey(); - this._userKeys = users.filter((user) => user.userGroups.includes(entityKey)).map((user) => user.key); - //this._updateProperty('users', this._userKeys); - // TODO: make a method on the UmbWorkspaceUserGroupContext: - //this._workspaceContext.setUsers(); - } - }); - } - - private _updateUserKeys(userKeys: Array) { - this._userKeys = userKeys; - // TODO: make a method on the UmbWorkspaceUserGroupContext: - //this._workspaceContext.setUsers(); - } - - private _updatePermission(permission: { name: string; description: string; value: boolean }) { - if (!this._workspaceContext) return; - - const checkValue = this._checkPermission(permission); - //const selectedPermissions = this._workspaceContext.getData().permissions; - // TODO: make a method on the UmbWorkspaceUserGroupContext: - //const selectedPermissions = this._workspaceContext.getPermissions(); - - /* - let newPermissions = []; - if (checkValue === false) { - newPermissions = [...selectedPermissions, permission.name]; - } else { - newPermissions = selectedPermissions.filter((p) => p !== permission.name); - } - */ - - //this._updateProperty('permissions', newPermissions); - // TODO: make a method on the UmbWorkspaceUserGroupContext: - //this._workspaceContext.setPermissions(); - } - - private _checkPermission(permission: { name: string; description: string; value: boolean }) { - if (!this._workspaceContext) return false; - - //return this._workspaceContext.getPermissions().includes(permission.name); - return false; - } - - private _updateSections(value: string[]) { - console.log('To be done'); - //this._workspaceContext.setSections(value); - } - - private renderLeftColumn() { - if (!this._userGroup) return nothing; - - return html` -
    Assign access
    - - this._updateSections(e.target.value)}> - - - - - - - - - - - - - - - -
    - - -
    Default Permissions
    -
    - ${repeat( - this.defaultPermissions, - (defaultPermission) => html` -
    - ${defaultPermission.name} - ${repeat( - defaultPermission.permissions, - (permission) => html` -
    - this._updatePermission(permission)}> -
    - ${permission.name} - ${permission.description} -
    -
    - ` - )} -
    - ` - )} -
    -
    - - -
    Granular permissions
    -
    `; - } - - private renderRightColumn() { - return html` -
    Users
    - this._updateUserKeys((e.target as any).value)} - .value=${this._userKeys || []}> -
    `; - } - - // TODO: find a way where we don't have to do this for all Workspaces. - private _handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this._workspaceContext.setName(target.value); - } - } - } + @state() + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (_component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, + ]; render() { - if (!this._userGroup) return nothing; - - return html` - - -
    -
    ${this.renderLeftColumn()}
    -
    ${this.renderRightColumn()}
    -
    -
    - `; + return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.test.ts index 8f2906ada9..d7d85083ba 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-groups/workspace/user-group-workspace.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import UmbWorkspaceUserGroupElement from './editor-user-group.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbWorkspaceUserGroupElement', () => { // let element: UmbWorkspaceUserGroupElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/manifests.ts index 227eb3bb15..69636ed32b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestSection, ManifestSectionView } from '@umbraco-cms/models'; +import type { ManifestSection, ManifestSectionView } from '@umbraco-cms/backoffice/extensions-registry'; const sectionAlias = 'Umb.Section.Users'; @@ -19,26 +19,30 @@ const sectionsViews: Array = [ alias: 'Umb.SectionView.Users.Users', name: 'Users Section View', loader: () => import('./views/users/section-view-users.element'), + weight: 200, meta: { - sections: [sectionAlias], label: 'Users', pathname: 'users', - weight: 200, icon: 'umb:user', }, + conditions: { + sections: [sectionAlias], + }, }, { type: 'sectionView', alias: 'Umb.SectionView.Users.UserGroups', name: 'User Groups Section View', loader: () => import('./views/user-groups/section-view-user-groups.element'), + weight: 100, meta: { - sections: [sectionAlias], label: 'User Groups', pathname: 'user-groups', - weight: 100, icon: 'umb:users', }, + conditions: { + sections: [sectionAlias], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/section-users.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/section-users.element.ts index a96c131930..8a1899563e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/section-users.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/section-users.element.ts @@ -1,7 +1,7 @@ import { html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import type { ManifestSectionView } from '@umbraco-cms/models'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import type { ManifestSectionView } from '@umbraco-cms/backoffice/extensions-registry'; @customElement('umb-users-section') export class UmbUsersSectionElement extends LitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/section-view-user-groups.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/section-view-user-groups.element.ts index 618d277b17..270825f4e6 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/section-view-user-groups.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/section-view-user-groups.element.ts @@ -1,10 +1,24 @@ -import { html, LitElement } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css'; +import { css, html, LitElement } from 'lit'; import { customElement } from 'lit/decorators.js'; import './workspace-view-user-groups.element'; @customElement('umb-section-view-user-groups') export class UmbSectionViewUserGroupsElement extends LitElement { + static styles = [ + UUITextStyles, + css` + :host { + height: 100%; + } + + #router-slot { + height: calc(100% - var(--umb-header-layout-height) - var(--umb-footer-layout-height)); + } + `, + ]; + render() { return html``; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-name-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-name-column-layout.element.ts index 4a1f79127f..b60dc36c88 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-name-column-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-name-column-layout.element.ts @@ -11,7 +11,7 @@ export class UmbUserGroupTableNameColumnLayoutElement extends LitElement { value!: any; render() { - return html` + return html` ${this.value.name} `; } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-sections-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-sections-column-layout.element.ts index e966a125ee..9171aa8c25 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-sections-column-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/user-group-table-sections-column-layout.element.ts @@ -1,8 +1,8 @@ import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { UmbTableItem } from '../../../../shared/components/table'; -import { umbExtensionsRegistry } from '@umbraco-cms/extensions-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extensions-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-user-group-table-sections-column-layout') export class UmbUserGroupTableSectionsColumnLayoutElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/workspace-view-user-groups.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/workspace-view-user-groups.element.ts index 4e2940ab73..61ae8d8384 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/workspace-view-user-groups.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/user-groups/workspace-view-user-groups.element.ts @@ -16,11 +16,11 @@ import { UMB_USER_GROUP_STORE_CONTEXT_TOKEN, } from '../../../user-groups/repository/user-group.store'; -import type { UserGroupDetails } from '@umbraco-cms/models'; +import type { UserGroupDetails } from '@umbraco-cms/backoffice/models'; import './user-group-table-name-column-layout.element'; import './user-group-table-sections-column-layout.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-workspace-view-user-groups') export class UmbWorkspaceViewUserGroupsElement extends UmbLitElement { @@ -31,6 +31,11 @@ export class UmbWorkspaceViewUserGroupsElement extends UmbLitElement { height: 100%; display: flex; flex-direction: column; + margin: var(--uui-size-layout-1); + } + + umb-table { + padding: 0; } `, ]; @@ -94,7 +99,7 @@ export class UmbWorkspaceViewUserGroupsElement extends UmbLitElement { private _createTableItems(userGroups: Array) { this._tableItems = userGroups.map((userGroup) => { return { - key: userGroup.key, + id: userGroup.id, icon: userGroup.icon, data: [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.element.ts index a8c88c9605..0cdb0edede 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.element.ts @@ -2,15 +2,15 @@ import { css, html, nothing } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { repeat } from 'lit/directives/repeat.js'; -import { ifDefined } from 'lit-html/directives/if-defined.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; import type { UmbSectionViewUsersElement } from '../../section-view-users.element'; import { UmbUserGroupStore, UMB_USER_GROUP_STORE_CONTEXT_TOKEN, } from '../../../../../user-groups/repository/user-group.store'; -import { getLookAndColorFromUserStatus } from '@umbraco-cms/utils'; -import type { UserDetails, UserEntity, UserGroupEntity } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { getLookAndColorFromUserStatus } from '@umbraco-cms/backoffice/utils'; +import type { UserDetails, UserEntity, UserGroupEntity } from '@umbraco-cms/backoffice/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-workspace-view-users-grid') export class UmbWorkspaceViewUsersGridElement extends UmbLitElement { @@ -18,7 +18,6 @@ export class UmbWorkspaceViewUsersGridElement extends UmbLitElement { UUITextStyles, css` :host { - height: 100%; display: flex; flex-direction: column; } @@ -86,27 +85,27 @@ export class UmbWorkspaceViewUsersGridElement extends UmbLitElement { this.observe(this._usersContext.selection, (selection) => (this._selection = selection)); } - private _isSelected(key: string) { - return this._selection.includes(key); + private _isSelected(id: string) { + return this._selection.includes(id); } //TODO How should we handle url stuff? - private _handleOpenCard(key: string) { - history.pushState(null, '', 'section/users/view/users/user/' + key); //TODO Change to a tag with href and make dynamic + private _handleOpenCard(id: string) { + history.pushState(null, '', 'section/users/view/users/user/' + id); //TODO Change to a tag with href and make dynamic } private _selectRowHandler(user: UserEntity) { - this._usersContext?.select(user.key); + this._usersContext?.select(user.id); } private _deselectRowHandler(user: UserEntity) { - this._usersContext?.deselect(user.key); + this._usersContext?.deselect(user.id); } - private _getUserGroupNames(keys: Array) { - return keys - .map((key: string) => { - return this._userGroups.find((x) => x.key === key)?.name; + private _getUserGroupNames(ids: Array) { + return ids + .map((id: string) => { + return this._userGroups.find((x) => x.id === id)?.name; }) .join(', '); } @@ -121,8 +120,8 @@ export class UmbWorkspaceViewUsersGridElement extends UmbLitElement { .name=${user.name} selectable ?select-only=${this._selection.length > 0} - ?selected=${this._isSelected(user.key)} - @open=${() => this._handleOpenCard(user.key)} + ?selected=${this._isSelected(user.id)} + @open=${() => this._handleOpenCard(user.id)} @selected=${() => this._selectRowHandler(user)} @unselected=${() => this._deselectRowHandler(user)}> ${user.status && user.status !== 'enabled' @@ -147,15 +146,13 @@ export class UmbWorkspaceViewUsersGridElement extends UmbLitElement { render() { return html` - -
    - ${repeat( - this._users, - (user) => user.key, - (user) => this.renderUserCard(user) - )} -
    -
    +
    + ${repeat( + this._users, + (user) => user.id, + (user) => this.renderUserCard(user) + )} +
    `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.test.ts index 737d9abf6b..42befffb67 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/grid/workspace-view-users-grid.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbWorkspaceViewUsersGridElement } from './workspace-view-users-grid.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbWorkspaceViewUsersCreateElement', () => { let element: UmbWorkspaceViewUsersGridElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/name/user-table-name-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/name/user-table-name-column-layout.element.ts index bf6d9fa7af..ed36318416 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/name/user-table-name-column-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/name/user-table-name-column-layout.element.ts @@ -16,7 +16,7 @@ export class UmbUserTableNameColumnLayoutElement extends LitElement { render() { return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/status/user-table-status-column-layout.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/status/user-table-status-column-layout.element.ts index 9511a017da..75ca3b5fb2 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/status/user-table-status-column-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/column-layouts/status/user-table-status-column-layout.element.ts @@ -1,6 +1,6 @@ import { html, LitElement, nothing } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { getLookAndColorFromUserStatus } from '@umbraco-cms/utils'; +import { getLookAndColorFromUserStatus } from '@umbraco-cms/backoffice/utils'; @customElement('umb-user-table-status-column-layout') export class UmbUserTableStatusColumnLayoutElement extends LitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/workspace-view-users-table.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/workspace-view-users-table.element.ts index 341bae823e..33b8e1aa1e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/workspace-view-users-table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/list-view-layouts/table/workspace-view-users-table.element.ts @@ -15,11 +15,11 @@ import { UmbUserGroupStore, UMB_USER_GROUP_STORE_CONTEXT_TOKEN, } from '../../../../../user-groups/repository/user-group.store'; -import type { UserDetails, UserGroupEntity } from '@umbraco-cms/models'; +import type { UserDetails, UserGroupEntity } from '@umbraco-cms/backoffice/models'; import './column-layouts/name/user-table-name-column-layout.element'; import './column-layouts/status/user-table-status-column-layout.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-workspace-view-users-table') export class UmbWorkspaceViewUsersTableElement extends UmbLitElement { @@ -27,10 +27,14 @@ export class UmbWorkspaceViewUsersTableElement extends UmbLitElement { UUITextStyles, css` :host { - height: 100%; display: flex; flex-direction: column; } + + umb-table { + padding: 0; + margin: 0 var(--uui-size-layout-1) var(--uui-size-layout-1); + } `, ]; @@ -115,10 +119,10 @@ export class UmbWorkspaceViewUsersTableElement extends UmbLitElement { }); } - private _getUserGroupNames(keys: Array) { - return keys - .map((key: string) => { - return this._userGroups.find((x) => x.key === key)?.name; + private _getUserGroupNames(ids: Array) { + return ids + .map((id: string) => { + return this._userGroups.find((x) => x.id === id)?.name; }) .join(', '); } @@ -126,7 +130,7 @@ export class UmbWorkspaceViewUsersTableElement extends UmbLitElement { private _createTableItems(users: Array) { this._tableItems = users.map((user) => { return { - key: user.key, + id: user.id, icon: 'umb:user', data: [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.element.ts index 5985ea2851..2cebe636ce 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.element.ts @@ -2,16 +2,17 @@ import { css, html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from '../../../users/repository/user.store'; -import type { IRoute, IRoutingInfo } from '@umbraco-cms/router'; -import { umbExtensionsRegistry, createExtensionElement } from '@umbraco-cms/extensions-api'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; +import { umbExtensionsRegistry, createExtensionElement } from '@umbraco-cms/backoffice/extensions-api'; import './list-view-layouts/table/workspace-view-users-table.element'; import './list-view-layouts/grid/workspace-view-users-grid.element'; import './workspace-view-users-selection.element'; -import type { ManifestWorkspace, UserDetails } from '@umbraco-cms/models'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { DeepState } from '@umbraco-cms/observable-api'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { DeepState } from '@umbraco-cms/backoffice/observable-api'; +import type { ManifestWorkspace } from '@umbraco-cms/backoffice/extensions-registry'; @customElement('umb-section-view-users') export class UmbSectionViewUsersElement extends UmbLitElement { @@ -21,6 +22,10 @@ export class UmbSectionViewUsersElement extends UmbLitElement { :host { height: 100%; } + + #router-slot { + height: calc(100% - var(--umb-header-layout-height)); + } `, ]; @@ -60,7 +65,7 @@ export class UmbSectionViewUsersElement extends UmbLitElement { } private _createRoutes() { - const routes: any[] = [ + const routes: IRoute[] = [ { path: 'overview', component: () => import('./workspace-view-users-overview.element'), @@ -70,12 +75,12 @@ export class UmbSectionViewUsersElement extends UmbLitElement { // TODO: find a way to make this reuseable across: this._workspaces?.map((workspace: ManifestWorkspace) => { routes.push({ - path: `${workspace.meta.entityType}/:key`, + path: `${workspace.meta.entityType}/:id`, component: () => createExtensionElement(workspace), - setup: (component: Promise, info: IRoutingInfo) => { - component.then((el: HTMLElement) => { - (el as any).entityKey = info.match.params.key; - }); + setup: (component, info) => { + if (component) { + (component as any).entityId = info.match.params.id; + } }, }); routes.push({ @@ -113,22 +118,22 @@ export class UmbSectionViewUsersElement extends UmbLitElement { this.requestUpdate('selection'); } - public select(key: string) { + public select(id: string) { const oldSelection = this.#selection.getValue(); - if (oldSelection.indexOf(key) !== -1) return; + if (oldSelection.indexOf(id) !== -1) return; - this.#selection.next([...oldSelection, key]); + this.#selection.next([...oldSelection, id]); this.requestUpdate('selection'); } - public deselect(key: string) { + public deselect(id: string) { const selection = this.#selection.getValue(); - this.#selection.next(selection.filter((k) => k !== key)); + this.#selection.next(selection.filter((k) => k !== id)); this.requestUpdate('selection'); } render() { - return html``; + return html``; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.test.ts index 08d9b69194..d43ea1fb0e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/section-view-users.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // import UmbSectionViewUsersElement from './section-view-users.element'; // describe('UmbSectionViewUsersElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.element.ts index c64248a145..b770de3c2b 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.element.ts @@ -2,13 +2,16 @@ import { css, html, nothing } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { UUIPopoverElement } from '@umbraco-ui/uui'; -import { UMB_INVITE_USER_MODAL_TOKEN } from '../../../../users/users/modals/invite-user'; -import { UMB_CREATE_USER_MODAL_TOKEN } from '../../../../users/users/modals/create-user'; import type { UmbSectionViewUsersElement } from './section-view-users.element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal'; -import type { IRoute } from '@umbraco-cms/router'; +import { + UmbModalContext, + UMB_MODAL_CONTEXT_TOKEN, + UMB_INVITE_USER_MODAL, + UMB_CREATE_USER_MODAL, +} from '@umbraco-cms/backoffice/modal'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import './list-view-layouts/table/workspace-view-users-table.element'; import './list-view-layouts/grid/workspace-view-users-grid.element'; @@ -28,7 +31,7 @@ export class UmbWorkspaceViewUsersOverviewElement extends UmbLitElement { #sticky-top { position: sticky; - top: -1px; + top: 0px; z-index: 1; box-shadow: 0 1px 3px rgba(0, 0, 0, 0), 0 1px 2px rgba(0, 0, 0, 0); transition: 250ms box-shadow ease-in-out; @@ -39,7 +42,7 @@ export class UmbWorkspaceViewUsersOverviewElement extends UmbLitElement { } #user-list-top-bar { - padding: var(--uui-size-space-4) var(--uui-size-space-6); + padding: var(--uui-size-space-4) var(--uui-size-layout-1); background-color: var(--uui-color-background); display: flex; justify-content: space-between; @@ -48,7 +51,7 @@ export class UmbWorkspaceViewUsersOverviewElement extends UmbLitElement { align-items: center; } #user-list { - padding: var(--uui-size-space-6); + padding: var(--uui-size-layout-1); padding-top: var(--uui-size-space-2); } #input-search { @@ -73,9 +76,6 @@ export class UmbWorkspaceViewUsersOverviewElement extends UmbLitElement { color: inherit; text-decoration: none; } - router-slot { - overflow: hidden; - } `, ]; @@ -163,9 +163,9 @@ export class UmbWorkspaceViewUsersOverviewElement extends UmbLitElement { let token = undefined; // TODO: we need to find a better way to determine if we should create or invite if (this.isCloud) { - token = UMB_INVITE_USER_MODAL_TOKEN; + token = UMB_INVITE_USER_MODAL; } else { - token = UMB_CREATE_USER_MODAL_TOKEN; + token = UMB_CREATE_USER_MODAL; } this._modalContext?.open(token); @@ -173,56 +173,58 @@ export class UmbWorkspaceViewUsersOverviewElement extends UmbLitElement { render() { return html` -
    -
    - - -
    - - - - Status: All + +
    +
    + + +
    + + + + Status: All + +
    + + + + +
    +
    + + + Groups: All + +
    + + + + +
    +
    + + + Order by: Name (A-Z) + +
    + + + + +
    +
    + + -
    - - - - -
    - - - - Groups: All - -
    - - - - -
    -
    - - - Order by: Name (A-Z) - -
    - - - - -
    -
    - - - +
    -
    - + + ${this._renderSelection()} `; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.test.ts index 188a3263e4..4058b4be91 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-overview.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // import UmbWorkspaceViewUsersOverviewElement from './workspace-view-users-overview.element'; // describe('UmbWorkspaceViewUsersOverviewElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.element.ts index 1b2c0a24ab..6cfff21f9f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.element.ts @@ -3,7 +3,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from '../../../../users/users/repository/user.store'; import { UmbSectionViewUsersElement } from './section-view-users.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-workspace-view-users-selection') export class UmbWorkspaceViewUsersSelectionElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.test.ts index ecf9f9bde5..d889b7f951 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/user-section/views/users/workspace-view-users-selection.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import UmbWorkspaceViewUsersSelectionElement from './workspace-view-users-selection.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbWorkspaceViewUsersSelectionElement', () => { // let element: UmbWorkspaceViewUsersSelectionElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.element.ts index a17a870036..39573a4e2c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.element.ts @@ -4,13 +4,13 @@ import { customElement, query, state } from 'lit/decorators.js'; import { UUIInputPasswordElement } from '@umbraco-ui/uui'; import { UmbInputPickerUserGroupElement } from '../../../../shared/components/input-user-group/input-user-group.element'; import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from '../../repository/user.store'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; -import type { UserDetails } from '@umbraco-cms/models'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; import { UmbNotificationDefaultData, UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN, -} from '@umbraco-cms/notification'; +} from '@umbraco-cms/backoffice/notification'; export type UsersViewType = 'list' | 'grid'; @customElement('umb-create-user-modal') @@ -126,7 +126,7 @@ export class UmbCreateUserModalElement extends UmbModalBaseElement { if (!this._createdUser) return; this._closeModal(); - history.pushState(null, '', '/section/users/view/users/user/' + this._createdUser?.key); //TODO: URL Should be dynamic + history.pushState(null, '', 'section/users/view/users/user/' + this._createdUser?.id); //TODO: URL Should be dynamic } private _renderForm() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.test.ts index 277462f828..3c38038129 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/create-user-modal.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // import UmbWorkspaceViewUsersCreateElement from './workspace-view-users-create.element'; // describe('UmbWorkspaceViewUsersCreateElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/index.ts deleted file mode 100644 index 7b8ff0d726..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/create-user/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; - -export const UMB_CREATE_USER_MODAL_TOKEN = new UmbModalToken('Umb.Modal.CreateUser', { - type: 'dialog', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/index.ts deleted file mode 100644 index 5c9a70ee64..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { UmbModalToken } from '@umbraco-cms/modal'; - -export const UMB_INVITE_USER_MODAL_TOKEN = new UmbModalToken('Umb.Modal.InviteUser', { - type: 'dialog', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.element.ts index a01e344bde..2c1eaed271 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.element.ts @@ -3,8 +3,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, query, state } from 'lit/decorators.js'; import { UmbInputPickerUserGroupElement } from '../../../../shared/components/input-user-group/input-user-group.element'; import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from '../../repository/user.store'; -import { UmbModalBaseElement } from '@umbraco-cms/modal'; -import type { UserDetails } from '@umbraco-cms/models'; +import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; export type UsersViewType = 'list' | 'grid'; @customElement('umb-invite-user-modal') @@ -105,7 +105,7 @@ export class UmbInviteUserModalElement extends UmbModalBaseElement { if (!this._invitedUser) return; this._closeModal(); - history.pushState(null, '', 'section/users/view/users/user/' + this._invitedUser?.key); //TODO: URL Should be dynamic + history.pushState(null, '', 'section/users/view/users/user/' + this._invitedUser?.id); //TODO: URL Should be dynamic } private _renderForm() { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.test.ts index e0e05bcce8..cf701e9fcc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/invite-user/invite-user-modal.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import UmbWorkspaceViewUsersInviteElement from './workspace-view-users-invite.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbWorkspaceViewUsersInviteElement', () => { // let element: UmbWorkspaceViewUsersInviteElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/manifests.ts index 623b47dc39..efdf1f2edc 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/manifests.ts @@ -1,4 +1,4 @@ -import type { ManifestModal } from '@umbraco-cms/extensions-registry'; +import type { ManifestModal } from '@umbraco-cms/backoffice/extensions-registry'; const modals: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/index.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/index.ts deleted file mode 100644 index 501ca347b8..0000000000 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { UserDetails } from '@umbraco-cms/models'; -import { UmbModalToken, UmbPickerModalData } from '@umbraco-cms/modal'; - -export const UMB_USER_PICKER_MODAL_TOKEN = new UmbModalToken>('Umb.Modal.UserPicker', { - type: 'sidebar', - size: 'small', -}); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.element.ts index d66a0d2ac8..a1f18890a1 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.element.ts @@ -2,8 +2,8 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbUserStore, UMB_USER_STORE_CONTEXT_TOKEN } from '../../repository/user.store'; -import { UmbModalElementPickerBase } from '@umbraco-cms/modal'; -import type { UserDetails } from '@umbraco-cms/models'; +import { UmbModalElementPickerBase } from '@umbraco-cms/internal/modal'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; @customElement('umb-user-picker-modal') export class UmbUserPickerModalElement extends UmbModalElementPickerBase { @@ -86,9 +86,9 @@ export class UmbUserPickerModalElement extends UmbModalElementPickerBase html`
    this.handleSelection(item.key)} - @keydown=${(e: KeyboardEvent) => this._handleKeydown(e, item.key)} - class=${this.isSelected(item.key) ? 'item selected' : 'item'}> + @click=${() => this.handleSelection(item.id)} + @keydown=${(e: KeyboardEvent) => this._handleKeydown(e, item.id)} + class=${this.isSelected(item.id) ? 'item selected' : 'item'}> ${item.name}
    diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.test.ts index 946a0468e5..cfe1aad2a3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/modals/user-picker/user-picker-modal.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment // import { UmbPickerLayoutUserElement } from './picker-layout-user.element'; -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // describe('UmbPickerUserElement', () => { // let element: UmbPickerLayoutUserElement; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/manifests.ts index 96ae970229..002802c161 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/manifests.ts @@ -1,6 +1,6 @@ import { UmbUserRepository } from '../repository/user.repository'; import { UmbUserStore } from './user.store'; -import type { ManifestStore, ManifestRepository } from '@umbraco-cms/extensions-registry'; +import type { ManifestStore, ManifestRepository } from '@umbraco-cms/backoffice/extensions-registry'; export const USER_REPOSITORY_ALIAS = 'Umb.Repository.User'; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.repository.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.repository.ts index 25ad4bc740..a9f65bc59d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.repository.ts @@ -1,10 +1,10 @@ -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; // TODO: implement export class UmbUserRepository { - #host: UmbControllerHostInterface; + #host: UmbControllerHostElement; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { this.#host = host; console.log(this.#host); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.store.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.store.ts index 2978ebf035..a52581484d 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.store.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/repository/user.store.ts @@ -1,8 +1,8 @@ -import type { UserDetails } from '@umbraco-cms/models'; -import { ArrayState, NumberState } from '@umbraco-cms/observable-api'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/store'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { ArrayState, NumberState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { UmbEntityDetailStore, UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; export type UmbUserStoreItemType = UserDetails; @@ -15,24 +15,24 @@ export const UMB_USER_STORE_CONTEXT_TOKEN = new UmbContextToken('U * @description - Data Store for Users */ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore { - #users = new ArrayState([], (x) => x.key); + #users = new ArrayState([], (x) => x.id); public users = this.#users.asObservable(); #totalUsers = new NumberState(0); public readonly totalUsers = this.#totalUsers.asObservable(); - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, UMB_USER_STORE_CONTEXT_TOKEN.toString()); } - getScaffold(entityType: string, parentKey: string | null) { + getScaffold(entityType: string, parentId: string | null) { return { - key: '', + id: '', name: '', icon: '', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', email: '', language: '', status: 'enabled', @@ -59,33 +59,33 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore)} * @memberof UmbDataTypeStore */ - getByKey(key: string) { + getByKey(id: string) { // TODO: use Fetcher API. // TODO: only fetch if the data type is not in the store? - fetch(`/umbraco/backoffice/users/details/${key}`) + fetch(`/umbraco/backoffice/users/details/${id}`) .then((res) => res.json()) .then((data) => { this.#users.appendOne(data); }); return this.#users.getObservablePart((users: Array) => - users.find((user: UmbUserStoreItemType) => user.key === key) + users.find((user: UmbUserStoreItemType) => user.id === id) ); } /** - * @description - Request Users by keys. - * @param {string} key + * @description - Request Users by ids. + * @param {string} id * @return {*} {(Observable)} * @memberof UmbDataTypeStore */ - getByKeys(keys: Array) { - const params = keys.map((key) => `key=${key}`).join('&'); + getByKeys(ids: Array) { + const params = ids.map((id) => `id=${id}`).join('&'); fetch(`/umbraco/backoffice/users/getByKeys?${params}`) .then((res) => res.json()) .then((data) => { @@ -93,7 +93,7 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore) => - users.filter((user: UmbUserStoreItemType) => keys.includes(user.key)) + users.filter((user: UmbUserStoreItemType) => ids.includes(user.id)) ); } @@ -124,7 +124,7 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore enabledKeys.includes(user.key)); + const storedUsers = this.#users.getValue().filter((user) => enabledKeys.includes(user.id)); storedUsers.forEach((user) => { user.status = 'enabled'; @@ -147,10 +147,10 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore enabledKeys.includes(user.key)); + const storedUsers = this.#users.getValue().filter((user) => enabledKeys.includes(user.id)); storedUsers.forEach((user) => { - if (userKeys.includes(user.key)) { + if (userKeys.includes(user.id)) { user.userGroups.push(userGroup); } else { user.userGroups = user.userGroups.filter((group) => group !== userGroup); @@ -174,7 +174,7 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore enabledKeys.includes(user.key)); + const storedUsers = this.#users.getValue().filter((user) => enabledKeys.includes(user.id)); storedUsers.forEach((user) => { user.userGroups = user.userGroups.filter((group) => group !== userGroup); @@ -197,7 +197,7 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore disabledKeys.includes(user.key)); + const storedUsers = this.#users.getValue().filter((user) => disabledKeys.includes(user.id)); storedUsers.forEach((user) => { user.status = 'disabled'; @@ -265,7 +265,7 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore u.key === user.key); + // const index = users.findIndex((u) => u.id === user.id); // if (index === -1) return; // users[index] = { ...users[index], ...user }; // console.log('updateUser', user, users[index]); @@ -277,7 +277,7 @@ export class UmbUserStore extends UmbStoreBase implements UmbEntityDetailStore u.key === key); + // const index = users.findIndex((u) => u.id === id); // if (index === -1) return; // users.splice(index, 1); // this._users.next(users); diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/actions/workspace-action-user-save.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/actions/workspace-action-user-save.element.ts index 000e11c34d..8c55d415e3 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/actions/workspace-action-user-save.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/actions/workspace-action-user-save.element.ts @@ -2,8 +2,9 @@ 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 { UmbWorkspaceUserContext } from '../user-workspace.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbUserWorkspaceContext } from '../user-workspace.context'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/context-api'; @customElement('umb-workspace-action-user-save') export class UmbWorkspaceActionUserSaveElement extends UmbLitElement { @@ -12,14 +13,13 @@ export class UmbWorkspaceActionUserSaveElement extends UmbLitElement { @state() private _saveButtonState?: UUIButtonState; - private _workspaceContext?: UmbWorkspaceUserContext; + private _workspaceContext?: UmbUserWorkspaceContext; constructor() { super(); - // TODO: Figure out how to get the magic string for the workspace context. - this.consumeContext('umbWorkspaceContext', (instance) => { - this._workspaceContext = instance; + this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (instance) => { + this._workspaceContext = instance as UmbUserWorkspaceContext; }); } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/manifests.ts index eeb5c42f4b..6716f9d31a 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/manifests.ts @@ -1,5 +1,9 @@ -import { UmbSaveWorkspaceAction } from '@umbraco-cms/workspace'; -import type { ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceView } from '@umbraco-cms/models'; +import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import type { + ManifestWorkspace, + ManifestWorkspaceAction, + ManifestWorkspaceView, +} from '@umbraco-cms/backoffice/extensions-registry'; const workspace: ManifestWorkspace = { type: 'workspace', @@ -18,12 +22,14 @@ const workspaceActions: Array = [ alias: 'Umb.WorkspaceAction.User.Save', name: 'Save User Workspace Action', meta: { - workspaces: ['Umb.Workspace.User'], label: 'Save', look: 'primary', color: 'positive', api: UmbSaveWorkspaceAction, }, + conditions: { + workspaces: ['Umb.Workspace.User'], + }, }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace-edit.element.ts new file mode 100644 index 0000000000..c0a9430280 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace-edit.element.ts @@ -0,0 +1,348 @@ +import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; +import { css, html, nothing, TemplateResult } from 'lit'; +import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; +import { customElement, state } from 'lit/decorators.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { repeat } from 'lit/directives/repeat.js'; + +import { UmbCurrentUserStore, UMB_CURRENT_USER_STORE_CONTEXT_TOKEN } from '../../current-user/current-user.store'; +import { UmbUserWorkspaceContext } from './user-workspace.context'; +import { UMB_CHANGE_PASSWORD_MODAL } from '@umbraco-cms/backoffice/modal'; +import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; +import { getLookAndColorFromUserStatus } from '@umbraco-cms/backoffice/utils'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +import '../../../shared/components/input-user-group/input-user-group.element'; +import '../../../shared/property-editors/uis/document-picker/property-editor-ui-document-picker.element'; +import '../../../shared/components/workspace/workspace-layout/workspace-layout.element'; + +@customElement('umb-user-workspace-edit') +export class UmbUserWorkspaceEditElement extends UmbLitElement { + static styles = [ + UUITextStyles, + css` + :host { + display: block; + height: 100%; + } + + #main { + display: grid; + grid-template-columns: 1fr 350px; + gap: var(--uui-size-layout-1); + padding: var(--uui-size-layout-1); + } + + #left-column { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-4); + } + #right-column > uui-box > div { + display: flex; + flex-direction: column; + gap: var(--uui-size-space-2); + } + uui-avatar { + font-size: var(--uui-size-16); + place-self: center; + } + hr { + border: none; + border-bottom: 1px solid var(--uui-color-divider); + width: 100%; + } + uui-input { + width: 100%; + } + .faded-text { + color: var(--uui-color-text-alt); + font-size: 0.8rem; + } + uui-tag { + width: fit-content; + } + #user-info { + display: flex; + gap: var(--uui-size-space-6); + } + #user-info > div { + display: flex; + flex-direction: column; + } + #assign-access { + display: flex; + flex-direction: column; + } + `, + ]; + + @state() + private _currentUser?: UserDetails; + + private _currentUserStore?: UmbCurrentUserStore; + private _modalContext?: UmbModalContext; + + private _languages = []; //TODO Add languages + + private _workspaceContext: UmbUserWorkspaceContext = new UmbUserWorkspaceContext(this); + + @state() + private _user?: UserDetails; + + @state() + private _userName = ''; + + constructor() { + super(); + + this.consumeContext(UMB_CURRENT_USER_STORE_CONTEXT_TOKEN, (store) => { + this._currentUserStore = store; + this._observeCurrentUser(); + }); + + this.observe(this._workspaceContext.data, (user) => { + // TODO: fix type mismatch: + this._user = user as any; + if (user && user.name !== this._userName) { + this._userName = user.name || ''; + } + }); + } + + private async _observeCurrentUser() { + if (!this._currentUserStore) return; + + // TODO: do not have static current user service, we need to make a ContextAPI for this. + this.observe(this._currentUserStore.currentUser, (currentUser) => { + this._currentUser = currentUser; + }); + } + + private _updateUserStatus() { + if (!this._user || !this._workspaceContext) return; + + const isDisabled = this._user.status === 'disabled'; + // TODO: make sure we use the workspace for this: + /* + isDisabled + ? this._workspaceContext.getStore()?.enableUsers([this._user.id]) + : this._workspaceContext.getStore()?.disableUsers([this._user.id]); + */ + } + + private _deleteUser() { + if (!this._user || !this._workspaceContext) return; + + // TODO: make sure we use the workspace for this: + //this._workspaceContext.getStore()?.deleteUsers([this._user.id]); + + history.pushState(null, '', 'section/users/view/users/overview'); + } + + // TODO. find a way where we don't have to do this for all workspaces. + private _handleInput(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this._updateProperty('name', target.value); + } + } + } + + private _updateProperty(propertyName: string, value: unknown) { + this._workspaceContext?.update({ [propertyName]: value }); + } + + private _renderContentStartNodes() { + if (!this._user) return; + + if (this._user.contentStartNodes.length < 1) + return html` + + + + `; + + //TODO Render the name of the content start node instead of it's id. + return repeat( + this._user.contentStartNodes, + (node) => node, + (node) => { + return html` + + + + `; + } + ); + } + + private _changePassword() { + this._modalContext?.open(UMB_CHANGE_PASSWORD_MODAL, { + requireOldPassword: this._currentUserStore?.isAdmin === false, + }); + } + + private _renderActionButtons() { + if (!this._user) return; + + const buttons: TemplateResult[] = []; + + if (this._currentUserStore?.isAdmin === false) return nothing; + + if (this._user?.status !== 'invited') + buttons.push( + html` + + ` + ); + + if (this._currentUser?.id !== this._user?.id) + buttons.push(html` `); + + buttons.push( + html` ` + ); + + return buttons; + } + + private _renderLeftColumn() { + if (!this._user) return nothing; + + return html` +
    Profile
    + + + + + + +
    + +
    Assign access
    +
    + + this._updateProperty('userGroups', e.target.value)}> + + + this._updateProperty('contentStartNodes', e.target.value)} + slot="editor"> + + + NEED MEDIA PICKER + +
    +
    + +
    + Based on the assigned groups and start nodes, the user has access to the following nodes +
    + + Content + ${this._renderContentStartNodes()} +
    + Media + + + +
    `; + } + + private _renderRightColumn() { + if (!this._user || !this._workspaceContext) return nothing; + + const statusLook = getLookAndColorFromUserStatus(this._user.status); + + return html` +
    + + +
    + ${this._renderActionButtons()} +
    + Status: + + ${this._user.status} + +
    + ${this._user?.status === 'invited' + ? html` + + + ` + : nothing} +
    + Last login: + ${this._user.lastLoginDate || `${this._user.name} has not logged in yet`} +
    +
    + Failed login attempts + ${this._user.failedLoginAttempts} +
    +
    + Last lockout date: + ${this._user.lastLockoutDate || `${this._user.name} has not been locked out`} +
    +
    + Password last changed: + ${this._user.lastLoginDate || `${this._user.name} has not changed password`} +
    +
    + User created: + ${this._user.createDate} +
    +
    + User last updated: + ${this._user.updateDate} +
    +
    + Key: + ${this._user.id} +
    +
    +
    `; + } + + render() { + if (!this._user) return html`User not found`; + + return html` + + +
    +
    ${this._renderLeftColumn()}
    +
    ${this._renderRightColumn()}
    +
    +
    + `; + } +} + +export default UmbUserWorkspaceEditElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-user-workspace-edit': UmbUserWorkspaceEditElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.context.ts index 71e99083fc..66d6589d2c 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.context.ts @@ -1,14 +1,14 @@ import { UMB_USER_STORE_CONTEXT_TOKEN } from '../repository/user.store'; import { UmbWorkspaceContext } from '../../../shared/components/workspace/workspace-context/workspace-context'; -import { UmbWorkspaceEntityContextInterface } from '../../../shared/components/workspace/workspace-context/workspace-entity-context.interface'; import { UmbEntityWorkspaceManager } from '../../../shared/components/workspace/workspace-context/entity-manager-controller'; import { UmbUserRepository } from '../repository/user.repository'; -import type { UserDetails } from '@umbraco-cms/models'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbEntityWorkspaceContextInterface } from '@umbraco-cms/backoffice/workspace'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; -export class UmbWorkspaceUserContext - extends UmbWorkspaceContext - implements UmbWorkspaceEntityContextInterface +export class UmbUserWorkspaceContext + extends UmbWorkspaceContext + implements UmbEntityWorkspaceContextInterface { #manager = new UmbEntityWorkspaceManager( this.host, @@ -22,7 +22,7 @@ export class UmbWorkspaceUserContext // TODO: remove this magic connection, instead create the necessary methods to update parts. update = this.#manager.state.update; - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host, new UmbUserRepository(host)); } @@ -31,7 +31,7 @@ export class UmbWorkspaceUserContext } getEntityType = this.#manager.getEntityType; getUnique = this.#manager.getEntityKey; - getEntityKey = this.#manager.getEntityKey; + getEntityId = this.#manager.getEntityKey; getStore = this.#manager.getStore; getData = this.#manager.getData as any; // TODO: fix type mismatch, this will mos likely be handled when switching to repositories. load = this.#manager.load; diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.element.ts index 3ef980f51e..7cfea7028f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.element.ts @@ -1,350 +1,36 @@ -import { UUIInputElement, UUIInputEvent } from '@umbraco-ui/uui'; -import { css, html, nothing, TemplateResult } from 'lit'; +import { html } from 'lit'; import { UUITextStyles } from '@umbraco-ui/uui-css/lib'; import { customElement, state } from 'lit/decorators.js'; -import { ifDefined } from 'lit/directives/if-defined.js'; -import { repeat } from 'lit/directives/repeat.js'; - -import { UmbCurrentUserStore, UMB_CURRENT_USER_STORE_CONTEXT_TOKEN } from '../../current-user/current-user.store'; -import type { UmbWorkspaceEntityElement } from '../../../shared/components/workspace/workspace-entity-element.interface'; -import { UMB_CHANGE_PASSWORD_MODAL_TOKEN } from '../../current-user/modals/change-password'; -import { UmbWorkspaceUserContext } from './user-workspace.context'; -import type { UmbModalContext } from '@umbraco-cms/modal'; -import { getLookAndColorFromUserStatus } from '@umbraco-cms/utils'; -import type { UserDetails } from '@umbraco-cms/models'; +import { UmbUserWorkspaceContext } from './user-workspace.context'; +import { UmbUserWorkspaceEditElement } from './user-workspace-edit.element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { IRoute } from '@umbraco-cms/backoffice/router'; import '../../../shared/components/input-user-group/input-user-group.element'; import '../../../shared/property-editors/uis/document-picker/property-editor-ui-document-picker.element'; import '../../../shared/components/workspace/workspace-layout/workspace-layout.element'; -import { UmbLitElement } from '@umbraco-cms/element'; @customElement('umb-user-workspace') -export class UmbUserWorkspaceElement extends UmbLitElement implements UmbWorkspaceEntityElement { - static styles = [ - UUITextStyles, - css` - :host { - display: block; - height: 100%; - } +export class UmbUserWorkspaceElement extends UmbLitElement { + static styles = [UUITextStyles]; - #main { - display: grid; - grid-template-columns: 1fr 350px; - gap: var(--uui-size-space-6); - padding: var(--uui-size-space-6); - } + #workspaceContext = new UmbUserWorkspaceContext(this); + #element = new UmbUserWorkspaceEditElement(); - #left-column { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-4); - } - #right-column > uui-box > div { - display: flex; - flex-direction: column; - gap: var(--uui-size-space-2); - } - uui-avatar { - font-size: var(--uui-size-16); - place-self: center; - } - hr { - border: none; - border-bottom: 1px solid var(--uui-color-divider); - width: 100%; - } - uui-input { - width: 100%; - } - .faded-text { - color: var(--uui-color-text-alt); - font-size: 0.8rem; - } - uui-tag { - width: fit-content; - } - #user-info { - display: flex; - gap: var(--uui-size-space-6); - } - #user-info > div { - display: flex; - flex-direction: column; - } - #assign-access { - display: flex; - flex-direction: column; - } - `, + @state() + _routes: IRoute[] = [ + { + path: 'edit/:id', + component: () => this.#element, + setup: (component, info) => { + const id = info.match.params.id; + this.#workspaceContext.load(id); + }, + }, ]; - @state() - private _currentUser?: UserDetails; - - private _currentUserStore?: UmbCurrentUserStore; - private _modalContext?: UmbModalContext; - - private _languages = []; //TODO Add languages - - private _workspaceContext: UmbWorkspaceUserContext = new UmbWorkspaceUserContext(this); - - @state() - private _user?: UserDetails; - - @state() - private _userName = ''; - - constructor() { - super(); - - this.consumeContext(UMB_CURRENT_USER_STORE_CONTEXT_TOKEN, (store) => { - this._currentUserStore = store; - this._observeCurrentUser(); - }); - - this.observe(this._workspaceContext.data, (user) => { - // TODO: fix type mismatch: - this._user = user as any; - if (user && user.name !== this._userName) { - this._userName = user.name || ''; - } - }); - } - - public load(entityKey: string) { - this._workspaceContext.load(entityKey); - } - - public create(parentKey: string | null) { - this._workspaceContext.create(parentKey); - } - - private async _observeCurrentUser() { - if (!this._currentUserStore) return; - - // TODO: do not have static current user service, we need to make a ContextAPI for this. - this.observe(this._currentUserStore.currentUser, (currentUser) => { - this._currentUser = currentUser; - }); - } - - private _updateUserStatus() { - if (!this._user || !this._workspaceContext) return; - - const isDisabled = this._user.status === 'disabled'; - // TODO: make sure we use the workspace for this: - /* - isDisabled - ? this._workspaceContext.getStore()?.enableUsers([this._user.key]) - : this._workspaceContext.getStore()?.disableUsers([this._user.key]); - */ - } - - private _deleteUser() { - if (!this._user || !this._workspaceContext) return; - - // TODO: make sure we use the workspace for this: - //this._workspaceContext.getStore()?.deleteUsers([this._user.key]); - - history.pushState(null, '', 'section/users/view/users/overview'); - } - - // TODO. find a way where we don't have to do this for all workspaces. - private _handleInput(event: UUIInputEvent) { - if (event instanceof UUIInputEvent) { - const target = event.composedPath()[0] as UUIInputElement; - - if (typeof target?.value === 'string') { - this._updateProperty('name', target.value); - } - } - } - - private _updateProperty(propertyName: string, value: unknown) { - this._workspaceContext?.update({ [propertyName]: value }); - } - - private _renderContentStartNodes() { - if (!this._user) return; - - if (this._user.contentStartNodes.length < 1) - return html` - - - - `; - - //TODO Render the name of the content start node instead of it's key. - return repeat( - this._user.contentStartNodes, - (node) => node, - (node) => { - return html` - - - - `; - } - ); - } - - private _changePassword() { - this._modalContext?.open(UMB_CHANGE_PASSWORD_MODAL_TOKEN, { - requireOldPassword: this._currentUserStore?.isAdmin === false, - }); - } - - private _renderActionButtons() { - if (!this._user) return; - - const buttons: TemplateResult[] = []; - - if (this._currentUserStore?.isAdmin === false) return nothing; - - if (this._user?.status !== 'invited') - buttons.push( - html` - - ` - ); - - if (this._currentUser?.key !== this._user?.key) - buttons.push(html` `); - - buttons.push( - html` ` - ); - - return buttons; - } - - private _renderLeftColumn() { - if (!this._user) return nothing; - - return html` -
    Profile
    - - - - - - -
    - -
    Assign access
    -
    - - this._updateProperty('userGroups', e.target.value)}> - - - this._updateProperty('contentStartNodes', e.target.value)} - slot="editor"> - - - NEED MEDIA PICKER - -
    -
    - -
    - Based on the assigned groups and start nodes, the user has access to the following nodes -
    - - Content - ${this._renderContentStartNodes()} -
    - Media - - - -
    `; - } - - private _renderRightColumn() { - if (!this._user || !this._workspaceContext) return nothing; - - const statusLook = getLookAndColorFromUserStatus(this._user.status); - - return html` -
    - - -
    - ${this._renderActionButtons()} -
    - Status: - - ${this._user.status} - -
    - ${this._user?.status === 'invited' - ? html` - - - ` - : nothing} -
    - Last login: - ${this._user.lastLoginDate || `${this._user.name} has not logged in yet`} -
    -
    - Failed login attempts - ${this._user.failedLoginAttempts} -
    -
    - Last lockout date: - ${this._user.lastLockoutDate || `${this._user.name} has not been locked out`} -
    -
    - Password last changed: - ${this._user.lastLoginDate || `${this._user.name} has not changed password`} -
    -
    - User created: - ${this._user.createDate} -
    -
    - User last updated: - ${this._user.updateDate} -
    -
    - Key: - ${this._user.key} -
    -
    -
    `; - } - render() { - if (!this._user) return html`User not found`; - - return html` - - -
    -
    ${this._renderLeftColumn()}
    -
    ${this._renderRightColumn()}
    -
    -
    - `; + return html` `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.test.ts index b69af7088d..561054e141 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/users/users/workspace/user-workspace.test.ts @@ -1,6 +1,6 @@ import { expect, fixture, html } from '@open-wc/testing'; //TODO: Test has been commented out while we figure out how to setup import maps for the test environment -// import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +// import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // import UmbWorkspaceUserElement from './editor-user.element'; // describe('UmbWorkspaceUserElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.test.ts b/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.test.ts index b2f6c44311..d64bd405c4 100644 --- a/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.test.ts +++ b/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { customElement } from 'lit/decorators.js'; import { UmbContextProviderElement } from './context-provider.element'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-context-test') export class ContextTestElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.ts b/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.ts index 5ffda8935e..d5e28380e9 100644 --- a/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/context-provider/context-provider.element.ts @@ -1,7 +1,7 @@ import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/element'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; @customElement('umb-context-provider') export class UmbContextProviderElement extends UmbLitElement { @@ -10,7 +10,7 @@ export class UmbContextProviderElement extends UmbLitElement { * @required */ @property({ type: Object, attribute: false }) - create?: (host: UmbControllerHostInterface) => unknown; + create?: (host: UmbControllerHostElement) => unknown; /** * The value to provide to the context. diff --git a/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.element.ts b/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.element.ts index 2b628489ce..14d703ffe7 100644 --- a/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.element.ts @@ -1,7 +1,7 @@ -import { html } from 'lit-html'; +import { html } from 'lit'; import { customElement, property } from 'lit/decorators.js'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-controller-host-test') export class UmbControllerHostTestElement extends UmbLitElement { @@ -10,7 +10,7 @@ export class UmbControllerHostTestElement extends UmbLitElement { * @required */ @property({ type: Object, attribute: false }) - create?: (host: UmbControllerHostInterface) => void; + create?: (host: UmbControllerHostElement) => void; connectedCallback() { super.connectedCallback(); diff --git a/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.test.ts b/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.test.ts index 5409840806..df0e1f3c42 100644 --- a/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.test.ts +++ b/src/Umbraco.Web.UI.Client/src/core/controller-host/controller-host-test.test.ts @@ -1,9 +1,9 @@ import { expect, fixture, html } from '@open-wc/testing'; import { customElement } from 'lit/decorators.js'; import { UmbControllerHostTestElement } from './controller-host-test.element'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { UmbContextProviderController } from '@umbraco-cms/context-api'; -import type { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; @customElement('umb-controller-host-test-consumer') export class ControllerHostTestConsumerElement extends UmbLitElement { @@ -24,7 +24,7 @@ describe('UmbControllerHostTestElement', () => { beforeEach(async () => { element = await fixture( html` + .create=${(host: UmbControllerHostElement) => new UmbContextProviderController(host, 'my-test-context-alias', contextValue)}> ` diff --git a/src/Umbraco.Web.UI.Client/src/core/css/custom-properties.css b/src/Umbraco.Web.UI.Client/src/core/css/custom-properties.css new file mode 100644 index 0000000000..f33b370e2d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/css/custom-properties.css @@ -0,0 +1,5 @@ +:root { + --uui-color-positive: #1c874c; + --umb-footer-layout-height: 54px; + --umb-header-layout-height: 70px; +} diff --git a/src/Umbraco.Web.UI.Client/src/core/lit-element/index.ts b/src/Umbraco.Web.UI.Client/src/core/lit-element/index.ts new file mode 100644 index 0000000000..d9bbccafa3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/lit-element/index.ts @@ -0,0 +1 @@ +export * from './lit-element.element'; diff --git a/src/Umbraco.Web.UI.Client/libs/element/lit-element.element.ts b/src/Umbraco.Web.UI.Client/src/core/lit-element/lit-element.element.ts similarity index 60% rename from src/Umbraco.Web.UI.Client/libs/element/lit-element.element.ts rename to src/Umbraco.Web.UI.Client/src/core/lit-element/lit-element.element.ts index daa2005b81..e30b536ec5 100644 --- a/src/Umbraco.Web.UI.Client/libs/element/lit-element.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/lit-element/lit-element.element.ts @@ -1,5 +1,5 @@ import { LitElement } from 'lit'; -import { UmbElementMixin } from './element.mixin'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element'; export class UmbLitElement extends UmbElementMixin(LitElement) { diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts index 29f1f1d104..e899c2aaf6 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/browser-handlers.ts @@ -1,4 +1,5 @@ -import { handlers as dataTypeHandlers } from './domains/data-type.handlers'; +import { handlers as dataTypeHandlers } from './domains/data-type'; +import { handlers as relationTypeHandlers } from './domains/relation-type.handlers'; import { handlers as documentTypeHandlers } from './domains/document-type.handlers'; import { handlers as installHandlers } from './domains/install.handlers'; import * as manifestsHandlers from './domains/manifests.handlers'; @@ -26,6 +27,8 @@ import { handlers as cultureHandlers } from './domains/culture.handlers'; import { handlers as redirectManagementHandlers } from './domains/redirect-management.handlers'; import { handlers as logViewerHandlers } from './domains/log-viewer.handlers'; import { handlers as packageHandlers } from './domains/package.handlers'; +import { handlers as rteEmbedHandlers } from './domains/rte-embed.handlers'; +import { handlers as stylesheetHandlers } from './domains/stylesheet.handlers'; const handlers = [ serverHandlers.serverVersionHandler, @@ -35,6 +38,7 @@ const handlers = [ ...documentHandlers, ...mediaHandlers, ...dataTypeHandlers, + ...relationTypeHandlers, ...documentTypeHandlers, ...telemetryHandlers, ...publishedStatusHandlers, @@ -55,6 +59,8 @@ const handlers = [ ...redirectManagementHandlers, ...logViewerHandlers, ...packageHandlers, + ...rteEmbedHandlers, + ...stylesheetHandlers, ]; switch (import.meta.env.VITE_UMBRACO_INSTALL_STATUS) { diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/browser.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/browser.ts index 57b0cd42be..980b6cbecf 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/browser.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/browser.ts @@ -1,6 +1,6 @@ import { MockedRequest, setupWorker } from 'msw'; import { handlers } from './browser-handlers'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; const worker = setupWorker(...handlers); diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/culture.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/culture.data.ts index 87d0f3904d..68fd93e4cf 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/culture.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/culture.data.ts @@ -1,12 +1,12 @@ -import type { CultureModel, PagedCultureModel } from '@umbraco-cms/backend-api'; +import type { CultureReponseModel, PagedCultureReponseModel } from '@umbraco-cms/backoffice/backend-api'; class UmbCulturesData { - get(): PagedCultureModel { + get(): PagedCultureReponseModel { return { total: culturesMock.length, items: culturesMock }; } } -export const culturesMock: Array = [ +export const culturesMock: Array = [ { name: 'af', englishName: 'Afrikaans', diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/data-type.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/data-type.data.ts index fd0b0b01c0..fccf52dbfa 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/data-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/data-type.data.ts @@ -1,28 +1,40 @@ import { UmbEntityData } from './entity.data'; import { createFolderTreeItem } from './utils'; -import type { FolderTreeItemModel, DataTypeModel } from '@umbraco-cms/backend-api'; +import type { + FolderTreeItemResponseModel, + DataTypeResponseModel, + CreateFolderRequestModel, +} from '@umbraco-cms/backoffice/backend-api'; -// TODO: investigate why we don't get an entity type as part of the DataTypeModel -export const data: Array = [ +// TODO: investigate why we don't get an type as part of the DataTypeModel +export const data: Array<(DataTypeResponseModel & { type: 'data-type' }) | FolderTreeItemResponseModel> = [ { $type: 'data-type', type: 'data-type', - key: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', - parentKey: null, + name: 'Folder 1', + id: 'dt-folder1', + parentId: null, + isFolder: true, + }, + { + $type: 'data-type', + type: 'data-type', + id: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + parentId: null, name: 'Textstring', propertyEditorAlias: 'Umbraco.TextBox', propertyEditorUiAlias: 'Umb.PropertyEditorUI.TextBox', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Text', - key: 'dt-textBox', - parentKey: null, + id: 'dt-textBox', + parentId: null, propertyEditorAlias: 'Umbraco.TextBox', propertyEditorUiAlias: 'Umb.PropertyEditorUI.TextBox', - data: [ + values: [ { alias: 'maxChars', value: 10, @@ -33,31 +45,31 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Text Area', - key: 'dt-textArea', - parentKey: null, + id: 'dt-textArea', + parentId: null, propertyEditorAlias: 'Umbraco.TextArea', propertyEditorUiAlias: 'Umb.PropertyEditorUI.TextArea', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'My JS Property Editor', - key: 'dt-custom', - parentKey: null, + id: 'dt-custom', + parentId: null, propertyEditorAlias: 'Umbraco.JSON', propertyEditorUiAlias: 'My.PropertyEditorUI.Custom', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Color Picker', - key: 'dt-colorPicker', - parentKey: null, + id: 'dt-colorPicker', + parentId: null, propertyEditorAlias: 'Umbraco.ColorPicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.ColorPicker', - data: [ + values: [ { alias: 'useLabel', value: true, @@ -109,11 +121,11 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Content Picker', - key: 'dt-contentPicker', - parentKey: null, + id: 'dt-contentPicker', + parentId: null, propertyEditorAlias: 'Umbraco.ContentPicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.DocumentPicker', - data: [ + values: [ { alias: 'validationLimit', value: { min: 2, max: 4 }, @@ -124,11 +136,11 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Eye Dropper', - key: 'dt-eyeDropper', - parentKey: null, + id: 'dt-eyeDropper', + parentId: null, propertyEditorAlias: 'Umbraco.ColorPicker.EyeDropper', propertyEditorUiAlias: 'Umb.PropertyEditorUI.EyeDropper', - data: [ + values: [ { //showPalette alias: 'palette', @@ -161,11 +173,11 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Multi URL Picker', - key: 'dt-multiUrlPicker', - parentKey: null, + id: 'dt-multiUrlPicker', + parentId: null, propertyEditorAlias: 'Umbraco.MultiUrlPicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.MultiUrlPicker', - data: [ + values: [ { alias: 'overlaySize', value: 'small', @@ -192,21 +204,21 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Multi Node Tree Picker', - key: 'dt-multiNodeTreePicker', - parentKey: null, + id: 'dt-multiNodeTreePicker', + parentId: null, propertyEditorAlias: 'Umbraco.MultiNodeTreePicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.TreePicker', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Date Picker', - key: 'dt-datePicker', - parentKey: null, + id: 'dt-datePicker', + parentId: null, propertyEditorAlias: 'Umbraco.DateTime', propertyEditorUiAlias: 'Umb.PropertyEditorUI.DatePicker', - data: [ + values: [ { alias: 'format', value: 'YYYY-MM-DD', @@ -221,11 +233,11 @@ export const data: Array = [ $type: 'data-type', name: 'Date Picker With Time', type: 'data-type', - key: 'dt-datePicker-time', - parentKey: null, + id: 'dt-datePicker-time', + parentId: null, propertyEditorAlias: 'Umbraco.DateTime', propertyEditorUiAlias: 'Umb.PropertyEditorUI.DatePicker', - data: [ + values: [ { alias: 'format', value: 'YYYY-MM-DD HH:mm:ss', @@ -240,11 +252,11 @@ export const data: Array = [ $type: 'data-type', name: 'Time', type: 'data-type', - key: 'dt-time', - parentKey: null, + id: 'dt-time', + parentId: null, propertyEditorAlias: 'Umbraco.DateTime', propertyEditorUiAlias: 'Umb.PropertyEditorUI.DatePicker', - data: [ + values: [ { alias: 'format', value: 'HH:mm:ss', @@ -259,21 +271,21 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Email', - key: 'dt-email', - parentKey: null, + id: 'dt-email', + parentId: null, propertyEditorAlias: 'Umbraco.EmailAddress', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Email', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Multiple Text String', - key: 'dt-multipleTextString', - parentKey: null, + id: 'dt-multipleTextString', + parentId: null, propertyEditorAlias: 'Umbraco.MultipleTextString', propertyEditorUiAlias: 'Umb.PropertyEditorUI.MultipleTextString', - data: [ + values: [ { alias: 'minNumber', value: 2, @@ -288,21 +300,21 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Dropdown', - key: 'dt-dropdown', - parentKey: null, + id: 'dt-dropdown', + parentId: null, propertyEditorAlias: 'Umbraco.DropDown.Flexible', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Dropdown', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Slider', - key: 'dt-slider', - parentKey: null, + id: 'dt-slider', + parentId: null, propertyEditorAlias: 'Umbraco.Slider', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Slider', - data: [ + values: [ { alias: 'enableRange', value: true, @@ -333,11 +345,11 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Toggle', - key: 'dt-toggle', - parentKey: null, + id: 'dt-toggle', + parentId: null, propertyEditorAlias: 'Umbraco.TrueFalse', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Toggle', - data: [ + values: [ { alias: 'default', value: false, @@ -360,31 +372,31 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Tags', - key: 'dt-tags', - parentKey: null, + id: 'dt-tags', + parentId: null, propertyEditorAlias: 'Umbraco.Tags', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Tags', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Markdown Editor', - key: 'dt-markdownEditor', - parentKey: null, + id: 'dt-markdownEditor', + parentId: null, propertyEditorAlias: 'Umbraco.MarkdownEditor', propertyEditorUiAlias: 'Umb.PropertyEditorUI.MarkdownEditor', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Radio Button List', - key: 'dt-radioButtonList', - parentKey: null, + id: 'dt-radioButtonList', + parentId: null, propertyEditorAlias: 'Umbraco.RadioButtonList', propertyEditorUiAlias: 'Umb.PropertyEditorUI.RadioButtonList', - data: [ + values: [ { alias: 'items', value: { @@ -399,11 +411,11 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Checkbox List', - key: 'dt-checkboxList', - parentKey: null, + id: 'dt-checkboxList', + parentId: null, propertyEditorAlias: 'Umbraco.CheckboxList', propertyEditorUiAlias: 'Umb.PropertyEditorUI.CheckboxList', - data: [ + values: [ { alias: 'items', value: { @@ -418,171 +430,176 @@ export const data: Array = [ $type: 'data-type', type: 'data-type', name: 'Block List', - key: 'dt-blockList', - parentKey: null, + id: 'dt-blockList', + parentId: null, propertyEditorAlias: 'Umbraco.BlockList', propertyEditorUiAlias: 'Umb.PropertyEditorUI.BlockList', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Media Picker', - key: 'dt-mediaPicker', - parentKey: null, + id: 'dt-mediaPicker', + parentId: null, propertyEditorAlias: 'Umbraco.MediaPicker3', propertyEditorUiAlias: 'Umb.PropertyEditorUI.MediaPicker', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Image Cropper', - key: 'dt-imageCropper', - parentKey: null, + id: 'dt-imageCropper', + parentId: null, propertyEditorAlias: 'Umbraco.ImageCropper', propertyEditorUiAlias: 'Umb.PropertyEditorUI.ImageCropper', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Upload Field', - key: 'dt-uploadField', - parentKey: null, + id: 'dt-uploadField', + parentId: null, propertyEditorAlias: 'Umbraco.UploadField', propertyEditorUiAlias: 'Umb.PropertyEditorUI.UploadField', - data: [], + values: [ + { + alias: 'fileExtensions', + value: ['jpg', 'jpeg', 'png'], + }, + ], }, { $type: 'data-type', type: 'data-type', name: 'Block Grid', - key: 'dt-blockGrid', - parentKey: null, + id: 'dt-blockGrid', + parentId: null, propertyEditorAlias: 'Umbraco.BlockGrid', propertyEditorUiAlias: 'Umb.PropertyEditorUI.BlockGrid', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Collection View', - key: 'dt-collectionView', - parentKey: null, + id: 'dt-collectionView', + parentId: null, propertyEditorAlias: 'Umbraco.ListView', propertyEditorUiAlias: 'Umb.PropertyEditorUI.CollectionView', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Icon Picker', - key: 'dt-iconPicker', - parentKey: null, + id: 'dt-iconPicker', + parentId: null, propertyEditorAlias: 'Umbraco.IconPicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.IconPicker', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Number Range', - key: 'dt-numberRange', - parentKey: null, + id: 'dt-numberRange', + parentId: null, propertyEditorAlias: 'Umbraco.JSON', propertyEditorUiAlias: 'Umb.PropertyEditorUI.NumberRange', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Order Direction', - key: 'dt-orderDirection', - parentKey: null, + id: 'dt-orderDirection', + parentId: null, propertyEditorAlias: 'Umbraco.JSON', propertyEditorUiAlias: 'Umb.PropertyEditorUI.OrderDirection', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Overlay Size', - key: 'dt-overlaySize', - parentKey: null, + id: 'dt-overlaySize', + parentId: null, propertyEditorAlias: 'Umbraco.JSON', propertyEditorUiAlias: 'Umb.PropertyEditorUI.OverlaySize', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Rich Text Editor', - key: 'dt-richTextEditor', - parentKey: null, + id: 'dt-richTextEditor', + parentId: null, propertyEditorAlias: 'Umbraco.TinyMCE', propertyEditorUiAlias: 'Umb.PropertyEditorUI.TinyMCE', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Label', - key: 'dt-label', - parentKey: null, + id: 'dt-label', + parentId: null, propertyEditorAlias: 'Umbraco.Label', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Label', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Integer', - key: 'dt-integer', - parentKey: null, + id: 'dt-integer', + parentId: null, propertyEditorAlias: 'Umbraco.Integer', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Integer', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Decimal', - key: 'dt-decimal', - parentKey: null, + id: 'dt-decimal', + parentId: null, propertyEditorAlias: 'Umbraco.Decimal', propertyEditorUiAlias: 'Umb.PropertyEditorUI.Decimal', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'User Picker', - key: 'dt-userPicker', - parentKey: null, + id: 'dt-userPicker', + parentId: null, propertyEditorAlias: 'Umbraco.UserPicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.UserPicker', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Member Picker', - key: 'dt-memberPicker', - parentKey: null, + id: 'dt-memberPicker', + parentId: null, propertyEditorAlias: 'Umbraco.MemberPicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.MemberPicker', - data: [], + values: [], }, { $type: 'data-type', type: 'data-type', name: 'Member Group Picker', - key: 'dt-memberGroupPicker', - parentKey: null, + id: 'dt-memberGroupPicker', + parentId: null, propertyEditorAlias: 'Umbraco.MemberGroupPicker', propertyEditorUiAlias: 'Umb.PropertyEditorUI.MemberGroupPicker', - data: [], + values: [], }, ]; @@ -590,25 +607,47 @@ export const data: Array = [ // TODO: all properties are optional in the server schema. I don't think this is correct. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore -class UmbDataTypeData extends UmbEntityData { +class UmbDataTypeData extends UmbEntityData { constructor() { super(data); } - getTreeRoot(): Array { - const rootItems = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): Array { + const rootItems = this.data.filter((item) => item.parentId === null); return rootItems.map((item) => createFolderTreeItem(item)); } - getTreeItemChildren(key: string): Array { - const childItems = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): Array { + const childItems = this.data.filter((item) => item.parentId === id); return childItems.map((item) => createFolderTreeItem(item)); } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createFolderTreeItem(item)); } + + createFolder(folder: CreateFolderRequestModel & { id: string | undefined }) { + const newFolder: FolderTreeItemResponseModel = { + name: folder.name, + id: folder.id, + parentId: folder.parentId, + $type: 'data-type', + type: 'data-type', + isFolder: true, + isContainer: false, + }; + + this.data.push(newFolder); + } + + // TODO: this could be reused across other types that support folders + deleteFolder(id: string) { + const item = this.getById(id) as FolderTreeItemResponseModel; + if (!item) throw new Error(`Item with id ${id} not found`); + if (!item.isFolder) throw new Error(`Item with id ${id} is not a folder`); + this.data = this.data.filter((item) => item.id !== id); + } } export const umbDataTypeData = new UmbDataTypeData(); diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/dictionary.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/dictionary.data.ts index b73bc7e0a5..aaf776a892 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/dictionary.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/dictionary.data.ts @@ -1,18 +1,12 @@ import { UmbEntityData } from './entity.data'; import { createEntityTreeItem } from './utils'; -import type { EntityTreeItemModel } from '@umbraco-cms/backend-api'; -import type { DictionaryDetails } from '@umbraco-cms/models'; +import type { DictionaryItemResponseModel, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; -export const data: Array = [ +export const data: Array = [ { $type: '', - parentKey: null, name: 'Hello', - key: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb', - hasChildren: true, - type: 'dictionary-item', - isContainer: false, - icon: 'umb:book-alt', + id: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb', translations: [ { isoCode: 'en', @@ -26,13 +20,8 @@ export const data: Array = [ }, { $type: '', - parentKey: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb', name: 'Hello again', - key: 'bbe7d0ab-53bb-485d-b8bd-12537f9925cb', - hasChildren: false, - type: 'dictionary-item', - isContainer: false, - icon: 'umb:book-alt', + id: 'bbe7d0ab-53bb-485d-b8bd-12537f9925cb', translations: [ { isoCode: 'en', @@ -46,27 +35,50 @@ export const data: Array = [ }, ]; +const dictionaryTree: Array = [ + { + $type: '', + parentId: null, + name: 'Hello', + id: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb', + hasChildren: true, + type: 'dictionary-item', + isContainer: false, + icon: 'umb:book-alt', + }, + { + $type: '', + parentId: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb', + name: 'Hello again', + id: 'bbe7d0ab-53bb-485d-b8bd-12537f9925cb', + hasChildren: false, + type: 'dictionary-item', + isContainer: false, + icon: 'umb:book-alt', + }, +]; + // Temp mocked database // TODO: all properties are optional in the server schema. I don't think this is correct. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore -class UmbDictionaryData extends UmbEntityData { +class UmbDictionaryData extends UmbEntityData { constructor() { super(data); } - getTreeRoot(): Array { - const rootItems = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): Array { + const rootItems = dictionaryTree.filter((item) => item.parentId === null); return rootItems.map((item) => createEntityTreeItem(item)); } - getTreeItemChildren(key: string): Array { - const childItems = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): Array { + const childItems = dictionaryTree.filter((item) => item.parentId === id); return childItems.map((item) => createEntityTreeItem(item)); } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = dictionaryTree.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createEntityTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-blueprint.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-blueprint.data.ts index 20255ded62..9ac544bffd 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-blueprint.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-blueprint.data.ts @@ -1,11 +1,11 @@ import { UmbEntityData } from './entity.data'; -import type { DocumentBlueprintDetails } from '@umbraco-cms/models'; +import type { DocumentBlueprintDetails } from '@umbraco-cms/backoffice/models'; export const data: Array = [ { name: 'Document Blueprint 1', type: 'document-blueprint', - key: '3fa85f64-5717-4562-b3fc-2c963f66afa6', + id: '3fa85f64-5717-4562-b3fc-2c963f66afa6', icon: 'umb:blueprint', documentTypeKey: 'd81c7957-153c-4b5a-aa6f-b434a4964624', properties: [], @@ -14,7 +14,7 @@ export const data: Array = [ { name: 'Document Blueprint 2', type: 'document-blueprint', - key: '3fa85f64-5717-4562-b3qc-2c963f66afa6', + id: '3fa85f64-5717-4562-b3qc-2c963f66afa6', icon: 'umb:blueprint', documentTypeKey: 'a99e4018-3ffc-486b-aa76-eecea9593d17', properties: [], diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-type.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-type.data.ts index 2b25677dfc..532186dde7 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document-type.data.ts @@ -1,16 +1,16 @@ import { UmbEntityData } from './entity.data'; import { createDocumentTypeTreeItem } from './utils'; import { - DocumentTypeTreeItemModel, - DocumentTypeModel, + DocumentTypeTreeItemResponseModel, + DocumentTypeResponseModel, ContentTypeCompositionTypeModel, -} from '@umbraco-cms/backend-api'; +} from '@umbraco-cms/backoffice/backend-api'; -export const data: Array = [ +export const data: Array = [ { - allowedTemplateKeys: [], - defaultTemplateKey: null, - key: 'all-property-editors-document-type-key', + allowedTemplateIds: [], + defaultTemplateId: null, + id: 'all-property-editors-document-type-id', alias: 'blogPost', name: 'Blog Post', description: null, @@ -21,12 +21,12 @@ export const data: Array = [ isElement: false, properties: [ { - key: '2', - containerKey: 'all-properties-group-key', + id: '2', + containerId: 'all-properties-group-id', alias: 'colorPicker', name: 'Color Picker', description: '', - dataTypeKey: 'dt-colorPicker', + dataTypeId: 'dt-colorPicker', variesByCulture: false, variesBySegment: false, validation: { @@ -40,12 +40,12 @@ export const data: Array = [ }, }, { - key: '3', - containerKey: 'all-properties-group-key', + id: '3', + containerId: 'all-properties-group-key', alias: 'contentPicker', name: 'Content Picker', description: '', - dataTypeKey: 'dt-contentPicker', + dataTypeId: 'dt-contentPicker', variesByCulture: false, variesBySegment: false, validation: { @@ -59,12 +59,12 @@ export const data: Array = [ }, }, { - key: '4', - containerKey: 'all-properties-group-key', + id: '4', + containerId: 'all-properties-group-key', alias: 'eyeDropper', name: 'Eye Dropper', description: '', - dataTypeKey: 'dt-eyeDropper', + dataTypeId: 'dt-eyeDropper', variesByCulture: false, variesBySegment: false, validation: { @@ -78,13 +78,13 @@ export const data: Array = [ }, }, { - key: '5', - containerKey: 'all-properties-group-key', + id: '5', + containerId: 'all-properties-group-key', alias: 'multiUrlPicker', name: 'Multi URL Picker', description: '', - dataTypeKey: 'dt-multiUrlPicker', - variesByCulture: false, + dataTypeId: 'dt-multiUrlPicker', + variesByCulture: true, variesBySegment: false, validation: { mandatory: true, @@ -97,12 +97,12 @@ export const data: Array = [ }, }, { - key: '6', - containerKey: 'all-properties-group-key', + id: '6', + containerId: 'all-properties-group-key', alias: 'multiNodeTreePicker', name: 'Multi Node Tree Picker', description: '', - dataTypeKey: 'dt-multiNodeTreePicker', + dataTypeId: 'dt-multiNodeTreePicker', variesByCulture: false, variesBySegment: false, validation: { @@ -116,12 +116,12 @@ export const data: Array = [ }, }, { - key: '7', - containerKey: 'all-properties-group-key', + id: '7', + containerId: 'all-properties-group-key', alias: 'datePicker', name: 'Date Picker', description: '', - dataTypeKey: 'dt-datePicker', + dataTypeId: 'dt-datePicker', variesByCulture: false, variesBySegment: false, validation: { @@ -135,12 +135,12 @@ export const data: Array = [ }, }, { - key: '8', - containerKey: 'all-properties-group-key', + id: '8', + containerId: 'all-properties-group-key', alias: 'email', name: 'Email', description: '', - dataTypeKey: 'dt-email', + dataTypeId: 'dt-email', variesByCulture: false, variesBySegment: false, validation: { @@ -154,12 +154,12 @@ export const data: Array = [ }, }, { - key: '9', - containerKey: 'all-properties-group-key', + id: '9', + containerId: 'all-properties-group-key', alias: 'textBox', name: 'Text Box', description: '', - dataTypeKey: 'dt-textBox', + dataTypeId: 'dt-textBox', variesByCulture: false, variesBySegment: false, validation: { @@ -173,12 +173,12 @@ export const data: Array = [ }, }, { - key: '19', - containerKey: 'all-properties-group-key', + id: '19', + containerId: 'all-properties-group-key', alias: 'dropdown', name: 'Dropdown', description: '', - dataTypeKey: 'dt-dropdown', + dataTypeId: 'dt-dropdown', variesByCulture: false, variesBySegment: false, validation: { @@ -192,12 +192,12 @@ export const data: Array = [ }, }, { - key: '11', - containerKey: 'all-properties-group-key', + id: '11', + containerId: 'all-properties-group-key', alias: 'textArea', name: 'Text Area', description: '', - dataTypeKey: 'dt-textArea', + dataTypeId: 'dt-textArea', variesByCulture: false, variesBySegment: false, validation: { @@ -211,12 +211,12 @@ export const data: Array = [ }, }, { - key: '12', - containerKey: 'all-properties-group-key', + id: '12', + containerId: 'all-properties-group-key', alias: 'slider', name: 'Slider', description: '', - dataTypeKey: 'dt-slider', + dataTypeId: 'dt-slider', variesByCulture: false, variesBySegment: false, validation: { @@ -230,12 +230,12 @@ export const data: Array = [ }, }, { - key: '13', - containerKey: 'all-properties-group-key', + id: '13', + containerId: 'all-properties-group-key', alias: 'toggle', name: 'Toggle', description: '', - dataTypeKey: 'dt-toggle', + dataTypeId: 'dt-toggle', variesByCulture: false, variesBySegment: false, validation: { @@ -249,12 +249,12 @@ export const data: Array = [ }, }, { - key: '14', - containerKey: 'all-properties-group-key', + id: '14', + containerId: 'all-properties-group-key', alias: 'tags', name: 'Tags', description: '', - dataTypeKey: 'dt-tags', + dataTypeId: 'dt-tags', variesByCulture: false, variesBySegment: false, validation: { @@ -268,12 +268,12 @@ export const data: Array = [ }, }, { - key: '15', - containerKey: 'all-properties-group-key', + id: '15', + containerId: 'all-properties-group-key', alias: 'markdownEditor', name: 'MarkdownEditor', description: '', - dataTypeKey: 'dt-markdownEditor', + dataTypeId: 'dt-markdownEditor', variesByCulture: false, variesBySegment: false, validation: { @@ -287,12 +287,12 @@ export const data: Array = [ }, }, { - key: '16', - containerKey: 'all-properties-group-key', + id: '16', + containerId: 'all-properties-group-key', alias: 'radioButtonList', name: 'Radio Button List', description: '', - dataTypeKey: 'dt-radioButtonList', + dataTypeId: 'dt-radioButtonList', variesByCulture: false, variesBySegment: false, validation: { @@ -306,12 +306,12 @@ export const data: Array = [ }, }, { - key: '17', - containerKey: 'all-properties-group-key', + id: '17', + containerId: 'all-properties-group-key', alias: 'checkboxList', name: 'Checkbox List', description: '', - dataTypeKey: 'dt-checkboxList', + dataTypeId: 'dt-checkboxList', variesByCulture: false, variesBySegment: false, validation: { @@ -325,12 +325,12 @@ export const data: Array = [ }, }, { - key: '18', - containerKey: 'all-properties-group-key', + id: '18', + containerId: 'all-properties-group-key', alias: 'blockList', name: 'Block List', description: '', - dataTypeKey: 'dt-blockList', + dataTypeId: 'dt-blockList', variesByCulture: false, variesBySegment: false, validation: { @@ -344,12 +344,12 @@ export const data: Array = [ }, }, { - key: '19', - containerKey: 'all-properties-group-key', + id: '19', + containerId: 'all-properties-group-key', alias: 'mediaPicker', name: 'Media Picker', description: '', - dataTypeKey: 'dt-mediaPicker', + dataTypeId: 'dt-mediaPicker', variesByCulture: false, variesBySegment: false, validation: { @@ -363,12 +363,12 @@ export const data: Array = [ }, }, { - key: '20', - containerKey: 'all-properties-group-key', + id: '20', + containerId: 'all-properties-group-key', alias: 'imageCropper', name: 'Image Cropper', description: '', - dataTypeKey: 'dt-imageCropper', + dataTypeId: 'dt-imageCropper', variesByCulture: false, variesBySegment: false, validation: { @@ -382,12 +382,12 @@ export const data: Array = [ }, }, { - key: '21', - containerKey: 'all-properties-group-key', + id: '21', + containerId: 'all-properties-group-key', alias: 'uploadField', name: 'Upload Field', description: '', - dataTypeKey: 'dt-uploadField', + dataTypeId: 'dt-uploadField', variesByCulture: false, variesBySegment: false, validation: { @@ -401,12 +401,12 @@ export const data: Array = [ }, }, { - key: '22', - containerKey: 'all-properties-group-key', + id: '22', + containerId: 'all-properties-group-key', alias: 'blockGrid', name: 'Block Grid', description: '', - dataTypeKey: 'dt-blockGrid', + dataTypeId: 'dt-blockGrid', variesByCulture: false, variesBySegment: false, validation: { @@ -420,12 +420,12 @@ export const data: Array = [ }, }, { - key: '23', - containerKey: 'all-properties-group-key', + id: '23', + containerId: 'all-properties-group-key', alias: 'blockGrid', name: 'Icon Picker', description: '', - dataTypeKey: 'dt-iconPicker', + dataTypeId: 'dt-iconPicker', variesByCulture: false, variesBySegment: false, validation: { @@ -439,12 +439,12 @@ export const data: Array = [ }, }, { - key: '24', - containerKey: 'all-properties-group-key', + id: '24', + containerId: 'all-properties-group-key', alias: 'numberRange', name: 'Number Range', description: '', - dataTypeKey: 'dt-numberRange', + dataTypeId: 'dt-numberRange', variesByCulture: false, variesBySegment: false, validation: { @@ -458,12 +458,12 @@ export const data: Array = [ }, }, { - key: '25', - containerKey: 'all-properties-group-key', + id: '25', + containerId: 'all-properties-group-key', alias: 'orderDirection', name: 'Order Direction', description: '', - dataTypeKey: 'dt-orderDirection', + dataTypeId: 'dt-orderDirection', variesByCulture: false, variesBySegment: false, validation: { @@ -477,12 +477,12 @@ export const data: Array = [ }, }, { - key: '26', - containerKey: 'all-properties-group-key', + id: '26', + containerId: 'all-properties-group-key', alias: 'overlaySize', name: 'Overlay Size', description: '', - dataTypeKey: 'dt-overlaySize', + dataTypeId: 'dt-overlaySize', variesByCulture: false, variesBySegment: false, validation: { @@ -496,12 +496,12 @@ export const data: Array = [ }, }, { - key: '27', - containerKey: 'all-properties-group-key', + id: '27', + containerId: 'all-properties-group-key', alias: 'label', name: 'Label', description: '', - dataTypeKey: 'dt-label', + dataTypeId: 'dt-label', variesByCulture: false, variesBySegment: false, validation: { @@ -515,12 +515,12 @@ export const data: Array = [ }, }, { - key: '28', - containerKey: 'all-properties-group-key', + id: '28', + containerId: 'all-properties-group-key', alias: 'integer', name: 'Integer', description: '', - dataTypeKey: 'dt-integer', + dataTypeId: 'dt-integer', variesByCulture: false, variesBySegment: false, validation: { @@ -534,12 +534,12 @@ export const data: Array = [ }, }, { - key: '29', - containerKey: 'all-properties-group-key', + id: '29', + containerId: 'all-properties-group-key', alias: 'decimal', name: 'Decimal', description: '', - dataTypeKey: 'dt-decimal', + dataTypeId: 'dt-decimal', variesByCulture: false, variesBySegment: false, validation: { @@ -553,12 +553,12 @@ export const data: Array = [ }, }, { - key: '30', - containerKey: 'all-properties-group-key', + id: '30', + containerId: 'all-properties-group-key', alias: 'memberPicker', name: 'Member Picker', description: '', - dataTypeKey: 'dt-memberPicker', + dataTypeId: 'dt-memberPicker', variesByCulture: false, variesBySegment: false, validation: { @@ -572,12 +572,12 @@ export const data: Array = [ }, }, { - key: '31', - containerKey: 'all-properties-group-key', + id: '31', + containerId: 'all-properties-group-key', alias: 'memberGroupPicker', name: 'Member Group Picker', description: '', - dataTypeKey: 'dt-memberGroupPicker', + dataTypeId: 'dt-memberGroupPicker', variesByCulture: false, variesBySegment: false, validation: { @@ -591,12 +591,12 @@ export const data: Array = [ }, }, { - key: '32', - containerKey: 'all-properties-group-key', + id: '32', + containerId: 'all-properties-group-key', alias: 'userPicker', name: 'User Picker', description: '', - dataTypeKey: 'dt-userPicker', + dataTypeId: 'dt-userPicker', variesByCulture: false, variesBySegment: false, validation: { @@ -612,8 +612,8 @@ export const data: Array = [ ], containers: [ { - key: 'all-properties-group-key', - parentKey: null, + id: 'all-properties-group-key', + parentId: null, name: 'Content', type: 'Group', sortOrder: 0, @@ -629,9 +629,9 @@ export const data: Array = [ }, { - allowedTemplateKeys: [], - defaultTemplateKey: null, - key: '29643452-cff9-47f2-98cd-7de4b6807681', + allowedTemplateIds: [], + defaultTemplateId: null, + id: '29643452-cff9-47f2-98cd-7de4b6807681', alias: 'blogPost', name: 'Blog Post', description: null, @@ -642,12 +642,12 @@ export const data: Array = [ isElement: false, properties: [ { - key: '5b4ca208-134e-4865-b423-06e5e97adf3c', - containerKey: 'c3cd2f12-b7c4-4206-8d8b-27c061589f75', + id: '5b4ca208-134e-4865-b423-06e5e97adf3c', + containerId: 'c3cd2f12-b7c4-4206-8d8b-27c061589f75', alias: 'blogPostText', name: 'Blog Post Text', description: null, - dataTypeKey: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', variesByCulture: false, variesBySegment: false, validation: { @@ -661,12 +661,12 @@ export const data: Array = [ }, }, { - key: 'ef7096b6-7c9e-49ba-8d49-395111e65ea2', - containerKey: '227d6ed2-e118-4494-b8f2-deb69854a56a', + id: 'ef7096b6-7c9e-49ba-8d49-395111e65ea2', + containerId: '227d6ed2-e118-4494-b8f2-deb69854a56a', alias: 'blogTextStringUnderMasterTab', name: 'Blog text string under master tab', description: null, - dataTypeKey: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', variesByCulture: true, variesBySegment: false, validation: { @@ -680,12 +680,12 @@ export const data: Array = [ }, }, { - key: 'e010c429-b298-499a-9bfe-79687af8972a', - containerKey: '22177c49-ecba-4f2e-b7fa-3f2c04d02cfb', + id: 'e010c429-b298-499a-9bfe-79687af8972a', + containerId: '22177c49-ecba-4f2e-b7fa-3f2c04d02cfb', alias: 'blogTextStringUnderGroupUnderMasterTab', name: 'Blog text string under group under master tab', description: null, - dataTypeKey: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', variesByCulture: true, variesBySegment: false, validation: { @@ -699,12 +699,12 @@ export const data: Array = [ }, }, { - key: '1a22749a-c7d2-44bb-b36b-c977c2ced6ef', - containerKey: '2c943997-b685-432d-a6c5-601d8e7a298a', + id: '1a22749a-c7d2-44bb-b36b-c977c2ced6ef', + containerId: '2c943997-b685-432d-a6c5-601d8e7a298a', alias: 'localBlogTabString', name: 'Local Blog Tab String', description: null, - dataTypeKey: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', variesByCulture: false, variesBySegment: false, validation: { @@ -718,12 +718,12 @@ export const data: Array = [ }, }, { - key: '22', - containerKey: '2c943997-b685-432d-a6c5-601d8e7a298a', + id: '22', + containerId: '2c943997-b685-432d-a6c5-601d8e7a298a', alias: 'blockGrid', name: 'Block Grid', description: '', - dataTypeKey: 'dt-blockGrid', + dataTypeId: 'dt-blockGrid', variesByCulture: false, variesBySegment: false, validation: { @@ -739,29 +739,29 @@ export const data: Array = [ ], containers: [ { - key: 'c3cd2f12-b7c4-4206-8d8b-27c061589f75', - parentKey: null, + id: 'c3cd2f12-b7c4-4206-8d8b-27c061589f75', + parentId: null, name: 'Content-group', type: 'Group', sortOrder: 0, }, { - key: '227d6ed2-e118-4494-b8f2-deb69854a56a', - parentKey: null, + id: '227d6ed2-e118-4494-b8f2-deb69854a56a', + parentId: null, name: 'Master Tab', type: 'Tab', sortOrder: 0, }, { - key: '22177c49-ecba-4f2e-b7fa-3f2c04d02cfb', - parentKey: '227d6ed2-e118-4494-b8f2-deb69854a56a', + id: '22177c49-ecba-4f2e-b7fa-3f2c04d02cfb', + parentId: '227d6ed2-e118-4494-b8f2-deb69854a56a', name: 'Blog Group under master tab', type: 'Group', sortOrder: 0, }, { - key: '2c943997-b685-432d-a6c5-601d8e7a298a', - parentKey: null, + id: '2c943997-b685-432d-a6c5-601d8e7a298a', + parentId: null, name: 'Local blog tab', type: 'Tab', sortOrder: 1, @@ -769,17 +769,17 @@ export const data: Array = [ ], allowedContentTypes: [ { - key: '29643452-cff9-47f2-98cd-7de4b6807681', + id: '29643452-cff9-47f2-98cd-7de4b6807681', sortOrder: 0, }, ], compositions: [ { - key: '5035d7d9-0a63-415c-9e75-ee2cf931db92', + id: '5035d7d9-0a63-415c-9e75-ee2cf931db92', compositionType: ContentTypeCompositionTypeModel.INHERITANCE, }, { - key: '8f68ba66-6fb2-4778-83b8-6ab4ca3a7c5d', + id: '8f68ba66-6fb2-4778-83b8-6ab4ca3a7c5d', compositionType: ContentTypeCompositionTypeModel.COMPOSITION, }, ], @@ -790,9 +790,9 @@ export const data: Array = [ }, }, { - allowedTemplateKeys: ['916cfecc-3295-490c-a16d-c41fa9f72980'], - defaultTemplateKey: '916cfecc-3295-490c-a16d-c41fa9f72980', - key: '5035d7d9-0a63-415c-9e75-ee2cf931db92', + allowedTemplateIds: ['916cfecc-3295-490c-a16d-c41fa9f72980'], + defaultTemplateId: '916cfecc-3295-490c-a16d-c41fa9f72980', + id: '5035d7d9-0a63-415c-9e75-ee2cf931db92', alias: 'masterPage', name: 'Master Page', description: null, @@ -803,12 +803,12 @@ export const data: Array = [ isElement: false, properties: [ { - key: '5e5f7456-c751-4846-9f2b-47965cc96ec6', - containerKey: '6f281e5a-0242-4649-bd9e-d6bf87f92b41', + id: '5e5f7456-c751-4846-9f2b-47965cc96ec6', + containerId: '6f281e5a-0242-4649-bd9e-d6bf87f92b41', alias: 'masterText', name: 'Master text', description: null, - dataTypeKey: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', variesByCulture: false, variesBySegment: false, validation: { @@ -824,8 +824,8 @@ export const data: Array = [ ], containers: [ { - key: '6f281e5a-0242-4649-bd9e-d6bf87f92b41', - parentKey: null, + id: '6f281e5a-0242-4649-bd9e-d6bf87f92b41', + parentId: null, name: 'Master Tab', type: 'Tab', sortOrder: 0, @@ -840,9 +840,9 @@ export const data: Array = [ }, }, { - allowedTemplateKeys: [], - defaultTemplateKey: null, - key: '8f68ba66-6fb2-4778-83b8-6ab4ca3a7c5d', + allowedTemplateIds: [], + defaultTemplateId: null, + id: '8f68ba66-6fb2-4778-83b8-6ab4ca3a7c5d', alias: 'baseElementType', name: 'Base Element Type', description: null, @@ -853,12 +853,12 @@ export const data: Array = [ isElement: true, properties: [ { - key: 'b92de6ac-1a22-4a45-a481-b6cae1cccbbf', - containerKey: '1e845ca8-1e3e-4b03-be1d-0b4149ce2129', + id: 'b92de6ac-1a22-4a45-a481-b6cae1cccbbf', + containerId: '1e845ca8-1e3e-4b03-be1d-0b4149ce2129', alias: 'pageTitle', name: 'Page title', description: null, - dataTypeKey: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', variesByCulture: false, variesBySegment: false, validation: { @@ -874,8 +874,8 @@ export const data: Array = [ ], containers: [ { - key: '1e845ca8-1e3e-4b03-be1d-0b4149ce2129', - parentKey: null, + id: '1e845ca8-1e3e-4b03-be1d-0b4149ce2129', + parentId: null, name: 'Content-group', type: 'Group', sortOrder: 0, @@ -889,38 +889,194 @@ export const data: Array = [ keepLatestVersionPerDayForDays: null, }, }, + { + allowedTemplateIds: [ + '2bf464b6-3aca-4388-b043-4eb439cc2643', + '9a84c0b3-03b4-4dd4-84ac-706740ac0f71', + '9a84c0b3-03b4-4dd4-84ac-706740ac0f72', + ], + defaultTemplateId: '2bf464b6-3aca-4388-b043-4eb439cc2643', + id: 'simple-document-type-key', + alias: 'simpleDocumentType', + name: 'Simple Document Type', + description: null, + icon: 'umb:document', + allowedAsRoot: true, + variesByCulture: false, + variesBySegment: false, + isElement: false, + properties: [ + { + id: '1680d4d2-cda8-4ac2-affd-a69fc10382b1', + containerId: '341b8521-fd43-4333-ae7a-a10cbbc6f4b0', + alias: 'prop1', + name: 'Prop 1', + description: null, + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + variesByCulture: false, + variesBySegment: false, + validation: { + mandatory: false, + mandatoryMessage: null, + regEx: null, + regExMessage: null, + }, + appearance: { + labelOnTop: false, + }, + }, + ], + containers: [ + { + id: '341b8521-fd43-4333-ae7a-a10cbbc6f4b0', + parentId: null, + name: 'Content', + type: 'Group', + sortOrder: 0, + }, + ], + allowedContentTypes: [ + { id: 'simple-document-type-key', sortOrder: 0 }, + { id: 'simple-document-type-2-key', sortOrder: 0 }, + ], + compositions: [], + cleanup: { + preventCleanup: false, + keepAllVersionsNewerThanDays: null, + keepLatestVersionPerDayForDays: null, + }, + }, + { + allowedTemplateIds: [], + defaultTemplateId: null, + id: 'simple-document-type-2-key', + alias: 'simpleDocumentType2', + name: 'Simple Document Type 2', + description: null, + icon: 'umb:document', + allowedAsRoot: true, + variesByCulture: false, + variesBySegment: false, + isElement: false, + properties: [ + { + id: '82d4b050-b128-42fe-ac8e-d5586e533592', + containerId: 'b275052a-1868-4901-bc8c-2b35b78a9ab2', + alias: 'prop1', + name: 'Prop 1', + description: null, + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + variesByCulture: false, + variesBySegment: false, + validation: { + mandatory: false, + mandatoryMessage: null, + regEx: null, + regExMessage: null, + }, + appearance: { + labelOnTop: false, + }, + }, + { + id: 'beadc69a-d669-4d01-9919-98bafba31e57', + containerId: 'b275052a-1868-4901-bc8c-2b35b78a9ab2', + alias: 'prop2', + name: 'Prop 2', + description: null, + dataTypeId: '0cc0eba1-9960-42c9-bf9b-60e150b429ae', + variesByCulture: false, + variesBySegment: false, + validation: { + mandatory: false, + mandatoryMessage: null, + regEx: null, + regExMessage: null, + }, + appearance: { + labelOnTop: false, + }, + }, + ], + containers: [ + { + id: 'b275052a-1868-4901-bc8c-2b35b78a9ab2', + parentId: null, + name: 'Content', + type: 'Group', + sortOrder: 0, + }, + ], + allowedContentTypes: [{ id: 'simple-document-type-key', sortOrder: 0 }], + compositions: [], + cleanup: { + preventCleanup: false, + keepAllVersionsNewerThanDays: null, + keepLatestVersionPerDayForDays: null, + }, + }, ]; -export const treeData: Array = [ +export const treeData: Array = [ { $type: 'DocumentTypeTreeItemViewModel', name: 'All property editors document type', type: 'document-type', hasChildren: false, - key: 'all-property-editors-document-type-key', + id: 'all-property-editors-document-type-id', isContainer: false, - parentKey: null, + parentId: null, icon: '', }, { $type: 'DocumentTypeTreeItemViewModel', - name: 'Document Type 1', + name: 'Page Document Type', type: 'document-type', hasChildren: false, - key: 'd81c7957-153c-4b5a-aa6f-b434a4964624', + id: '29643452-cff9-47f2-98cd-7de4b6807681', isContainer: false, - parentKey: null, - icon: '', + parentId: null, + icon: 'umb:document', }, { $type: 'DocumentTypeTreeItemViewModel', - name: 'Document Type 2', + name: 'Page Document Type Compositional', type: 'document-type', hasChildren: false, - key: 'a99e4018-3ffc-486b-aa76-eecea9593d17', + id: '5035d7d9-0a63-415c-9e75-ee2cf931db92', isContainer: false, - parentKey: null, - icon: '', + parentId: null, + icon: 'umb:document', + }, + { + $type: 'DocumentTypeTreeItemViewModel', + name: 'Page Document Type Inherited', + type: 'document-type', + hasChildren: false, + id: '8f68ba66-6fb2-4778-83b8-6ab4ca3a7c5d', + isContainer: false, + parentId: null, + icon: 'umb:document', + }, + { + $type: 'DocumentTypeTreeItemViewModel', + name: 'Simple Document Type', + type: 'document-type', + hasChildren: false, + id: 'simple-document-type-key', + isContainer: false, + parentId: null, + icon: 'umb:document', + }, + { + $type: 'DocumentTypeTreeItemViewModel', + name: 'Simple Document Type 2', + type: 'document-type', + hasChildren: false, + id: 'simple-document-type-2-key', + isContainer: false, + parentId: null, + icon: 'umb:document', }, ]; @@ -928,25 +1084,32 @@ export const treeData: Array = [ // TODO: all properties are optional in the server schema. I don't think this is correct. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore -class UmbDocumentTypeData extends UmbEntityData { +class UmbDocumentTypeData extends UmbEntityData { private treeData = treeData; constructor() { super(data); } - getTreeRoot(): Array { - const rootItems = this.treeData.filter((item) => item.parentKey === null); + getTreeRoot(): Array { + const rootItems = this.treeData.filter((item) => item.parentId === null); return rootItems.map((item) => createDocumentTypeTreeItem(item)); } - getTreeItemChildren(key: string): Array { - const childItems = this.treeData.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): Array { + const childItems = this.treeData.filter((item) => item.parentId === id); return childItems.map((item) => createDocumentTypeTreeItem(item)); } - getTreeItem(keys: Array): Array { - const items = this.treeData.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.treeData.filter((item) => ids.includes(item.id ?? '')); + return items.map((item) => createDocumentTypeTreeItem(item)); + } + + getAllowedTypesOf(id: string): Array { + const documentType = this.getById(id); + const allowedTypeKeys = documentType?.allowedContentTypes?.map((documentType) => documentType.id) ?? []; + const items = this.treeData.filter((item) => allowedTypeKeys.includes(item.id ?? '')); return items.map((item) => createDocumentTypeTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts index 8f5b4bfd10..15224b187d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/document.data.ts @@ -2,12 +2,12 @@ import { UmbEntityData } from './entity.data'; import { createDocumentTreeItem } from './utils'; import { ContentStateModel, - DocumentModel, - DocumentTreeItemModel, - PagedDocumentTreeItemModel, -} from '@umbraco-cms/backend-api'; + DocumentResponseModel, + DocumentTreeItemResponseModel, + PagedDocumentTreeItemResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; -export const data: Array = [ +export const data: Array = [ { urls: [ { @@ -15,209 +15,260 @@ export const data: Array = [ url: '/', }, ], - templateKey: null, - key: 'all-property-editors-document-key', - contentTypeKey: 'all-property-editors-document-type-key', + templateId: null, + id: 'all-property-editors-document-id', + contentTypeId: 'all-property-editors-document-type-id', values: [ { + $type: '', alias: 'email', culture: null, segment: null, value: null, }, { + $type: '', alias: 'colorPicker', culture: null, segment: null, value: null, }, { + $type: '', alias: 'contentPicker', culture: null, segment: null, value: null, }, { + $type: '', alias: 'eyeDropper', culture: null, segment: null, value: null, }, { + $type: '', alias: 'multiUrlPicker', - culture: null, + culture: 'en-us', + segment: null, + value: [ + { + name: undefined, + published: undefined, + queryString: undefined, + target: undefined, + trashed: undefined, + udi: 'umb://document/c05da24d7740447b9cdcbd8ce2172e38', + url: 'umb://document/c05da24d7740447b9cdcbd8ce2172e38', + }, + ], + }, + { + $type: '', + alias: 'multiUrlPicker', + culture: 'da-dk', segment: null, value: null, }, { + $type: '', alias: 'multiNodeTreePicker', culture: null, segment: null, value: null, }, { + $type: '', alias: 'datePicker', culture: null, segment: null, value: '2023-12-24', }, { + $type: '', alias: 'datePickerTime', culture: null, segment: null, value: '2023-12-24 14:52', }, { + $type: '', alias: 'time', culture: null, segment: null, value: '14:52:00', }, { + $type: '', alias: 'email', culture: null, segment: null, value: null, }, { + $type: '', alias: 'textBox', culture: null, segment: null, value: null, }, { + $type: '', alias: 'dropdown', culture: null, segment: null, value: null, }, { + $type: '', alias: 'textArea', culture: null, segment: null, value: null, }, { + $type: '', alias: 'slider', culture: null, segment: null, value: null, }, { + $type: '', alias: 'toggle', culture: null, segment: null, value: null, }, { + $type: '', alias: 'tags', culture: null, segment: null, value: null, }, { + $type: '', alias: 'markdownEditor', culture: null, segment: null, value: null, }, { + $type: '', alias: 'radioButtonList', culture: null, segment: null, value: null, }, { + $type: '', alias: 'checkboxList', culture: null, segment: null, value: null, }, { + $type: '', alias: 'blockList', culture: null, segment: null, value: null, }, { + $type: '', alias: 'mediaPicker', culture: null, segment: null, value: null, }, { + $type: '', alias: 'imageCropper', culture: null, segment: null, value: null, }, { + $type: '', alias: 'uploadField', culture: null, segment: null, value: null, }, { + $type: '', alias: 'blockGrid', culture: null, segment: null, value: null, }, { + $type: '', alias: 'blockGrid', culture: null, segment: null, value: null, }, { + $type: '', alias: 'numberRange', culture: null, segment: null, value: null, }, { + $type: '', alias: 'orderDirection', culture: null, segment: null, value: null, }, { + $type: '', alias: 'overlaySize', culture: null, segment: null, value: null, }, { + $type: '', alias: 'label', culture: null, segment: null, value: null, }, { + $type: '', alias: 'integer', culture: null, segment: null, value: null, }, { + $type: '', alias: 'decimal', culture: null, segment: null, value: null, }, { + $type: '', alias: 'memberPicker', culture: null, segment: null, value: null, }, { + $type: '', alias: 'memberGroupPicker', culture: null, segment: null, value: null, }, { + $type: '', alias: 'userPicker', culture: null, segment: null, @@ -226,6 +277,7 @@ export const data: Array = [ ], variants: [ { + $type: '', state: ContentStateModel.PUBLISHED, publishDate: '2023-02-06T15:31:51.354764', culture: 'en-us', @@ -234,6 +286,16 @@ export const data: Array = [ createDate: '2023-02-06T15:31:46.876902', updateDate: '2023-02-06T15:31:51.354764', }, + { + $type: '', + state: ContentStateModel.PUBLISHED, + publishDate: '2023-02-06T15:31:51.354764', + culture: 'da-dk', + segment: null, + name: 'Alle redigeringsfelter', + createDate: '2023-02-06T15:31:46.876902', + updateDate: '2023-02-06T15:31:51.354764', + }, ], }, { @@ -243,65 +305,75 @@ export const data: Array = [ url: '/', }, ], - templateKey: null, - key: 'c05da24d-7740-447b-9cdc-bd8ce2172e38', - contentTypeKey: '29643452-cff9-47f2-98cd-7de4b6807681', + templateId: null, + id: 'c05da24d-7740-447b-9cdc-bd8ce2172e38', + contentTypeId: '29643452-cff9-47f2-98cd-7de4b6807681', values: [ { + $type: '', culture: null, segment: null, alias: 'masterText', value: 'i have a master text', }, { + $type: '', culture: null, segment: null, alias: 'pageTitle', value: 'with a page title', }, { + $type: '', culture: null, segment: null, alias: 'blogPostText', value: 'My first blog post', }, { + $type: '', culture: 'en-us', segment: null, alias: 'blogTextStringUnderMasterTab', value: 'in the master tab', }, { + $type: '', culture: 'en-us', segment: null, alias: 'blogTextStringUnderGroupUnderMasterTab', value: 'which is under another group in the tab', }, { + $type: '', culture: 'da-dk', segment: null, alias: 'blogTextStringUnderMasterTab', value: 'på master dokument tab B', }, { + $type: '', culture: 'da-dk', segment: null, alias: 'blogTextStringUnderGroupUnderMasterTab', value: 'denne er under en anden gruppe i tab B', }, { + $type: '', culture: 'no-no', segment: null, alias: 'blogTextStringUnderMasterTab', value: 'Norsk på master dokument tab B', }, { + $type: '', culture: 'no-no', segment: null, alias: 'blogTextStringUnderGroupUnderMasterTab', value: 'Norsk denne er under en anden gruppe i tab B', }, { + $type: '', culture: null, segment: null, alias: 'localBlogTabString', @@ -310,6 +382,7 @@ export const data: Array = [ ], variants: [ { + $type: '', state: ContentStateModel.PUBLISHED, publishDate: '2023-02-06T15:31:51.354764', culture: 'en-us', @@ -319,6 +392,7 @@ export const data: Array = [ updateDate: '2023-02-06T15:31:51.354764', }, { + $type: '', state: ContentStateModel.PUBLISHED, publishDate: '2023-02-06T15:31:51.354764', culture: 'da-dk', @@ -328,6 +402,7 @@ export const data: Array = [ updateDate: '2023-02-06T15:31:51.354764', }, { + $type: '', state: ContentStateModel.PUBLISHED, publishDate: '2023-02-06T15:31:51.354764', culture: 'no-no', @@ -336,57 +411,85 @@ export const data: Array = [ createDate: '2023-02-06T15:31:46.876902', updateDate: '2023-02-06T15:31:51.354764', }, + { + $type: '', + state: ContentStateModel.PUBLISHED_PENDING_CHANGES, + publishDate: '2023-02-06T15:31:51.354764', + culture: 'es-es', + segment: null, + name: 'Articulo en ingles', + createDate: '2023-02-06T15:31:46.876902', + updateDate: '2023-02-06T15:31:51.354764', + }, + { + $type: '', + state: ContentStateModel.NOT_CREATED, + publishDate: '2023-02-06T15:31:51.354764', + culture: 'pl-pl', + segment: null, + name: 'Artykuł w języku polskim', + createDate: '2023-02-06T15:31:46.876902', + updateDate: '2023-02-06T15:31:51.354764', + }, ], }, { urls: [], - templateKey: null, - key: 'fd56a0b5-01a0-4da2-b428-52773bfa9cc4', - contentTypeKey: '29643452-cff9-47f2-98cd-7de4b6807681', + templateId: null, + id: 'fd56a0b5-01a0-4da2-b428-52773bfa9cc4', + contentTypeId: '29643452-cff9-47f2-98cd-7de4b6807681', values: [ { + $type: '', culture: null, segment: null, alias: 'masterText', value: 'i have a master text B', }, { + $type: '', culture: null, segment: null, alias: 'pageTitle', value: 'with a page title B', }, { + $type: '', culture: null, segment: null, alias: 'blogPostText', value: 'My first blog post B', }, { + $type: '', culture: 'en-us', segment: null, alias: 'blogTextStringUnderMasterTab', value: 'in the master tab B', }, { + $type: '', culture: 'en-us', segment: null, alias: 'blogTextStringUnderGroupUnderMasterTab', value: 'which is under another group in the tab B', }, { + $type: '', culture: 'da-dk', segment: null, alias: 'blogTextStringUnderMasterTab', value: 'på master dokument tab B', }, { + $type: '', culture: 'da-dk', segment: null, alias: 'blogTextStringUnderGroupUnderMasterTab', value: 'denne er under en anden gruppe i tab B', }, { + $type: '', culture: null, segment: null, alias: 'localBlogTabString', @@ -395,6 +498,25 @@ export const data: Array = [ ], variants: [ { + $type: '', + state: ContentStateModel.DRAFT, + publishDate: '2023-02-06T15:32:24.957009', + culture: 'en-us', + segment: null, + name: 'Blog post B', + createDate: '2023-02-06T15:32:05.350038', + updateDate: '2023-02-06T15:32:24.957009', + }, + ], + }, + { + urls: [], + templateId: null, + id: 'simple-document-id', + contentTypeId: 'simple-document-type-id', + variants: [ + { + $type: '', state: ContentStateModel.DRAFT, publishDate: '2023-02-06T15:32:24.957009', culture: 'en-us', @@ -407,7 +529,7 @@ export const data: Array = [ }, ]; -export const treeData: Array = [ +export const treeData: Array = [ { $type: 'DocumentTreeItemViewModel', isProtected: false, @@ -415,13 +537,13 @@ export const treeData: Array = [ isEdited: false, noAccess: false, isTrashed: false, - key: 'all-property-editors-document-key', + id: 'all-property-editors-document-id', isContainer: false, - parentKey: null, + parentId: null, name: 'All property editors', type: 'document', - icon: 'icon-item-arrangement', - hasChildren: true, + icon: 'document', + hasChildren: false, }, { $type: 'DocumentTreeItemViewModel', @@ -430,12 +552,12 @@ export const treeData: Array = [ isEdited: false, noAccess: false, isTrashed: false, - key: 'c05da24d-7740-447b-9cdc-bd8ce2172e38', + id: 'c05da24d-7740-447b-9cdc-bd8ce2172e38', isContainer: false, - parentKey: null, + parentId: null, name: 'Article in english', type: 'document', - icon: 'icon-item-arrangement', + icon: 'document', hasChildren: true, }, { @@ -445,12 +567,12 @@ export const treeData: Array = [ isEdited: false, noAccess: false, isTrashed: false, - key: 'fd56a0b5-01a0-4da2-b428-52773bfa9cc4', + id: 'fd56a0b5-01a0-4da2-b428-52773bfa9cc4', isContainer: false, - parentKey: 'c05da24d-7740-447b-9cdc-bd8ce2172e38', + parentId: 'c05da24d-7740-447b-9cdc-bd8ce2172e38', name: 'Blog post B', type: 'document', - icon: 'icon-item-arrangement', + icon: 'document', hasChildren: false, }, { @@ -459,9 +581,24 @@ export const treeData: Array = [ type: 'document', icon: 'document', hasChildren: false, - key: 'f6n7a5b2-e7c1-463a-956bc-6ck5b9bdf447', + id: 'f6n7a5b2-e7c1-463a-956bc-6ck5b9bdf447', isContainer: false, - parentKey: 'cdd30288-2d1c-41b4-89a9-61647b4a10d5', + parentId: 'cdd30288-2d1c-41b4-89a9-61647b4a10d5', + noAccess: false, + isProtected: false, + isPublished: false, + isEdited: false, + isTrashed: false, + }, + { + $type: 'DocumentTreeItemViewModel', + name: 'Simple', + type: 'document', + icon: 'document', + hasChildren: false, + id: 'simple-document-id', + isContainer: false, + parentId: null, noAccess: false, isProtected: false, isPublished: false, @@ -474,29 +611,29 @@ export const treeData: Array = [ // TODO: all properties are optional in the server schema. I don't think this is correct. // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore -class UmbDocumentData extends UmbEntityData { +class UmbDocumentData extends UmbEntityData { private treeData = treeData; constructor() { super(data); } - getTreeRoot(): PagedDocumentTreeItemModel { - const items = this.treeData.filter((item) => item.parentKey === null); + getTreeRoot(): PagedDocumentTreeItemResponseModel { + const items = this.treeData.filter((item) => item.parentId === null); const treeItems = items.map((item) => createDocumentTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItemChildren(key: string): PagedDocumentTreeItemModel { - const items = this.treeData.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): PagedDocumentTreeItemResponseModel { + const items = this.treeData.filter((item) => item.parentId === id); const treeItems = items.map((item) => createDocumentTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItem(keys: Array): Array { - const items = this.treeData.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.treeData.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createDocumentTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/entity.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/entity.data.ts index 29d9fc8f09..d3a7356430 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/entity.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/entity.data.ts @@ -1,5 +1,5 @@ import { UmbData } from './data'; -import type { Entity } from '@umbraco-cms/models'; +import type { Entity } from '@umbraco-cms/backoffice/models'; // Temp mocked database export class UmbEntityData extends UmbData { @@ -10,37 +10,45 @@ export class UmbEntityData extends UmbData { getList(skip: number, take: number) { return this.data.slice(skip, skip + take); } - - getByKey(key: string) { - return this.data.find((item) => item.key === key); + + getById(id: string) { + return this.data.find((item) => item.id === id); } - getByKeys(keys: Array) { - return this.data.filter((item) => keys.includes(item.key)); + getByIds(ids: Array) { + return this.data.filter((item) => ids.includes(item.id)); } - save(saveItems: Array) { - saveItems.forEach((saveItem) => { - const foundIndex = this.data.findIndex((item) => item.key === saveItem.key); - if (foundIndex !== -1) { - // update - this.data[foundIndex] = saveItem; - this.updateData(saveItem); - } else { - // new - this.data.push(saveItem); - } - }); + insert(item: T) { + const exits = this.data.find((i) => i.id === item.id); - return saveItems; + if (exits) { + throw new Error(`Item with key ${item.id} already exists`); + } + + this.data.push(item); } - move(keys: Array, destinationKey: string) { - const items = this.getByKeys(keys); + save(saveItem: T) { + const foundIndex = this.data.findIndex((item) => item.id === saveItem.id); + if (foundIndex !== -1) { + // update + this.data[foundIndex] = saveItem; + this.updateData(saveItem); + } else { + // new + this.data.push(saveItem); + } + + return saveItem; + } + + move(ids: Array, destinationKey: string) { + const items = this.getByIds(ids); const movedItems = items.map((item) => { return { ...item, - parentKey: destinationKey, + parentId: destinationKey, }; }); @@ -48,11 +56,11 @@ export class UmbEntityData extends UmbData { return movedItems; } - trash(keys: Array) { + trash(ids: Array) { const trashedItems: Array = []; - keys.forEach((key) => { - const item = this.getByKey(key); + ids.forEach((id) => { + const item = this.getById(id); if (!item) return; // TODO: how do we handle trashed items? @@ -67,17 +75,18 @@ export class UmbEntityData extends UmbData { return trashedItems; } - delete(keys: Array) { - const deletedKeys = this.data.filter((item) => keys.includes(item.key)).map((item) => item.key); - this.data = this.data.filter((item) => keys.indexOf(item.key) === -1); + delete(ids: Array) { + const deletedKeys = this.data.filter((item) => ids.includes(item.id)).map((item) => item.id); + this.data = this.data.filter((item) => ids.indexOf(item.id) === -1); return deletedKeys; } protected updateData(updateItem: T) { - const itemIndex = this.data.findIndex((item) => item.key === updateItem.key); + const itemIndex = this.data.findIndex((item) => item.id === updateItem.id); const item = this.data[itemIndex]; if (!item) return; + // TODO: revisit this code, seems like something we can solve smarter/type safer now: const itemKeys = Object.keys(item); const newItem = {}; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/examine.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/examine.data.ts index ab0a0ed3e6..9ca0c9d0e8 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/examine.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/examine.data.ts @@ -1,4 +1,4 @@ -import { HealthStatusModel, IndexModel, PagedIndexModel, SearchResultModel } from '@umbraco-cms/backend-api'; +import { HealthStatusModel, IndexResponseModel, PagedIndexResponseModel, SearchResultResponseModel } from '@umbraco-cms/backoffice/backend-api'; export function getIndexByName(indexName: string) { return Indexers.find((index) => { @@ -7,11 +7,11 @@ export function getIndexByName(indexName: string) { }); } -export function getSearchResultsMockData(): SearchResultModel[] { +export function getSearchResultsMockData(): SearchResultResponseModel[] { return searchResultMockData; } -export const Indexers: IndexModel[] = [ +export const Indexers: IndexResponseModel[] = [ { name: 'ExternalIndex', canRebuild: true, @@ -71,12 +71,12 @@ export const Indexers: IndexModel[] = [ }, ]; -export const PagedIndexers: PagedIndexModel = { +export const PagedIndexers: PagedIndexResponseModel = { items: Indexers, total: 0, }; -export const searchResultMockData: SearchResultModel[] = [ +export const searchResultMockData: SearchResultResponseModel[] = [ { id: '1', score: 1, diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/health-check.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/health-check.data.ts index ae7bfdac46..b21934a28f 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/health-check.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/health-check.data.ts @@ -1,8 +1,8 @@ import { - HealthCheckGroupModel, - HealthCheckGroupWithResultModel, + HealthCheckGroupPresentationModel, + HealthCheckGroupWithResultResponseModel, StatusResultTypeModel, -} from '@umbraco-cms/backend-api'; +} from '@umbraco-cms/backoffice/backend-api'; export function getGroupByName(name: string) { return healthGroupsWithoutResult.find((group) => group.name?.toLowerCase() == name.toLowerCase()); @@ -12,7 +12,7 @@ export function getGroupWithResultsByName(name: string) { return healthGroups.find((group) => group.name.toLowerCase() === name.toLowerCase()); } -export const healthGroups: Array = [ +export const healthGroups: Array = [ { name: 'Configuration', checks: [ @@ -25,7 +25,7 @@ export const healthGroups: Arrayyour@email.here.`, @@ -51,7 +51,7 @@ export const healthGroups: Array { - constructor(data: LanguageModel[]) { +class UmbLanguagesData extends UmbData { + constructor(data: LanguageResponseModel[]) { super(data); } // skip can be number or null - getAll(skip = 0, take = this.data.length): Array { + getAll(skip = 0, take = this.data.length): Array { return this.data.slice(skip, take); } - getByKey(key: string) { - return this.data.find((item) => item.isoCode === key); + getByKey(isoCode: string) { + return this.data.find((item) => item.isoCode === isoCode); } - insert(language: LanguageModel) { + insert(language: LanguageResponseModel) { const foundIndex = this.data.findIndex((item) => item.isoCode === language.isoCode); if (foundIndex !== -1) { @@ -26,7 +26,7 @@ class UmbLanguagesData extends UmbData { this.data.push(language); } - save(saveItems: Array) { + save(saveItems: Array) { saveItems.forEach((saveItem) => { const foundIndex = this.data.findIndex((item) => item.isoCode === saveItem.isoCode); if (foundIndex !== -1) { @@ -49,18 +49,18 @@ class UmbLanguagesData extends UmbData { return this.data; } - delete(keys: Array) { - keys.forEach((key) => { - const foundIndex = this.data.findIndex((item) => item.isoCode === key); + delete(isoCodes: Array) { + isoCodes.forEach((isoCode) => { + const foundIndex = this.data.findIndex((item) => item.isoCode === isoCode); if (foundIndex !== -1) { this.data.splice(foundIndex, 1); } }); - return keys; + return isoCodes; } - updateData(updateItem: LanguageModel) { + updateData(updateItem: LanguageResponseModel) { const itemIndex = this.data.findIndex((item) => item.isoCode === updateItem.isoCode); const item = this.data[itemIndex]; if (!item) return; @@ -91,7 +91,7 @@ class UmbLanguagesData extends UmbData { } } -export const MockData: Array = [ +export const MockData: Array = [ { name: 'English', isoCode: 'en', diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/log-viewer.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/log-viewer.data.ts index b74e755fa9..30ea41f140 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/log-viewer.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/log-viewer.data.ts @@ -1,15 +1,19 @@ import { logs } from './logs.data'; import { UmbData } from './data'; -import { LogMessageModel, LogTemplateModel, SavedLogSearchModel } from '@umbraco-cms/backend-api'; +import { + LogMessageResponseModel, + LogTemplateResponseModel, + SavedLogSearchResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; // Temp mocked database -class UmbLogviewerSearchesData extends UmbData { - constructor(data: SavedLogSearchModel[]) { +class UmbLogViewerSearchesData extends UmbData { + constructor(data: SavedLogSearchResponseModel[]) { super(data); } // skip can be number or null - getSavedSearches(skip = 0, take = this.data.length): Array { + getSavedSearches(skip = 0, take = this.data.length): Array { return this.data.slice(skip, take); } @@ -18,24 +22,24 @@ class UmbLogviewerSearchesData extends UmbData { } } -class UmbLogviewerTemplatesData extends UmbData { - constructor(data: LogTemplateModel[]) { +class UmbLogviewerTemplatesData extends UmbData { + constructor(data: LogTemplateResponseModel[]) { super(data); } // skip can be number or null - getTemplates(skip = 0, take = this.data.length): Array { + getTemplates(skip = 0, take = this.data.length): Array { return this.data.slice(skip, take); } } -class UmbLogviewerMessagesData extends UmbData { - constructor(data: LogTemplateModel[]) { +class UmbLogviewerMessagesData extends UmbData { + constructor(data: LogTemplateResponseModel[]) { super(data); } // skip can be number or null - getLogs(skip = 0, take = this.data.length): Array { + getLogs(skip = 0, take = this.data.length): Array { return this.data.slice(skip, take); } @@ -51,7 +55,7 @@ class UmbLogviewerMessagesData extends UmbData { } } -export const savedSearches: Array = [ +export const savedSearches: Array = [ { name: 'Find all logs where the Level is NOT Verbose and NOT Debug', query: "Not(@Level='Verbose') and Not(@Level='Debug')", @@ -98,7 +102,7 @@ export const savedSearches: Array = [ }, ]; -export const messageTemplates: LogTemplateModel[] = [ +export const messageTemplates: LogTemplateResponseModel[] = [ { messageTemplate: 'Create Foreign Key:\n {Sql}', count: 90, @@ -405,8 +409,8 @@ export const logLevels = { ], }; -export const umbLogviewerData = { - searches: new UmbLogviewerSearchesData(savedSearches), +export const umbLogViewerData = { + searches: new UmbLogViewerSearchesData(savedSearches), templates: new UmbLogviewerTemplatesData(messageTemplates), logs: new UmbLogviewerMessagesData(logs), logLevels: logLevels, diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/logs.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/logs.data.ts index 974ec00f50..9a38c6bb40 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/logs.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/logs.data.ts @@ -1,4 +1,4 @@ -import { LogLevelModel, LogMessageModel } from '@umbraco-cms/backend-api'; +import { LogLevelModel, LogMessageResponseModel } from '@umbraco-cms/backoffice/backend-api'; const allLogs = [ { @@ -7309,7 +7309,7 @@ const randomEnumValue = (enumeration: any): LogLevelModel => { return enumeration[enumKey]; }; -export const logs: LogMessageModel[] = allLogs.map((log) => { +export const logs: LogMessageResponseModel[] = allLogs.map((log) => { const randomLevel = randomEnumValue(LogLevelModel); diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/media-type.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/media-type.data.ts index e5189fbd01..601f5fc6c3 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/media-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/media-type.data.ts @@ -1,7 +1,7 @@ import { UmbEntityData } from './entity.data'; import { createFolderTreeItem } from './utils'; -import { FolderTreeItemModel, PagedFolderTreeItemModel } from '@umbraco-cms/backend-api'; -import type { MediaTypeDetails } from '@umbraco-cms/models'; +import { FolderTreeItemResponseModel, PagedFolderTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { MediaTypeDetails } from '@umbraco-cms/backoffice/models'; export const data: Array = [ { @@ -9,9 +9,9 @@ export const data: Array = [ name: 'Media Type 1', type: 'media-type', hasChildren: false, - key: 'c5159663-eb82-43ee-bd23-e42dc5e71db6', + id: 'c5159663-eb82-43ee-bd23-e42dc5e71db6', isContainer: false, - parentKey: null, + parentId: null, isFolder: false, icon: '', alias: 'mediaType1', @@ -22,9 +22,9 @@ export const data: Array = [ name: 'Media Type 2', type: 'media-type', hasChildren: false, - key: '22da1b0b-c310-4730-9912-c30b3eb9802e', + id: '22da1b0b-c310-4730-9912-c30b3eb9802e', isContainer: false, - parentKey: null, + parentId: null, isFolder: false, icon: '', alias: 'mediaType2', @@ -41,22 +41,22 @@ class UmbMediaTypeData extends UmbEntityData { super(data); } - getTreeRoot(): PagedFolderTreeItemModel { - const items = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): PagedFolderTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === null); const treeItems = items.map((item) => createFolderTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItemChildren(key: string): PagedFolderTreeItemModel { - const items = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): PagedFolderTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === id); const treeItems = items.map((item) => createFolderTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createFolderTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/media.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/media.data.ts index e77e6d2691..31a930b596 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/media.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/media.data.ts @@ -1,7 +1,7 @@ +import type { MediaDetails } from '../../../backoffice/media/media'; import { UmbEntityData } from './entity.data'; import { createContentTreeItem } from './utils'; -import { ContentTreeItemModel, PagedContentTreeItemModel } from '@umbraco-cms/backend-api'; -import type { MediaDetails } from '@umbraco-cms/models'; +import { ContentTreeItemResponseModel, PagedContentTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; export const data: Array = [ { @@ -10,9 +10,9 @@ export const data: Array = [ type: 'media', icon: 'picture', hasChildren: false, - key: 'f2f81a40-c989-4b6b-84e2-057cecd3adc1', + id: 'f2f81a40-c989-4b6b-84e2-057cecd3adc1', isContainer: false, - parentKey: null, + parentId: null, noAccess: false, isTrashed: false, properties: [ @@ -20,7 +20,7 @@ export const data: Array = [ alias: 'myMediaHeadline', label: 'Media Headline', description: 'Text string property', - dataTypeKey: 'dt-textBox', + dataTypeId: 'dt-textBox', }, ], data: [ @@ -37,9 +37,9 @@ export const data: Array = [ type: 'media', icon: 'picture', hasChildren: false, - key: '69431027-8867-45bf-a93b-72bbdabfb177', + id: '69431027-8867-45bf-a93b-72bbdabfb177', isContainer: false, - parentKey: null, + parentId: null, noAccess: false, isTrashed: false, properties: [ @@ -47,7 +47,7 @@ export const data: Array = [ alias: 'myMediaDescription', label: 'Description', description: 'Textarea property', - dataTypeKey: 'dt-textArea', + dataTypeId: 'dt-textArea', }, ], data: [ @@ -64,9 +64,9 @@ export const data: Array = [ type: 'media', icon: 'folder', hasChildren: true, - key: '69461027-8867-45bf-a93b-72bbdabfb177', + id: '69461027-8867-45bf-a93b-72bbdabfb177', isContainer: true, - parentKey: null, + parentId: null, noAccess: false, isTrashed: false, properties: [], @@ -79,9 +79,9 @@ export const data: Array = [ type: 'media', icon: 'folder', hasChildren: true, - key: '69461027-8867-45bf-a93b-5224dabfb177', + id: '69461027-8867-45bf-a93b-5224dabfb177', isContainer: true, - parentKey: null, + parentId: null, noAccess: false, isTrashed: false, properties: [], @@ -94,9 +94,9 @@ export const data: Array = [ type: 'media', icon: 'picture', hasChildren: false, - key: '69431027-8867-45s7-a93b-7uibdabfb177', + id: '69431027-8867-45s7-a93b-7uibdabfb177', isContainer: false, - parentKey: '69461027-8867-45bf-a93b-72bbdabfb177', + parentId: '69461027-8867-45bf-a93b-72bbdabfb177', noAccess: false, isTrashed: false, properties: [ @@ -104,7 +104,7 @@ export const data: Array = [ alias: 'myMediaDescription', label: 'Description', description: 'Textarea property', - dataTypeKey: 'dt-textArea', + dataTypeId: 'dt-textArea', }, ], data: [ @@ -121,9 +121,9 @@ export const data: Array = [ type: 'media', icon: 'picture', hasChildren: false, - key: '69431027-8867-45s7-a93b-7uibdabf2147', + id: '69431027-8867-45s7-a93b-7uibdabf2147', isContainer: false, - parentKey: '69461027-8867-45bf-a93b-72bbdabfb177', + parentId: '69461027-8867-45bf-a93b-72bbdabfb177', noAccess: false, isTrashed: false, properties: [ @@ -131,7 +131,7 @@ export const data: Array = [ alias: 'myMediaDescription', label: 'Description', description: 'Textarea property', - dataTypeKey: 'dt-textArea', + dataTypeId: 'dt-textArea', }, ], data: [ @@ -148,9 +148,9 @@ export const data: Array = [ type: 'media', icon: 'picture', hasChildren: false, - key: '694hdj27-8867-45s7-a93b-7uibdabf2147', + id: '694hdj27-8867-45s7-a93b-7uibdabf2147', isContainer: false, - parentKey: '69461027-8867-45bf-a93b-5224dabfb177', + parentId: '69461027-8867-45bf-a93b-5224dabfb177', noAccess: false, isTrashed: false, properties: [ @@ -158,7 +158,7 @@ export const data: Array = [ alias: 'myMediaDescription', label: 'Description', description: 'Textarea property', - dataTypeKey: 'dt-textArea', + dataTypeId: 'dt-textArea', }, ], data: [ @@ -175,9 +175,9 @@ export const data: Array = [ type: 'media', icon: 'picture', hasChildren: false, - key: '694hdj27-1237-45s7-a93b-7uibdabfas47', + id: '694hdj27-1237-45s7-a93b-7uibdabfas47', isContainer: false, - parentKey: '69461027-8867-45bf-a93b-5224dabfb177', + parentId: '69461027-8867-45bf-a93b-5224dabfb177', noAccess: false, isTrashed: false, properties: [ @@ -185,7 +185,7 @@ export const data: Array = [ alias: 'myMediaDescription', label: 'Description', description: 'Textarea property', - dataTypeKey: 'dt-textArea', + dataTypeId: 'dt-textArea', }, ], data: [ @@ -207,22 +207,22 @@ class UmbMediaData extends UmbEntityData { super(data); } - getTreeRoot(): PagedContentTreeItemModel { - const items = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): PagedContentTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === null); const treeItems = items.map((item) => createContentTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItemChildren(key: string): PagedContentTreeItemModel { - const items = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): PagedContentTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === id); const treeItems = items.map((item) => createContentTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key)); + getTreeItem(ids: Array): Array { + const items = this.data.filter((item) => ids.includes(item.id)); return items.map((item) => createContentTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-group.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-group.data.ts index 5e88700348..db2d57d5e7 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-group.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-group.data.ts @@ -1,7 +1,7 @@ import { UmbEntityData } from './entity.data'; import { createEntityTreeItem } from './utils'; -import type { MemberGroupDetails } from '@umbraco-cms/models'; -import { EntityTreeItemModel, PagedEntityTreeItemModel } from '@umbraco-cms/backend-api'; +import type { MemberGroupDetails } from '@umbraco-cms/backoffice/models'; +import { EntityTreeItemResponseModel, PagedEntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; export const data: Array = [ { @@ -10,9 +10,9 @@ export const data: Array = [ type: 'member-group', icon: 'umb:document', hasChildren: false, - key: '76708ccd-4179-464c-b694-6969149dd9f9', + id: '76708ccd-4179-464c-b694-6969149dd9f9', isContainer: false, - parentKey: null, + parentId: null, }, ]; @@ -25,22 +25,22 @@ class UmbMemberGroupData extends UmbEntityData { super(data); } - getTreeRoot(): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === null); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItemChildren(key: string): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === id); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createEntityTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts index 5220847f6b..7200916cb4 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member-type.data.ts @@ -1,7 +1,7 @@ import { UmbData } from './data'; import { createEntityTreeItem } from './utils'; -import { EntityTreeItemModel, PagedEntityTreeItemModel } from '@umbraco-cms/backend-api'; -import type { MemberTypeDetails } from '@umbraco-cms/models'; +import { EntityTreeItemResponseModel, PagedEntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import type { MemberTypeDetails } from '@umbraco-cms/backoffice/models'; export const data: Array = [ { @@ -10,9 +10,9 @@ export const data: Array = [ type: 'member-type', icon: 'icon-user', hasChildren: false, - key: 'd59be02f-1df9-4228-aa1e-01917d806cda', + id: 'd59be02f-1df9-4228-aa1e-01917d806cda', isContainer: false, - parentKey: null, + parentId: null, alias: 'memberType1', properties: [], }, @@ -24,22 +24,22 @@ class UmbMemberTypeData extends UmbData { super(data); } - getTreeRoot(): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === null); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItemChildren(key: string): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === id); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createEntityTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member.data.ts index 2a77411e27..75faed9860 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/member.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/member.data.ts @@ -1,7 +1,10 @@ import { UmbEntityData } from './entity.data'; import { createEntityTreeItem } from './utils'; -import type { MemberDetails } from '@umbraco-cms/models'; -import type { EntityTreeItemModel, PagedEntityTreeItemModel } from '@umbraco-cms/backend-api'; +import type { MemberDetails } from '@umbraco-cms/backoffice/models'; +import type { + EntityTreeItemResponseModel, + PagedEntityTreeItemResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; export const data: Array = [ { @@ -10,9 +13,9 @@ export const data: Array = [ type: 'member', icon: 'umb:user', hasChildren: false, - key: 'aaa08ccd-4179-464c-b634-6969149dd9f9', + id: 'aaa08ccd-4179-464c-b634-6969149dd9f9', isContainer: false, - parentKey: null, + parentId: null, }, ]; @@ -25,22 +28,22 @@ class UmbMemberData extends UmbEntityData { super(data); } - getTreeRoot(): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === null); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItemChildren(key: string): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === id); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createEntityTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/relation-type.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/relation-type.data.ts new file mode 100644 index 0000000000..c39f9dc2e4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/relation-type.data.ts @@ -0,0 +1,150 @@ +import { UmbEntityData } from './entity.data'; +import { createEntityTreeItem } from './utils'; +import type { EntityTreeItemResponseModel, RelationTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +// TODO: investigate why we don't get an entity type as part of the RelationTypeResponseModel +export const data: Array = [ + { + id: 'e0d39ff5-71d8-453f-b682-9d8d31ee5e06', + alias: 'relateDocumentOnCopy', + name: 'Relate Document On Copy', + path: '', + isSystemRelationType: true, + isBidirectional: false, + isDependency: false, + parentObjectType: 'Document', + childObjectType: 'Document', + parentObjectTypeName: 'Document', + childObjectTypeName: 'Document', + }, + { + id: 'ac68cde6-763f-4231-a751-1101b57defd2', + alias: 'relateParentDocumentOnDelete', + name: 'Relate Parent Document On Delete', + path: '', + isSystemRelationType: true, + isBidirectional: false, + isDependency: false, + parentObjectType: 'Document', + childObjectType: 'Document', + parentObjectTypeName: 'Document', + childObjectTypeName: 'Document', + }, + { + id: '6f9b800c-762c-42d4-85d9-bf40a77d689e', + alias: 'relateParentMediaFolderOnDelete', + name: 'Relate Parent Media Folder On Delete', + path: '', + isSystemRelationType: true, + isBidirectional: false, + isDependency: false, + parentObjectType: 'Document', + childObjectType: 'Document', + parentObjectTypeName: 'Document', + childObjectTypeName: 'Document', + }, + { + id: 'd421727d-43de-4205-b4c6-037404f309ad', + alias: 'relatedMedia', + name: 'Related Media', + path: '', + isSystemRelationType: true, + isBidirectional: false, + isDependency: false, + parentObjectType: 'Document', + childObjectType: 'Document', + parentObjectTypeName: 'Document', + childObjectTypeName: 'Document', + }, + { + id: 'e9a0a28e-2d5b-4229-ac00-66f2df230513', + alias: 'relatedDocument', + name: 'Related Document', + path: '', + isSystemRelationType: true, + isBidirectional: false, + isDependency: false, + parentObjectType: 'Document', + childObjectType: 'Document', + parentObjectTypeName: 'Document', + childObjectTypeName: 'Document', + }, +]; + +export const treeData: Array = [ + { + id: 'e0d39ff5-71d8-453f-b682-9d8d31ee5e06', + $type: 'EntityTreeItemViewModel', + isContainer: false, + parentId: null, + name: 'Relate Document On Copy', + icon: 'umb:trafic', + type: 'relation-type', + }, + { + id: 'ac68cde6-763f-4231-a751-1101b57defd2', + $type: 'EntityTreeItemViewModel', + isContainer: false, + parentId: null, + name: 'Relate Parent Document On Delete', + icon: 'umb:trafic', + type: 'relation-type', + }, + { + id: '6f9b800c-762c-42d4-85d9-bf40a77d689e', + $type: 'EntityTreeItemViewModel', + isContainer: false, + parentId: null, + name: 'Relate Parent Media Folder On Delete', + icon: 'umb:trafic', + type: 'relation-type', + }, + { + id: 'd421727d-43de-4205-b4c6-037404f309ad', + $type: 'EntityTreeItemViewModel', + isContainer: false, + parentId: null, + name: 'Related Media', + icon: 'umb:trafic', + type: 'relation-type', + }, + { + id: 'e9a0a28e-2d5b-4229-ac00-66f2df230513', + $type: 'EntityTreeItemViewModel', + isContainer: false, + parentId: null, + name: 'Related Document', + icon: 'umb:trafic', + type: 'relation-type', + }, +]; + +// Temp mocked database +// TODO: all properties are optional in the server schema. I don't think this is correct. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +class UmbRelationTypeData extends UmbEntityData { + private treeData = treeData; + constructor() { + super(data); + } + + //TODO Can relation types have children? + getTreeRoot(): Array { + const rootItems = this.treeData; + return rootItems.map((item) => createEntityTreeItem(item)); + } + + //TODO Can relation types have children? + getTreeItemChildren(id: string): Array { + const childItems = this.treeData.filter((item) => item.parentId === id); + return childItems.map((item) => createEntityTreeItem(item)); + } + + getTreeItem(ids: Array): Array { + const items = this.treeData.filter((item) => ids.includes(item.id ?? '')); + return items.map((item) => createEntityTreeItem(item)); + } +} + +export const umbRelationTypeData = new UmbRelationTypeData(); diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/stylesheet.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/stylesheet.data.ts new file mode 100644 index 0000000000..f73ee09968 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/stylesheet.data.ts @@ -0,0 +1,80 @@ +import { UmbEntityData } from './entity.data'; +import { createFileSystemTreeItem } from './utils'; +import { + FileSystemTreeItemPresentationModel, + PagedFileSystemTreeItemPresentationModel, +} from '@umbraco-cms/backoffice/backend-api'; + +type StylesheetDBItem = FileSystemTreeItemPresentationModel & { + content: string; +}; + +export const data: Array = [ + { + path: 'Stylesheet File 1.css', + isFolder: false, + name: 'Stylesheet File 1.css', + type: 'stylesheet', + icon: 'umb:brackets', + hasChildren: false, + content: `Stylesheet content 1`, + }, + { + path: 'Stylesheet File 2.css', + isFolder: false, + name: 'Stylesheet File 2.css', + type: 'stylesheet', + icon: 'umb:brackets', + hasChildren: false, + content: `Stylesheet content 2`, + }, + { + path: 'Folder 1', + isFolder: true, + name: 'Folder 1', + type: 'stylesheet', + icon: 'umb:folder', + hasChildren: true, + content: `Stylesheet content 3`, + }, + { + path: 'Folder 1/Stylesheet File 3.css', + isFolder: false, + name: 'Stylesheet File 3.css', + type: 'stylesheet', + icon: 'umb:brackets', + hasChildren: false, + content: `Stylesheet content 3`, + }, +]; + +// Temp mocked database +// TODO: all properties are optional in the server schema. I don't think this is correct. +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +class UmbStylesheetData extends UmbEntityData { + constructor() { + super(data); + } + + getTreeRoot(): PagedFileSystemTreeItemPresentationModel { + const items = this.data.filter((item) => item.path?.includes('/') === false); + const treeItems = items.map((item) => createFileSystemTreeItem(item)); + const total = items.length; + return { items: treeItems, total }; + } + + getTreeItemChildren(parentPath: string): PagedFileSystemTreeItemPresentationModel { + const items = this.data.filter((item) => item.path?.startsWith(parentPath + '/')); + const treeItems = items.map((item) => createFileSystemTreeItem(item)); + const total = items.length; + return { items: treeItems, total }; + } + + getTreeItem(paths: Array): Array { + const items = this.data.filter((item) => paths.includes(item.path ?? '')); + return items.map((item) => createFileSystemTreeItem(item)); + } +} + +export const umbStylesheetData = new UmbStylesheetData(); diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/template.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/template.data.ts index e7ad3d0c8c..70a5fc11f8 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/template.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/template.data.ts @@ -2,19 +2,19 @@ import { v4 as uuid } from 'uuid'; import { UmbEntityData } from './entity.data'; import { createEntityTreeItem } from './utils'; import { - EntityTreeItemModel, - PagedEntityTreeItemModel, - TemplateModel, - TemplateCreateModel, - TemplateScaffoldModel, -} from '@umbraco-cms/backend-api'; + EntityTreeItemResponseModel, + PagedEntityTreeItemResponseModel, + TemplateResponseModel, + TemplateModelBaseModel, + TemplateScaffoldResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; -type TemplateDBItem = TemplateModel & EntityTreeItemModel; +type TemplateDBItem = TemplateResponseModel & EntityTreeItemResponseModel; -const createTemplate = (dbItem: TemplateDBItem): TemplateModel => { +const createTemplate = (dbItem: TemplateDBItem): TemplateResponseModel => { return { $type: '', - key: dbItem.key, + id: dbItem.id, name: dbItem.name, alias: dbItem.alias, content: dbItem.content, @@ -24,22 +24,33 @@ const createTemplate = (dbItem: TemplateDBItem): TemplateModel => { export const data: Array = [ { $type: '', - key: '2bf464b6-3aca-4388-b043-4eb439cc2643', + id: '2bf464b6-3aca-4388-b043-4eb439cc2643', isContainer: false, - parentKey: null, + parentId: null, name: 'Doc 1', type: 'template', icon: 'icon-layout', hasChildren: false, alias: 'Doc1', - content: - '@using Umbraco.Cms.Web.Common.PublishedModels;\n@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage\r\n@using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;\r\n@{\r\n\tLayout = null;\r\n}', + content: `@using Umbraco.Extensions + @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage + @{ + if (Model?.Areas.Any() != true) { return; } + } + +
    + @foreach (var area in Model.Areas) + { + @await Html.GetBlockGridItemAreaHtmlAsync(area) + } +
    `, }, { $type: '', - key: '9a84c0b3-03b4-4dd4-84ac-706740ac0f71', + id: '9a84c0b3-03b4-4dd4-84ac-706740ac0f71', isContainer: false, - parentKey: null, + parentId: null, name: 'Test', type: 'template', icon: 'icon-layout', @@ -50,9 +61,9 @@ export const data: Array = [ }, { $type: '', - key: '9a84c0b3-03b4-4dd4-84ac-706740ac0f72', + id: '9a84c0b3-03b4-4dd4-84ac-706740ac0f72', isContainer: false, - parentKey: '9a84c0b3-03b4-4dd4-84ac-706740ac0f71', + parentId: '9a84c0b3-03b4-4dd4-84ac-706740ac0f71', name: 'Child', type: 'template', icon: 'icon-layout', @@ -76,48 +87,48 @@ class UmbTemplateData extends UmbEntityData { super(data); } - getByKey(key: string): TemplateModel | undefined { - const item = this.data.find((item) => item.key === key); + getById(id: string): TemplateResponseModel | undefined { + const item = this.data.find((item) => item.id === id); return item ? createTemplate(item) : undefined; } - getScaffold(masterTemplateAlias: string): TemplateScaffoldModel { + getScaffold(masterTemplateAlias: string): TemplateScaffoldResponseModel { return { content: `Template Scaffold Mock: Layout = ${masterTemplateAlias || null};`, }; } - create(templateData: TemplateCreateModel) { + create(templateData: TemplateModelBaseModel) { const template = { $type: '', - key: uuid(), + id: uuid(), ...templateData, }; this.data.push(template); return template; } - update(template: TemplateModel) { + update(template: TemplateResponseModel) { this.updateData(template); return template; } - getTreeRoot(): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === null); + getTreeRoot(): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === null); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItemChildren(key: string): PagedEntityTreeItemModel { - const items = this.data.filter((item) => item.parentKey === key); + getTreeItemChildren(id: string): PagedEntityTreeItemResponseModel { + const items = this.data.filter((item) => item.parentId === id); const treeItems = items.map((item) => createEntityTreeItem(item)); const total = items.length; return { items: treeItems, total }; } - getTreeItem(keys: Array): Array { - const items = this.data.filter((item) => keys.includes(item.key ?? '')); + getTreeItem(ids: Array): Array { + const items = this.data.filter((item) => ids.includes(item.id ?? '')); return items.map((item) => createEntityTreeItem(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/user-groups.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/user-groups.data.ts index 2c62dbae2c..3c4b99b1ca 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/user-groups.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/user-groups.data.ts @@ -1,5 +1,5 @@ import { UmbEntityData } from './entity.data'; -import type { UserGroupDetails } from '@umbraco-cms/models'; +import type { UserGroupDetails } from '@umbraco-cms/backoffice/models'; // Temp mocked database class UmbUserGroupsData extends UmbEntityData { @@ -14,10 +14,10 @@ class UmbUserGroupsData extends UmbEntityData { export const data: Array = [ { - key: 'c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', + id: 'c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', name: 'Administrators', icon: 'umb:medal', - parentKey: '', + parentId: '', type: 'user-group', hasChildren: false, sections: [ @@ -31,10 +31,10 @@ export const data: Array = [ permissions: [], }, { - key: '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949', + id: '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949', name: 'Workspaces', icon: 'umb:tools', - parentKey: '', + parentId: '', type: 'user-group', hasChildren: false, sections: ['Umb.Section.Members', 'Umb.Section.Media'], @@ -42,10 +42,10 @@ export const data: Array = [ contentStartNode: '74e4008a-ea4f-4793-b924-15e02fd380d1', }, { - key: 'b847398a-6875-4d7a-9f6d-231256b81471', + id: 'b847398a-6875-4d7a-9f6d-231256b81471', name: 'Sensitive Data', icon: 'umb:lock', - parentKey: '', + parentId: '', type: 'user-group', hasChildren: false, sections: ['Umb.Section.Settings', 'Umb.Section.Members', 'Umb.Section.Media', 'Umb.Section.Content'], @@ -53,10 +53,10 @@ export const data: Array = [ contentStartNode: 'cdd30288-2d1c-41b4-89a9-61647b4a10d5', }, { - key: '2668f09b-320c-48a7-a78a-95047026ec0e', + id: '2668f09b-320c-48a7-a78a-95047026ec0e', name: 'Translators', icon: 'umb:globe', - parentKey: '', + parentId: '', type: 'user-group', hasChildren: false, sections: ['Umb.Section.Packages', 'Umb.Section.Settings'], @@ -64,10 +64,10 @@ export const data: Array = [ contentStartNode: 'cdd30288-2d1c-41b4-89a9-61647b4a10d5', }, { - key: '397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', + id: '397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', name: 'Writers', icon: 'umb:edit', - parentKey: '', + parentId: '', type: 'user-group', hasChildren: false, sections: ['Umb.Section.Content'], diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts index 2ac21363a2..740b6a1957 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/users.data.ts @@ -1,5 +1,5 @@ import { UmbEntityData } from './entity.data'; -import type { UserDetails } from '@umbraco-cms/models'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; // Temp mocked database class UmbUsersData extends UmbEntityData { @@ -11,9 +11,9 @@ class UmbUsersData extends UmbEntityData { return this.data; } - updateUserGroup(keys: string[], userGroup: string) { + updateUserGroup(ids: string[], userGroup: string) { this.data.forEach((user) => { - if (keys.includes(user.key)) { + if (ids.includes(user.id)) { user.userGroups = [...user.userGroups, userGroup]; } else { user.userGroups = user.userGroups.filter((group) => group !== userGroup); @@ -22,34 +22,34 @@ class UmbUsersData extends UmbEntityData { this.updateData(user); }); - return this.data.map((user) => user.key); + return this.data.map((user) => user.id); } - enable(keys: string[]) { - const users = this.data.filter((user) => keys.includes(user.key)); + enable(ids: string[]) { + const users = this.data.filter((user) => ids.includes(user.id)); users.forEach((user) => { user.status = 'enabled'; this.updateData(user); }); - return users.map((user) => user.key); + return users.map((user) => user.id); } - disable(keys: string[]) { - const users = this.data.filter((user) => keys.includes(user.key)); + disable(ids: string[]) { + const users = this.data.filter((user) => ids.includes(user.id)); users.forEach((user) => { user.status = 'disabled'; this.updateData(user); }); - return users.map((user) => user.key); + return users.map((user) => user.id); } } export const data: Array = [ { - key: 'a953e376-89f8-46d1-bed9-1b47743aa38a', + id: 'a953e376-89f8-46d1-bed9-1b47743aa38a', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -66,10 +66,10 @@ export const data: Array = [ userGroups: ['397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', 'c630d49e-4e7b-42ea-b2bc-edc0edacb6b1'], }, { - key: 'bca6c733-a63d-4353-a271-9a8b6bcca8bd', + id: 'bca6c733-a63d-4353-a271-9a8b6bcca8bd', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -90,10 +90,10 @@ export const data: Array = [ ], }, { - key: '9f63996f-71e9-49be-bc21-5a69ea97e72e', + id: '9f63996f-71e9-49be-bc21-5a69ea97e72e', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -114,10 +114,10 @@ export const data: Array = [ ], }, { - key: 'ff1d1bff-b6d2-444b-950a-68b5eec46277', + id: 'ff1d1bff-b6d2-444b-950a-68b5eec46277', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -138,10 +138,10 @@ export const data: Array = [ ], }, { - key: 'c9cf849f-0536-4e38-a91a-02c8c45a6f47', + id: 'c9cf849f-0536-4e38-a91a-02c8c45a6f47', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -158,10 +158,10 @@ export const data: Array = [ userGroups: ['b847398a-6875-4d7a-9f6d-231256b81471', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: 'd9cbd4cd-6950-42b2-be57-1f5829c6dd19', + id: 'd9cbd4cd-6950-42b2-be57-1f5829c6dd19', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -178,10 +178,10 @@ export const data: Array = [ userGroups: ['397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: '515b2c5c-c195-43f2-8e52-4733572030c7', + id: '515b2c5c-c195-43f2-8e52-4733572030c7', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -204,10 +204,10 @@ export const data: Array = [ ], }, { - key: 'db8a0800-28b3-4f0b-9152-37debea6b8d7', + id: 'db8a0800-28b3-4f0b-9152-37debea6b8d7', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -228,10 +228,10 @@ export const data: Array = [ ], }, { - key: '3fe38c9b-b5a3-4897-8507-3f062a25659e', + id: '3fe38c9b-b5a3-4897-8507-3f062a25659e', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -248,10 +248,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: '09e99152-bc3e-449f-9fa1-322ab3390b7d', + id: '09e99152-bc3e-449f-9fa1-322ab3390b7d', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -272,10 +272,10 @@ export const data: Array = [ ], }, { - key: '5680bd61-9b58-4ecb-ae06-bdfacebe05f2', + id: '5680bd61-9b58-4ecb-ae06-bdfacebe05f2', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -292,10 +292,10 @@ export const data: Array = [ userGroups: ['397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', 'c630d49e-4e7b-42ea-b2bc-edc0edacb6b1'], }, { - key: '1c2cb6b5-1b96-47c0-a2b7-f5dd6bd3d325', + id: '1c2cb6b5-1b96-47c0-a2b7-f5dd6bd3d325', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -316,10 +316,10 @@ export const data: Array = [ ], }, { - key: 'ac6cc4e4-ab38-4920-8646-63c7652fc97a', + id: 'ac6cc4e4-ab38-4920-8646-63c7652fc97a', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -336,10 +336,10 @@ export const data: Array = [ userGroups: ['b847398a-6875-4d7a-9f6d-231256b81471', '2668f09b-320c-48a7-a78a-95047026ec0e'], }, { - key: 'a5e5bbe4-acb4-4c40-b15a-eab510338620', + id: 'a5e5bbe4-acb4-4c40-b15a-eab510338620', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -360,10 +360,10 @@ export const data: Array = [ ], }, { - key: 'c775af23-4aec-4d24-a2d1-5b0d666c9eb4', + id: 'c775af23-4aec-4d24-a2d1-5b0d666c9eb4', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -384,10 +384,10 @@ export const data: Array = [ ], }, { - key: '3333e2dc-b8a6-4db3-af00-ac1c1e1d5d9c', + id: '3333e2dc-b8a6-4db3-af00-ac1c1e1d5d9c', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -404,10 +404,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: '506126e3-2b96-4746-bd0a-1e6b2283021f', + id: '506126e3-2b96-4746-bd0a-1e6b2283021f', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -424,10 +424,10 @@ export const data: Array = [ userGroups: ['9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: 'caf10593-3710-4417-af3d-7015f88f5fe3', + id: 'caf10593-3710-4417-af3d-7015f88f5fe3', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -448,10 +448,10 @@ export const data: Array = [ ], }, { - key: 'e2492eeb-bcc2-4c95-8893-27c45c895c9c', + id: 'e2492eeb-bcc2-4c95-8893-27c45c895c9c', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -473,10 +473,10 @@ export const data: Array = [ ], }, { - key: '8c93b359-a719-4453-991c-e2d5bcc965c3', + id: '8c93b359-a719-4453-991c-e2d5bcc965c3', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -497,10 +497,10 @@ export const data: Array = [ ], }, { - key: '4cd22c7c-baeb-463f-89e5-e0a6bb3ea27e', + id: '4cd22c7c-baeb-463f-89e5-e0a6bb3ea27e', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -521,10 +521,10 @@ export const data: Array = [ ], }, { - key: 'ccd03e29-e924-4240-a1e4-b0114c66aae9', + id: 'ccd03e29-e924-4240-a1e4-b0114c66aae9', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -547,10 +547,10 @@ export const data: Array = [ ], }, { - key: '7ffa97ca-0702-4bcf-8e32-751bae9aa156', + id: '7ffa97ca-0702-4bcf-8e32-751bae9aa156', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -571,10 +571,10 @@ export const data: Array = [ ], }, { - key: 'e139ec4b-b49a-48c0-a1a3-1c2e8e95366d', + id: 'e139ec4b-b49a-48c0-a1a3-1c2e8e95366d', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -595,10 +595,10 @@ export const data: Array = [ ], }, { - key: '30d29d56-cbb2-41fd-9154-94b0f0d9a385', + id: '30d29d56-cbb2-41fd-9154-94b0f0d9a385', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -619,10 +619,10 @@ export const data: Array = [ ], }, { - key: '3ecac483-c4df-4971-a357-a0be03c520ca', + id: '3ecac483-c4df-4971-a357-a0be03c520ca', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -639,10 +639,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', '2668f09b-320c-48a7-a78a-95047026ec0e'], }, { - key: '2dae8bf8-5fdd-4efa-a493-cbec11b179e2', + id: '2dae8bf8-5fdd-4efa-a493-cbec11b179e2', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -663,10 +663,10 @@ export const data: Array = [ ], }, { - key: '0397dd89-72c5-4d0b-a544-dc1c9c0a932d', + id: '0397dd89-72c5-4d0b-a544-dc1c9c0a932d', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -688,10 +688,10 @@ export const data: Array = [ ], }, { - key: '4f2f64c1-1b9b-4217-80c7-7760962215af', + id: '4f2f64c1-1b9b-4217-80c7-7760962215af', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -713,10 +713,10 @@ export const data: Array = [ ], }, { - key: '6cefa1e1-4302-4003-81df-3fa4759245a4', + id: '6cefa1e1-4302-4003-81df-3fa4759245a4', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -738,10 +738,10 @@ export const data: Array = [ ], }, { - key: '2ba9ae27-7860-42ea-b628-c5484b64b2c6', + id: '2ba9ae27-7860-42ea-b628-c5484b64b2c6', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -758,10 +758,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: 'f4bee7c8-7a94-4937-8e6e-ceb55c9ec8b4', + id: 'f4bee7c8-7a94-4937-8e6e-ceb55c9ec8b4', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -778,10 +778,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: '3ccfeec3-1c96-4205-ae90-3297702d0d59', + id: '3ccfeec3-1c96-4205-ae90-3297702d0d59', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -802,10 +802,10 @@ export const data: Array = [ ], }, { - key: 'cb0e3a46-1e99-4dc3-a206-462c3d985916', + id: 'cb0e3a46-1e99-4dc3-a206-462c3d985916', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -826,10 +826,10 @@ export const data: Array = [ ], }, { - key: 'eb5af046-f2af-490f-a195-b0faff73f538', + id: 'eb5af046-f2af-490f-a195-b0faff73f538', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -846,10 +846,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', '397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2'], }, { - key: '42037971-4e06-41a8-be76-04313571fe54', + id: '42037971-4e06-41a8-be76-04313571fe54', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -866,10 +866,10 @@ export const data: Array = [ userGroups: ['2668f09b-320c-48a7-a78a-95047026ec0e', '397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2'], }, { - key: 'd71ba775-2920-42de-b5a1-09104e81cf27', + id: 'd71ba775-2920-42de-b5a1-09104e81cf27', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -892,10 +892,10 @@ export const data: Array = [ ], }, { - key: 'ed94e56b-64d5-43d0-9c9c-7149a0b26657', + id: 'ed94e56b-64d5-43d0-9c9c-7149a0b26657', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -916,10 +916,10 @@ export const data: Array = [ ], }, { - key: '8acfe50e-2e15-460d-b368-0510d08fea4c', + id: '8acfe50e-2e15-460d-b368-0510d08fea4c', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -941,10 +941,10 @@ export const data: Array = [ ], }, { - key: '73401c00-3b05-465b-ab59-8def5af4ec54', + id: '73401c00-3b05-465b-ab59-8def5af4ec54', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -965,10 +965,10 @@ export const data: Array = [ ], }, { - key: 'ffed1abb-aee0-45f1-9915-5ea7da165011', + id: 'ffed1abb-aee0-45f1-9915-5ea7da165011', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -989,10 +989,10 @@ export const data: Array = [ ], }, { - key: '754fafb2-ec86-4313-8c5a-26a0a460df70', + id: '754fafb2-ec86-4313-8c5a-26a0a460df70', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1013,10 +1013,10 @@ export const data: Array = [ ], }, { - key: 'eae3c035-1b9d-4d1d-b626-89a7c3b3bc39', + id: 'eae3c035-1b9d-4d1d-b626-89a7c3b3bc39', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1037,10 +1037,10 @@ export const data: Array = [ ], }, { - key: '4bbf5669-99ec-4e60-b159-2198990ee8f1', + id: '4bbf5669-99ec-4e60-b159-2198990ee8f1', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1057,10 +1057,10 @@ export const data: Array = [ userGroups: ['397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: 'bc17c986-9869-49f4-baee-d888bf013f27', + id: 'bc17c986-9869-49f4-baee-d888bf013f27', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1082,10 +1082,10 @@ export const data: Array = [ ], }, { - key: 'f015b8a7-35b7-4859-a506-253ee95f92f4', + id: 'f015b8a7-35b7-4859-a506-253ee95f92f4', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1107,10 +1107,10 @@ export const data: Array = [ ], }, { - key: 'b5fd8d4f-eecc-4bea-b841-b4ba3621e8ba', + id: 'b5fd8d4f-eecc-4bea-b841-b4ba3621e8ba', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1131,10 +1131,10 @@ export const data: Array = [ ], }, { - key: '0bfe956a-5293-48bf-8c43-fd9be5c8dd19', + id: '0bfe956a-5293-48bf-8c43-fd9be5c8dd19', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1155,10 +1155,10 @@ export const data: Array = [ ], }, { - key: 'f2914aaa-de0a-4285-b820-88d22ae7a566', + id: 'f2914aaa-de0a-4285-b820-88d22ae7a566', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1179,10 +1179,10 @@ export const data: Array = [ ], }, { - key: 'f5489ee0-589d-47e5-8c11-b5e2ef027519', + id: 'f5489ee0-589d-47e5-8c11-b5e2ef027519', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1203,10 +1203,10 @@ export const data: Array = [ ], }, { - key: '293074af-8188-4151-b025-2b43f6aa6c2c', + id: '293074af-8188-4151-b025-2b43f6aa6c2c', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1223,10 +1223,10 @@ export const data: Array = [ userGroups: ['2668f09b-320c-48a7-a78a-95047026ec0e', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: '93765192-b40f-4bf2-8c06-1d5ffb6989ae', + id: '93765192-b40f-4bf2-8c06-1d5ffb6989ae', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1243,10 +1243,10 @@ export const data: Array = [ userGroups: ['397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: '59f1023c-7ce6-4c78-a1ee-dcb4625b9281', + id: '59f1023c-7ce6-4c78-a1ee-dcb4625b9281', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1263,10 +1263,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', '397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2'], }, { - key: '42592a81-f584-4b77-b312-b8e268203c22', + id: '42592a81-f584-4b77-b312-b8e268203c22', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1283,10 +1283,10 @@ export const data: Array = [ userGroups: ['397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', '2668f09b-320c-48a7-a78a-95047026ec0e'], }, { - key: '8ad78a84-8183-4833-9f8b-07b3ea8a881c', + id: '8ad78a84-8183-4833-9f8b-07b3ea8a881c', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1307,10 +1307,10 @@ export const data: Array = [ ], }, { - key: '3f7bc8b5-df8b-4a79-a8bf-f379c63b8d01', + id: '3f7bc8b5-df8b-4a79-a8bf-f379c63b8d01', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1331,10 +1331,10 @@ export const data: Array = [ ], }, { - key: '09901602-688a-4c83-a977-51c16950a2c1', + id: '09901602-688a-4c83-a977-51c16950a2c1', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1355,10 +1355,10 @@ export const data: Array = [ ], }, { - key: '060972c7-9b23-4788-8dc3-c2fcec1d002e', + id: '060972c7-9b23-4788-8dc3-c2fcec1d002e', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1379,10 +1379,10 @@ export const data: Array = [ ], }, { - key: 'ccf7639c-09d9-4de6-88ec-be51be7f9d69', + id: 'ccf7639c-09d9-4de6-88ec-be51be7f9d69', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1403,10 +1403,10 @@ export const data: Array = [ ], }, { - key: '2c6b24a4-c0d2-4efe-8a09-68b61d2a17ef', + id: '2c6b24a4-c0d2-4efe-8a09-68b61d2a17ef', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1427,10 +1427,10 @@ export const data: Array = [ ], }, { - key: 'ff7a2003-f8d7-4fbc-96cb-ee221bdc01c9', + id: 'ff7a2003-f8d7-4fbc-96cb-ee221bdc01c9', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1447,10 +1447,10 @@ export const data: Array = [ userGroups: ['2668f09b-320c-48a7-a78a-95047026ec0e', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: 'b7f7b275-f62d-44ba-a6b0-0e7e83fe4e49', + id: 'b7f7b275-f62d-44ba-a6b0-0e7e83fe4e49', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1471,10 +1471,10 @@ export const data: Array = [ ], }, { - key: '18a9a6bc-ae4c-49b0-8afd-43bc214053f4', + id: '18a9a6bc-ae4c-49b0-8afd-43bc214053f4', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1495,10 +1495,10 @@ export const data: Array = [ ], }, { - key: '14fa1c36-1252-433e-a1ad-63cf5c9aba62', + id: '14fa1c36-1252-433e-a1ad-63cf5c9aba62', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1521,10 +1521,10 @@ export const data: Array = [ ], }, { - key: '7cb9327f-6aeb-47af-80b3-4b85abde1f5f', + id: '7cb9327f-6aeb-47af-80b3-4b85abde1f5f', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1545,10 +1545,10 @@ export const data: Array = [ ], }, { - key: '0574e903-ba72-49ee-b838-4eb200e68612', + id: '0574e903-ba72-49ee-b838-4eb200e68612', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1570,10 +1570,10 @@ export const data: Array = [ ], }, { - key: '6e4515d6-4a67-4f47-8783-1d074c1d1f75', + id: '6e4515d6-4a67-4f47-8783-1d074c1d1f75', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1594,10 +1594,10 @@ export const data: Array = [ ], }, { - key: '4faa2064-6776-4cc0-8bc1-3ceaa5884a0f', + id: '4faa2064-6776-4cc0-8bc1-3ceaa5884a0f', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1614,10 +1614,10 @@ export const data: Array = [ userGroups: ['b847398a-6875-4d7a-9f6d-231256b81471', '2668f09b-320c-48a7-a78a-95047026ec0e'], }, { - key: '0cccec0d-d7c4-47bc-97b0-bd55dca42dd7', + id: '0cccec0d-d7c4-47bc-97b0-bd55dca42dd7', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1639,10 +1639,10 @@ export const data: Array = [ ], }, { - key: 'd6ffe266-f024-45c2-a1cd-f39bdbc00a5b', + id: 'd6ffe266-f024-45c2-a1cd-f39bdbc00a5b', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1663,10 +1663,10 @@ export const data: Array = [ ], }, { - key: '72d3047a-8c48-4425-ad11-a4a64281e7e5', + id: '72d3047a-8c48-4425-ad11-a4a64281e7e5', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1687,10 +1687,10 @@ export const data: Array = [ ], }, { - key: 'ebfe0335-6926-433d-90de-82f9661955f9', + id: 'ebfe0335-6926-433d-90de-82f9661955f9', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1711,10 +1711,10 @@ export const data: Array = [ ], }, { - key: 'e6e833fb-a872-4364-893c-b6bfc9802043', + id: 'e6e833fb-a872-4364-893c-b6bfc9802043', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1735,10 +1735,10 @@ export const data: Array = [ ], }, { - key: 'abd4d295-9ebb-4a0d-bc07-e2a662671e18', + id: 'abd4d295-9ebb-4a0d-bc07-e2a662671e18', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1759,10 +1759,10 @@ export const data: Array = [ ], }, { - key: '29d42fe1-b465-4dfe-8d29-10286474d625', + id: '29d42fe1-b465-4dfe-8d29-10286474d625', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1783,10 +1783,10 @@ export const data: Array = [ ], }, { - key: '690535f5-194a-4e32-b569-608fbf279059', + id: '690535f5-194a-4e32-b569-608fbf279059', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1807,10 +1807,10 @@ export const data: Array = [ ], }, { - key: '13b5e542-e779-48df-b7f9-2c7def0e2e55', + id: '13b5e542-e779-48df-b7f9-2c7def0e2e55', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1831,10 +1831,10 @@ export const data: Array = [ ], }, { - key: 'af5bfaaf-1597-4ad1-aa1e-206f78a91674', + id: 'af5bfaaf-1597-4ad1-aa1e-206f78a91674', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1851,10 +1851,10 @@ export const data: Array = [ userGroups: ['397f3a8b-4ca3-4b01-9dd3-94e5c9eaa9b2', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: '8f39464a-2e49-498b-b8b8-cf2926978e83', + id: '8f39464a-2e49-498b-b8b8-cf2926978e83', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1876,10 +1876,10 @@ export const data: Array = [ ], }, { - key: 'ac4785f1-b6f5-4d2d-99e6-f62a96947f8c', + id: 'ac4785f1-b6f5-4d2d-99e6-f62a96947f8c', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1896,10 +1896,10 @@ export const data: Array = [ userGroups: ['2668f09b-320c-48a7-a78a-95047026ec0e', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: 'd89ada67-eca1-475a-9273-0c69b56116da', + id: 'd89ada67-eca1-475a-9273-0c69b56116da', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1921,10 +1921,10 @@ export const data: Array = [ ], }, { - key: '03ced59c-40b3-482a-8470-b12f56974a0f', + id: '03ced59c-40b3-482a-8470-b12f56974a0f', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1946,10 +1946,10 @@ export const data: Array = [ ], }, { - key: 'dcfba56e-5f3c-446b-a4ef-18da66df8181', + id: 'dcfba56e-5f3c-446b-a4ef-18da66df8181', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1970,10 +1970,10 @@ export const data: Array = [ ], }, { - key: '63be3c07-9178-4c2e-810a-6bbdbbe16dcb', + id: '63be3c07-9178-4c2e-810a-6bbdbbe16dcb', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -1995,10 +1995,10 @@ export const data: Array = [ ], }, { - key: 'c57661ef-8f66-4502-91cb-2069a186ce79', + id: 'c57661ef-8f66-4502-91cb-2069a186ce79', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2019,10 +2019,10 @@ export const data: Array = [ ], }, { - key: 'b5fbd289-2900-4328-8d1f-0a6780be3585', + id: 'b5fbd289-2900-4328-8d1f-0a6780be3585', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2043,10 +2043,10 @@ export const data: Array = [ ], }, { - key: '9ca26535-5288-4b37-8e3b-96b3530de3d1', + id: '9ca26535-5288-4b37-8e3b-96b3530de3d1', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2067,10 +2067,10 @@ export const data: Array = [ ], }, { - key: '19998fc5-2902-4646-9cf2-395404da2b2a', + id: '19998fc5-2902-4646-9cf2-395404da2b2a', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2092,10 +2092,10 @@ export const data: Array = [ ], }, { - key: '468a904c-f87c-4079-920b-74c6aa3a5242', + id: '468a904c-f87c-4079-920b-74c6aa3a5242', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2117,10 +2117,10 @@ export const data: Array = [ ], }, { - key: '60336828-85ed-4b5a-abf6-869d6902ad93', + id: '60336828-85ed-4b5a-abf6-869d6902ad93', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2142,10 +2142,10 @@ export const data: Array = [ ], }, { - key: '2b0c8ffe-4bcb-4df6-b519-3358a5c90480', + id: '2b0c8ffe-4bcb-4df6-b519-3358a5c90480', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2166,10 +2166,10 @@ export const data: Array = [ ], }, { - key: 'c967ff49-f967-449b-9aab-e5ca72255a61', + id: 'c967ff49-f967-449b-9aab-e5ca72255a61', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2191,10 +2191,10 @@ export const data: Array = [ ], }, { - key: '594040ce-c6f7-49e7-8f4a-ffa8c42a2102', + id: '594040ce-c6f7-49e7-8f4a-ffa8c42a2102', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2211,10 +2211,10 @@ export const data: Array = [ userGroups: ['b847398a-6875-4d7a-9f6d-231256b81471', '9a9ad4e9-3b5b-4fe7-b0d9-e301b9675949'], }, { - key: '33806fc1-d4a9-4ddb-8d57-3c087ea1f489', + id: '33806fc1-d4a9-4ddb-8d57-3c087ea1f489', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2235,10 +2235,10 @@ export const data: Array = [ ], }, { - key: 'a59a5259-9393-4c49-a5be-56a475b27640', + id: 'a59a5259-9393-4c49-a5be-56a475b27640', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2259,10 +2259,10 @@ export const data: Array = [ ], }, { - key: '9e96841c-131d-420a-bdc8-4ba087f0f11c', + id: '9e96841c-131d-420a-bdc8-4ba087f0f11c', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2283,10 +2283,10 @@ export const data: Array = [ ], }, { - key: '84eaae2a-9aa8-4745-b4c3-fad2f5632e85', + id: '84eaae2a-9aa8-4745-b4c3-fad2f5632e85', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2308,10 +2308,10 @@ export const data: Array = [ ], }, { - key: '6fe86358-f3fd-4f7d-8d28-e867562569f2', + id: '6fe86358-f3fd-4f7d-8d28-e867562569f2', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2328,10 +2328,10 @@ export const data: Array = [ userGroups: ['c630d49e-4e7b-42ea-b2bc-edc0edacb6b1', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: '365fd725-81c7-48f0-be68-4dbcf15f1ca9', + id: '365fd725-81c7-48f0-be68-4dbcf15f1ca9', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', @@ -2348,10 +2348,10 @@ export const data: Array = [ userGroups: ['2668f09b-320c-48a7-a78a-95047026ec0e', 'b847398a-6875-4d7a-9f6d-231256b81471'], }, { - key: 'b6028623-995e-4eee-8142-723141030692', + id: 'b6028623-995e-4eee-8142-723141030692', type: 'user', hasChildren: false, - parentKey: '', + parentId: '', contentStartNodes: [], mediaStartNodes: [], icon: 'umb:user', diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/data/utils.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/data/utils.ts index 2b470d3ebc..5c847f47e8 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/data/utils.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/data/utils.ts @@ -1,27 +1,28 @@ import type { - ContentTreeItemModel, - DocumentTreeItemModel, - DocumentTypeTreeItemModel, - EntityTreeItemModel, - FolderTreeItemModel, - DocumentTypeModel, - DocumentModel, -} from '@umbraco-cms/backend-api'; + ContentTreeItemResponseModel, + DocumentTreeItemResponseModel, + DocumentTypeTreeItemResponseModel, + EntityTreeItemResponseModel, + FolderTreeItemResponseModel, + DocumentTypeResponseModel, + DocumentResponseModel, + FileSystemTreeItemPresentationModel, +} from '@umbraco-cms/backoffice/backend-api'; -export const createEntityTreeItem = (item: any): EntityTreeItemModel => { +export const createEntityTreeItem = (item: any): EntityTreeItemResponseModel => { return { $type: '', name: item.name, type: item.type, icon: item.icon, hasChildren: item.hasChildren, - key: item.key, + id: item.id, isContainer: item.isContainer, - parentKey: item.parentKey, + parentId: item.parentId, }; }; -export const createFolderTreeItem = (item: any): FolderTreeItemModel => { +export const createFolderTreeItem = (item: any): FolderTreeItemResponseModel => { return { ...createEntityTreeItem(item), isFolder: item.isFolder, @@ -29,7 +30,7 @@ export const createFolderTreeItem = (item: any): FolderTreeItemModel => { }; // TODO: remove isTrashed type extension when we have found a solution to trashed items -export const createContentTreeItem = (item: any): ContentTreeItemModel & { isTrashed: boolean } => { +export const createContentTreeItem = (item: any): ContentTreeItemResponseModel & { isTrashed: boolean } => { return { ...createEntityTreeItem(item), noAccess: item.noAccess, @@ -38,7 +39,9 @@ export const createContentTreeItem = (item: any): ContentTreeItemModel & { isTra }; // TODO: remove isTrashed type extension when we have found a solution to trashed items -export const createDocumentTreeItem = (item: DocumentModel): DocumentTreeItemModel & { isTrashed: boolean } => { +export const createDocumentTreeItem = ( + item: DocumentResponseModel +): DocumentTreeItemResponseModel & { isTrashed: boolean } => { return { ...createContentTreeItem(item), /* @@ -51,9 +54,16 @@ export const createDocumentTreeItem = (item: DocumentModel): DocumentTreeItemMod }; }; -export const createDocumentTypeTreeItem = (item: DocumentTypeModel): DocumentTypeTreeItemModel => { +export const createDocumentTypeTreeItem = (item: DocumentTypeResponseModel): DocumentTypeTreeItemResponseModel => { return { ...createFolderTreeItem(item), isElement: item.isElement, }; }; + +export const createFileSystemTreeItem = (item: any): FileSystemTreeItemPresentationModel => { + return { + ...createFolderTreeItem(item), + path: item.path, + }; +}; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/culture.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/culture.handlers.ts index 84b194254e..8c18cf5a2d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/culture.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/culture.handlers.ts @@ -1,6 +1,6 @@ import { rest } from 'msw'; import { umbCulturesData } from '../data/culture.data'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; export const handlers = [ rest.get(umbracoPath('/culture'), (req, res, ctx) => { diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type.handlers.ts deleted file mode 100644 index a7aea08797..0000000000 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type.handlers.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { rest } from 'msw'; -import { umbDataTypeData } from '../data/data-type.data'; -import { umbracoPath } from '@umbraco-cms/utils'; - -// TODO: add schema -export const handlers = [ - rest.delete('/umbraco/backoffice/data-type/:key', async (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; - - umbDataTypeData.delete([key]); - - return res(ctx.status(200)); - }), - - rest.get('/umbraco/management/api/v1/tree/data-type/root', (req, res, ctx) => { - const rootItems = umbDataTypeData.getTreeRoot(); - const response = { - total: rootItems.length, - items: rootItems, - }; - return res(ctx.status(200), ctx.json(response)); - }), - - rest.get('/umbraco/management/api/v1/tree/data-type/children', (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; - - const children = umbDataTypeData.getTreeItemChildren(parentKey); - - const response = { - total: children.length, - items: children, - }; - - return res(ctx.status(200), ctx.json(response)); - }), - - rest.get('/umbraco/management/api/v1/tree/data-type/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; - const items = umbDataTypeData.getTreeItem(keys); - return res(ctx.status(200), ctx.json(items)); - }), - - rest.get(umbracoPath('/data-type/:key'), (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; - - const dataType = umbDataTypeData.getByKey(key); - - return res(ctx.status(200), ctx.json(dataType)); - }), - - rest.post(umbracoPath('/data-type/:key'), async (req, res, ctx) => { - const data = await req.json(); - if (!data) return; - - const saved = umbDataTypeData.save(data); - - return res(ctx.status(200), ctx.json(saved)); - }), - - rest.put(umbracoPath('/data-type/:key'), async (req, res, ctx) => { - const data = await req.json(); - if (!data) return; - - const saved = umbDataTypeData.save(data); - - return res(ctx.status(200), ctx.json(saved)); - }), -]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/detail.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/detail.handlers.ts new file mode 100644 index 0000000000..c362a16141 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/detail.handlers.ts @@ -0,0 +1,42 @@ +import { rest } from 'msw'; +import { umbDataTypeData } from '../../data/data-type.data'; +import { slug } from './slug'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; + +export const detailHandlers = [ + rest.post(umbracoPath(`${slug}`), async (req, res, ctx) => { + const data = await req.json(); + if (!data) return; + + umbDataTypeData.insert(data); + + return res(ctx.status(200)); + }), + + rest.get(umbracoPath(`${slug}/:id`), (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + + const dataType = umbDataTypeData.getById(id); + + return res(ctx.status(200), ctx.json(dataType)); + }), + + rest.put(umbracoPath(`${slug}/:id`), async (req, res, ctx) => { + const data = await req.json(); + if (!data) return; + + const saved = umbDataTypeData.save(data); + + return res(ctx.status(200), ctx.json(saved)); + }), + + rest.delete(umbracoPath(`${slug}/:id`), async (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + + umbDataTypeData.delete([id]); + + return res(ctx.status(200)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/folder.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/folder.handlers.ts new file mode 100644 index 0000000000..9a0d5bc071 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/folder.handlers.ts @@ -0,0 +1,53 @@ +import { rest } from 'msw'; +import { umbDataTypeData } from '../../data/data-type.data'; +import { slug } from './slug'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; + +export const folderHandlers = [ + rest.post(umbracoPath(`${slug}/folder`), async (req, res, ctx) => { + const data = await req.json(); + if (!data) return; + + umbDataTypeData.createFolder(data); + + return res(ctx.status(200)); + }), + + rest.get(umbracoPath(`${slug}/folder/:id`), (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + + const dataType = umbDataTypeData.getById(id); + + return res(ctx.status(200), ctx.json(dataType)); + }), + + rest.put(umbracoPath(`${slug}/folder/:id`), async (req, res, ctx) => { + const data = await req.json(); + if (!data) return; + + umbDataTypeData.save(data); + + return res(ctx.status(200)); + }), + + rest.delete(umbracoPath(`${slug}/folder/:id`), async (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + + try { + umbDataTypeData.deleteFolder(id); + return res(ctx.status(200)); + } catch (error) { + return res( + ctx.status(404), + ctx.json({ + status: 404, + type: 'error', + detail: 'Not Found', + }) + ); + } + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/index.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/index.ts new file mode 100644 index 0000000000..fb46e23ffd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/index.ts @@ -0,0 +1,6 @@ +import { folderHandlers } from './folder.handlers'; +import { treeHandlers } from './tree.handlers'; +import { detailHandlers } from './detail.handlers'; +import { itemHandlers } from './item.handlers'; + +export const handlers = [...treeHandlers, ...itemHandlers, ...folderHandlers, ...detailHandlers]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/item.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/item.handlers.ts new file mode 100644 index 0000000000..24d17c79e0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/item.handlers.ts @@ -0,0 +1,13 @@ +import { rest } from 'msw'; +import { umbDataTypeData } from '../../data/data-type.data'; +import { slug } from './slug'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; + +export const itemHandlers = [ + rest.get(umbracoPath(`${slug}/item`), (req, res, ctx) => { + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; + const items = umbDataTypeData.getTreeItem(ids); + return res(ctx.status(200), ctx.json(items)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/slug.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/slug.ts new file mode 100644 index 0000000000..5c453df84c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/slug.ts @@ -0,0 +1 @@ +export const slug = '/data-type'; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/tree.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/tree.handlers.ts new file mode 100644 index 0000000000..203acd560f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/data-type/tree.handlers.ts @@ -0,0 +1,29 @@ +import { rest } from 'msw'; +import { umbDataTypeData } from '../../data/data-type.data'; +import { slug } from './slug'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; + +export const treeHandlers = [ + rest.get(umbracoPath(`/tree${slug}/root`), (req, res, ctx) => { + const rootItems = umbDataTypeData.getTreeRoot(); + const response = { + total: rootItems.length, + items: rootItems, + }; + return res(ctx.status(200), ctx.json(response)); + }), + + rest.get(umbracoPath(`/tree${slug}/children`), (req, res, ctx) => { + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; + + const children = umbDataTypeData.getTreeItemChildren(parentId); + + const response = { + total: children.length, + items: children, + }; + + return res(ctx.status(200), ctx.json(response)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/dictionary.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/dictionary.handlers.ts index cba8bd2327..33b51c2ad4 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/dictionary.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/dictionary.handlers.ts @@ -1,19 +1,23 @@ import { rest } from 'msw'; import { umbDictionaryData } from '../data/dictionary.data'; -import { DictionaryImportModel, DictionaryOverviewModel } from '@umbraco-cms/backend-api'; -import type { DictionaryDetails } from '@umbraco-cms/models'; +import { + ImportDictionaryRequestModel, + DictionaryOverviewResponseModel, + DictionaryItemResponseModel, + EntityTreeItemResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; -const uploadResponse: DictionaryImportModel = { - fileName: 'c:/path/to/tempfilename.udt', - parentKey: 'b7e7d0ab-53ba-485d-dddd-12537f9925aa', +const uploadResponse: ImportDictionaryRequestModel = { + temporaryFileId: 'c:/path/to/tempfilename.udt', + parentId: 'b7e7d0ab-53ba-485d-dddd-12537f9925aa', }; -/// -const importResponse: DictionaryDetails = { +/// TODO: get correct type +const importResponse: DictionaryItemResponseModel & EntityTreeItemResponseModel = { $type: '', - parentKey: null, + parentId: null, name: 'Uploaded dictionary', - key: 'b7e7d0ab-53ba-485d-dddd-12537f9925cb', + id: 'b7e7d0ab-53ba-485d-dddd-12537f9925cb', hasChildren: false, type: 'dictionary-item', isContainer: false, @@ -31,27 +35,26 @@ const importResponse: DictionaryDetails = { }; // alternate data for dashboard view -const overviewData: Array = [ +const overviewData: Array = [ { name: 'Hello', - key: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb', + id: 'aae7d0ab-53ba-485d-b8bd-12537f9925cb', translatedIsoCodes: ['en'], }, { name: 'Hello again', - key: 'bbe7d0ab-53bb-485d-b8bd-12537f9925cb', + id: 'bbe7d0ab-53bb-485d-b8bd-12537f9925cb', translatedIsoCodes: ['en', 'fr'], }, ]; // TODO: add schema export const handlers = [ - rest.get('/umbraco/management/api/v1/dictionary/:key', (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get('/umbraco/management/api/v1/dictionary/:id', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const dictionary = umbDictionaryData.getByKey(key); - console.log(dictionary); + const dictionary = umbDictionaryData.getById(id); return res(ctx.status(200), ctx.json(dictionary)); }), @@ -77,7 +80,6 @@ export const handlers = [ const data = await req.json(); if (!data) return; - data.parentKey = data.parentId; data.icon = 'umb:book-alt'; data.hasChildren = false; data.type = 'dictionary-item'; @@ -92,7 +94,7 @@ export const handlers = [ }, ]; - const value = umbDictionaryData.save([data])[0]; + const value = umbDictionaryData.save(data); const createdResult = { value, @@ -102,15 +104,15 @@ export const handlers = [ return res(ctx.status(200), ctx.json(createdResult)); }), - rest.patch('/umbraco/management/api/v1/dictionary/:key', async (req, res, ctx) => { + rest.patch('/umbraco/management/api/v1/dictionary/:id', async (req, res, ctx) => { const data = await req.json(); if (!data) return; - const key = req.params.key as string; - if (!key) return; + const id = req.params.id as string; + if (!id) return; const dataToSave = JSON.parse(data[0].value); - const saved = umbDictionaryData.save([dataToSave]); + const saved = umbDictionaryData.save(dataToSave); return res(ctx.status(200), ctx.json(saved)); }), @@ -125,10 +127,10 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/dictionary/children', (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; - const items = umbDictionaryData.getTreeItemChildren(parentKey); + const items = umbDictionaryData.getTreeItemChildren(parentId); const response = { total: items.length, @@ -139,30 +141,30 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/dictionary/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbDictionaryData.getTreeItem(keys); + const items = umbDictionaryData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), - rest.delete('/umbraco/management/api/v1/dictionary/:key', (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.delete('/umbraco/management/api/v1/dictionary/:id', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const deletedKeys = umbDictionaryData.delete([key]); + const deletedKeys = umbDictionaryData.delete([id]); return res(ctx.status(200), ctx.json(deletedKeys)); }), // TODO => handle properly, querystring breaks handler - rest.get('/umbraco/management/api/v1/dictionary/:key/export', (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get('/umbraco/management/api/v1/dictionary/:id/export', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; const includeChildren = req.url.searchParams.get('includeChildren'); - const item = umbDictionaryData.getByKey(key); + const item = umbDictionaryData.getById(id); alert( `Downloads file for dictionary "${item?.name}", ${includeChildren === 'true' ? 'with' : 'without'} children.` @@ -179,16 +181,16 @@ export const handlers = [ rest.post('/umbraco/management/api/v1/dictionary/import', async (req, res, ctx) => { const file = req.url.searchParams.get('file'); - if (!file) return; + if (!file || !importResponse.id) return; - importResponse.parentKey = req.url.searchParams.get('parentId') ?? null; - umbDictionaryData.save([importResponse]); + importResponse.parentId = req.url.searchParams.get('parentId') ?? null; + umbDictionaryData.save(importResponse); // build the path to the new item => reflects the expected server response const path = ['-1']; - if (importResponse.parentKey) path.push(importResponse.parentKey); + if (importResponse.parentId) path.push(importResponse.parentId); - path.push(importResponse.key); + path.push(importResponse.id); const contentResult = { content: path.join(','), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document-type.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document-type.handlers.ts index bc06e3b5b8..1daea0ba0f 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document-type.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document-type.handlers.ts @@ -1,10 +1,10 @@ import { rest } from 'msw'; import { umbDocumentTypeData } from '../data/document-type.data'; -import type { DocumentTypeModel } from '@umbraco-cms/backend-api'; +import type { DocumentTypeResponseModel } from '@umbraco-cms/backoffice/backend-api'; // TODO: add schema export const handlers = [ - rest.post('/umbraco/management/api/v1/document-type/:key', (req, res, ctx) => { + rest.post('/umbraco/management/api/v1/document-type/:id', (req, res, ctx) => { const data = req.body; if (!data) return; @@ -13,16 +13,16 @@ export const handlers = [ return res(ctx.status(200), ctx.json(saved)); }), - rest.get('/umbraco/management/api/v1/document-type/details/:key', (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get('/umbraco/management/api/v1/document-type/details/:id', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const document = umbDocumentTypeData.getByKey(key); + const document = umbDocumentTypeData.getById(id); return res(ctx.status(200), ctx.json([document])); }), - rest.post('/umbraco/management/api/v1/document-type/details/save', (req, res, ctx) => { + rest.post('/umbraco/management/api/v1/document-type/details/save', (req, res, ctx) => { const data = req.body; if (!data) return; @@ -41,10 +41,10 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/document-type/children', (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; - const children = umbDocumentTypeData.getTreeItemChildren(parentKey); + const children = umbDocumentTypeData.getTreeItemChildren(parentId); const response = { total: children.length, @@ -55,20 +55,29 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/document-type/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbDocumentTypeData.getTreeItem(keys); + const items = umbDocumentTypeData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), - rest.get('/umbraco/management/api/v1/document-type/:key', (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get('/umbraco/management/api/v1/document-type/:id', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const document = umbDocumentTypeData.getByKey(key); + const documentType = umbDocumentTypeData.getById(id); - return res(ctx.status(200), ctx.json(document)); + return res(ctx.status(200), ctx.json(documentType)); + }), + + rest.get('/umbraco/management/api/v1/document-type/allowed-children-of/:id', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + + const items = umbDocumentTypeData.getAllowedTypesOf(id); + + return res(ctx.status(200), ctx.json(items)); }), ]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document.handlers.ts index 560b50131e..44c3eb41da 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/document.handlers.ts @@ -1,15 +1,15 @@ import { rest } from 'msw'; import { umbDocumentData } from '../data/document.data'; -import type { DocumentModel } from '@umbraco-cms/backend-api'; -import { umbracoPath } from '@umbraco-cms/utils'; +import type { DocumentResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; // TODO: add schema export const handlers = [ rest.post('/umbraco/management/api/v1/document/trash', async (req, res, ctx) => { console.warn('Please move to schema'); - const keys = await req.json(); + const ids = await req.json(); - const trashed = umbDocumentData.trash(keys); + const trashed = umbDocumentData.trash(ids); return res(ctx.status(200), ctx.json(trashed)); }), @@ -20,22 +20,22 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/document/children', (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; - const response = umbDocumentData.getTreeItemChildren(parentKey); + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; + const response = umbDocumentData.getTreeItemChildren(parentId); return res(ctx.status(200), ctx.json(response)); }), rest.get('/umbraco/management/api/v1/tree/document/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbDocumentData.getTreeItem(keys); + const items = umbDocumentData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), - rest.post('/umbraco/management/api/v1/document/:key', async (req, res, ctx) => { + rest.post('/umbraco/management/api/v1/document/:id', async (req, res, ctx) => { const data = await req.json(); if (!data) return; @@ -44,11 +44,11 @@ export const handlers = [ return res(ctx.status(200), ctx.json(saved)); }), - rest.get(umbracoPath('/document/:key'), (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get(umbracoPath('/document/:id'), (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const document = umbDocumentData.getByKey(key); + const document = umbDocumentData.getById(id); return res(ctx.status(200), ctx.json(document)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/examine-management.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/examine-management.handlers.ts index e0e704fa4a..82bae0ed50 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/examine-management.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/examine-management.handlers.ts @@ -1,15 +1,15 @@ import { rest } from 'msw'; import { searchResultMockData, getIndexByName, PagedIndexers } from '../data/examine.data'; -import { umbracoPath } from '@umbraco-cms/utils'; -import { IndexModel, PagedIndexModel, PagedSearcherModel, PagedSearchResultModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { IndexResponseModel, PagedIndexResponseModel, PagedSearcherResponseModel, PagedSearchResultResponseModel } from '@umbraco-cms/backoffice/backend-api'; export const handlers = [ rest.get(umbracoPath('/indexer'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json(PagedIndexers) + ctx.json(PagedIndexers) ); }), @@ -20,7 +20,7 @@ export const handlers = [ const indexFound = getIndexByName(indexName); if (indexFound) { - return res(ctx.status(200), ctx.json(indexFound)); + return res(ctx.status(200), ctx.json(indexFound)); } else { return res(ctx.status(404)); } @@ -43,7 +43,7 @@ export const handlers = [ rest.get(umbracoPath('/searcher'), (_req, res, ctx) => { return res( ctx.status(200), - ctx.json({ + ctx.json({ total: 0, items: [{ name: 'ExternalSearcher' }, { name: 'InternalSearcher' }, { name: 'InternalMemberSearcher' }], }) @@ -61,7 +61,7 @@ export const handlers = [ if (searcherName) { return res( ctx.status(200), - ctx.json({ + ctx.json({ total: 0, items: searchResultMockData, }) diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/health-check.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/health-check.handlers.ts index 7756158382..a4e075f140 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/health-check.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/health-check.handlers.ts @@ -8,21 +8,21 @@ import { } from '../data/health-check.data'; import { - HealthCheckActionModel, - HealthCheckGroupModel, - HealthCheckGroupWithResultModel, - HealthCheckResultModel, - PagedHealthCheckGroupModelBaseModel, + HealthCheckActionRequestModel, + HealthCheckGroupResponseModel, + HealthCheckGroupWithResultResponseModel, + HealthCheckResultResponseModel, + PagedHealthCheckGroupResponseModel, StatusResultTypeModel, -} from '@umbraco-cms/backend-api'; -import { umbracoPath } from '@umbraco-cms/utils'; +} from '@umbraco-cms/backoffice/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; export const handlers = [ rest.get(umbracoPath('/health-check-group'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ total: 9999, items: healthGroupsWithoutResult }) + ctx.json({ total: 9999, items: healthGroupsWithoutResult }) ); }), @@ -33,7 +33,7 @@ export const handlers = [ const group = getGroupByName(name); if (group) { - return res(ctx.status(200), ctx.json(group)); + return res(ctx.status(200), ctx.json(group)); } else { return res(ctx.status(404)); } @@ -46,17 +46,17 @@ export const handlers = [ const group = getGroupWithResultsByName(name); if (group) { - return res(ctx.status(200), ctx.json(group)); + return res(ctx.status(200), ctx.json(group)); } else { return res(ctx.status(404)); } }), - rest.post(umbracoPath('/health-check/execute-action'), async (req, res, ctx) => { - const body = await req.json(); - const healthCheckKey = body.healthCheckKey; - // Find the health check based on the healthCheckKey from the healthGroups[].checks - const healthCheck = healthGroups.flatMap((group) => group.checks).find((check) => check?.key === healthCheckKey); + rest.post(umbracoPath('/health-check/execute-action'), async (req, res, ctx) => { + const body = await req.json(); + const healthCheckId = body.healthCheckId; + // Find the health check based on the healthCheckId from the healthGroups[].checks + const healthCheck = healthGroups.flatMap((group) => group.checks).find((check) => check?.id === healthCheckId); if (!healthCheck) { return res(ctx.status(404)); @@ -74,7 +74,7 @@ export const handlers = [ // Respond with a 200 status code ctx.delay(1000), ctx.status(200), - ctx.json(result) + ctx.json(result) ); }), ]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts index 3bd73fa492..819c06305a 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/install.handlers.ts @@ -1,19 +1,19 @@ import { rest } from 'msw'; import { - DatabaseInstallModel, - InstallModel, - InstallSettingsModel, + DatabaseInstallResponseModel, + InstallVResponseModel, + InstallSettingsResponseModel, ProblemDetailsModel, TelemetryLevelModel, -} from '@umbraco-cms/backend-api'; -import { umbracoPath } from '@umbraco-cms/utils'; +} from '@umbraco-cms/backoffice/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; export const handlers = [ rest.get(umbracoPath('/install/settings'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ user: { minCharLength: 2, minNonAlphaNumericLength: 0, @@ -79,7 +79,7 @@ export const handlers = [ }), rest.post(umbracoPath('/install/validate-database'), async (req, res, ctx) => { - const body = await req.json(); + const body = await req.json(); if (body.name === 'validate') { return res( @@ -99,7 +99,7 @@ export const handlers = [ }), rest.post(umbracoPath('/install/setup'), async (req, res, ctx) => { - const body = await req.json(); + const body = await req.json(); if (body.database?.name === 'fail') { return res( diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/language.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/language.handlers.ts index 153894b174..41158abe5b 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/language.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/language.handlers.ts @@ -1,7 +1,7 @@ import { rest } from 'msw'; import { umbLanguagesData } from '../data/languages.data'; -import { LanguageModel, ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { LanguageResponseModel, ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; // TODO: add schema export const handlers = [ @@ -21,16 +21,16 @@ export const handlers = [ return res(ctx.status(200), ctx.json(response)); }), - rest.get(umbracoPath('/language/:key'), (req, res, ctx) => { - const key = req.params.key as string; + rest.get(umbracoPath('/language/:id'), (req, res, ctx) => { + const id = req.params.id as string; - if (!key) return; + if (!id) return; - const item = umbLanguagesData.getByKey(key); + const item = umbLanguagesData.getByKey(id); return res(ctx.status(200), ctx.json(item)); }), - rest.post(umbracoPath('/language'), async (req, res, ctx) => { + rest.post(umbracoPath('/language'), async (req, res, ctx) => { const data = await req.json(); if (!data) return; @@ -53,7 +53,7 @@ export const handlers = [ } }), - rest.put(umbracoPath('/language/:key'), async (req, res, ctx) => { + rest.put(umbracoPath('/language/:id'), async (req, res, ctx) => { const data = await req.json(); if (!data) return; @@ -63,7 +63,7 @@ export const handlers = [ return res(ctx.status(200)); }), - rest.delete(umbracoPath('/language/:key'), async (req, res, ctx) => { + rest.delete(umbracoPath('/language/:id'), async (req, res, ctx) => { return res(ctx.status(200)); }), ]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/log-viewer.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/log-viewer.handlers.ts index 70eabc1d7c..03491bbf88 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/log-viewer.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/log-viewer.handlers.ts @@ -1,7 +1,7 @@ import { rest } from 'msw'; -import { umbLogviewerData } from '../data/log-viewer.data'; -import { umbracoPath } from '@umbraco-cms/utils'; -import { SavedLogSearchModel } from '@umbraco-cms/backend-api'; +import { umbLogViewerData } from '../data/log-viewer.data'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { SavedLogSearchRequestModel } from '@umbraco-cms/backoffice/backend-api'; export const handlers = [ //#region Searches @@ -11,7 +11,7 @@ export const handlers = [ const take = req.url.searchParams.get('take'); const takeNumber = take ? Number.parseInt(take) : undefined; - const items = umbLogviewerData.searches.getSavedSearches(skipNumber, takeNumber); + const items = umbLogViewerData.searches.getSavedSearches(skipNumber, takeNumber); const response = { total: items.length, @@ -22,19 +22,20 @@ export const handlers = [ }), rest.get(umbracoPath('/log-viewer/saved-search/:name'), (req, res, ctx) => { - const name = req.params.key as string; + const name = req.params.name as string; if (!name) return; - const item = umbLogviewerData.searches.getByName(name); + const item = umbLogViewerData.searches.getByName(name); return res(ctx.delay(), ctx.status(200), ctx.json(item)); }), - rest.post(umbracoPath('/log-viewer/saved-search'), async (req, res, ctx) => { + rest.post(umbracoPath('/log-viewer/saved-search'), async (req, res, ctx) => { return res(ctx.delay(), ctx.status(200)); }), rest.delete(umbracoPath('/log-viewer/saved-search/:name'), async (req, res, ctx) => { + // TODO: implement this return res(ctx.status(200)); }), //#endregion @@ -46,10 +47,10 @@ export const handlers = [ const take = req.url.searchParams.get('take'); const takeNumber = take ? Number.parseInt(take) : undefined; - const items = umbLogviewerData.templates.getTemplates(skipNumber, takeNumber); + const items = umbLogViewerData.templates.getTemplates(skipNumber, takeNumber); const response = { - total: umbLogviewerData.templates.total, + total: umbLogViewerData.templates.total, items, }; @@ -58,11 +59,11 @@ export const handlers = [ //#endregion //#region Logs rest.get(umbracoPath('/log-viewer/level'), (req, res, ctx) => { - return res(ctx.delay(), ctx.status(200), ctx.json(umbLogviewerData.logLevels)); + return res(ctx.delay(), ctx.status(200), ctx.json(umbLogViewerData.logLevels)); }), rest.get(umbracoPath('/log-viewer/level-count'), (req, res, ctx) => { - return res(ctx.delay(), ctx.status(200), ctx.json(umbLogviewerData.logs.getLevelCount())); + return res(ctx.delay(), ctx.status(200), ctx.json(umbLogViewerData.logs.getLevelCount())); }), rest.get(umbracoPath('/log-viewer/validate-logs-size'), (req, res, ctx) => { @@ -75,9 +76,9 @@ export const handlers = [ const take = req.url.searchParams.get('take'); const takeNumber = take ? Number.parseInt(take) : undefined; - const items = umbLogviewerData.logs.getLogs(skipNumber, takeNumber); + const items = umbLogViewerData.logs.getLogs(skipNumber, takeNumber); const response = { - total: umbLogviewerData.logs.total, + total: umbLogViewerData.logs.total, items, }; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/manifests.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/manifests.handlers.ts index 47104cf642..3f92603754 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/manifests.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/manifests.handlers.ts @@ -1,8 +1,7 @@ - import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; -import type { PackageManifestResponse } from '@umbraco-cms/models'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import type { PackageManifestResponse } from '@umbraco-cms/backoffice/models'; export const manifestDevelopmentHandler = rest.get(umbracoPath('/package/manifest'), (_req, res, ctx) => { return res( diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media-type.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media-type.handlers.ts index 0b16b0e0a8..c7f6cfdc13 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media-type.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media-type.handlers.ts @@ -9,18 +9,18 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/media-type/children', (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; - const response = umbMediaTypeData.getTreeItemChildren(parentKey); + const response = umbMediaTypeData.getTreeItemChildren(parentId); return res(ctx.status(200), ctx.json(response)); }), rest.get('/umbraco/management/api/v1/tree/media-type/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbMediaTypeData.getTreeItem(keys); + const items = umbMediaTypeData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), ]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media.handlers.ts index 02e419c0a8..efb5a91845 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/media.handlers.ts @@ -1,15 +1,15 @@ import { rest } from 'msw'; import { umbMediaData } from '../data/media.data'; -import type { MediaDetails } from '@umbraco-cms/models'; +import type { MediaDetails } from '../../../backoffice/media/media'; // TODO: add schema export const handlers = [ - rest.get('/umbraco/management/api/v1/media/details/:key', (req, res, ctx) => { + rest.get('/umbraco/management/api/v1/media/details/:id', (req, res, ctx) => { console.warn('Please move to schema'); - const key = req.params.key as string; - if (!key) return; + const id = req.params.id as string; + if (!id) return; - const media = umbMediaData.getByKey(key); + const media = umbMediaData.getById(id); return res(ctx.status(200), ctx.json([media])); }), @@ -26,13 +26,13 @@ export const handlers = [ rest.post('/umbraco/management/api/v1/media/move', async (req, res, ctx) => { const data = await req.json(); if (!data) return; - const moved = umbMediaData.move(data.keys, data.destination); + const moved = umbMediaData.move(data.ids, data.destination); return res(ctx.status(200), ctx.json(moved)); }), rest.post('/umbraco/management/api/v1/media/trash', async (req, res, ctx) => { - const keys = await req.json(); - const trashed = umbMediaData.trash(keys); + const ids = await req.json(); + const trashed = umbMediaData.trash(ids); return res(ctx.status(200), ctx.json(trashed)); }), @@ -42,17 +42,17 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/media/children', (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; - const response = umbMediaData.getTreeItemChildren(parentKey); + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; + const response = umbMediaData.getTreeItemChildren(parentId); return res(ctx.status(200), ctx.json(response)); }), rest.get('/umbraco/management/api/v1/tree/media/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbMediaData.getTreeItem(keys); + const items = umbMediaData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-group.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-group.handlers.ts index 04f3c6817b..a438855cdb 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-group.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-group.handlers.ts @@ -9,10 +9,10 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/member-group/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbMemberGroupData.getTreeItem(keys); + const items = umbMemberGroupData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-type.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-type.handlers.ts index 9411d8a2aa..4905f5fc1e 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-type.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member-type.handlers.ts @@ -9,10 +9,10 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/member-type/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbMemberTypeData.getTreeItem(keys); + const items = umbMemberTypeData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member.handlers.ts index 41555f9b2f..b3a45839ae 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/member.handlers.ts @@ -9,10 +9,10 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/member/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbMemberData.getTreeItem(keys); + const items = umbMemberData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/modelsbuilder.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/modelsbuilder.handlers.ts index ce5c859bff..f718f778de 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/modelsbuilder.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/modelsbuilder.handlers.ts @@ -1,7 +1,7 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; -import { ModelsBuilderModel, ModelsModeModel, OutOfDateStatusModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { ModelsBuilderResponseModel, ModelsModeModel, OutOfDateStatusResponseModel } from '@umbraco-cms/backoffice/backend-api'; export const handlers = [ rest.post(umbracoPath('/models-builder/build'), async (_req, res, ctx) => { @@ -15,20 +15,20 @@ export const handlers = [ }), rest.get(umbracoPath('/models-builder/dashboard'), async (_req, res, ctx) => { - return res(ctx.status(200), ctx.json(model)); + return res(ctx.status(200), ctx.json(model)); }), rest.get(umbracoPath('/models-builder/status'), async (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({}) + ctx.json({}) ); }), ]; // Mock Data for now -const modelBeforeBuild: ModelsBuilderModel = { +const modelBeforeBuild: ModelsBuilderResponseModel = { mode: ModelsModeModel.IN_MEMORY_AUTO, canGenerate: true, outOfDateModels: true, @@ -49,7 +49,7 @@ at async TransformContext.transform (file:///C:/Users/Umbraco/Documents/Umbraco. trackingOutOfDateModels: true, }; -const modelAfterBuild: ModelsBuilderModel = { +const modelAfterBuild: ModelsBuilderResponseModel = { mode: ModelsModeModel.IN_MEMORY_AUTO, canGenerate: true, outOfDateModels: false, diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/package.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/package.handlers.ts index c056cc616a..840dbc0371 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/package.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/package.handlers.ts @@ -1,20 +1,20 @@ import { rest } from 'msw'; import { v4 as uuidv4 } from 'uuid'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; import { - PackageCreateModel, - PackageDefinitionModel, - PagedPackageDefinitionModel, - PagedPackageMigrationStatusModel, -} from '@umbraco-cms/backend-api'; + PackageMigrationStatusResponseModel, + PackageDefinitionResponseModel, + PagedPackageDefinitionResponseModel, + PagedPackageMigrationStatusResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; export const handlers = [ rest.get(umbracoPath('/package/migration-status'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ total: 3, items: [ { @@ -44,7 +44,7 @@ export const handlers = [ // read all return res( ctx.status(200), - ctx.json({ + ctx.json({ total: packageArray.length, items: packageArray, }) @@ -53,54 +53,54 @@ export const handlers = [ rest.post(umbracoPath('/package/created'), async (_req, res, ctx) => { //save - const data: PackageCreateModel = await _req.json(); - const newPackage: PackageDefinitionModel = { ...data, key: uuidv4() }; + const data: PackageMigrationStatusResponseModel = await _req.json(); + const newPackage: PackageDefinitionResponseModel = { ...data, id: uuidv4() }; packageArray.push(newPackage); - return res(ctx.status(200), ctx.json(newPackage)); + return res(ctx.status(200), ctx.json(newPackage)); }), - rest.get(umbracoPath('/package/created/:key'), (_req, res, ctx) => { + rest.get(umbracoPath('/package/created/:id'), (_req, res, ctx) => { //read 1 - const key = _req.params.key as string; - if (!key) return res(ctx.status(404)); - const found = packageArray.find((p) => p.key == key); + const id = _req.params.id as string; + if (!id) return res(ctx.status(404)); + const found = packageArray.find((p) => p.id == id); if (!found) return res(ctx.status(404)); - return res(ctx.status(200), ctx.json(found)); + return res(ctx.status(200), ctx.json(found)); }), - rest.put(umbracoPath('/package/created/:key'), async (_req, res, ctx) => { + rest.put(umbracoPath('/package/created/:id'), async (_req, res, ctx) => { //update - const data: PackageDefinitionModel = await _req.json(); - if (!data.key) return; - const index = packageArray.findIndex((x) => x.key === data.key); + const data: PackageDefinitionResponseModel = await _req.json(); + if (!data.id) return; + const index = packageArray.findIndex((x) => x.id === data.id); packageArray[index] = data; return res(ctx.status(200)); }), - rest.delete(umbracoPath('/package/created/:key'), (_req, res, ctx) => { + rest.delete(umbracoPath('/package/created/:id'), (_req, res, ctx) => { //delete - const key = _req.params.key as string; - if (!key) return res(ctx.status(404)); - const index = packageArray.findIndex((p) => p.key == key); + const id = _req.params.id as string; + if (!id) return res(ctx.status(404)); + const index = packageArray.findIndex((p) => p.id == id); if (index <= -1) return res(ctx.status(404)); packageArray.splice(index, 1); return res(ctx.status(200)); }), - rest.get(umbracoPath('/package/created/:key/download'), (_req, res, ctx) => { + rest.get(umbracoPath('/package/created/:id/download'), (_req, res, ctx) => { //download return res(ctx.status(200)); }), ]; -const packageArray: PackageDefinitionModel[] = [ +const packageArray: PackageDefinitionResponseModel[] = [ { - key: '2a0181ec-244b-4068-a1d7-2f95ed7e6da6', + id: '2a0181ec-244b-4068-a1d7-2f95ed7e6da6', packagePath: undefined, name: 'My Package', //contentNodeId?: string | null; //contentLoadChildNodes?: boolean; - //mediaKeys?: Array; + //mediaIds?: Array; //mediaLoadChildNodes?: boolean; //documentTypes?: Array; //mediaTypes?: Array; @@ -113,13 +113,13 @@ const packageArray: PackageDefinitionModel[] = [ //dictionaryItems?: Array; }, { - key: '2a0181ec-244b-4068-a1d7-2f95ed7e6da7', + id: '2a0181ec-244b-4068-a1d7-2f95ed7e6da7', packagePath: undefined, name: 'My Second Package', }, { - key: '2a0181ec-244b-4068-a1d7-2f95ed7e6da8', + id: '2a0181ec-244b-4068-a1d7-2f95ed7e6da8', packagePath: undefined, name: 'My Third Package', }, diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/performance-profiling.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/performance-profiling.handlers.ts index 074a7c6edb..2cc0c51edf 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/performance-profiling.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/performance-profiling.handlers.ts @@ -1,14 +1,14 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; -import type { ProfilingStatusModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import type { ProfilingStatusResponseModel } from '@umbraco-cms/backoffice/backend-api'; export const handlers = [ rest.get(umbracoPath('/profiling/status'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ enabled: true }) + ctx.json({ enabled: true }) ); }), ]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/published-status.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/published-status.handlers.ts index aa113abd37..29820f0d5a 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/published-status.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/published-status.handlers.ts @@ -1,6 +1,6 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; export const handlers = [ rest.get(umbracoPath('/published-cache/status'), (_req, res, ctx) => { diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/redirect-management.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/redirect-management.handlers.ts index dc72903041..af6d756e80 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/redirect-management.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/redirect-management.handlers.ts @@ -1,11 +1,11 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; import { - PagedRedirectUrlModel, - RedirectUrlModel, + PagedRedirectUrlResponseModel, + RedirectUrlResponseModel, RedirectStatusModel, - RedirectUrlStatusModel, -} from '@umbraco-cms/backend-api'; + RedirectUrlStatusResponseModel, +} from '@umbraco-cms/backoffice/backend-api'; export const handlers = [ rest.get(umbracoPath('/redirect-management'), (_req, res, ctx) => { @@ -14,42 +14,42 @@ export const handlers = [ const take = parseInt(_req.url.searchParams.get('take') ?? '20', 10); if (filter) { - const filtered: RedirectUrlModel[] = []; + const filtered: RedirectUrlResponseModel[] = []; PagedRedirectUrlData.items.forEach((item) => { if (item.originalUrl?.includes(filter)) filtered.push(item); }); - const filteredPagedData: PagedRedirectUrlModel = { + const filteredPagedData: PagedRedirectUrlResponseModel = { total: filtered.length, items: filtered.slice(skip, skip + take), }; - return res(ctx.status(200), ctx.json(filteredPagedData)); + return res(ctx.status(200), ctx.json(filteredPagedData)); } else { const items = PagedRedirectUrlData.items.slice(skip, skip + take); - const PagedData: PagedRedirectUrlModel = { + const PagedData: PagedRedirectUrlResponseModel = { total: PagedRedirectUrlData.total, items, }; - return res(ctx.status(200), ctx.json(PagedData)); + return res(ctx.status(200), ctx.json(PagedData)); } }), - rest.get(umbracoPath('/redirect-management/:key'), async (_req, res, ctx) => { - const key = _req.params.key as string; - if (!key) return res(ctx.status(404)); - if (key === 'status') return res(ctx.status(200), ctx.json(UrlTracker)); + rest.get(umbracoPath('/redirect-management/:id'), async (_req, res, ctx) => { + const id = _req.params.id as string; + if (!id) return res(ctx.status(404)); + if (id === 'status') return res(ctx.status(200), ctx.json(UrlTracker)); - const PagedRedirectUrlObject = _getRedirectUrlByKey(key); + const PagedRedirectUrlObject = _getRedirectUrlByKey(id); - return res(ctx.status(200), ctx.json(PagedRedirectUrlObject)); + return res(ctx.status(200), ctx.json(PagedRedirectUrlObject)); }), - rest.delete(umbracoPath('/redirect-management/:key'), async (_req, res, ctx) => { - const key = _req.params.key as string; - if (!key) return res(ctx.status(404)); + rest.delete(umbracoPath('/redirect-management/:id'), async (_req, res, ctx) => { + const id = _req.params.id as string; + if (!id) return res(ctx.status(404)); - const PagedRedirectUrlObject = _deleteRedirectUrlByKey(key); + const PagedRedirectUrlObject = _deleteRedirectUrlByKey(id); return res(ctx.status(200), ctx.json(PagedRedirectUrlObject)); }), @@ -67,15 +67,15 @@ export const handlers = [ // Mock Data -const UrlTracker: RedirectUrlStatusModel = { status: RedirectStatusModel.ENABLED, userIsAdmin: true }; +const UrlTracker: RedirectUrlStatusResponseModel = { status: RedirectStatusModel.ENABLED, userIsAdmin: true }; -const _getRedirectUrlByKey = (key: string) => { - const PagedResult: PagedRedirectUrlModel = { +const _getRedirectUrlByKey = (id: string) => { + const PagedResult: PagedRedirectUrlResponseModel = { total: 0, items: [], }; RedirectUrlData.forEach((data) => { - if (data.key?.includes(key)) { + if (data.id?.includes(id)) { PagedResult.items.push(data); PagedResult.total++; } @@ -83,97 +83,97 @@ const _getRedirectUrlByKey = (key: string) => { return PagedResult; }; -const _deleteRedirectUrlByKey = (key: string) => { - const index = RedirectUrlData.findIndex((data) => data.key === key); +const _deleteRedirectUrlByKey = (id: string) => { + const index = RedirectUrlData.findIndex((data) => data.id === id); if (index > -1) RedirectUrlData.splice(index, 1); - const PagedResult: PagedRedirectUrlModel = { + const PagedResult: PagedRedirectUrlResponseModel = { items: RedirectUrlData, total: RedirectUrlData.length, }; return PagedResult; }; -const RedirectUrlData: RedirectUrlModel[] = [ +const RedirectUrlData: RedirectUrlResponseModel[] = [ { - key: '1', + id: '1', created: '2022-12-05T13:59:43.6827244', destinationUrl: 'kitty.com', originalUrl: 'kitty.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9f2', + contentId: '7191c911-6747-4824-849e-5208e2b31d9f2', }, { - key: '2', + id: '2', created: '2022-13-05T13:59:43.6827244', destinationUrl: 'umbraco.com', originalUrl: 'umbraco.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9f', + contentId: '7191c911-6747-4824-849e-5208e2b31d9f', }, { - key: '3', + id: '3', created: '2022-12-05T13:59:43.6827244', destinationUrl: 'uui.umbraco.com', originalUrl: 'uui.umbraco.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9f23', + contentId: '7191c911-6747-4824-849e-5208e2b31d9f23', }, { - key: '4', + id: '4', created: '2022-13-05T13:59:43.6827244', destinationUrl: 'umbracoffee.com', originalUrl: 'umbracoffee.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9fdsaa', + contentId: '7191c911-6747-4824-849e-5208e2b31d9fdsaa', }, { - key: '5', + id: '5', created: '2022-12-05T13:59:43.6827244', destinationUrl: 'section/settings', originalUrl: 'section/settings/123', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9f2e23', + contentId: '7191c911-6747-4824-849e-5208e2b31d9f2e23', }, { - key: '6', + id: '6', created: '2022-13-05T13:59:43.6827244', destinationUrl: 'dxp.com', originalUrl: 'dxp.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9fsafsfd', + contentId: '7191c911-6747-4824-849e-5208e2b31d9fsafsfd', }, { - key: '7', + id: '7', created: '2022-12-05T13:59:43.6827244', destinationUrl: 'google.com', originalUrl: 'google.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9f2cxza', + contentId: '7191c911-6747-4824-849e-5208e2b31d9f2cxza', }, { - key: '8', + id: '8', created: '2022-13-05T13:59:43.6827244', destinationUrl: 'unicorns.com', originalUrl: 'unicorns.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31d9fweds', + contentId: '7191c911-6747-4824-849e-5208e2b31d9fweds', }, { - key: '9', + id: '9', created: '2022-12-05T13:59:43.6827244', destinationUrl: 'h5yr.com', originalUrl: 'h5yr.dk', - contentKey: '7191c911-6747-4824-849e-5208e2b31ddsfsdsfadsfdx9f2', + contentId: '7191c911-6747-4824-849e-5208e2b31ddsfsdsfadsfdx9f2', }, { - key: '10', + id: '10', created: '2022-13-05T13:59:43.6827244', destinationUrl: 'our.umbraco.com', originalUrl: 'our.umbraco.dk', - contentKey: '7191c911-6747-4824-849e-52dsacx08e2b31d9dsafdsff', + contentId: '7191c911-6747-4824-849e-52dsacx08e2b31d9dsafdsff', }, { - key: '11', + id: '11', created: '2022-13-05T13:59:43.6827244', destinationUrl: 'your.umbraco.com', originalUrl: 'your.umbraco.dk', - contentKey: '7191c911-6747-4824-849e-52dsacx08e2b31d9fsda', + contentId: '7191c911-6747-4824-849e-52dsacx08e2b31d9fsda', }, ]; -const PagedRedirectUrlData: PagedRedirectUrlModel = { +const PagedRedirectUrlData: PagedRedirectUrlResponseModel = { total: RedirectUrlData.length, items: RedirectUrlData, }; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/relation-type.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/relation-type.handlers.ts new file mode 100644 index 0000000000..0e4c1d4ea6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/relation-type.handlers.ts @@ -0,0 +1,72 @@ +import { rest } from 'msw'; +import { umbRelationTypeData } from '../data/relation-type.data'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; + +// TODO: add schema +export const handlers = [ + rest.delete('/umbraco/backoffice/relation-type/:id', async (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + + umbRelationTypeData.delete([id]); + + return res(ctx.status(200)); + }), + + rest.get('/umbraco/management/api/v1/tree/relation-type/root', (req, res, ctx) => { + const rootItems = umbRelationTypeData.getTreeRoot(); + const response = { + total: rootItems.length, + items: rootItems, + }; + return res(ctx.status(200), ctx.json(response)); + }), + + rest.get('/umbraco/management/api/v1/tree/relation-type/children', (req, res, ctx) => { + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; + + const children = umbRelationTypeData.getTreeItemChildren(parentId); + + const response = { + total: children.length, + items: children, + }; + + return res(ctx.status(200), ctx.json(response)); + }), + + rest.get('/umbraco/management/api/v1/tree/relation-type/item', (req, res, ctx) => { + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; + const items = umbRelationTypeData.getTreeItem(ids); + return res(ctx.status(200), ctx.json(items)); + }), + + rest.get(umbracoPath('/relation-type/:id'), (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; + + const RelationType = umbRelationTypeData.getById(id); + + return res(ctx.status(200), ctx.json(RelationType)); + }), + + rest.post(umbracoPath('/relation-type/:id'), async (req, res, ctx) => { + const data = await req.json(); + if (!data) return; + + const saved = umbRelationTypeData.save(data); + + return res(ctx.status(200), ctx.json(saved)); + }), + + rest.put(umbracoPath('/relation-type/:id'), async (req, res, ctx) => { + const data = await req.json(); + if (!data) return; + + const saved = umbRelationTypeData.save(data); + + return res(ctx.status(200), ctx.json(saved)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/rte-embed.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/rte-embed.handlers.ts new file mode 100644 index 0000000000..dd811943f0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/rte-embed.handlers.ts @@ -0,0 +1,17 @@ +import { rest } from 'msw'; +import { OEmbedResult, OEmbedStatus } from '@umbraco-cms/backoffice/modal'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; + +export const handlers = [ + rest.get(umbracoPath('/rteembed'), (req, res, ctx) => { + const width = req.url.searchParams.get('width') ?? 360; + const height = req.url.searchParams.get('height') ?? 240; + const response: OEmbedResult = { + supportsDimensions: true, + markup: ``, + oEmbedStatus: OEmbedStatus.Success, + }; + + return res(ctx.status(200), ctx.json(response)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/server.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/server.handlers.ts index 97a80dc6b1..0c3ca91e23 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/server.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/server.handlers.ts @@ -1,12 +1,12 @@ import { rest } from 'msw'; -import { RuntimeLevelModel, ServerStatusModel, VersionModel } from '@umbraco-cms/backend-api'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { RuntimeLevelModel, ServerStatusResponseModel, VersionResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; export const serverRunningHandler = rest.get(umbracoPath('/server/status'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ serverStatus: RuntimeLevelModel.RUN, }) ); @@ -16,7 +16,7 @@ export const serverMustInstallHandler = rest.get(umbracoPath('/server/status'), return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ serverStatus: RuntimeLevelModel.INSTALL, }) ); @@ -26,7 +26,7 @@ export const serverMustUpgradeHandler = rest.get(umbracoPath('/server/status'), return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ serverStatus: RuntimeLevelModel.UPGRADE, }) ); @@ -36,7 +36,7 @@ export const serverVersionHandler = rest.get(umbracoPath('/server/version'), (_r return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ version: '13.0.0', }) ); diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/stylesheet.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/stylesheet.handlers.ts new file mode 100644 index 0000000000..ef252a199e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/stylesheet.handlers.ts @@ -0,0 +1,26 @@ +import { rest } from 'msw'; +import { umbStylesheetData } from '../data/stylesheet.data'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; + +export const handlers = [ + rest.get(umbracoPath('/tree/stylesheet/root'), (req, res, ctx) => { + const response = umbStylesheetData.getTreeRoot(); + return res(ctx.status(200), ctx.json(response)); + }), + + rest.get(umbracoPath('/tree/stylesheet/children'), (req, res, ctx) => { + const path = req.url.searchParams.get('path'); + if (!path) return; + + const response = umbStylesheetData.getTreeItemChildren(path); + return res(ctx.status(200), ctx.json(response)); + }), + + rest.get(umbracoPath('/tree/stylesheet/item'), (req, res, ctx) => { + const paths = req.url.searchParams.getAll('paths'); + if (!paths) return; + + const items = umbStylesheetData.getTreeItem(paths); + return res(ctx.status(200), ctx.json(items)); + }), +]; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/telemetry.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/telemetry.handlers.ts index b8651b539e..d01ca3ee74 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/telemetry.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/telemetry.handlers.ts @@ -1,7 +1,7 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; -import { PagedTelemetryModel, TelemetryModel, TelemetryLevelModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { PagedTelemetryResponseModel, TelemetryResponseModel, TelemetryLevelModel } from '@umbraco-cms/backoffice/backend-api'; let telemetryLevel = TelemetryLevelModel.BASIC; @@ -10,7 +10,7 @@ export const handlers = [ return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ telemetryLevel, }) ); @@ -20,7 +20,7 @@ export const handlers = [ return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ total: 3, items: [ { telemetryLevel: TelemetryLevelModel.MINIMAL }, @@ -31,8 +31,8 @@ export const handlers = [ ); }), - rest.post(umbracoPath('/telemetry/level'), async (_req, res, ctx) => { - const newLevel = (await _req.json()).telemetryLevel; + rest.post(umbracoPath('/telemetry/level'), async (_req, res, ctx) => { + const newLevel = (await _req.json()).telemetryLevel; if (newLevel) { telemetryLevel = newLevel; return res( diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/template.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/template.handlers.ts index 6b159c625e..55e73ea95b 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/template.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/template.handlers.ts @@ -1,7 +1,7 @@ import { rest } from 'msw'; import { umbTemplateData } from '../data/template.data'; -import { umbracoPath } from '@umbraco-cms/utils'; -import { TemplateCreateModel, TemplateUpdateModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import { TemplateModelBaseModel } from '@umbraco-cms/backoffice/backend-api'; // TODO: add schema export const handlers = [ @@ -11,18 +11,18 @@ export const handlers = [ }), rest.get(umbracoPath('/tree/template/children'), (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; - const response = umbTemplateData.getTreeItemChildren(parentKey); + const response = umbTemplateData.getTreeItemChildren(parentId); return res(ctx.status(200), ctx.json(response)); }), rest.get(umbracoPath('/tree/template/item'), (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbTemplateData.getTreeItem(keys); + const items = umbTemplateData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), @@ -34,24 +34,24 @@ export const handlers = [ return res(ctx.status(200), ctx.json(response)); }), - rest.get(umbracoPath('/template/:key'), (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get(umbracoPath('/template/:id'), (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const response = umbTemplateData.getByKey(key); + const response = umbTemplateData.getById(id); return res(ctx.status(200), ctx.json(response)); }), - rest.put(umbracoPath('/template/:key'), async (req, res, ctx) => { - const key = req.params.key as string; + rest.put(umbracoPath('/template/:id'), async (req, res, ctx) => { + const id = req.params.id as string; const data = await req.json(); - if (!key) return; + if (!id) return; umbTemplateData.update(data); return res(ctx.status(200)); }), - rest.post(umbracoPath('/template'), async (req, res, ctx) => { + rest.post(umbracoPath('/template'), async (req, res, ctx) => { const data = await req.json(); if (!data) return; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-media.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-media.handlers.ts index b61126fa72..666bd348ed 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-media.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/tree-media.handlers.ts @@ -9,17 +9,17 @@ export const handlers = [ }), rest.get('/umbraco/management/api/v1/tree/media/children', (req, res, ctx) => { - const parentKey = req.url.searchParams.get('parentKey'); - if (!parentKey) return; - const response = umbMediaData.getTreeItemChildren(parentKey); + const parentId = req.url.searchParams.get('parentId'); + if (!parentId) return; + const response = umbMediaData.getTreeItemChildren(parentId); return res(ctx.status(200), ctx.json(response)); }), rest.get('/umbraco/management/api/v1/tree/media/item', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (!keys) return; + const ids = req.url.searchParams.getAll('id'); + if (!ids) return; - const items = umbMediaData.getTreeItem(keys); + const items = umbMediaData.getTreeItem(ids); return res(ctx.status(200), ctx.json(items)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/upgrade.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/upgrade.handlers.ts index d947764f8c..bc8a42c93a 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/upgrade.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/upgrade.handlers.ts @@ -1,14 +1,14 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; -import type { UpgradeSettingsModel } from '@umbraco-cms/backend-api'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; +import type { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/backend-api'; export const handlers = [ rest.get(umbracoPath('/upgrade/settings'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ currentState: '2b20c6e7', newState: '2b20c6e8', oldVersion: '13.0.0', diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user-groups.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user-groups.handlers.ts index 0d97ede719..929979ba43 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user-groups.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user-groups.handlers.ts @@ -1,6 +1,6 @@ import { rest } from 'msw'; import { umbUserGroupsData } from '../data/user-groups.data'; -import type { UserGroupDetails } from '@umbraco-cms/models'; +import type { UserGroupDetails } from '@umbraco-cms/backoffice/models'; export const handlers = [ rest.get('/umbraco/backoffice/user-groups/list/items', (req, res, ctx) => { @@ -14,19 +14,19 @@ export const handlers = [ return res(ctx.status(200), ctx.json(response)); }), - rest.get('/umbraco/backoffice/user-groups/details/:key', (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get('/umbraco/backoffice/user-groups/details/:id', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const userGroup = umbUserGroupsData.getByKey(key); + const userGroup = umbUserGroupsData.getById(id); return res(ctx.status(200), ctx.json(userGroup)); }), rest.get('/umbraco/backoffice/user-groups/getByKeys', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (keys.length === 0) return; - const userGroups = umbUserGroupsData.getByKeys(keys); + const ids = req.url.searchParams.getAll('id'); + if (ids.length === 0) return; + const userGroups = umbUserGroupsData.getByIds(ids); return res(ctx.status(200), ctx.json(userGroups)); }), diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user.handlers.ts index ffceb99c85..76728489fa 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/user.handlers.ts @@ -1,6 +1,6 @@ import { rest } from 'msw'; -import { umbracoPath } from '@umbraco-cms/utils'; +import { umbracoPath } from '@umbraco-cms/backoffice/utils'; let isAuthenticated = false; diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/users.handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/users.handlers.ts index e6b8cea1fc..e56784f793 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/domains/users.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/domains/users.handlers.ts @@ -1,7 +1,7 @@ import { rest } from 'msw'; import { v4 as uuidv4 } from 'uuid'; import { umbUsersData } from '../data/users.data'; -import type { UserDetails } from '@umbraco-cms/models'; +import type { UserDetails } from '@umbraco-cms/backoffice/models'; // TODO: add schema export const handlers = [ @@ -16,19 +16,19 @@ export const handlers = [ return res(ctx.status(200), ctx.json(response)); }), - rest.get('/umbraco/backoffice/users/details/:key', (req, res, ctx) => { - const key = req.params.key as string; - if (!key) return; + rest.get('/umbraco/backoffice/users/details/:id', (req, res, ctx) => { + const id = req.params.id as string; + if (!id) return; - const user = umbUsersData.getByKey(key); + const user = umbUsersData.getById(id); return res(ctx.status(200), ctx.json(user)); }), rest.get('/umbraco/backoffice/users/getByKeys', (req, res, ctx) => { - const keys = req.url.searchParams.getAll('key'); - if (keys.length === 0) return; - const users = umbUsersData.getByKeys(keys); + const ids = req.url.searchParams.getAll('id'); + if (ids.length === 0) return; + const users = umbUsersData.getByIds(ids); return res(ctx.status(200), ctx.json(users)); }), @@ -49,7 +49,7 @@ export const handlers = [ if (!data) return; const newUser: UserDetails = { - key: uuidv4(), + id: uuidv4(), name: data.name, email: data.email, status: 'invited', @@ -57,7 +57,7 @@ export const handlers = [ updateDate: new Date().toISOString(), createDate: new Date().toISOString(), failedLoginAttempts: 0, - parentKey: '', + parentId: '', hasChildren: false, type: 'user', icon: 'umb:icon-user', @@ -66,7 +66,7 @@ export const handlers = [ mediaStartNodes: [], }; - const invited = umbUsersData.save([newUser]); + const invited = umbUsersData.save(newUser); console.log('invited', invited); diff --git a/src/Umbraco.Web.UI.Client/src/core/mocks/e2e-handlers.ts b/src/Umbraco.Web.UI.Client/src/core/mocks/e2e-handlers.ts index eb8be4c283..e0a5d8efe6 100644 --- a/src/Umbraco.Web.UI.Client/src/core/mocks/e2e-handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/core/mocks/e2e-handlers.ts @@ -1,4 +1,4 @@ -import { handlers as dataTypeHandlers } from './domains/data-type.handlers'; +import { handlers as dataTypeHandlers } from './domains/data-type'; import { handlers as documentTypeHandlers } from './domains/document-type.handlers'; import { handlers as installHandlers } from './domains/install.handlers'; import * as manifestsHandlers from './domains/manifests.handlers'; diff --git a/src/Umbraco.Web.UI.Client/src/core/modal/index.ts b/src/Umbraco.Web.UI.Client/src/core/modal/index.ts new file mode 100644 index 0000000000..ee83635e51 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/modal/index.ts @@ -0,0 +1,2 @@ +export * from './modal-element-picker-base'; +export * from './modal-element.element'; diff --git a/src/Umbraco.Web.UI.Client/libs/modal/elements/modal-element-picker-base.ts b/src/Umbraco.Web.UI.Client/src/core/modal/modal-element-picker-base.ts similarity index 80% rename from src/Umbraco.Web.UI.Client/libs/modal/elements/modal-element-picker-base.ts rename to src/Umbraco.Web.UI.Client/src/core/modal/modal-element-picker-base.ts index 8e7ff3d404..6cee4e6443 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/elements/modal-element-picker-base.ts +++ b/src/Umbraco.Web.UI.Client/src/core/modal/modal-element-picker-base.ts @@ -1,16 +1,6 @@ import { property } from 'lit/decorators.js'; -import { UmbModalBaseElement } from '..'; -import './modal-element.element'; - -export interface UmbPickerModalData { - multiple: boolean; - selection: Array; - filter?: (language: T) => boolean; -} - -export interface UmbPickerModalResult { - selection: Array; -} +import { UmbModalBaseElement } from './modal-element.element'; +import { UmbPickerModalData, UmbPickerModalResult } from '@umbraco-cms/backoffice/modal'; // TODO: we should consider moving this into a class/context instead of an element. // So we don't have to extend an element to get basic picker/selection logic diff --git a/src/Umbraco.Web.UI.Client/libs/modal/elements/modal-element.element.ts b/src/Umbraco.Web.UI.Client/src/core/modal/modal-element.element.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/libs/modal/elements/modal-element.element.ts rename to src/Umbraco.Web.UI.Client/src/core/modal/modal-element.element.ts index e51b4f959a..005bf6baac 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/elements/modal-element.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/modal/modal-element.element.ts @@ -1,9 +1,9 @@ import { customElement, property } from 'lit/decorators.js'; -import { UmbModalHandler } from '..'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UmbModalHandler } from '@umbraco-cms/backoffice/modal'; @customElement('umb-modal-element') -export class UmbModalBaseElement extends UmbLitElement { +export class UmbModalBaseElement extends UmbLitElement { @property({ attribute: false }) modalHandler?: UmbModalHandler; @@ -13,6 +13,6 @@ export class UmbModalBaseElement ext declare global { interface HTMLElementTagNameMap { - 'umb-modal-element': UmbModalBaseElement; + 'umb-modal-element': UmbModalBaseElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/core/modal/stories/modal.mdx b/src/Umbraco.Web.UI.Client/src/core/modal/stories/modal.mdx new file mode 100644 index 0000000000..e04cdacc9e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/modal/stories/modal.mdx @@ -0,0 +1,276 @@ +import { Meta } from '@storybook/blocks'; + + + +# Modals + +A modal is a popup that darkens the background and has focus lock. There are two types of modals: "dialog" and "sidebar". + +**Dialog modals** appears in the middle of the screen. +| option | values | +|:------:|:--------------------------:| +| No options yet | | + +**Sidebar modals** slides in from the right. +| option | values | +|:------:|:--------------------------:| +| size | small, medium, large, full | + +## Basic Usage + +### Consume UmbModalContext from an element + +The UmbModal context can be used to open modals. + +```ts +import { LitElement } from 'lit'; +import { UmbElementMixin } from '@umbraco-cms/element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_ALIAS } from '@umbraco-cms/modal'; + +class MyElement extends UmbElementMixin(LitElement) { + #modalContext?: UmbModalContext; + + constructor() { + super(); + this.consumeContext(UMB_MODAL_CONTEXT_ALIAS, (instance) => { + this.#modalContext = instance; + // modalContext is now ready to be used. + }); + } +} +``` + +### Open a modal + +A modal can be opned in two ways. Either you registrer the modal with a route or at runtime open the modal. Notice the first one will enable users to deep link to the modal, this might be preferable in some cases if not go for the last. + +#### Simple Modal Route Registration + +A modal can be registred via the UmbModalRouteRegistrationController. The registration will accept a modal token (or extension alias). + +Notice we are using a Controller here, this means your element has to be a Controller Host (TODO: Insert link to story about Controller Host also available through the UmbElementMixin) + +```ts +this.myModalRegistration = new UmbModalRouteRegistrationController(this, UMB_LINK_PICKER_MODAL) + .onSubmit((submitData) => { + console.log('Modal submitted with data'.submitData); + }) + .observeRouteBuilder((routeBuilder) => { + this._modalRouteBuilder = routeBuilder; + }); +``` + +The registration holds an instance of its UmbModalHandler when the modal it active. +The modal registration accepts 4 different callbacks: + +- onSetup - called when the modal is opened +- onSubmit - called when the modal is submitted +- onReject - called when the modal is rejected +- observeRouteBuilder - called when the modal route changes, use the given route builder to build a route to open the modal. + +#### TODOS: + +descripe the addional features of the route Registration: + +##### Hints: + +- Add unique parts to the path. (How is this cone properly as part of a Property Editor) +- A modal registred in a dashboard can be relatively simple. +- A modal registred in a property editor, needs to become specific for the property and the variant of that property. + +- Build some data for the setup. +- Reject a modal by returning false in setup. +- Use a param as part of setup to determin the data going to the modal. + +#### Modal registration for UI as part of a Property Editor + +```ts + + + @property() + public set alias(value: string | undefined) { + this.myModalRegistration.setUniqueIdentifier('propertyAlias', value); + } + + @property() + public set variantId(value: string | UmbVariantId | undefined) { + this.myModalRegistration.setUniqueIdentifier('variantId', value?.toString()); + } + + private _items = [ + { name: 'Item 1' }, + { name: 'Item 2' }, + { name: 'Item 3' }, + ] + + + constructor() { + super(); + + this.myModalRegistration = new UmbModalRouteRegistrationController( + this, + MY_MODAL_TOKEN, + `:index`, + new Map([ + ['propertyAlias', undefined], + ['variantId', undefined], + ]) + ) + .onSetup((params) => { + // Get item index: + const indexParam = params.index; + if (!indexParam) return false; + let index: number | null = parseInt(params.index); + if (Number.isNaN(index)) return false; + + // Use the index to find data: + let data = null; + if (index >= 0 && index < this._items.length) { + data = this._items[index]; + } else { + // If not then make a new pick: + index = null; + } + + return { + index: index, + itemData: { + name: data?.name + }, + }; + }) + .onSubmit((submitData) => { + if (!submitData) return; + this._items[submitData.index] = submitData.itemData; + }) + .observeRouteBuilder((routeBuilder) => { + this._modalRouteBuilder = routeBuilder; + }); + } + + render() { + return html` + ${this._items?.map((item, index) => + html`Add` + )} + `; + } +``` + +#### Generate the URL to a Modal Route Registration + +The Modal registration has an option to retrive a URL Builder, this is a function that can be used to generate a URL to a modal. + +```ts +const modalLink = _myUrlBuilder?.({ alias: 'my-input-alias' }); +``` + +The modalLink from above could look like: /umbraco/backoffice/my/location/modal/Our.Modal.SomethingPicker/my-input-alias + +Notice the Property Editor registration will add the property alias and variant id to the URL, so it becomes: + +/umbraco/backoffice/my/location/modal/Our.Modal.SomethingPicker/my-property-alias/en-us/my-input-alias + +#### Open A Modal at own initiative + +A modal can be opened by calling the open method on the UmbModalContext. The methods will accept a modal token (or extension alias), an optional dataset, and optional modal options. It returns an instance of UmbModalHandler. + +```ts +import { html, LitElement } from 'lit'; +import { UmbElementMixin } from '@umbraco-cms/element'; +import { UmbModalContext, UMB_MODAL_CONTEXT_ALIAS } from '@umbraco-cms/modal'; +class MyElement extends UmbElementMixin(LitElement) { + #modalContext?: UmbModalContext; + + constructor() { + super(); + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.#modalContext = instance; + // modalContext is now ready to be used + }); + } + + #onClick() { + const data = {'data goes here'}; + const options {'options go here'}; + const modalHandler = this.#modalContext?.open(MY_MODAL_TOKEN), data, options); + + modalHandler?.onSubmit().then((data) => { + // if modal submitted, then data is supplied here. + }); + } + + render() { + return html``; + } +} +``` + +## Create a custom modal + +### Register in the extension registry + +The manifest + +```json +{ + "type": "modal", + "alias": "My.Modal", + "name": "My Modal", + "js": "../path/to/my-modal.element.js" +} +``` + +### Create a modal token + +A modal token is a string that identifies a modal. It should be the modal extension alias. It is used to open a modal and is also to set default options for the modal. + +```ts +interface MyModalData = { + headline: string; + content: string; +} + +interface MyModalResult = { + myReturnData: string; +} + +const MY_MODAL_TOKEN = new ModalToken('My.Modal', { + type: 'sidebar', + size: 'small' +}); +``` + +The Modal element + +```ts +import { html, LitElement } from 'lit'; +import { UmbElementMixin } from '@umbraco-cms/element'; +import type { UmbModalHandler } from '@umbraco-cms/modal'; + +class MyDialog extends UmbElementMixin(LitElement) { + // the modal handler will be injected into the element when the modal is opened. + @property({ attribute: false }) + modalHandler?: UmbModalHandler; + + private _handleCancel() { + this._modalHandler?.close(); + } + + private _handleSubmit() { + /* Optional data of any type can be applied to the submit method to pass it + to the modal parent through the onSubmit promise. */ + this._modalHandler?.submit({ myReturnData: 'hello world' }); + } + + render() { + return html` +
    +

    My Modal

    + + +
    + `; + } +} +``` diff --git a/src/Umbraco.Web.UI.Client/libs/modal/stories/modal.stories.ts b/src/Umbraco.Web.UI.Client/src/core/modal/stories/modal.stories.ts similarity index 93% rename from src/Umbraco.Web.UI.Client/libs/modal/stories/modal.stories.ts rename to src/Umbraco.Web.UI.Client/src/core/modal/stories/modal.stories.ts index a1002bf1cf..e1c4bb2daa 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/stories/modal.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/core/modal/stories/modal.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; export default { title: 'API/Modals', diff --git a/src/Umbraco.Web.UI.Client/libs/modal/stories/story-modal-service-example.element.ts b/src/Umbraco.Web.UI.Client/src/core/modal/stories/story-modal-service-example.element.ts similarity index 86% rename from src/Umbraco.Web.UI.Client/libs/modal/stories/story-modal-service-example.element.ts rename to src/Umbraco.Web.UI.Client/src/core/modal/stories/story-modal-service-example.element.ts index 3a84115b8d..42f97388b3 100644 --- a/src/Umbraco.Web.UI.Client/libs/modal/stories/story-modal-service-example.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/modal/stories/story-modal-service-example.element.ts @@ -1,7 +1,7 @@ -import { html } from 'lit-html'; +import { html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '..'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_MODAL_CONTEXT_TOKEN, UmbModalContext } from '@umbraco-cms/backoffice/modal'; @customElement('story-modal-context-example') export class StoryModalContextExampleElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.element.ts b/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.element.ts index 9865415b78..a93352938d 100644 --- a/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.element.ts @@ -2,7 +2,7 @@ import { html, LitElement } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { UUITextStyles } from '@umbraco-ui/uui-css'; -import type { UmbNotificationDefaultData, UmbNotificationHandler } from '@umbraco-cms/notification'; +import type { UmbNotificationDefaultData, UmbNotificationHandler } from '@umbraco-cms/backoffice/notification'; export type { UmbNotificationDefaultData }; diff --git a/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.test.ts b/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.test.ts index 740526e1c6..bd9255136f 100644 --- a/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.test.ts +++ b/src/Umbraco.Web.UI.Client/src/core/notification/layouts/default/notification-layout-default.test.ts @@ -1,7 +1,7 @@ import { fixture, expect, html } from '@open-wc/testing'; import { UUIToastNotificationLayoutElement } from '@umbraco-ui/uui'; import { UmbNotificationLayoutDefaultElement, UmbNotificationDefaultData } from './notification-layout-default.element'; -import { UmbNotificationHandler } from '@umbraco-cms/notification'; +import { UmbNotificationHandler } from '@umbraco-cms/backoffice/notification'; describe('UmbNotificationLayoutDefault', () => { let element: UmbNotificationLayoutDefaultElement; diff --git a/src/Umbraco.Web.UI.Client/src/core/notification/stories/notification.stories.ts b/src/Umbraco.Web.UI.Client/src/core/notification/stories/notification.stories.ts index 8d019e412e..3c8e401107 100644 --- a/src/Umbraco.Web.UI.Client/src/core/notification/stories/notification.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/core/notification/stories/notification.stories.ts @@ -2,7 +2,7 @@ import './story-notification-default-example.element'; import { Meta, Story } from '@storybook/web-components'; import { html } from 'lit'; -import { UmbNotificationContext } from '@umbraco-cms/notification'; +import { UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; export default { title: 'API/Notifications/Overview', diff --git a/src/Umbraco.Web.UI.Client/src/core/notification/stories/story-notification-default-example.element.ts b/src/Umbraco.Web.UI.Client/src/core/notification/stories/story-notification-default-example.element.ts index b22fefe7ba..de78281ffb 100644 --- a/src/Umbraco.Web.UI.Client/src/core/notification/stories/story-notification-default-example.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/notification/stories/story-notification-default-example.element.ts @@ -5,8 +5,8 @@ import { UmbNotificationOptions, UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN, -} from '@umbraco-cms/notification'; -import { UmbLitElement } from '@umbraco-cms/element'; +} from '@umbraco-cms/backoffice/notification'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('story-notification-default-example') export class StoryNotificationDefaultExampleElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/core/router/index.ts b/src/Umbraco.Web.UI.Client/src/core/router/index.ts index 75fd79f5e4..fbbe29d96c 100644 --- a/src/Umbraco.Web.UI.Client/src/core/router/index.ts +++ b/src/Umbraco.Web.UI.Client/src/core/router/index.ts @@ -1,4 +1,4 @@ -export * from 'router-slot'; export * from './router-slot.element'; export * from './router-slot-change.event'; export * from './router-slot-init.event'; +export * from './variant-router-slot.element'; diff --git a/src/Umbraco.Web.UI.Client/src/core/router/router-slot.element.ts b/src/Umbraco.Web.UI.Client/src/core/router/router-slot.element.ts index 1269dcd227..d055f41278 100644 --- a/src/Umbraco.Web.UI.Client/src/core/router/router-slot.element.ts +++ b/src/Umbraco.Web.UI.Client/src/core/router/router-slot.element.ts @@ -1,28 +1,45 @@ -import type { IRoute } from 'router-slot/model'; -import { RouterSlot } from 'router-slot'; -import { LitElement, PropertyValueMap } from 'lit'; +// eslint-disable-next-line local-rules/no-external-imports +import { RouterSlot } from 'router-slot/router-slot'; +import { css, html, PropertyValueMap } from 'lit'; import { customElement, property } from 'lit/decorators.js'; +import { UmbLitElement } from '../lit-element'; import { UmbRouterSlotInitEvent } from './router-slot-init.event'; import { UmbRouterSlotChangeEvent } from './router-slot-change.event'; +import { UmbRouteContext, UmbRoute } from '@umbraco-cms/backoffice/router'; /** - * @element umb-router-slot-element + * @element umb-router-slot * @description - Component for wrapping Router Slot element, providing some local events for implementation. - * @extends UmbRouterSlotElement + * @extends UmbLitElement * @fires {UmbRouterSlotInitEvent} init - fires when the router is connected * @fires {UmbRouterSlotChangeEvent} change - fires when a path of this router is changed */ @customElement('umb-router-slot') -export class UmbRouterSlotElement extends LitElement { +export class UmbRouterSlotElement extends UmbLitElement { + static styles = [ + css` + :host { + display: flex; + flex-direction: column; + height: 100%; + } + + router-slot { + height: 100%; + } + `, + ]; + #router: RouterSlot = new RouterSlot(); + #modalRouter: RouterSlot = new RouterSlot(); #listening = false; @property() - public get routes(): IRoute[] | undefined { - return (this.#router as any).routes; + public get routes(): UmbRoute[] | undefined { + return this.#router.routes; } - public set routes(value: IRoute[] | undefined) { - (this.#router as any).routes = value; + public set routes(value: UmbRoute[] | undefined) { + this.#router.routes = value || []; } private _routerPath?: string; @@ -39,14 +56,30 @@ export class UmbRouterSlotElement extends LitElement { return this._routerPath + '/' + this._activeLocalPath; } + #routeContext = new UmbRouteContext(this, (contextRoutes) => { + this.#modalRouter.routes = contextRoutes; + // Force a render? + this.#modalRouter.render(); + }); + constructor() { super(); - this.#router.addEventListener('changestate', this._onChangeState); + this.#modalRouter.parent = this.#router; + this.#modalRouter.style.display = 'none'; + this.#router.addEventListener('changestate', this._updateRouterPath.bind(this)); + //this.#router.appendChild(this.#modalRouter); this.#router.appendChild(document.createElement('slot')); } + protected _constructAbsoluteRouterPath() { + return this.#router.constructAbsolutePath('') || ''; + } + connectedCallback() { super.connectedCallback(); + // Currently we have to set this every time as RouteSlot looks for its parent every-time it is connected. Aka it has not way to explicitly set the parent. + // And we cannot insert the modal router as a slotted-child of the router, as it flushes its children on every route change. + this.#modalRouter.parent = this.#router; if (this.#listening === false) { window.addEventListener('navigationsuccess', this._onNavigationChanged); this.#listening = true; @@ -61,14 +94,16 @@ export class UmbRouterSlotElement extends LitElement { protected firstUpdated(_changedProperties: PropertyValueMap | Map): void { super.firstUpdated(_changedProperties); - this._routerPath = this.#router.constructAbsolutePath('') || ''; + this._routerPath = this._constructAbsoluteRouterPath(); + this.#routeContext._internal_routerGotBasePath(this._routerPath); this.dispatchEvent(new UmbRouterSlotInitEvent()); } - private _onChangeState = () => { - const newAbsolutePath = this.#router.constructAbsolutePath('') || ''; + protected _updateRouterPath() { + const newAbsolutePath = this._constructAbsoluteRouterPath(); if (this._routerPath !== newAbsolutePath) { this._routerPath = newAbsolutePath; + this.#routeContext._internal_routerGotBasePath(this._routerPath); this.dispatchEvent(new UmbRouterSlotInitEvent()); const newActiveLocalPath = this.#router.match?.route.path; @@ -77,17 +112,20 @@ export class UmbRouterSlotElement extends LitElement { this.dispatchEvent(new UmbRouterSlotChangeEvent()); } } - }; + } private _onNavigationChanged = (event?: any) => { if (event.detail.slot === this.#router) { this._activeLocalPath = event.detail.match.route.path; this.dispatchEvent(new UmbRouterSlotChangeEvent()); + } else if (event.detail.slot === this.#modalRouter) { + const newActiveModalLocalPath = event.detail.match.route.path; + this.#routeContext._internal_modalRouterChanged(newActiveModalLocalPath); } }; render() { - return this.#router; + return html`${this.#router}${this.#modalRouter}`; } } diff --git a/src/Umbraco.Web.UI.Client/src/core/router/variant-router-slot.element.ts b/src/Umbraco.Web.UI.Client/src/core/router/variant-router-slot.element.ts new file mode 100644 index 0000000000..c5e125fee7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/core/router/variant-router-slot.element.ts @@ -0,0 +1,79 @@ +import { customElement, property } from 'lit/decorators.js'; +import { UmbVariantId } from '../../backoffice/shared/variants/variant-id.class'; +import { UmbRouterSlotElement } from './router-slot.element'; +import { UmbRoute } from '@umbraco-cms/backoffice/router'; + +function variantIdsToString(variantIds: UmbVariantId[]): string { + return variantIds.map((id) => id.toString()).join('_&_'); +} + +/** + * @element umb-variant-router-slot-element + * @description - Component for wrapping Router Slot element, providing + * @extends UmbRouterSlotElement + * @fires {UmbRouterSlotInitEvent} init - fires when the router is connected + * @fires {UmbRouterSlotChangeEvent} change - fires when a path of this router is changed + */ +@customElement('umb-variant-router-slot') +export class UmbVariantRouterSlotElement extends UmbRouterSlotElement { + #variantIds: UmbVariantId[] = []; + + #getPathPrefix() { + return variantIdsToString(this.#variantIds); + } + + #currentPathPrefix = ''; + private _routes?: UmbRoute[]; + public get routes(): UmbRoute[] | undefined { + return this._routes; + } + public set routes(value: UmbRoute[] | undefined) { + this._routes = value; + if (this.#variantIds.length > 0) { + this._updateRoutes(); + } + } + + private _updateRoutes() { + const newPrefix = this.#getPathPrefix(); + if (newPrefix !== this.#currentPathPrefix) { + this.#currentPathPrefix = newPrefix; + const prepend = newPrefix === '' ? '' : newPrefix + '/'; + const mappedRoutes = this._routes?.map((route) => { + return { + ...route, + path: prepend + route.path, + }; + }); + super.routes = mappedRoutes; + this._updateRouterPath(); + } + } + + @property() + public get variantId(): UmbVariantId[] { + return this.#variantIds; + } + public set variantId(value: UmbVariantId[] | UmbVariantId) { + if (Array.isArray(value)) { + this.#variantIds = [...(value as UmbVariantId[])]; + } else if (value) { + this.#variantIds = [value]; + } else { + this.#variantIds = []; + } + if (this._routes) { + this._updateRoutes(); + } + } + + protected _constructAbsoluteRouterPath() { + return super._constructAbsoluteRouterPath() + (this.#currentPathPrefix !== '' ? '/' + this.#currentPathPrefix : ''); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-variant-router-slot': UmbVariantRouterSlotElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/icon.store.ts b/src/Umbraco.Web.UI.Client/src/core/stores/icon/icon.store.ts similarity index 93% rename from src/Umbraco.Web.UI.Client/libs/store/icon/icon.store.ts rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/icon.store.ts index db6e4f237c..654e767ca2 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/icon/icon.store.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/icon/icon.store.ts @@ -1,5 +1,5 @@ import { UUIIconRegistry } from '@umbraco-ui/uui-icon-registry'; -import icons from '../../../public-assets/icons/icons.json'; +import icons from '../../../../public-assets/icons/icons.json'; interface UmbIconDescriptor { name: string; diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/icon.stories.ts b/src/Umbraco.Web.UI.Client/src/core/stores/icon/icon.stories.ts similarity index 90% rename from src/Umbraco.Web.UI.Client/libs/store/icon/icon.stories.ts rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/icon.stories.ts index 3ff7779ff8..33a278ba1c 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/icon/icon.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/core/stores/icon/icon.stories.ts @@ -1,7 +1,7 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { repeat } from 'lit/directives/repeat.js'; -import icons from '../../../public-assets/icons/icons.json'; +import icons from '../../../../public-assets/icons/icons.json'; export default { title: 'API/Icons', diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-activity.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-activity.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-activity.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-activity.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-add.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-add.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-add.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-add.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-addressbook.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-addressbook.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-addressbook.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-addressbook.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alarm-clock.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alarm-clock.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alarm-clock.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alarm-clock.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alert-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alert-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alert-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alert-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alert.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alert.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alert.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alert.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-anchor.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-anchor.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-anchor.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-anchor.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-app.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-app.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-app.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-app.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-application-error.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-application-error.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-application-error.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-application-error.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-application-window-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-application-window-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-application-window-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-application-window-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-application-window.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-application-window.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-application-window.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-application-window.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrivals.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrivals.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrivals.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrivals.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-down.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-down.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-down.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-down.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-left.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-left.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-left.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-left.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-right.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-right.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-right.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-right.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-up.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-up.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-arrow-up.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-arrow-up.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-art-easel.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-art-easel.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-art-easel.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-art-easel.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-article.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-article.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-article.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-article.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-attachment.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-attachment.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-attachment.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-attachment.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-auction-hammer.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-auction-hammer.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-auction-hammer.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-auction-hammer.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-autofill.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-autofill.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-autofill.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-autofill.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-award.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-award.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-award.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-award.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-axis-rotation-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-axis-rotation-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-axis-rotation-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-axis-rotation-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-axis-rotation-3.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-axis-rotation-3.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-axis-rotation-3.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-axis-rotation-3.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-axis-rotation.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-axis-rotation.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-axis-rotation.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-axis-rotation.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-baby-stroller.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-baby-stroller.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-baby-stroller.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-baby-stroller.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-backspace.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-backspace.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-backspace.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-backspace.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-add.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-add.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-add.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-add.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-count.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-count.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-count.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-count.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-remove.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-remove.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-remove.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-remove.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-restricted.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-restricted.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-badge-restricted.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-badge-restricted.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ball.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ball.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ball.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ball.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-band-aid.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-band-aid.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-band-aid.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-band-aid.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bar-chart.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bar-chart.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bar-chart.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bar-chart.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-barcode.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-barcode.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-barcode.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-barcode.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bars.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bars.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bars.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bars.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-battery-full.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-battery-full.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-battery-full.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-battery-full.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-battery-low.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-battery-low.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-battery-low.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-battery-low.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-beer-glass.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-beer-glass.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-beer-glass.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-beer-glass.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bell-off.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bell-off.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bell-off.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bell-off.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bell.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bell.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bell.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bell.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-dollar.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-dollar.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-dollar.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-dollar.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-euro.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-euro.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-euro.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-euro.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-pound.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-pound.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-pound.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-pound.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-yen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-yen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill-yen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill-yen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bill.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bill.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-billboard.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-billboard.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-billboard.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-billboard.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-dollar.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-dollar.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-dollar.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-dollar.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-euro.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-euro.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-euro.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-euro.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-pound.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-pound.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-pound.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-pound.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-yen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-yen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills-yen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills-yen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bills.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bills.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-binarycode.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-binarycode.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-binarycode.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-binarycode.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-binoculars.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-binoculars.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-binoculars.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-binoculars.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bird.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bird.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bird.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bird.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-birthday-cake.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-birthday-cake.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-birthday-cake.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-birthday-cake.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-block.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-block.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-block.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-block.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-blueprint.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-blueprint.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-blueprint.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-blueprint.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bluetooth.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bluetooth.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bluetooth.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bluetooth.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-boat-shipping.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-boat-shipping.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-boat-shipping.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-boat-shipping.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bomb.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bomb.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bomb.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bomb.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bones.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bones.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bones.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bones.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-book-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-book-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-book-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-book-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-book-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-book-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-book-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-book-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-book.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-book.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-book.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-book.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bookmark.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bookmark.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bookmark.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bookmark.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-books.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-books.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-books.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-books.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-box-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-box-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-box-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-box-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-box-open.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-box-open.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-box-open.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-box-open.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-box.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-box.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-box.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-box.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brackets.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brackets.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brackets.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brackets.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brick.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brick.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brick.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brick.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-briefcase.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-briefcase.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-briefcase.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-briefcase.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-browser-window.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-browser-window.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-browser-window.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-browser-window.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brush-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brush-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brush-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brush-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brush-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brush-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brush-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brush-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brush.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brush.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-brush.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-brush.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bug.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bug.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bug.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bug.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bulleted-list.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bulleted-list.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bulleted-list.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bulleted-list.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-burn.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-burn.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-burn.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-burn.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bus.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bus.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-bus.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-bus.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-calculator.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-calculator.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-calculator.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-calculator.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-calendar-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-calendar-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-calendar-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-calendar-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-calendar.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-calendar.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-calendar.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-calendar.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-camcorder.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-camcorder.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-camcorder.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-camcorder.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-camera-roll.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-camera-roll.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-camera-roll.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-camera-roll.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-candy.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-candy.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-candy.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-candy.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-caps-lock.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-caps-lock.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-caps-lock.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-caps-lock.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-car.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-car.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-car.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-car.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cash-register.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cash-register.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cash-register.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cash-register.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-categories.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-categories.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-categories.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-categories.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-certificate.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-certificate.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-certificate.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-certificate.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chart-curve.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chart-curve.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chart-curve.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chart-curve.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chart.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chart.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chart.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chart.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chat-active.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chat-active.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chat-active.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chat-active.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chat.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chat.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chat.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chat.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-check.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-check.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-check.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-check.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox-dotted-active.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox-dotted-active.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox-dotted-active.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox-dotted-active.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox-dotted.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox-dotted.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox-dotted.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox-dotted.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox-empty.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox-empty.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox-empty.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox-empty.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-checkbox.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-checkbox.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chess.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chess.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chess.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chess.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chip-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chip-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chip-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chip-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chip.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chip.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-chip.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-chip.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cinema.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cinema.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cinema.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cinema.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circle-dotted-active.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circle-dotted-active.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circle-dotted-active.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circle-dotted-active.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circle-dotted.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circle-dotted.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circle-dotted.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circle-dotted.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circuits.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circuits.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circuits.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circuits.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circus.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circus.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-circus.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-circus.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-client.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-client.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-client.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-client.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-clothes-hanger.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-clothes-hanger.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-clothes-hanger.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-clothes-hanger.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloud-drive.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloud-drive.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloud-drive.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloud-drive.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloud-upload.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloud-upload.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloud-upload.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloud-upload.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloud.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloud.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloud.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloud.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloudy.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloudy.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cloudy.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cloudy.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-clubs.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-clubs.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-clubs.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-clubs.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cocktail.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cocktail.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cocktail.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cocktail.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-code.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-code.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-code.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-code.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coffee.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coffee.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coffee.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coffee.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-dollar.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-dollar.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-dollar.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-dollar.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-euro.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-euro.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-euro.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-euro.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-pound.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-pound.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-pound.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-pound.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-yen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-yen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin-yen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin-yen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coin.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coin.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-dollar-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-dollar-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-dollar-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-dollar-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-dollar.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-dollar.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-dollar.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-dollar.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-euro-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-euro-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-euro-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-euro-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-euro.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-euro.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-euro.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-euro.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-pound-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-pound-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-pound-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-pound-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-pound.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-pound.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-pound.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-pound.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-yen-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-yen-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-yen-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-yen-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-yen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-yen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins-yen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins-yen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coins.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coins.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-color-bucket.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-color-bucket.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-color-bucket.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-color-bucket.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-colorpicker.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-colorpicker.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-colorpicker.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-colorpicker.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-columns.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-columns.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-columns.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-columns.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-comb.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-comb.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-comb.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-comb.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-combination-lock-open.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-combination-lock-open.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-combination-lock-open.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-combination-lock-open.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-combination-lock.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-combination-lock.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-combination-lock.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-combination-lock.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-command.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-command.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-command.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-command.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-company.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-company.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-company.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-company.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-compress.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-compress.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-compress.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-compress.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-connection.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-connection.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-connection.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-connection.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-console.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-console.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-console.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-console.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-contrast.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-contrast.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-contrast.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-contrast.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-conversation-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-conversation-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-conversation-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-conversation-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-conversation.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-conversation.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-conversation.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-conversation.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coverflow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coverflow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-coverflow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-coverflow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-credit-card-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-credit-card-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-credit-card-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-credit-card-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-credit-card.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-credit-card.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-credit-card.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-credit-card.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crop.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crop.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crop.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crop.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crosshair.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crosshair.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crosshair.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crosshair.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crown-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crown-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crown-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crown-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crown.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crown.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-crown.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-crown.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cupcake.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cupcake.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cupcake.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cupcake.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-curve.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-curve.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-curve.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-curve.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cut.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cut.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-cut.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-cut.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dashboard.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dashboard.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dashboard.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dashboard.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-defrag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-defrag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-defrag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-defrag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-delete-key.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-delete-key.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-delete-key.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-delete-key.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-delete.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-delete.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-delete.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-delete.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-departure.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-departure.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-departure.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-departure.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-desk.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-desk.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-desk.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-desk.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-desktop.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-desktop.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-desktop.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-desktop.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diagnostics.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diagnostics.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diagnostics.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diagnostics.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diagonal-arrow-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diagonal-arrow-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diagonal-arrow-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diagonal-arrow-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diagonal-arrow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diagonal-arrow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diagonal-arrow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diagonal-arrow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diamond.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diamond.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diamond.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diamond.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diamonds.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diamonds.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diamonds.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diamonds.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dice.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dice.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dice.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dice.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diploma-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diploma-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diploma-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diploma-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diploma.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diploma.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-diploma.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-diploma.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-directions-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-directions-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-directions-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-directions-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-directions.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-directions.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-directions.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-directions.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-disc.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-disc.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-disc.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-disc.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-disk-image.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-disk-image.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-disk-image.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-disk-image.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-display.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-display.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-display.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-display.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dna.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dna.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dna.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dna.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dock-connector.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dock-connector.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dock-connector.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dock-connector.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-document-dashed-line.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-document-dashed-line.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-document-dashed-line.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-document-dashed-line.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-document.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-document.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-document.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-document.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-documents.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-documents.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-documents.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-documents.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dollar-bag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dollar-bag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-dollar-bag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-dollar-bag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-donate.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-donate.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-donate.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-donate.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-door-open-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-door-open-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-door-open-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-door-open-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-door-open.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-door-open.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-door-open.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-door-open.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-download-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-download-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-download-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-download-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-download.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-download.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-download.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-download.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-drop.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-drop.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-drop.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-drop.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-eco.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-eco.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-eco.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-eco.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-economy.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-economy.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-economy.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-economy.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-edit.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-edit.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-edit.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-edit.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-eject.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-eject.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-eject.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-eject.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-employee.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-employee.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-employee.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-employee.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-energy-saving-bulb.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-energy-saving-bulb.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-energy-saving-bulb.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-energy-saving-bulb.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-enter.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-enter.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-enter.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-enter.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-equalizer.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-equalizer.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-equalizer.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-equalizer.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-escape.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-escape.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-escape.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-escape.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ethernet.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ethernet.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ethernet.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ethernet.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-euro-bag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-euro-bag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-euro-bag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-euro-bag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-exit-fullscreen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-exit-fullscreen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-exit-fullscreen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-exit-fullscreen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-eye.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-eye.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-eye.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-eye.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-facebook-like.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-facebook-like.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-facebook-like.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-facebook-like.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-factory.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-factory.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-factory.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-factory.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-favorite.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-favorite.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-favorite.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-favorite.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-female-symbol.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-female-symbol.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-female-symbol.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-female-symbol.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-file-cabinet.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-file-cabinet.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-file-cabinet.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-file-cabinet.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-files.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-files.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-files.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-files.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-filter-arrows.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-filter-arrows.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-filter-arrows.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-filter-arrows.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-filter.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-filter.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-filter.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-filter.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fingerprint.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fingerprint.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fingerprint.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fingerprint.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fire.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fire.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fire.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fire.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-firewall.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-firewall.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-firewall.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-firewall.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-firewire.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-firewire.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-firewire.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-firewire.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flag-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flag-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flag-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flag-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flash.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flash.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flash.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flash.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flashlight.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flashlight.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flashlight.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flashlight.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flowerpot.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flowerpot.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-flowerpot.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-flowerpot.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folder-open.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folder-open.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folder-open.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folder-open.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folder-outline.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folder-outline.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folder-outline.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folder-outline.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folder.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folder.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folder.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folder.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folders.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folders.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-folders.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-folders.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-font.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-font.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-font.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-font.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-food.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-food.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-food.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-food.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-footprints.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-footprints.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-footprints.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-footprints.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-forking.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-forking.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-forking.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-forking.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-frame-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-frame-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-frame-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-frame-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-frame.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-frame.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-frame.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-frame.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fullscreen-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fullscreen-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fullscreen-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fullscreen-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fullscreen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fullscreen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-fullscreen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-fullscreen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-game.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-game.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-game.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-game.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-geometry.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-geometry.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-geometry.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-geometry.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-gift.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-gift.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-gift.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-gift.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-glasses.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-glasses.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-glasses.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-glasses.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-asia.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-asia.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-asia.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-asia.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-europe-africa.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-europe-africa.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-europe-africa.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-europe-africa.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-inverted-america.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-inverted-america.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-inverted-america.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-inverted-america.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-inverted-asia.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-inverted-asia.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-inverted-asia.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-inverted-asia.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-inverted-europe-africa.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-inverted-europe-africa.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe-inverted-europe-africa.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe-inverted-europe-africa.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-globe.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-globe.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-gps.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-gps.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-gps.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-gps.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-graduate.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-graduate.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-graduate.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-graduate.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-grid.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-grid.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-grid.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-grid.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hammer.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hammer.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hammer.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hammer.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-active-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-active-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-active-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-active-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-active.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-active.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-active.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-active.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-pointer-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-pointer-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-pointer-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-pointer-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-pointer.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-pointer.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hand-pointer.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hand-pointer.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handprint.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handprint.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handprint.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handprint.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handshake.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handshake.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handshake.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handshake.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handtool-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handtool-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handtool-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handtool-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handtool.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handtool.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-handtool.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-handtool.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hard-drive-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hard-drive-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hard-drive-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hard-drive-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hard-drive.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hard-drive.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hard-drive.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hard-drive.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hat.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hat.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hat.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hat.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hd.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hd.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hd.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hd.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-headphones.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-headphones.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-headphones.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-headphones.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-headset.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-headset.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-headset.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-headset.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hearts.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hearts.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hearts.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hearts.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-height.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-height.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-height.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-height.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-help-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-help-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-help-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-help-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-help.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-help.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-help.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-help.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-home.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-home.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-home.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-home.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hourglass.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hourglass.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-hourglass.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-hourglass.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-imac.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-imac.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-imac.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-imac.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-inactive-line.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-inactive-line.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-inactive-line.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-inactive-line.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-inbox-full.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-inbox-full.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-inbox-full.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-inbox-full.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-inbox.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-inbox.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-inbox.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-inbox.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-indent.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-indent.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-indent.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-indent.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-infinity.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-infinity.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-infinity.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-infinity.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-info.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-info.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-info.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-info.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-invoice.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-invoice.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-invoice.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-invoice.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ipad.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ipad.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ipad.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ipad.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-iphone.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-iphone.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-iphone.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-iphone.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-item-arrangement.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-item-arrangement.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-item-arrangement.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-item-arrangement.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-junk.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-junk.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-junk.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-junk.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-key.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-key.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-key.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-key.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-keyboard.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-keyboard.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-keyboard.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-keyboard.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-keychain.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-keychain.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-keychain.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-keychain.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-keyhole.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-keyhole.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-keyhole.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-keyhole.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lab.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lab.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lab.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lab.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-laptop.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-laptop.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-laptop.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-laptop.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-layers-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-layers-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-layers-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-layers-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-layers.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-layers.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-layers.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-layers.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-layout.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-layout.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-layout.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-layout.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-left-double-arrow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-left-double-arrow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-left-double-arrow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-left-double-arrow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-legal.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-legal.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-legal.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-legal.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lense.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lense.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lense.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lense.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-library.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-library.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-library.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-library.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-light-down.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-light-down.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-light-down.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-light-down.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-light-up.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-light-up.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-light-up.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-light-up.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lightbulb-active.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lightbulb-active.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lightbulb-active.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lightbulb-active.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lightbulb.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lightbulb.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lightbulb.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lightbulb.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lightning.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lightning.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lightning.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lightning.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-link.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-link.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-link.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-link.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-linux-tux.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-linux-tux.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-linux-tux.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-linux-tux.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-list.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-list.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-list.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-list.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-load.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-load.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-load.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-load.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-loading.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-loading.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-loading.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-loading.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-locate.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-locate.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-locate.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-locate.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-location-near-me.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-location-near-me.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-location-near-me.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-location-near-me.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-location-nearby.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-location-nearby.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-location-nearby.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-location-nearby.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lock.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lock.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-lock.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-lock.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-log-out.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-log-out.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-log-out.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-log-out.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-logout.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-logout.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-logout.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-logout.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-loupe.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-loupe.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-loupe.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-loupe.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-magnet.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-magnet.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-magnet.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-magnet.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mailbox.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mailbox.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mailbox.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mailbox.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-male-and-female.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-male-and-female.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-male-and-female.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-male-and-female.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-male-symbol.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-male-symbol.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-male-symbol.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-male-symbol.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map-location.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map-location.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map-location.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map-location.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map-marker.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map-marker.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map-marker.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map-marker.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-map.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-map.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-medal.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-medal.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-medal.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-medal.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-medical-emergency.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-medical-emergency.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-medical-emergency.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-medical-emergency.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-medicine.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-medicine.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-medicine.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-medicine.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-meeting.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-meeting.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-meeting.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-meeting.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-megaphone.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-megaphone.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-megaphone.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-megaphone.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-merge.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-merge.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-merge.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-merge.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-message-open.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-message-open.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-message-open.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-message-open.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-message-unopened.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-message-unopened.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-message-unopened.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-message-unopened.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-message.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-message.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-message.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-message.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-microscope.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-microscope.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-microscope.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-microscope.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mindmap.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mindmap.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mindmap.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mindmap.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mobile.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mobile.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mobile.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mobile.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-molecular-network.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-molecular-network.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-molecular-network.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-molecular-network.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-molecular.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-molecular.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-molecular.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-molecular.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mountain.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mountain.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mountain.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mountain.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mouse-cursor.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mouse-cursor.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mouse-cursor.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mouse-cursor.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mouse.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mouse.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-mouse.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-mouse.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-movie-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-movie-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-movie-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-movie-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-movie.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-movie.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-movie.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-movie.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-multiple-credit-cards.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-multiple-credit-cards.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-multiple-credit-cards.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-multiple-credit-cards.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-multiple-windows.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-multiple-windows.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-multiple-windows.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-multiple-windows.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-music.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-music.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-music.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-music.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-name-badge.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-name-badge.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-name-badge.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-name-badge.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-bottom.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-bottom.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-bottom.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-bottom.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-down.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-down.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-down.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-down.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-first.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-first.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-first.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-first.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-horizontal.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-horizontal.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-horizontal.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-horizontal.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-last.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-last.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-last.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-last.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-left.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-left.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-left.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-left.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-right.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-right.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-right.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-right.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-road.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-road.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-road.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-road.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-top.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-top.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-top.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-top.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-up.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-up.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-up.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-up.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-vertical.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-vertical.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation-vertical.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation-vertical.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigation.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigation.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigational-arrow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigational-arrow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-navigational-arrow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-navigational-arrow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-network-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-network-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-network-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-network-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-newspaper-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-newspaper-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-newspaper-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-newspaper-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-newspaper.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-newspaper.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-newspaper.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-newspaper.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-next-media.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-next-media.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-next-media.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-next-media.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-next.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-next.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-next.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-next.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-nodes.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-nodes.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-nodes.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-nodes.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-notepad-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-notepad-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-notepad-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-notepad-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-notepad.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-notepad.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-notepad.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-notepad.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-old-key.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-old-key.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-old-key.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-old-key.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-old-phone.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-old-phone.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-old-phone.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-old-phone.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-operator.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-operator.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-operator.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-operator.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ordered-list.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ordered-list.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ordered-list.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ordered-list.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-os-x.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-os-x.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-os-x.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-os-x.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-out.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-out.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-out.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-out.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-outbox.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-outbox.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-outbox.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-outbox.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-outdent.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-outdent.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-outdent.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-outdent.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-add.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-add.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-add.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-add.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-down.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-down.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-down.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-down.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-remove.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-remove.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-remove.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-remove.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-restricted.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-restricted.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-restricted.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-restricted.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-up.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-up.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-page-up.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-page-up.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paint-roller.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paint-roller.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paint-roller.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paint-roller.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-palette.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-palette.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-palette.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-palette.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-panel-show.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-panel-show.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-panel-show.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-panel-show.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pannel-close.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pannel-close.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pannel-close.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pannel-close.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pants.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pants.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pants.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pants.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paper-bag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paper-bag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paper-bag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paper-bag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paper-plane-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paper-plane-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paper-plane-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paper-plane-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paper-plane.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paper-plane.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paper-plane.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paper-plane.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-parachute-drop.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-parachute-drop.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-parachute-drop.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-parachute-drop.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-parental-control.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-parental-control.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-parental-control.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-parental-control.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-partly-cloudy.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-partly-cloudy.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-partly-cloudy.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-partly-cloudy.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paste-in.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paste-in.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-paste-in.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-paste-in.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-path.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-path.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-path.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-path.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pause.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pause.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pause.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pause.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pc.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pc.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pc.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pc.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people-female.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people-female.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people-female.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people-female.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-people.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-people.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-phone-ring.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-phone-ring.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-phone-ring.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-phone-ring.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-phone.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-phone.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-phone.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-phone.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-photo-album.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-photo-album.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-photo-album.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-photo-album.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-picture.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-picture.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-picture.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-picture.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pictures-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pictures-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pictures-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pictures-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pictures-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pictures-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pictures-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pictures-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pictures.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pictures.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pictures.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pictures.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pie-chart.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pie-chart.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pie-chart.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pie-chart.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-piggy-bank.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-piggy-bank.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-piggy-bank.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-piggy-bank.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pin-location.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pin-location.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pin-location.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pin-location.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-piracy.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-piracy.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-piracy.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-piracy.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-plane.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-plane.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-plane.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-plane.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-planet.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-planet.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-planet.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-planet.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-play.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-play.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-play.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-play.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-playing-cards.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-playing-cards.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-playing-cards.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-playing-cards.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-playlist.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-playlist.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-playlist.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-playlist.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-plugin.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-plugin.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-plugin.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-plugin.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-podcast.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-podcast.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-podcast.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-podcast.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-poker-chip.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-poker-chip.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-poker-chip.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-poker-chip.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-poll.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-poll.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-poll.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-poll.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-post-it.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-post-it.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-post-it.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-post-it.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pound-bag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pound-bag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pound-bag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pound-bag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-power-outlet.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-power-outlet.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-power-outlet.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-power-outlet.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-power.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-power.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-power.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-power.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-presentation.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-presentation.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-presentation.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-presentation.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-previous-media.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-previous-media.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-previous-media.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-previous-media.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-previous.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-previous.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-previous.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-previous.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-dollar.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-dollar.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-dollar.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-dollar.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-euro.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-euro.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-euro.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-euro.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-pound.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-pound.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-pound.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-pound.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-yen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-yen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-price-yen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-price-yen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-print.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-print.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-print.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-print.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-printer-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-printer-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-printer-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-printer-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-projector.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-projector.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-projector.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-projector.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pulse.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pulse.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pulse.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pulse.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pushpin.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pushpin.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-pushpin.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-pushpin.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-qr-code.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-qr-code.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-qr-code.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-qr-code.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-quote.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-quote.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-quote.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-quote.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-radio-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-radio-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-radio-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-radio-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-radio-receiver.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-radio-receiver.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-radio-receiver.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-radio-receiver.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-radio.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-radio.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-radio.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-radio.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rain.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rain.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rain.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rain.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rate.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rate.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rate.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rate.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-re-post.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-re-post.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-re-post.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-re-post.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-readonly.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-readonly.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-readonly.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-readonly.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-dollar.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-dollar.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-dollar.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-dollar.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-euro.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-euro.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-euro.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-euro.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-pound.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-pound.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-pound.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-pound.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-yen.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-yen.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-receipt-yen.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-receipt-yen.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-reception.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-reception.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-reception.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-reception.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-record.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-record.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-record.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-record.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-redo.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-redo.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-redo.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-redo.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-refresh.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-refresh.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-refresh.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-refresh.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-remote.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-remote.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-remote.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-remote.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-remove.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-remove.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-remove.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-remove.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-repeat-one.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-repeat-one.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-repeat-one.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-repeat-one.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-repeat.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-repeat.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-repeat.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-repeat.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-reply-arrow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-reply-arrow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-reply-arrow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-reply-arrow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-resize.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-resize.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-resize.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-resize.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-return-to-top.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-return-to-top.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-return-to-top.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-return-to-top.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-right-double-arrow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-right-double-arrow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-right-double-arrow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-right-double-arrow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-road.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-road.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-road.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-road.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-roadsign.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-roadsign.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-roadsign.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-roadsign.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rocket.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rocket.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rocket.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rocket.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rss.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rss.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-rss.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-rss.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ruler-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ruler-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ruler-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ruler-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ruler.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ruler.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ruler.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ruler.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-safe.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-safe.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-safe.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-safe.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-safedial.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-safedial.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-safedial.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-safedial.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sandbox-toys.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sandbox-toys.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sandbox-toys.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sandbox-toys.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-satellite-dish.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-satellite-dish.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-satellite-dish.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-satellite-dish.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-save.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-save.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-save.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-save.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-scan.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-scan.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-scan.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-scan.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-school.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-school.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-school.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-school.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-screensharing.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-screensharing.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-screensharing.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-screensharing.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-script-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-script-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-script-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-script-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-script.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-script.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-script.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-script.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-scull.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-scull.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-scull.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-scull.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-search.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-search.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-search.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-search.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-security-camera.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-security-camera.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-security-camera.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-security-camera.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sensor.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sensor.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sensor.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sensor.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-server-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-server-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-server-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-server-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-server.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-server.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-server.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-server.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-settings-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-settings-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-settings-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-settings-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-settings-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-settings-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-settings-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-settings-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-settings.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-settings.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-settings.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-settings.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-share-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-share-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-share-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-share-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-share-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-share-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-share-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-share-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-share.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-share.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-share.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-share.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sharing-iphone.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sharing-iphone.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sharing-iphone.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sharing-iphone.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shield.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shield.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shield.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shield.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shift.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shift.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shift.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shift.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shipping-box.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shipping-box.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shipping-box.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shipping-box.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shipping.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shipping.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shipping.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shipping.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shoe.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shoe.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shoe.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shoe.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shopping-basket-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shopping-basket-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shopping-basket-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shopping-basket-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shopping-basket-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shopping-basket-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shopping-basket-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shopping-basket-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shopping-basket.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shopping-basket.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shopping-basket.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shopping-basket.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shorts.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shorts.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shorts.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shorts.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shuffle.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shuffle.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-shuffle.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-shuffle.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sience.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sience.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sience.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sience.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-simcard.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-simcard.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-simcard.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-simcard.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-single-note.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-single-note.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-single-note.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-single-note.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sitemap.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sitemap.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sitemap.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sitemap.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sleep.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sleep.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sleep.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sleep.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-slideshow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-slideshow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-slideshow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-slideshow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-smiley-inverted.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-smiley-inverted.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-smiley-inverted.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-smiley-inverted.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-smiley.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-smiley.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-smiley.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-smiley.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-snow.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-snow.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-snow.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-snow.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-low.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-low.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-low.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-low.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-medium.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-medium.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-medium.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-medium.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-off.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-off.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-off.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-off.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-waves.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-waves.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound-waves.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound-waves.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sound.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sound.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-spades.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-spades.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-spades.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-spades.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-speaker.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-speaker.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-speaker.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-speaker.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-speed-gauge.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-speed-gauge.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-speed-gauge.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-speed-gauge.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-split-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-split-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-split-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-split-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-split.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-split.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-split.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-split.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sprout.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sprout.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sprout.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sprout.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-squiggly-line.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-squiggly-line.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-squiggly-line.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-squiggly-line.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ssd.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ssd.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ssd.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ssd.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stacked-disks.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stacked-disks.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stacked-disks.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stacked-disks.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stamp.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stamp.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stamp.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stamp.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stop-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stop-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stop-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stop-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stop-hand.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stop-hand.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stop-hand.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stop-hand.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stop.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stop.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stop.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stop.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-store.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-store.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-store.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-store.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stream.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stream.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-stream.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-stream.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sunny.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sunny.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sunny.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sunny.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sweatshirt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sweatshirt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sweatshirt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sweatshirt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sync.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sync.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-sync.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-sync.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-t-shirt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-t-shirt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-t-shirt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-t-shirt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tab-key.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tab-key.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tab-key.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tab-key.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tab.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tab.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tab.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tab.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tactics.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tactics.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tactics.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tactics.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tags.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tags.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tags.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tags.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-takeaway-cup.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-takeaway-cup.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-takeaway-cup.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-takeaway-cup.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-target.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-target.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-target.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-target.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-temperatrure-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-temperatrure-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-temperatrure-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-temperatrure-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-temperature.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-temperature.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-temperature.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-temperature.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-terminal.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-terminal.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-terminal.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-terminal.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-theater.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-theater.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-theater.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-theater.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-theif.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-theif.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-theif.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-theif.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thought-bubble.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thought-bubble.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thought-bubble.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thought-bubble.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumb-down.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumb-down.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumb-down.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumb-down.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumb-up.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumb-up.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumb-up.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumb-up.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumbnail-list.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumbnail-list.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumbnail-list.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumbnail-list.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumbnails-small.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumbnails-small.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumbnails-small.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumbnails-small.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumbnails.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumbnails.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-thumbnails.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-thumbnails.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ticket.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ticket.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-ticket.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-ticket.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-time.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-time.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-time.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-time.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-timer.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-timer.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-timer.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-timer.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tools.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tools.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tools.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tools.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-top.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-top.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-top.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-top.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-traffic-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-traffic-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-traffic-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-traffic-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trafic.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trafic.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trafic.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trafic.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-train.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-train.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-train.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-train.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trash-alt-2.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trash-alt-2.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trash-alt-2.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trash-alt-2.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trash-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trash-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trash-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trash-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trash.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trash.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trash.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trash.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tree.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tree.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tree.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tree.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trophy.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trophy.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-trophy.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-trophy.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-truck.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-truck.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-truck.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-truck.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tv-old.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tv-old.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tv-old.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tv-old.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tv.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tv.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-tv.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-tv.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-content.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-content.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-content.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-content.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-contour.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-contour.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-contour.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-contour.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-deploy.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-deploy.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-deploy.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-deploy.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-developer.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-developer.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-developer.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-developer.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-media.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-media.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-media.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-media.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-members.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-members.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-members.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-members.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-settings.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-settings.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-settings.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-settings.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-users.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-users.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umb-users.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umb-users.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umbraco.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umbraco.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umbraco.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umbraco.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umbrella.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umbrella.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-umbrella.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-umbrella.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-undo.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-undo.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-undo.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-undo.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-universal.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-universal.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-universal.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-universal.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-unlocked.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-unlocked.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-unlocked.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-unlocked.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-untitled.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-untitled.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-untitled.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-untitled.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-usb-connector.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-usb-connector.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-usb-connector.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-usb-connector.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-usb.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-usb.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-usb.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-usb.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-female.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-female.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-female.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-female.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-females-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-females-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-females-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-females-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-females.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-females.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-females.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-females.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-glasses.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-glasses.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user-glasses.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user-glasses.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-user.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-user.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-users-alt.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-users-alt.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-users-alt.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-users-alt.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-users.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-users.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-users.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-users.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-utilities.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-utilities.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-utilities.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-utilities.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-vcard.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-vcard.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-vcard.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-vcard.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-video.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-video.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-video.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-video.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-voice.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-voice.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-voice.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-voice.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wall-plug.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wall-plug.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wall-plug.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wall-plug.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wallet.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wallet.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wallet.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wallet.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wand.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wand.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wand.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wand.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-war.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-war.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-war.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-war.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-weight.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-weight.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-weight.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-weight.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-width.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-width.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-width.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-width.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wifi.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wifi.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wifi.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wifi.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-window-popin.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-window-popin.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-window-popin.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-window-popin.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-window-sizes.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-window-sizes.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-window-sizes.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-window-sizes.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-windows.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-windows.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-windows.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-windows.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wine-glass.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wine-glass.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wine-glass.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wine-glass.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wrench.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wrench.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wrench.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wrench.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wrong.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wrong.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-wrong.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-wrong.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-yen-bag.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-yen-bag.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-yen-bag.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-yen-bag.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-zip.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-zip.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-zip.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-zip.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-zom-out.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-zom-out.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-zom-out.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-zom-out.svg diff --git a/src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-zoom-in.svg b/src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-zoom-in.svg similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/store/icon/svgs/icon-zoom-in.svg rename to src/Umbraco.Web.UI.Client/src/core/stores/icon/svgs/icon-zoom-in.svg diff --git a/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.element.ts b/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.element.ts index cf243a7f8d..21df7a7844 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.element.ts @@ -3,8 +3,8 @@ import { customElement, state } from 'lit/decorators.js'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import { UmbInstallerContext, UMB_INSTALLER_CONTEXT_TOKEN } from '../installer.context'; -import { ConsentLevelModel, TelemetryModel, TelemetryLevelModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { ConsentLevelPresentationModel, TelemetryResponseModel, TelemetryLevelModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-installer-consent') export class UmbInstallerConsentElement extends UmbLitElement { @@ -45,10 +45,10 @@ export class UmbInstallerConsentElement extends UmbLitElement { ]; @state() - private _telemetryLevels: ConsentLevelModel[] = []; + private _telemetryLevels: ConsentLevelPresentationModel[] = []; @state() - private _telemetryFormData?: TelemetryModel['telemetryLevel']; + private _telemetryFormData?: TelemetryResponseModel['telemetryLevel']; private _installerContext?: UmbInstallerContext; diff --git a/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.stories.ts index 747b7665ca..df99ad1c6c 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/consent/installer-consent.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { installerContextProvider } from '../shared/utils.story-helpers'; import type { UmbInstallerConsentElement } from './installer-consent.element'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/consent/installer-content.test.ts b/src/Umbraco.Web.UI.Client/src/installer/consent/installer-content.test.ts index 4dd22ce571..00690dfceb 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/consent/installer-content.test.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/consent/installer-content.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInstallerConsentElement } from './installer-consent.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // TODO: Write tests describe('UmbInstallerConsentElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts index 40d9cf223c..7b6f8921df 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.element.ts @@ -4,13 +4,13 @@ import { customElement, property, query, state } from 'lit/decorators.js'; import { UmbInstallerContext, UMB_INSTALLER_CONTEXT_TOKEN } from '../installer.context'; import { - DatabaseInstallModel, - DatabaseSettingsModel, + DatabaseInstallResponseModel, + DatabaseSettingsPresentationModel, InstallResource, ProblemDetailsModel, -} from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; -import { tryExecute } from '@umbraco-cms/resources'; +} from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { tryExecute } from '@umbraco-cms/backoffice/resources'; @customElement('umb-installer-database') export class UmbInstallerDatabaseElement extends UmbLitElement { @@ -35,7 +35,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { uui-form-layout-item { margin-top: 0; - margin-bottom: var(--uui-size-space-6); + margin-bottom: var(--uui-size-layout-1); } uui-input, @@ -47,7 +47,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { hr { width: 100%; margin-top: var(--uui-size-space-2); - margin-bottom: var(--uui-size-space-6); + margin-bottom: var(--uui-size-layout-1); border: none; border-bottom: 1px solid var(--uui-color-border); } @@ -82,16 +82,16 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { private _installButton!: UUIButtonElement; @property({ attribute: false }) - public databaseFormData!: DatabaseInstallModel; + public databaseFormData!: DatabaseInstallResponseModel; @state() private _options: Option[] = []; @state() - private _databases: DatabaseSettingsModel[] = []; + private _databases: DatabaseSettingsPresentationModel[] = []; @state() - private _preConfiguredDatabase?: DatabaseSettingsModel; + private _preConfiguredDatabase?: DatabaseSettingsPresentationModel; @state() private _validationErrorMessage = ''; @@ -151,7 +151,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { value[target.name] = target.checked ?? target.value; // handle boolean and text inputs // TODO: Mark id and providerName as non-optional in schema - const database: DatabaseInstallModel = { + const database: DatabaseInstallResponseModel = { id: '0', providerName: '', ...this._installerContext?.getData().database, @@ -161,7 +161,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { this._setDatabase(database); } - private _setDatabase(database: DatabaseInstallModel) { + private _setDatabase(database: DatabaseInstallResponseModel) { this._installerContext?.appendData({ database }); } @@ -199,7 +199,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { } if (selectedDatabase.requiresConnectionTest) { - const databaseDetails: DatabaseInstallModel = { + const databaseDetails: DatabaseInstallResponseModel = { id, username, password, @@ -221,7 +221,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { } } - const database: DatabaseInstallModel = { + const database: DatabaseInstallResponseModel = { ...this._installerContext?.getData().database, id, username, @@ -253,7 +253,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { // TODO: The post install will probably return a user in the future, so we have to set that context somewhere to let the client know that it is authenticated console.warn('TODO: Set up real authentication'); sessionStorage.setItem('is-authenticated', 'true'); - history.replaceState(null, '', '/content'); + history.replaceState(null, '', 'section/content'); } private _handleRejected(e: ProblemDetailsModel) { @@ -397,7 +397,7 @@ export class UmbInstallerDatabaseElement extends UmbLitElement { ${this._renderSettings()} `; - private _renderPreConfiguredDatabase = (database: DatabaseSettingsModel) => html` + private _renderPreConfiguredDatabase = (database: DatabaseSettingsPresentationModel) => html`

    A database has already been pre-configured on the server and will be used:

    Type: ${database.displayName} diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.stories.ts index dd2537af89..0c4df7d1e3 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.stories.ts @@ -1,13 +1,13 @@ import './installer-database.element'; import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { rest } from 'msw'; import { installerContextProvider } from '../shared/utils.story-helpers'; import type { UmbInstallerDatabaseElement } from './installer-database.element'; -import type { InstallSettingsModel } from '@umbraco-cms/backend-api'; +import type { InstallSettingsResponseModel } from '@umbraco-cms/backoffice/backend-api'; export default { title: 'Apps/Installer/Steps', component: 'umb-installer-database', @@ -30,7 +30,7 @@ Step3DatabasePreconfigured.parameters = { rest.get('/umbraco/backoffice/install/settings', (_req, res, ctx) => { return res( ctx.status(200), - ctx.json({ + ctx.json({ user: { consentLevels: [], minCharLength: 2, minNonAlphaNumericLength: 2 }, databases: [ { diff --git a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.test.ts b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.test.ts index 772e6ba8cb..7ca91a12e3 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.test.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/database/installer-database.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInstallerDatabaseElement } from './installer-database.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // TODO: Write tests describe('UmbInstallerDatabaseElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts index 44af0aa601..e7939497ab 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.element.ts @@ -2,8 +2,8 @@ import { css, CSSResultGroup, html, nothing } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbInstallerContext, UMB_INSTALLER_CONTEXT_TOKEN } from '../installer.context'; -import { ProblemDetailsModel } from '@umbraco-cms/backend-api'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { ProblemDetailsModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-installer-error') export class UmbInstallerErrorElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.stories.ts index 941eba5c87..8583f1ec65 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { installerContextProvider } from '../shared/utils.story-helpers'; import { UmbInstallerContext } from '../installer.context'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.test.ts b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.test.ts index 03d2e8ea2c..2c065ea671 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.test.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/error/installer-error.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInstallerErrorElement } from './installer-error.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // TODO: Write tests describe('UmbInstallerErrorElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts index d51f3d2c28..9e6b26b8cf 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.context.ts @@ -1,14 +1,14 @@ import { Observable } from 'rxjs'; import { - InstallModel, + InstallVResponseModel, InstallResource, - InstallSettingsModel, + InstallSettingsResponseModel, ProblemDetailsModel, TelemetryLevelModel, -} from '@umbraco-cms/backend-api'; -import { tryExecute } from '@umbraco-cms/resources'; -import { UmbContextToken } from '@umbraco-cms/context-api'; -import { ObjectState, NumberState } from '@umbraco-cms/observable-api'; +} from '@umbraco-cms/backoffice/backend-api'; +import { tryExecute } from '@umbraco-cms/backoffice/resources'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import { ObjectState, NumberState } from '@umbraco-cms/backoffice/observable-api'; /** * Context API for the installer @@ -16,7 +16,7 @@ import { ObjectState, NumberState } from '@umbraco-cms/observable-api'; * @class UmbInstallerContext */ export class UmbInstallerContext { - private _data = new ObjectState({ + private _data = new ObjectState({ user: { name: '', email: '', password: '', subscribeToNewsletter: false }, database: { id: '', providerName: '' }, telemetryLevel: TelemetryLevelModel.BASIC, @@ -26,7 +26,7 @@ export class UmbInstallerContext { private _currentStep = new NumberState(1); public readonly currentStep = this._currentStep.asObservable(); - private _settings = new ObjectState(undefined); + private _settings = new ObjectState(undefined); public readonly settings = this._settings.asObservable(); private _installStatus = new ObjectState(null); @@ -90,7 +90,7 @@ export class UmbInstallerContext { * @param {Partial} data * @memberof UmbInstallerContext */ - public appendData(data: Partial): void { + public appendData(data: Partial): void { this._data.next({ ...this.getData(), ...data }); } @@ -100,7 +100,7 @@ export class UmbInstallerContext { * @return {*} {PostInstallRequest} * @memberof UmbInstallerContext */ - public getData(): InstallModel { + public getData(): InstallVResponseModel { return this._data.getValue(); } diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts index 3b5b64cd64..25f6161721 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.element.ts @@ -1,7 +1,7 @@ import { css, CSSResultGroup, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbInstallerContext, UMB_INSTALLER_CONTEXT_TOKEN } from './installer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import './consent/installer-consent.element'; import './database/installer-database.element'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts index 5022d30ccd..ee6dcf05da 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.stories.ts @@ -1,5 +1,5 @@ import { Meta } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import '.'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/installer.test.ts b/src/Umbraco.Web.UI.Client/src/installer/installer.test.ts index 8861e53e43..26048e713f 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installer.test.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installer.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInstallerElement } from './installer.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // TODO: Write tests describe('UmbInstallerElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.stories.ts index 585bd6fb62..679d66ef66 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { installerContextProvider } from '../shared/utils.story-helpers'; import type { UmbInstallerInstallingElement } from './installer-installing.element'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.test.ts b/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.test.ts index 71768902d8..d4f81e7aed 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.test.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/installing/installer-installing.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInstallerInstallingElement } from './installer-installing.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // TODO: Write tests describe('UmbInstallerInstallingElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.stories.ts index 3b6a66584e..e84aab175e 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import type { UmbInstallerLayoutElement } from './installer-layout.element'; import './installer-layout.element'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.test.ts b/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.test.ts index 44a6f3b268..20871d6deb 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.test.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/shared/layout/installer-layout.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInstallerLayoutElement } from './installer-layout.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // TODO: Write tests describe('UmbInstallerLayoutElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/installer/shared/utils.story-helpers.ts b/src/Umbraco.Web.UI.Client/src/installer/shared/utils.story-helpers.ts index 7b03df75c4..f131df752a 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/shared/utils.story-helpers.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/shared/utils.story-helpers.ts @@ -1,4 +1,4 @@ -import { html } from 'lit-html'; +import { html } from 'lit'; import { UmbInstallerContext } from '../installer.context'; import '../../core/context-provider/context-provider.element'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.element.ts b/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.element.ts index 50a6c3da9c..a96d159a06 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.element.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.element.ts @@ -1,7 +1,7 @@ import { css, CSSResultGroup, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; import { UmbInstallerContext, UMB_INSTALLER_CONTEXT_TOKEN } from '../installer.context'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-installer-user') export class UmbInstallerUserElement extends UmbLitElement { @@ -16,7 +16,7 @@ export class UmbInstallerUserElement extends UmbLitElement { uui-form-layout-item { margin-top: 0; - margin-bottom: var(--uui-size-space-6); + margin-bottom: var(--uui-size-layout-1); } uui-form { diff --git a/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.stories.ts b/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.stories.ts index 625ef190a1..5ad27fc76e 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.stories.ts @@ -1,5 +1,5 @@ import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import { html } from 'lit'; import { installerContextProvider } from '../shared/utils.story-helpers'; import type { UmbInstallerUserElement } from './installer-user.element'; diff --git a/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.test.ts b/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.test.ts index e6599f9326..899c5d3984 100644 --- a/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.test.ts +++ b/src/Umbraco.Web.UI.Client/src/installer/user/installer-user.test.ts @@ -1,7 +1,7 @@ import { expect, fixture, html } from '@open-wc/testing'; import { UmbInstallerUserElement } from './installer-user.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; // TODO: Write tests describe('UmbInstallerUserElement', () => { diff --git a/src/Umbraco.Web.UI.Client/src/stories/extending/entity-actions.mdx b/src/Umbraco.Web.UI.Client/src/stories/extending/entity-actions.mdx index e7847203d0..eb9fe3121d 100644 --- a/src/Umbraco.Web.UI.Client/src/stories/extending/entity-actions.mdx +++ b/src/Umbraco.Web.UI.Client/src/stories/extending/entity-actions.mdx @@ -64,12 +64,14 @@ const manifest = { name: 'My Entity Action', weight: 10, meta: { - entityType: 'my-entity', icon: 'umb:add', label: 'My Entity Action', repositoryAlias: 'My.Repository', api: MyEntityAction, }, + conditions: { + entityType: 'my-entity', + }, }; extensionRegistry.register(manifest); @@ -88,11 +90,11 @@ As part of the Extension Manifest you can attach a class that will be instanciat ```ts import { UmbEntityActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/controller'; import type { MyRepository } from './my-repository'; export class MyEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); } @@ -111,7 +113,7 @@ import { UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '@umbraco-cms/modal'; import { MyRepository } from './my-repository'; export class MyEntityAction extends UmbEntityActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, unique: string) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); new UmbContextConsumerController(this.host, UMB_MODAL_SERVICE_CONTEXT_TOKEN, (instance) => { @@ -155,12 +157,14 @@ const manifest = { name: 'My Entity Bulk Action', weight: 10, meta: { - entityType: 'my-entity', icon: 'umb:add', label: 'My Entity Bulk Action', repositoryAlias: 'My.Repository', api: MyEntityBulkAction, }, + conditions: { + entityType: 'my-entity', + }, }; extensionRegistry.register(manifest); @@ -172,11 +176,11 @@ As part of the Extension Manifest you can attach a class that will be instanciat ```ts import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/controller'; import { MyRepository } from './my-repository'; export class MyEntityBulkAction extends UmbEntityBulkActionBase { - constructor(host: UmbControllerHostInterface, repositoryAlias: string, selection: Array) { + constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); } diff --git a/src/Umbraco.Web.UI.Client/src/stories/extending/intro.mdx b/src/Umbraco.Web.UI.Client/src/stories/extending/intro.mdx index c0ede6a70b..dbb9dcb584 100644 --- a/src/Umbraco.Web.UI.Client/src/stories/extending/intro.mdx +++ b/src/Umbraco.Web.UI.Client/src/stories/extending/intro.mdx @@ -16,3 +16,4 @@ The Umbraco Backoffice currently support the following extension types: - [Property Editor](?path=/docs/guides-extending-the-backoffice-property-editors--docs) - [Repository](?path=/docs/guides-extending-the-backoffice-property-editors--docs) - [Menu](?path=/docs/guides-extending-the-backoffice-menu--docs) +- [Tree](?path=/docs/guides-extending-the-backoffice-trees--docs) diff --git a/src/Umbraco.Web.UI.Client/src/stories/extending/modals/intro.mdx b/src/Umbraco.Web.UI.Client/src/stories/extending/modals/intro.mdx new file mode 100644 index 0000000000..cde473b6b8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/stories/extending/modals/intro.mdx @@ -0,0 +1,57 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Modals + +// TODO: add description about what modals is + +- Sidebar +- Infinite Editors +- Dialogs + +## Define a Manifest for a Modal Type + +### Manifest + +```json +{ + "type": "modal", + "alias": "Our.Modal.SomethingPicker", + "name": "My Something Picker Modal", + "loader": "./my-something-picker-modal-element.js", +}, +``` + +## Implement a Modal + +### Modal Token + +For type safety we recommend that you make a Modal Token, Its posible to go without. +The Modal Token binds the Modal Type to the Modal Data Type and Modal Result Type. + +`` + +```ts +import { ModalToken } from '@umbraco-cms/element'; + +export type OurSomethingPickerModalData = { + key: string | null; +}; + +export type OurSomethingPickerModalResult = { + key: string; +}; + +export const MY_SOMETHING_PICKER_MODAL = new UmbModalToken( + 'Our.Modal.SomethingPicker', + { + type: 'sidebar', + size: 'small', + } +); +``` + +### Make a modal registration + +# TODO Link to modal documentation here. diff --git a/src/Umbraco.Web.UI.Client/src/stories/extending/registration.mdx b/src/Umbraco.Web.UI.Client/src/stories/extending/registration.mdx index 2366eecb43..7ead7a5cc1 100644 --- a/src/Umbraco.Web.UI.Client/src/stories/extending/registration.mdx +++ b/src/Umbraco.Web.UI.Client/src/stories/extending/registration.mdx @@ -62,6 +62,67 @@ const manifest = { extensionRegistry.register(extension); ``` +## Using Kinds for registration + +Generally UI extensions, requires you to bring everything for the extension. +But there are several situations where you dont want to bring the full solution, just some configuration. + +In this case we can use Extension 'Kinds'. Kinds enables you to extend a base configuration and make it your own. + +To understand the concept of Kinds, lets look at the Header App extension type: + +```ts +import { extensionRegistry } from '@umbraco-cms/extension-registry'; + +const manifest = { + type: 'headerApp', + kind: 'button', + name: 'My Header App Example', + alias: 'My.HeaderApp.Example', + meta: { + label: 'My Example', + icon: 'umb:home', + href: '/some/path/to/open/when/clicked', + }, +}; + +extensionRegistry.register(extension); +``` + +The above example does not provide a element, but is still visually present through a button element. +The this element comes from the kind 'button'. + +Backoffice comes with a set of predefined Kinds, and you can even create your own. + +Many of the build-in Kinds comes with a default element, but it could be anything. To understand the abilities we can look closer at the registration of your own Kinds. + +## Registering a kind + +The registration of Kinds, is done in the same maner as the registration of other extensions. +But the format of it is quite different, lets look at the Kind registration of the Header App Button Kind (The kind used in the above example): + +```ts +import { extensionRegistry } from '@umbraco-cms/extension-registry'; + +const manifest: ManifestKind = { + type: 'kind', + alias: 'Umb.Kind.Button', + matchType: 'headerApp', + matchKind: 'button', + manifest: { + elementName: 'umb-header-app-button', + }, +}; + +umbExtensionsRegistry.register(manifest); +``` + +The root properties of this object, defines the Kind registration. +And then the manifest property holds the base extension manifest that users of this Kind will be extending. +This object can hold the property values that makes sense for the Kind. + +In the above example the only property value defined a elementName, which is enough to create the button element for all extensions using this Kind. + ### JSON Manifest files TODO: describe how and where to position the JSON manifest files diff --git a/src/Umbraco.Web.UI.Client/src/stories/extending/tree.mdx b/src/Umbraco.Web.UI.Client/src/stories/extending/tree.mdx new file mode 100644 index 0000000000..2f750ce0fe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/stories/extending/tree.mdx @@ -0,0 +1,136 @@ +import { Meta } from '@storybook/addon-docs'; + + + +# Trees + +// TODO: add description of trees. +Rough notes: +The tree is a hierarchical structure of nodes. The tree is registered in the Backoffice extension registry. A tree can be rendered anywhere in the Backoffice with the help of the umb-tree element. + +## Registering a tree + +Tree Manifest + +```json +// TODO: add interface +{ + "type": "tree", + "alias": "My.Tree.Alias", + "name": "My Tree", + "meta": { + "repositoryAlias": "My.Repository.Alias" + } +}, +{ + "type": "treeItem", + "kind": "entity", + "alias": "My.TreeItem.Alias", + "name": "My Tree Item", + "conditions": { + "entityType": "my-entity-type", + }, +} +``` + +The backoffice comes with two different tree item kinds out of the box: +entity and fileSystem + +## Rendering a tree + +```html + +``` + +## Render a Custom Tree Item + +The Tree Item Manifest + +```json +{ + "type": "treeItem", + "alias": "Umb.TreeItem.Alias", + "name": "My Tree Item", + "js": "./my-tree-item.element.js", + "conditions": { + "entityType": "my-entity-type", + }, +}; +``` + +### The Tree Item Element + +```typescript +import { css, html, nothing } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element'; +import { UmbMyTreeItemContext, MyTreeItemDataModel } from './my-tree-item.context'; + +@customElement('my-tree-item') +export class MyTreeItemElement extends UmbElementMixin(LitElement) { + private _item?: MyTreeItemDataModel; + @property({ type: Object, attribute: false }) + public get item() { + return this._item; + } + public set item(value: MyTreeItemDataModel | undefined) { + this._item = value; + this.#context.setTreeItem(value); + } + + #context = new UmbMyTreeItemContext(this); + + render() { + if (!this.item) return nothing; + return html` Some custom markup `; + } +} + +export default MyTreeItemElement; +``` + +### The Tree Item Context + +```typescript +// TODO: auto generate this from the interface +export interface UmbTreeItemContext { + host: UmbControllerHostElement; + unique?: string; + type?: string; + + treeItem: Observable; + hasChildren: Observable; + isLoading: Observable; + isSelectable: Observable; + isSelected: Observable; + isActive: Observable; + hasActions: Observable; + path: Observable; + + setTreeItem(treeItem: T | undefined): void; + + requestChildren(): Promise<{ + data: PagedResponse | undefined; + error: ProblemDetailsModel | undefined; + asObservable?: () => Observable; + }>; + toggleContextMenu(): void; + select(): void; + deselect(): void; + constructPath(pathname: string, entityType: string, unique: string): string; +} +``` + +### Extending the Tree Item Context base + +We provide a base class for the tree item context. This class provides some default implementations for the context. You can extend this class to overwrite any of the default implementations. + +```typescript +export class UmbMyTreeItemContext extends UmbTreeItemContextBase { + constructor(host: UmbControllerHostElement) { + super(host, (x: MyTreeItemDataModel) => x.unique); + } + + // overwrite any methods or properties here if needed +} +``` diff --git a/src/Umbraco.Web.UI.Client/src/stories/extending/workspaces/actions.mdx b/src/Umbraco.Web.UI.Client/src/stories/extending/workspaces/actions.mdx index 994c52edd7..d9ff5db436 100644 --- a/src/Umbraco.Web.UI.Client/src/stories/extending/workspaces/actions.mdx +++ b/src/Umbraco.Web.UI.Client/src/stories/extending/workspaces/actions.mdx @@ -26,10 +26,12 @@ const manifest = { alias: 'My.WorkspaceAction', name: 'My Workspace Action', meta: { - workspaces: ['My.Workspace'], label: 'My Action', api: MyWorkspaceAction, }, + conditions: { + workspaces: ['My.Workspace'], + }, }; extensionRegistry.register(manifest); @@ -41,11 +43,11 @@ As part of the Extension Manifest you can attach a class that will be instanciat ```ts import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action'; -import { UmbControllerHostInterface } from '@umbraco-cms/controller'; +import { UmbControllerHostElement } from '@umbraco-cms/controller'; import { MyRepository } from './my-repository'; export class MyWorkspaceAction extends UmbWorkspaceActionBase { - constructor(host: UmbControllerHostInterface) { + constructor(host: UmbControllerHostElement) { super(host); } diff --git a/src/Umbraco.Web.UI.Client/src/stories/store.mdx b/src/Umbraco.Web.UI.Client/src/stories/store.mdx index 3a95ffbc11..1140ee8e40 100644 --- a/src/Umbraco.Web.UI.Client/src/stories/store.mdx +++ b/src/Umbraco.Web.UI.Client/src/stories/store.mdx @@ -11,12 +11,12 @@ Generally a Store will be holding one or more RxJS Subjects, each Subject is mad ```typescript class MyProductStore { - #products = new ArrayState(>[], (product) => product.key); + #products = new ArrayState(>[], (product) => product.id); public readonly products = this.#products.asObservable(); - protected host: UmbControllerHostInterface; - constructor(host: UmbControllerHostInterface) { + protected host: UmbControllerHostElement; + constructor(host: UmbControllerHostElement) { this.host = host; // The Store provides it self as a Context-API. @@ -65,10 +65,10 @@ class MyProductStore { ... - getByKey(key: string) { + getByKey(id: string) { // Request data via a Resource to then take part of this state when recieved. - tryExecuteAndNotify(this.host, ProductResource.getByKey({key})).then(({ data }) => { + tryExecuteAndNotify(this.host, ProductResource.getByKey({id})).then(({ data }) => { if (data) { this.#products.append(data.items); } @@ -76,7 +76,7 @@ class MyProductStore { // Return a Observable part, to listen for this specific product and the future changes of it. return this.#data.getObservablePart((documents) => - documents.find((document) => document.key === key) + documents.find((document) => document.id === id) ); } } @@ -134,11 +134,11 @@ With this we can make a high performant application, only triggering the parts t ### Ensure unique data: For incoming data to replace existing data, we need to clarify what makes a entry of the array unique. -In the examples of this guide each product has a key, and we have clarified this to the State by giving it the little method `(product) => product.key` as part of the its creation: +In the examples of this guide each product has a id, and we have clarified this to the State by giving it the little method `(product) => product.id` as part of the its creation: ```typescript class MyProductStore { - #products = new ArrayState(>[], (product) => product.key); + #products = new ArrayState(>[], (product) => product.id); ... } ``` diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.element.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.element.ts index 44de67977d..d66130096b 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.element.ts @@ -1,14 +1,14 @@ import { css, CSSResultGroup, html, LitElement } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; -import { UpgradeSettingsModel } from '@umbraco-cms/backend-api'; +import { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/backend-api'; /** * @element umb-upgrader-view * @fires {CustomEvent} onAuthorizeUpgrade - fires when the user clicks the continue button */ @customElement('umb-upgrader-view') -export class UmbUpgraderView extends LitElement { +export class UmbUpgraderViewElement extends LitElement { static styles: CSSResultGroup = [ css` .center { @@ -32,7 +32,7 @@ export class UmbUpgraderView extends LitElement { errorMessage = ''; @property({ type: Object, reflect: true }) - settings?: UpgradeSettingsModel; + settings?: UpgradeSettingsResponseModel; private _renderLayout() { return html` @@ -100,10 +100,10 @@ export class UmbUpgraderView extends LitElement { }; } -export default UmbUpgraderView; +export default UmbUpgraderViewElement; declare global { interface HTMLElementTagNameMap { - 'umb-upgrader-view': UmbUpgraderView; + 'umb-upgrader-view': UmbUpgraderViewElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.test.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.test.ts index 1ad362d987..6d5f6dec83 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.test.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader-view.test.ts @@ -1,17 +1,17 @@ import { expect, fixture, html } from '@open-wc/testing'; -import { UmbUpgraderView } from './upgrader-view.element'; -import { defaultA11yConfig } from '@umbraco-cms/test-utils'; +import { UmbUpgraderViewElement } from './upgrader-view.element'; +import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils'; describe('UmbUpgraderView', () => { - let element: UmbUpgraderView; + let element: UmbUpgraderViewElement; beforeEach(async () => { element = await fixture(html``); }); it('is defined with its own instance', () => { - expect(element).to.be.instanceOf(UmbUpgraderView); + expect(element).to.be.instanceOf(UmbUpgraderViewElement); }); it('passes the a11y audit', async () => { diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts index bd38add924..b483b5c8e2 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.element.ts @@ -3,17 +3,17 @@ import './upgrader-view.element'; import { html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UpgradeResource, UpgradeSettingsModel } from '@umbraco-cms/backend-api'; -import { tryExecute } from '@umbraco-cms/resources'; -import { UmbLitElement } from '@umbraco-cms/element'; +import { UpgradeResource, UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { tryExecute } from '@umbraco-cms/backoffice/resources'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; /** * @element umb-upgrader */ @customElement('umb-upgrader') -export class UmbUpgrader extends UmbLitElement { +export class UmbUpgraderElement extends UmbLitElement { @state() - private upgradeSettings?: UpgradeSettingsModel; + private upgradeSettings?: UpgradeSettingsResponseModel; @state() private fetching = true; @@ -64,17 +64,17 @@ export class UmbUpgrader extends UmbLitElement { if (error) { this.errorMessage = error.detail || 'Unknown error, please try again'; } else { - history.pushState(null, '', '/'); + history.pushState(null, '', 'section/content'); } this.upgrading = false; }; } -export default UmbUpgrader; +export default UmbUpgraderElement; declare global { interface HTMLElementTagNameMap { - 'umb-upgrader': UmbUpgrader; + 'umb-upgrader': UmbUpgraderElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts index 5485bf1bf5..5363224718 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.stories.ts @@ -1,12 +1,13 @@ -import '.'; +import './upgrader-view.element'; -import { Meta, Story } from '@storybook/web-components'; -import { html } from 'lit-html'; +import type { Meta, StoryObj } from '@storybook/web-components'; +import { html } from 'lit'; -import { UmbUpgraderView } from './upgrader-view.element'; +import type { UmbUpgraderViewElement } from './upgrader-view.element'; export default { title: 'Apps/Upgrader/States', + component: 'umb-upgrader-view', args: { errorMessage: '', upgrading: false, @@ -31,28 +32,26 @@ export default { ${story()}

    `, ], -} as Meta; +} satisfies Meta; -const Template: Story = ({ upgrading, errorMessage, settings, fetching }) => - html``; +type Story = StoryObj; -export const Overview = Template.bind({}); +export const Overview: Story = {}; -export const Upgrading = Template.bind({}); -Upgrading.args = { - upgrading: true, +export const Upgrading: Story = { + args: { + upgrading: true, + }, }; -export const Fetching = Template.bind({}); -Fetching.args = { - fetching: true, +export const Fetching: Story = { + args: { + fetching: true, + }, }; -export const Error = Template.bind({}); -Error.args = { - errorMessage: 'Something went wrong', +export const Error: Story = { + args: { + errorMessage: 'Something went wrong', + }, }; diff --git a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.test.ts b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.test.ts index 152dacda45..24561b45ac 100644 --- a/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.test.ts +++ b/src/Umbraco.Web.UI.Client/src/upgrader/upgrader.test.ts @@ -1,15 +1,15 @@ import { expect, fixture, html } from '@open-wc/testing'; -import { UmbUpgrader } from './upgrader.element'; +import { UmbUpgraderElement } from './upgrader.element'; describe('UmbUpgrader', () => { - let element: UmbUpgrader; + let element: UmbUpgraderElement; beforeEach(async () => { element = await fixture(html``); }); it('is defined with its own instance', () => { - expect(element).to.be.instanceOf(UmbUpgrader); + expect(element).to.be.instanceOf(UmbUpgraderElement); }); }); diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index 4cacd68027..147a4a8288 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -3,9 +3,7 @@ "module": "esnext", "target": "esnext", "lib": ["es2020", "dom", "dom.iterable"], - "declaration": true, - "emitDeclarationOnly": true, - "noEmitOnError": true, + "noEmit": true, "outDir": "./types", "strict": true, "noImplicitReturns": true, @@ -20,29 +18,31 @@ "resolveJsonModule": true, "baseUrl": ".", "paths": { - "@umbraco-cms/backend-api": ["libs/backend-api"], - "@umbraco-cms/components/*": ["src/backoffice/components/*"], - "@umbraco-cms/context-api": ["libs/context-api"], - "@umbraco-cms/controller": ["libs/controller"], - "@umbraco-cms/css": ["libs/css/custom-properties.css"], - "@umbraco-cms/element": ["libs/element"], - "@umbraco-cms/entity-action": ["libs/entity-action"], - "@umbraco-cms/events": ["libs/events"], - "@umbraco-cms/extensions-api": ["libs/extensions-api"], - "@umbraco-cms/extensions-registry": ["libs/extensions-registry"], - "@umbraco-cms/modal": ["libs/modal"], - "@umbraco-cms/models": ["libs/models"], - "@umbraco-cms/notification": ["libs/notification"], - "@umbraco-cms/observable-api": ["libs/observable-api"], - "@umbraco-cms/property-editor": ["libs/property-editor"], - "@umbraco-cms/repository": ["libs/repository"], - "@umbraco-cms/resources": ["libs/resources"], - "@umbraco-cms/router": ["src/core/router"], - "@umbraco-cms/sections/*": ["src/backoffice/sections/*"], - "@umbraco-cms/store": ["libs/store"], - "@umbraco-cms/test-utils": ["libs/test-utils"], - "@umbraco-cms/utils": ["libs/utils"], - "@umbraco-cms/workspace": ["libs/workspace"] + "@umbraco-cms/backoffice/backend-api": ["libs/backend-api"], + "@umbraco-cms/backoffice/context-api": ["libs/context-api"], + "@umbraco-cms/backoffice/controller": ["libs/controller"], + "@umbraco-cms/backoffice/css": ["libs/css/custom-properties.css"], + "@umbraco-cms/backoffice/element": ["libs/element"], + "@umbraco-cms/backoffice/element.js": ["libs/element"], + "@umbraco-cms/backoffice/entity-action": ["libs/entity-action"], + "@umbraco-cms/backoffice/events": ["libs/umb-events"], + "@umbraco-cms/backoffice/extensions-api": ["libs/extensions-api"], + "@umbraco-cms/backoffice/extensions-registry": ["libs/extensions-registry"], + "@umbraco-cms/backoffice/modal": ["libs/modal"], + "@umbraco-cms/backoffice/models": ["libs/models"], + "@umbraco-cms/backoffice/notification": ["libs/notification"], + "@umbraco-cms/backoffice/observable-api": ["libs/observable-api"], + "@umbraco-cms/backoffice/property-editor": ["libs/property-editor"], + "@umbraco-cms/backoffice/repository": ["libs/repository"], + "@umbraco-cms/backoffice/resources": ["libs/resources"], + "@umbraco-cms/backoffice/router": ["libs/router"], + "@umbraco-cms/backoffice/store": ["libs/store"], + "@umbraco-cms/backoffice/utils": ["libs/utils"], + "@umbraco-cms/backoffice/workspace": ["libs/workspace"], + "@umbraco-cms/internal/lit-element": ["src/core/lit-element"], + "@umbraco-cms/internal/modal": ["src/core/modal"], + "@umbraco-cms/internal/router": ["src/core/router"], + "@umbraco-cms/internal/test-utils": ["utils/test-utils.ts"] } }, "include": ["src/**/*.ts", "apps/**/*.ts", "libs/**/*.ts", "e2e/**/*.ts"], diff --git a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-0.0.0.tgz b/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-0.0.0.tgz deleted file mode 100644 index 59e52f8bd6..0000000000 Binary files a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-0.0.0.tgz and /dev/null differ diff --git a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-container-0.0.0.tgz b/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-container-0.0.0.tgz deleted file mode 100644 index f5639e9552..0000000000 Binary files a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-container-0.0.0.tgz and /dev/null differ diff --git a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-dialog-0.0.0.tgz b/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-dialog-0.0.0.tgz deleted file mode 100644 index 1b6f3b50bb..0000000000 Binary files a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-dialog-0.0.0.tgz and /dev/null differ diff --git a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-sidebar-0.0.0.tgz b/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-sidebar-0.0.0.tgz deleted file mode 100644 index a49b019951..0000000000 Binary files a/src/Umbraco.Web.UI.Client/umbraco-ui-uui-modal-sidebar-0.0.0.tgz and /dev/null differ diff --git a/src/Umbraco.Web.UI.Client/utils/move-libs.js b/src/Umbraco.Web.UI.Client/utils/move-libs.js new file mode 100644 index 0000000000..59c3f7d044 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/utils/move-libs.js @@ -0,0 +1,58 @@ +// Load all .d.ts files from the dist/libs folder +// and replace all imports from @umbraco-cms/backoffice with relative imports +// Example: import { Foo } from '@umbraco-cms/backoffice/element' -> import { Foo } from './element' +// This is needed because the d.ts files are not in the same folder as the source files +// and the absolute paths are not valid when the d.ts files are copied to the dist folder +// This is only used when building the d.ts files +// +// Usage: node utils/transform-dts.js +// +// Note: This script is not used in the build process, it is only used to transform the d.ts files +// when the d.ts files are copied to the dist folder + +// Note: Updated to help copy the two JSON files generated from webcomponant analyzer tool +// One is specific to VSCode HTMLCutomData for intellisense and the other is a more broad format used in storybook etc + +import { readdirSync, readFileSync, writeFileSync, cpSync, mkdirSync } from 'fs'; + +const rootDir = './'; +const srcDir = './libs'; +const inputDir = './dist/libs'; +const outputDir = '../Umbraco.Cms.StaticAssets/wwwroot/umbraco/backoffice/libs'; + +// Copy package files +cpSync(`${srcDir}/package.json`, `${inputDir}/package.json`, { recursive: true }); +cpSync(`${srcDir}/README.md`, `${inputDir}/README.md`, { recursive: true }); +cpSync(`${rootDir}/custom-elements.json`, `${inputDir}/custom-elements.json`, { recursive: true }); +cpSync(`${rootDir}/vscode-html-custom-data.json`, `${inputDir}/vscode-html-custom-data.json`, { recursive: true }); + +const libs = readdirSync(inputDir); + +// Create output folder +try { + mkdirSync(outputDir, { recursive: true }); +} catch { + // Ignore +} + +// Transform all .d.ts files and copy all other files to the output folder +libs.forEach(lib => { + + console.log(`Transforming ${lib}`); + + const dtsFile = `${inputDir}/${lib}`; + + let code = readFileSync(dtsFile, 'utf8'); + + // Replace all absolute imports with relative imports + if (lib.endsWith('.d.ts')) { + code = code.replace(/from '(@umbraco-cms\/backoffice\/[^']+)'/g, (match, p1) => { + return `from './${p1.split('/').pop()}'`; + }); + } + + writeFileSync(dtsFile, code, 'utf8'); + + cpSync(dtsFile, `${outputDir}/${lib}`, { recursive: true }); + +}); diff --git a/src/Umbraco.Web.UI.Client/utils/rollup.config.js b/src/Umbraco.Web.UI.Client/utils/rollup.config.js deleted file mode 100644 index ce5b924ecc..0000000000 --- a/src/Umbraco.Web.UI.Client/utils/rollup.config.js +++ /dev/null @@ -1,27 +0,0 @@ -import esbuild from 'rollup-plugin-esbuild'; -import pluginJson from '@rollup/plugin-json'; -import { nodeResolve } from '@rollup/plugin-node-resolve'; -import dts from 'rollup-plugin-dts'; - -/** @type {import('rollup').RollupOptions[]} */ -export default [ - { - input: 'index.ts', - external: [/^@umbraco-cms\//, /^lit/], - output: { - file: 'dist/index.js', - format: 'es', - sourcemap: true - }, - plugins: [nodeResolve(), pluginJson(), esbuild()] - }, - { - input: 'index.ts', - external: [/^@umbraco-cms\//, /^lit/, /^rxjs/], - output: { - file: './dist/index.d.ts', - format: 'es' - }, - plugins: [dts({ respectExternal: true })], - } -]; diff --git a/src/Umbraco.Web.UI.Client/libs/test-utils/chai.ts b/src/Umbraco.Web.UI.Client/utils/test-utils.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/libs/test-utils/chai.ts rename to src/Umbraco.Web.UI.Client/utils/test-utils.ts diff --git a/src/Umbraco.Web.UI.Client/vite.cms.config.ts b/src/Umbraco.Web.UI.Client/vite.cms.config.ts index 286c7d237b..4cca6ea50c 100644 --- a/src/Umbraco.Web.UI.Client/vite.cms.config.ts +++ b/src/Umbraco.Web.UI.Client/vite.cms.config.ts @@ -10,8 +10,11 @@ export default defineConfig({ formats: ['es'], fileName: 'main', }, + rollupOptions: { + external: [/^@umbraco-cms\/backoffice\//] + }, outDir: '../Umbraco.Cms.StaticAssets/wwwroot/umbraco/backoffice', - emptyOutDir: true, + emptyOutDir: false, sourcemap: true, }, base: '/umbraco/backoffice/', diff --git a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs index cd570c5c4d..2aa8016715 100644 --- a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs +++ b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs @@ -38,27 +38,28 @@ export default { importMap: { imports: { 'src/': './src/', - '@umbraco-cms/backend-api': './libs/backend-api/index.ts', - '@umbraco-cms/context-api': './libs/context-api/index.ts', - '@umbraco-cms/controller': './libs/controller/index.ts', - '@umbraco-cms/css': './libs/css/custom-properties.css', - '@umbraco-cms/element': './libs/element/index.ts', - '@umbraco-cms/entity-action': './libs/entity-action/index.ts', - '@umbraco-cms/events': './libs/events/index.ts', - '@umbraco-cms/extensions-api': './libs/extensions-api/index.ts', - '@umbraco-cms/extensions-registry': './libs/extensions-registry/index.ts', - '@umbraco-cms/modal': './libs/modal/index.ts', - '@umbraco-cms/models': './libs/models/index.ts', - '@umbraco-cms/notification': './libs/notification/index.ts', - '@umbraco-cms/observable-api': './libs/observable-api/index.ts', - '@umbraco-cms/property-editor': './libs/property-editor/index.ts', - '@umbraco-cms/repository': './libs/repository/index.ts', - '@umbraco-cms/resources': './libs/resources/index.ts', - '@umbraco-cms/router': './src/core/router/index.ts', - '@umbraco-cms/store': './libs/store/index.ts', - '@umbraco-cms/test-utils': './libs/test-utils/index.ts', - '@umbraco-cms/utils': './libs/utils/index.ts', - '@umbraco-cms/workspace': './libs/workspace/index.ts', + '@umbraco-cms/backoffice/backend-api': './libs/backend-api/index.ts', + '@umbraco-cms/backoffice/context-api': './libs/context-api/index.ts', + '@umbraco-cms/backoffice/controller': './libs/controller/index.ts', + '@umbraco-cms/backoffice/element': './libs/element/index.ts', + '@umbraco-cms/backoffice/entity-action': './libs/entity-action/index.ts', + '@umbraco-cms/backoffice/events': './libs/umb-events/index.ts', + '@umbraco-cms/backoffice/extensions-api': './libs/extensions-api/index.ts', + '@umbraco-cms/backoffice/extensions-registry': './libs/extensions-registry/index.ts', + '@umbraco-cms/backoffice/modal': './libs/modal/index.ts', + '@umbraco-cms/backoffice/models': './libs/models/index.ts', + '@umbraco-cms/backoffice/notification': './libs/notification/index.ts', + '@umbraco-cms/backoffice/observable-api': './libs/observable-api/index.ts', + '@umbraco-cms/backoffice/property-editor': './libs/property-editor/index.ts', + '@umbraco-cms/backoffice/repository': './libs/repository/index.ts', + '@umbraco-cms/backoffice/resources': './libs/resources/index.ts', + '@umbraco-cms/backoffice/store': './libs/store/index.ts', + '@umbraco-cms/backoffice/utils': './libs/utils/index.ts', + '@umbraco-cms/backoffice/workspace': './libs/workspace/index.ts', + '@umbraco-cms/internal/lit-element': './src/core/lit-element/index.ts', + '@umbraco-cms/internal/modal': './src/core/modal/index.ts', + '@umbraco-cms/internal/router': './src/core/router/index.ts', + '@umbraco-cms/internal/test-utils': './utils/test-utils.ts' }, }, }, @@ -77,7 +78,7 @@ export default { Umbraco - +