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 index dc3413e2d1..bab658e4b9 100644 --- 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 @@ -9,6 +9,7 @@ on: branches: [main] paths: - 'src/**' + - 'devops/publish/**' - 'package.json' - 'package-lock.json' - 'tsconfig.json' diff --git a/src/Umbraco.Web.UI.Client/.storybook/preview.js b/src/Umbraco.Web.UI.Client/.storybook/preview.js index 743d7694e9..c824d3a7ef 100644 --- a/src/Umbraco.Web.UI.Client/.storybook/preview.js +++ b/src/Umbraco.Web.UI.Client/.storybook/preview.js @@ -4,23 +4,21 @@ import '../src/css/umb-css.css'; import 'element-internals-polyfill'; import '@umbraco-ui/uui'; +import { handlers } from '../src/mocks/browser-handlers'; import { html } from 'lit'; import { initialize, mswDecorator } from 'msw-storybook-addon'; +import { onUnhandledRequest } from '../src/mocks'; import { setCustomElements } from '@storybook/web-components'; +import { UMB_MODAL_CONTEXT_TOKEN, UmbModalManagerContext } from '../src/packages/core/modal'; import { UmbDataTypeStore } from '../src/packages/settings/data-types/repository/data-type.store.ts'; -import { UmbDocumentTypeStore } from '../src/packages/documents/document-types/repository/document-type.store.ts'; import { UmbDocumentStore } from '../src/packages/documents/documents/repository/document.store.ts'; import { UmbDocumentTreeStore } from '../src/packages/documents/documents/repository/document.tree.store.ts'; - -import customElementManifests from '../dist-cms/custom-elements.json'; -import { UmbIconRegistry } from '../src/shared/icon-registry/icon.registry'; -import { onUnhandledRequest } from '../src/mocks'; -import { handlers } from '../src/mocks/browser-handlers'; -import { UMB_MODAL_CONTEXT_TOKEN, UmbModalContext } from '../src/packages/core/modal'; -import { UmbLitElement } from '../src/shared/lit-element'; - +import { UmbDocumentTypeStore } from '../src/packages/documents/document-types/repository/document-type.store.ts'; import { umbExtensionsRegistry } from '../src/packages/core/extension-registry'; +import { UmbIconRegistry } from '../src/shared/icon-registry/icon.registry'; +import { UmbLitElement } from '../src/shared/lit-element'; +import customElementManifests from '../dist-cms/custom-elements.json'; import '../src/libs/context-api/provide/context-provider.element'; import '../src/libs/controller-api/controller-host-initializer.element.ts'; @@ -35,7 +33,7 @@ class UmbStoryBookElement extends UmbLitElement { super(); this._umbIconRegistry.attach(this); this._registerExtensions(documentManifests); - this.provideContext(UMB_MODAL_CONTEXT_TOKEN, new UmbModalContext(this)); + this.provideContext(UMB_MODAL_CONTEXT_TOKEN, new UmbModalManagerContext(this)); } _registerExtensions(manifests) { diff --git a/src/Umbraco.Web.UI.Client/devops/publish/cleanse-pkg.js b/src/Umbraco.Web.UI.Client/devops/publish/cleanse-pkg.js index fe7fa46d63..4380c48e3c 100644 --- a/src/Umbraco.Web.UI.Client/devops/publish/cleanse-pkg.js +++ b/src/Umbraco.Web.UI.Client/devops/publish/cleanse-pkg.js @@ -10,5 +10,12 @@ const packageJson = JSON.parse(readFileSync(packageFile, 'utf8')); */ delete packageJson.dependencies['router-slot']; +// Remove all DevDependencies +delete packageJson.devDependencies; + +// Rename dependencies to peerDependencies +packageJson.peerDependencies = packageJson.dependencies; +delete packageJson.dependencies; + // Write the package.json back to disk writeFileSync(packageFile, JSON.stringify(packageJson, null, 2), 'utf8'); diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index e3ea6f1981..ba676b73ef 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -16,7 +16,7 @@ "lit": "^2.7.4", "lodash-es": "4.17.21", "monaco-editor": "^0.36.1", - "router-slot": "file:router-slot-2.2.0.tgz", + "router-slot": "file:router-slot-2.3.0.tgz", "rxjs": "^7.8.0", "uuid": "^9.0.0" }, @@ -18065,9 +18065,9 @@ "dev": true }, "node_modules/router-slot": { - "version": "2.2.0", - "resolved": "file:router-slot-2.2.0.tgz", - "integrity": "sha512-AAFrwU5Hr9p8Qb1NRIjO2z2IK/VU5SCobaXcboOq9zmfSr990oCKEpDF62t/Ij9P78+jR9fWxcIl7Tdc9Wx0ng==", + "version": "2.3.0", + "resolved": "file:router-slot-2.3.0.tgz", + "integrity": "sha512-bH3g1/xOwbkuwE4iQ0tLwp1/r+dqttQr/ezO0tzp+KCttsCcxxgSCbEYy8+ePuSCLsiS3WhuTfFSED74d+tMjg==", "license": "MIT" }, "node_modules/run-applescript": { diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 0fa23a2ca7..5aba949cbc 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -11,13 +11,15 @@ "./element-api": "./dist-cms/libs/element-api/index.js", "./extension-api": "./dist-cms/libs/extension-api/index.js", "./observable-api": "./dist-cms/libs/observable-api/index.js", + "./auth": "./dist-cms/shared/auth/index.js", + "./context": "./dist-cms/shared/context/index.js", "./events": "./dist-cms/shared/umb-events/index.js", + "./icon": "./dist-cms/shared/icon/index.js", "./models": "./dist-cms/shared/models/index.js", "./repository": "./dist-cms/shared/repository/index.js", "./resources": "./dist-cms/shared/resources/index.js", "./router": "./dist-cms/shared/router/index.js", "./utils": "./dist-cms/shared/utils/index.js", - "./icon": "./dist-cms/shared/icon/index.js", "./action": "./dist-cms/packages/core/action/index.js", "./collection": "./dist-cms/packages/core/collection/index.js", "./components": "./dist-cms/packages/core/components/index.js", @@ -38,9 +40,23 @@ "./variant": "./dist-cms/packages/core/variant/index.js", "./workspace": "./dist-cms/packages/core/workspace/index.js", "./property-editor": "./dist-cms/packages/core/property-editor/index.js", - "./document": "./dist-cms/packages/documents/documents/index.js", - "./data-type": "./dist-cms/packages/settings/data-types/index.js", - "./themes": "./dist-cms/packages/settings/themes/index.js", + "./document": "./dist-cms/packages/documents/documents/index.ts", + "./document-blueprint": "./dist-cms/packages/documents/document-blueprints/index.ts", + "./document-type": "./dist-cms/packages/documents/document-types/index.ts", + "./media": "./dist-cms/packages/media/media/index.ts", + "./media-type": "./dist-cms/packages/media/media-types/index.ts", + "./member": "./dist-cms/packages/members/members/index.ts", + "./member-group": "./dist-cms/packages/members/member-groups/index.ts", + "./member-type": "./dist-cms/packages/members/member-types/index.ts", + "./package": "./dist-cms/packages/packages/package/index.ts", + "./data-type": "./dist-cms/packages/settings/data-types/index.ts", + "./language": "./dist-cms/packages/settings/languages/index.ts", + "./relation-type": "./dist-cms/packages/settings/relation-types/index.ts", + "./themes": "./dist-cms/packages/settings/themes/index.ts", + "./tags": "./dist-cms/packages/tags/index.ts", + "./partial-view": "./dist-cms/packages/templating/partial-views/index.ts", + "./stylesheet": "./dist-cms/packages/templating/stylesheets/index.ts", + "./template": "./dist-cms/packages/templating/templates/index.ts", "./user-group": "./dist-cms/packages/users/user-groups/index.js", "./current-user": "./dist-cms/packages/users/current-user/index.js", "./users": "./dist-cms/packages/users/users/index.js", @@ -109,7 +125,7 @@ "lit": "^2.7.4", "lodash-es": "4.17.21", "monaco-editor": "^0.36.1", - "router-slot": "file:router-slot-2.2.0.tgz", + "router-slot": "file:router-slot-2.3.0.tgz", "rxjs": "^7.8.0", "uuid": "^9.0.0" }, diff --git a/src/Umbraco.Web.UI.Client/public-assets/App_Plugins/package-view.js b/src/Umbraco.Web.UI.Client/public-assets/App_Plugins/package-view.js index d10ba9e5a7..63b75442da 100644 --- a/src/Umbraco.Web.UI.Client/public-assets/App_Plugins/package-view.js +++ b/src/Umbraco.Web.UI.Client/public-assets/App_Plugins/package-view.js @@ -23,8 +23,7 @@ export default class MyPackageViewCustom extends HTMLElement { } onClick() { - console.log(this.modalHandler); - this.modalHandler.close(); + this.modalContext.close(); } } diff --git a/src/Umbraco.Web.UI.Client/router-slot-2.2.0.tgz b/src/Umbraco.Web.UI.Client/router-slot-2.2.0.tgz deleted file mode 100644 index dac0dca447..0000000000 Binary files a/src/Umbraco.Web.UI.Client/router-slot-2.2.0.tgz and /dev/null differ diff --git a/src/Umbraco.Web.UI.Client/router-slot-2.3.0.tgz b/src/Umbraco.Web.UI.Client/router-slot-2.3.0.tgz new file mode 100644 index 0000000000..af84cfe3d3 Binary files /dev/null and b/src/Umbraco.Web.UI.Client/router-slot-2.3.0.tgz differ diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts index ed09065f09..4e0e8a11fb 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/app/app.element.ts @@ -1,6 +1,6 @@ import type { UmbAppErrorElement } from './app-error.element.js'; -import { UmbAuthFlow } from './auth/index.js'; -import { UMB_APP, UmbAppContext } from './app.context.js'; +import { UMB_AUTH, UmbAuthFlow } from '@umbraco-cms/backoffice/auth'; +import { UMB_APP, UmbAppContext } from '@umbraco-cms/backoffice/context'; import { css, html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UUIIconRegistryEssential } from '@umbraco-cms/backoffice/external/uui'; import { UmbIconRegistry } from '@umbraco-cms/backoffice/icon'; @@ -81,6 +81,8 @@ export class UmbAppElement extends UmbLitElement { this.#authFlow = new UmbAuthFlow(this.serverUrl, redirectUrl); + this.provideContext(UMB_AUTH, this.#authFlow); + this.provideContext(UMB_APP, new UmbAppContext({ backofficePath: this.backofficePath, serverUrl: this.serverUrl })); // Try to initialise the auth flow and get the runtime status diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/auth/index.ts b/src/Umbraco.Web.UI.Client/src/apps/app/auth/index.ts deleted file mode 100644 index 16f8c38e67..0000000000 --- a/src/Umbraco.Web.UI.Client/src/apps/app/auth/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './auth-flow.js'; diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/index.ts b/src/Umbraco.Web.UI.Client/src/apps/app/index.ts index 8eb4f65238..0834e3b2c8 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/app/index.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/app/index.ts @@ -1,4 +1,3 @@ export * from './app-context-config.interface.js'; export * from './app-error.element.js'; -export * from './app.context.js'; export * from './app.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts index 1c9be757c1..983b190c0a 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/backoffice/backoffice.element.ts @@ -3,7 +3,10 @@ import { UmbBackofficeContext, UMB_BACKOFFICE_CONTEXT_TOKEN } from './backoffice import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -import { UmbEntryPointExtensionInitializer } from '@umbraco-cms/backoffice/extension-api'; +import { + UmbBundleExtensionInitializer, + UmbEntryPointExtensionInitializer, +} from '@umbraco-cms/backoffice/extension-api'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import './components/index.js'; @@ -31,6 +34,7 @@ export class UmbBackofficeElement extends UmbLitElement { constructor() { super(); this.provideContext(UMB_BACKOFFICE_CONTEXT_TOKEN, new UmbBackofficeContext()); + new UmbBundleExtensionInitializer(this, umbExtensionsRegistry); new UmbEntryPointExtensionInitializer(this, umbExtensionsRegistry); new UmbExtensionInitializer(this, umbExtensionsRegistry); this.#extensionInitializer.setLocalPackages(CORE_PACKAGES); diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/bundle-extension-initializer.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/bundle-extension-initializer.ts new file mode 100644 index 0000000000..4f7fac564e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/bundle-extension-initializer.ts @@ -0,0 +1,39 @@ +import type { ManifestBundle } from './types.js'; +import { loadExtension } from './load-extension.function.js'; +import { UmbExtensionRegistry } from './registry/extension.registry.js'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbBundleExtensionInitializer { + #host; + #extensionRegistry; + #bundleMap = new Map(); + + constructor(host: UmbControllerHostElement, extensionRegistry: UmbExtensionRegistry) { + this.#host = host; + this.#extensionRegistry = extensionRegistry; + extensionRegistry.extensionsOfType('bundle').subscribe((bundles) => { + bundles.forEach((bundle) => { + if (this.#bundleMap.has(bundle.alias)) return; + this.#bundleMap.set(bundle.alias, bundle); + // TODO: Should we unInit a entry point if is removed? + this.instantiateBundle(bundle); + }); + }); + } + + async instantiateBundle(manifest: ManifestBundle) { + const js = await loadExtension(manifest); + + if (js) { + Object.keys(js).forEach((key) => { + const value = js[key]; + + if (Array.isArray(value)) { + this.#extensionRegistry.registerMany(value); + } else if (typeof value === 'object') { + this.#extensionRegistry.register(value); + } + }); + } + } +} diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/index.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/index.ts index b1b67865e7..53457d7459 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/index.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/index.ts @@ -1,11 +1,12 @@ -export * from './registry/extension.registry.js'; -export * from './type-guards/index.js'; +export * from './bundle-extension-initializer.js'; +export * from './create-extension-class.function.js'; +export * from './create-extension-element-or-fallback.function.js'; export * from './create-extension-element.function.js'; +export * from './entry-point-extension-initializer.js'; export * from './has-default-export.function.js'; export * from './has-init-export.function.js'; export * from './load-extension.function.js'; -export * from './create-extension-element-or-fallback.function.js'; -export * from './create-extension-class.function.js'; -export * from './umb-lifecycle.interface.js'; -export * from './entry-point-extension-initializer.js'; +export * from './registry/extension.registry.js'; +export * from './type-guards/index.js'; export * from './types.js'; +export * from './umb-lifecycle.interface.js'; diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts index 1bbecf1ed2..107dbcfd41 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/registry/extension.registry.ts @@ -62,6 +62,8 @@ export class UmbExtensionRegistry< } register(manifest: ManifestTypes | ManifestKind): void { + // TODO: Consider if we need to implement some safety features here, like checking if the object has a 'type' and/or 'alias'? + if (manifest.type === 'kind') { this.defineKind(manifest as ManifestKind); return; diff --git a/src/Umbraco.Web.UI.Client/src/libs/extension-api/types.ts b/src/Umbraco.Web.UI.Client/src/libs/extension-api/types.ts index 8389ad3f9f..c65069481d 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/extension-api/types.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/extension-api/types.ts @@ -1,3 +1,7 @@ +import type { UmbExtensionRegistry } from './registry/extension.registry.js'; +import { UmbBackofficeExtensionRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; + // eslint-disable-next-line @typescript-eslint/no-explicit-any export type HTMLElementConstructor = new (...args: any[]) => T; @@ -71,6 +75,9 @@ export interface ManifestWithLoader extends ManifestBase { */ export interface ManifestClass extends ManifestWithLoader<{ default: ClassConstructor }> { + /** + * @TJS-ignore + */ readonly CLASS_TYPE?: ClassType; /** @@ -97,6 +104,9 @@ export interface ManifestClassWithClassConstructor extends Manifest export interface ManifestElement extends ManifestWithLoader<{ default: ClassConstructor } | Omit> { + /** + * @TJS-ignore + */ readonly ELEMENT_TYPE?: ElementType; /** @@ -149,7 +159,10 @@ export interface ManifestWithMeta extends ManifestBase { * 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 */ -export interface ManifestEntryPoint extends ManifestBase { +export interface ManifestEntryPoint + extends ManifestWithLoader<{ + onInit: (host: UmbControllerHostElement, extensionApi: UmbBackofficeExtensionRegistry) => void; + }> { type: 'entryPoint'; /** @@ -157,3 +170,16 @@ export interface ManifestEntryPoint extends ManifestBase { */ js: string; } + +/** + * This type of extension takes a JS module and registers all exported manifests from the pointed JS file. + */ +export interface ManifestBundle + extends ManifestWithLoader<{ [key: string]: Array }> { + type: 'bundle'; + + /** + * The file location of the javascript file to load in the backoffice + */ + js: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts index 950825cb99..2b6252fea1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts @@ -1,19 +1,23 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { css, CSSResultGroup, html, repeat, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbModalHandler, UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalContext, + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, +} from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-backoffice-modal-container') export class UmbBackofficeModalContainerElement extends UmbLitElement { @state() - private _modals?: UmbModalHandler[]; + private _modals?: UmbModalContext[]; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; this._observeModals(); }); @@ -30,7 +34,7 @@ export class UmbBackofficeModalContainerElement extends UmbLitElement { render() { return html` - ${this._modals ? repeat(this._modals, (modalHandler) => html`${modalHandler.modalElement}`) : ''} + ${this._modals ? repeat(this._modals, (modalContext) => html`${modalContext.modalElement}`) : ''} `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-list-base/input-list-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-list-base/input-list-base.ts index 5e6036bd1e..bb957c23c4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-list-base/input-list-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-list-base/input-list-base.ts @@ -1,10 +1,10 @@ import { html, property } from '@umbraco-cms/backoffice/external/lit'; import type { UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui'; import { - UmbModalContext, + UmbModalManagerContext, UmbModalToken, UmbModalType, - UMB_MODAL_CONTEXT_TOKEN, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, UmbPickerModalResult, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -25,11 +25,11 @@ export class UmbInputListBaseElement extends UmbLitElement { // TODO: not great that we use any, any here. Investigate if we can have some interface or base modal token for this type. protected pickerToken?: UmbModalToken; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -37,12 +37,12 @@ export class UmbInputListBaseElement extends UmbLitElement { private _openPicker() { if (!this.pickerToken) return; - const modalHandler = this._modalContext?.open(this.pickerToken, { + const modalContext = this._modalContext?.open(this.pickerToken, { multiple: this.multiple, selection: this.value, }); - modalHandler?.onSubmit().then((data: UmbPickerModalResult) => { + modalContext?.onSubmit().then((data: UmbPickerModalResult) => { if (data) { this.value = data.selection?.filter((id) => id !== null && id !== undefined) as Array; this.selectionUpdated(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/debug/debug.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/debug/debug.element.ts index f9e8b29621..1d549eec3b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/debug/debug.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/debug/debug.element.ts @@ -16,7 +16,11 @@ import { 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'; +import { + UmbModalManagerContext, + UMB_CONTEXT_DEBUGGER_MODAL, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, +} from '@umbraco-cms/backoffice/modal'; @customElement('umb-debug') export class UmbDebugElement extends UmbLitElement { @@ -32,11 +36,11 @@ export class UmbDebugElement extends UmbLitElement { @state() private _debugPaneOpen = false; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/debug/modals/debug/debug-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/debug/modals/debug/debug-modal.element.ts index 8c02c9fa71..26c78690f5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/debug/modals/debug/debug-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/debug/modals/debug/debug-modal.element.ts @@ -6,7 +6,7 @@ import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; @customElement('umb-context-debugger-modal') export default class UmbContextDebuggerModalElement extends UmbModalBaseElement { private _handleClose() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete-folder/delete-folder.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete-folder/delete-folder.action.ts index c88392abfb..9f7075db06 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete-folder/delete-folder.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete-folder/delete-folder.action.ts @@ -1,16 +1,20 @@ import { UmbEntityActionBase } from '../../entity-action.js'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UmbFolderRepository } from '@umbraco-cms/backoffice/repository'; export class UmbDeleteFolderEntityAction extends UmbEntityActionBase { - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -22,14 +26,14 @@ export class UmbDeleteFolderEntityAction extends if (folder) { // TODO: maybe we can show something about how many items are part of the folder? - const modalHandler = this.#modalContext.open(UMB_CONFIRM_MODAL, { + const modalContext = this.#modalContext.open(UMB_CONFIRM_MODAL, { headline: `Delete folder ${folder.name}`, content: 'Are you sure you want to delete this folder?', color: 'danger', confirmLabel: 'Delete', }); - await modalHandler.onSubmit(); + await modalContext.onSubmit(); await this.repository?.deleteFolder(this.unique); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts index 11d43207cd..3f91a4e0b1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts @@ -1,18 +1,22 @@ import { UmbEntityActionBase } from '../../entity-action.js'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UmbDetailRepository, UmbItemRepository } from '@umbraco-cms/backoffice/repository'; export class UmbDeleteEntityAction< T extends UmbDetailRepository & UmbItemRepository > extends UmbEntityActionBase { - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -25,14 +29,14 @@ export class UmbDeleteEntityAction< if (data) { const item = data[0]; - const modalHandler = this.#modalContext.open(UMB_CONFIRM_MODAL, { + const modalContext = this.#modalContext.open(UMB_CONFIRM_MODAL, { headline: `Delete ${item.name}`, content: 'Are you sure you want to delete this item?', color: 'danger', confirmLabel: 'Delete', }); - await modalHandler.onSubmit(); + await modalContext.onSubmit(); await this.repository?.delete(this.unique); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/folder-update/folder-update.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/folder-update/folder-update.action.ts index cd3916541c..a9551680cc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/folder-update/folder-update.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/folder-update/folder-update.action.ts @@ -1,18 +1,22 @@ import { UmbEntityActionBase } from '../../entity-action.js'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_FOLDER_MODAL, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_FOLDER_MODAL, + UMB_MODAL_MANAGER_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; + #modalContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -20,11 +24,11 @@ export class UmbFolderUpdateEntityAction< async execute() { if (!this.repository || !this.#modalContext) return; - const modalHandler = this.#modalContext.open(UMB_FOLDER_MODAL, { + const modalContext = this.#modalContext.open(UMB_FOLDER_MODAL, { repositoryAlias: this.repositoryAlias, unique: this.unique, }); - await modalHandler.onSubmit(); + await modalContext.onSubmit(); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/trash/trash.action.ts index 0429e455d3..bdd062beeb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/trash/trash.action.ts @@ -1,18 +1,22 @@ import { UmbEntityActionBase } from '../../entity-action.js'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; export class UmbTrashEntityAction< T extends UmbItemRepository & { trash(unique: Array): Promise } > extends UmbEntityActionBase { - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -25,14 +29,14 @@ export class UmbTrashEntityAction< if (data) { const item = data[0]; - const modalHandler = this.#modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = 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', confirmLabel: 'Trash', }); - modalHandler?.onSubmit().then(() => { + modalContext?.onSubmit().then(() => { this.repository?.trash([this.unique]); }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/interfaces/modal-extension-element.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/interfaces/modal-extension-element.interface.ts index 672d68c0c3..d8d478fd31 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/interfaces/modal-extension-element.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/interfaces/modal-extension-element.interface.ts @@ -1,5 +1,5 @@ import type { ManifestModal } from '../models/index.js'; -import type { UmbModalHandler } from '@umbraco-cms/backoffice/modal'; +import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; export interface UmbModalExtensionElement< UmbModalData extends object = object, @@ -8,7 +8,7 @@ export interface UmbModalExtensionElement< > extends HTMLElement { manifest?: ModalManifestType; - modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; data?: UmbModalData; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts index d90a705168..7cdb6d1d10 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts @@ -25,7 +25,7 @@ import type { ManifestWorkspace } from './workspace.model.js'; import type { ManifestWorkspaceAction } from './workspace-action.model.js'; import type { ManifestWorkspaceEditorView } from './workspace-editor-view.model.js'; import type { ManifestWorkspaceViewCollection } from './workspace-view-collection.model.js'; -import type { ManifestBase, ManifestEntryPoint } from '@umbraco-cms/backoffice/extension-api'; +import type { ManifestBase, ManifestBundle, ManifestEntryPoint } from '@umbraco-cms/backoffice/extension-api'; export * from './collection-view.model.js'; export * from './dashboard-collection.model.js'; @@ -56,6 +56,7 @@ export * from './workspace-editor-view.model.js'; export * from './workspace.model.js'; export type ManifestTypes = + | ManifestBundle | ManifestCollectionView | ManifestDashboard | ManifestDashboardCollection diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/index.ts index 0663c36adf..1f3d426742 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/index.ts @@ -2,11 +2,12 @@ import { UmbBackofficeNotificationContainerElement, UmbBackofficeModalContainerE import { manifests as debugManifests } from './debug/manifests.js'; import { manifests as propertyActionManifests } from './property-actions/manifests.js'; import { manifests as propertyEditorManifests } from './property-editors/manifests.js'; +import { manifests as workspaceManifests } from './workspace/manifests.js'; import { manifests as modalManifests } from './modal/common/manifests.js'; import { UmbStoreExtensionInitializer } from './store/index.js'; import { UmbNotificationContext, UMB_NOTIFICATION_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/notification'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbModalManagerContext, UMB_MODAL_MANAGER_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api'; import { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry'; @@ -37,6 +38,7 @@ const manifests: Array = [ ...debugManifests, ...propertyActionManifests, ...propertyEditorManifests, + ...workspaceManifests, ...modalManifests, ]; @@ -52,5 +54,5 @@ export const onInit: UmbEntryPointOnInit = (host, extensionRegistry) => { host.appendChild(modalContainerElement); new UmbContextProviderController(host, UMB_NOTIFICATION_CONTEXT_TOKEN, new UmbNotificationContext()); - new UmbContextProviderController(host, UMB_MODAL_CONTEXT_TOKEN, new UmbModalContext(host)); + new UmbContextProviderController(host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, new UmbModalManagerContext(host)); }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/confirm/confirm-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/confirm/confirm-modal.element.ts index 38a2ce02b9..c14da1353f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/confirm/confirm-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/confirm/confirm-modal.element.ts @@ -1,22 +1,22 @@ import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { UmbConfirmModalData, UmbConfirmModalResult, UmbModalHandler } from '@umbraco-cms/backoffice/modal'; +import { UmbConfirmModalData, UmbConfirmModalResult, UmbModalContext } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-confirm-modal') export class UmbConfirmModalElement extends UmbLitElement { @property({ attribute: false }) - modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; @property({ type: Object }) data?: UmbConfirmModalData; private _handleConfirm() { - this.modalHandler?.submit(); + this.modalContext?.submit(); } private _handleCancel() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/embedded-media/embedded-media-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/embedded-media/embedded-media-modal.element.ts index 169b7a39e7..1007034938 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/embedded-media/embedded-media-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/embedded-media/embedded-media-modal.element.ts @@ -5,7 +5,7 @@ import { OEmbedStatus, UmbEmbeddedMediaModalData, UmbEmbeddedMediaModalResult, - UmbModalHandler, + UmbModalContext, } from '@umbraco-cms/backoffice/modal'; import { umbracoPath } from '@umbraco-cms/backoffice/utils'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -27,17 +27,17 @@ export class UmbEmbeddedMediaModalElement extends UmbLitElement { #embedResult!: OEmbedResult; @property({ attribute: false }) - modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; @property({ type: Object }) data?: UmbEmbeddedMediaModalData; #handleConfirm() { - this.modalHandler?.submit({ selection: this.#embedResult }); + this.modalContext?.submit({ selection: this.#embedResult }); } #handleCancel() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } @state() @@ -159,7 +159,7 @@ export class UmbEmbeddedMediaModalElement extends UmbLitElement { render() { return html` - +
@@ -222,7 +222,7 @@ export class UmbEmbeddedMediaModalElement extends UmbLitElement { look="primary" label="Submit" @click=${this.#handleConfirm}> - + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/folder/folder-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/folder/folder-modal.element.ts index bd4937690c..5e2fdeb512 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/folder/folder-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/folder/folder-modal.element.ts @@ -1,6 +1,6 @@ import { css, html, customElement, property, query, state } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { UmbFolderModalData, UmbFolderModalResult, UmbModalHandler } from '@umbraco-cms/backoffice/modal'; +import { UmbFolderModalData, UmbFolderModalResult, UmbModalContext } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UmbFolderRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionClass, ManifestBase } from '@umbraco-cms/backoffice/extension-api'; @@ -11,7 +11,7 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr @customElement('umb-folder-modal') export class UmbFolderModalElement extends UmbLitElement { @property({ attribute: false }) - modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; private _data?: UmbFolderModalData; @property({ type: Object, attribute: false }) @@ -87,7 +87,7 @@ export class UmbFolderModalElement extends UmbLitElement { private _formElement?: HTMLFormElement; #onCancel() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } #submitForm() { @@ -119,7 +119,7 @@ export class UmbFolderModalElement extends UmbLitElement { } if (!error) { - this.modalHandler?.submit(); + this.modalContext?.submit(); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts index 8ee5c548d7..fa6ffb100e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/icon-picker/icon-picker-modal.element.ts @@ -1,4 +1,4 @@ -import icons from '../../../../../shared/icon-registry/icons/icons.json' assert { type: "json" }; +import icons from '../../../../../shared/icon-registry/icons/icons.json' assert { type: 'json' }; import type { UUIColorSwatchesEvent } from '@umbraco-cms/backoffice/external/uui'; import { css, html, styleMap, customElement, state } from '@umbraco-cms/backoffice/external/lit'; @@ -61,11 +61,11 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement +
${this.renderSearchbar()}
@@ -102,7 +102,7 @@ export class UmbIconPickerModalElement extends UmbModalBaseElement Submit - + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts index 52cb177348..265772d8f4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/link-picker/link-picker-modal.element.ts @@ -1,6 +1,6 @@ import { UmbTreeElement } from '../../../tree/tree.element.js'; import { css, html, nothing, customElement, query, state } from '@umbraco-cms/backoffice/external/lit'; -import { UUITextStyles , UUIBooleanInputEvent, UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; +import { UUITextStyles, UUIBooleanInputEvent, UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; import { UmbLinkPickerConfig, UmbLinkPickerLink, @@ -80,16 +80,16 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement + @@ -119,7 +119,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement
- +
`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts index a0e28f3ce7..38efddb9e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/property-settings/property-settings-modal.element.ts @@ -1,4 +1,9 @@ -import { UUIBooleanInputEvent, UUIInputEvent, UUISelectEvent , UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; +import { + UUIBooleanInputEvent, + UUIInputEvent, + UUISelectEvent, + UUITextStyles, +} from '@umbraco-cms/backoffice/external/uui'; import { PropertyValueMap, css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; import { UmbPropertySettingsModalResult, UmbPropertySettingsModalData } from '@umbraco-cms/backoffice/modal'; @@ -66,10 +71,6 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement< }); } - #onClose() { - this.modalHandler?.reject(); - } - #onSubmit(event: SubmitEvent) { event.preventDefault(); @@ -83,7 +84,7 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement< this._returnData.validation!.mandatoryMessage = formData.get('mandatory-message')?.toString() || ''; - this.modalHandler?.submit(this._returnData); + this.modalContext?.submit(this._returnData); } #onNameChange(event: UUIInputEvent) { @@ -175,11 +176,14 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement< this.requestUpdate('_returnData'); } + // TODO: This would conceptually be a Property Editor Workspace, should be changed at one point in the future. + // For now this is hacky made available by giving the element an fixed alias. + // This would allow for workspace views and workspace actions. render() { return html`
- +
@@ -225,7 +229,6 @@ export class UmbPropertySettingsModalElement extends UmbModalBaseElement<
-
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/section-picker/section-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/section-picker/section-picker-modal.element.ts index 6b7d5ec5d6..b411e35fd1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/section-picker/section-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/section-picker/section-picker-modal.element.ts @@ -16,13 +16,13 @@ export class UmbSectionPickerModalElement extends UmbModalBaseElement< #selectionManager = new UmbSelectionManagerBase(); #submit() { - this.modalHandler?.submit({ + this.modalContext?.submit({ selection: this.#selectionManager.getSelection(), }); } #close() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } connectedCallback(): void { @@ -40,7 +40,7 @@ export class UmbSectionPickerModalElement extends UmbModalBaseElement< render() { return html` - + ${this._sections.map( (item) => html` @@ -57,7 +57,7 @@ export class UmbSectionPickerModalElement extends UmbModalBaseElement<
-
+ `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/template/template-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/template/template-modal.element.ts index 6642820602..28496e8cec 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/template/template-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/common/template/template-modal.element.ts @@ -52,11 +52,11 @@ export class UmbTemplateModalElement extends UmbModalBaseElement = Omit< - UmbModalHandlerClass, +export type UmbModalContext = Omit< + UmbModalContextClass, 'submit' > & OptionalSubmitArgumentIfUndefined; @@ -40,23 +41,23 @@ type OptionalSubmitArgumentIfUndefined = T extends undefined }; // TODO: consider splitting this into two separate handlers -// TODO: Rename to become a controller. -export class UmbModalHandlerClass extends UmbController { - private _submitPromise: Promise; - private _submitResolver?: (value: ModalResult) => void; - private _submitRejecter?: () => void; +export class UmbModalContextClass { + #host: UmbControllerHostElement; - public modalElement: UUIModalDialogElement | UUIModalSidebarElement; + #submitPromise: Promise; + #submitResolver?: (value: ModalResult) => void; + #submitRejecter?: () => void; + + public readonly modalElement: UUIModalDialogElement | UUIModalSidebarElement; #modalRouterElement: UmbRouterSlotElement = document.createElement('umb-router-slot'); #innerElement = new BehaviorSubject(undefined); public readonly innerElement = this.#innerElement.asObservable(); - public key: string; - public type: UmbModalType = 'dialog'; - public size: UUIModalSidebarSize = 'small'; - - private modalAlias: string; //TEMP... TODO: Remove this. + public readonly key: string; + public readonly data: ModalData; + public readonly type: UmbModalType = 'dialog'; + public readonly size: UUIModalSidebarSize = 'small'; constructor( host: UmbControllerHostElement, @@ -65,9 +66,8 @@ export class UmbModalHandlerClass { - this._submitResolver = resolve; - this._submitRejecter = reject; + this.#submitPromise = new Promise((resolve, reject) => { + this.#submitResolver = resolve; + this.#submitRejecter = reject; }); this.modalElement = this.#createContainerElement(); this.modalElement.addEventListener('close', () => { - this._submitRejecter?.(); + this.#submitRejecter?.(); }); /** @@ -106,14 +106,14 @@ export class UmbModalHandlerClass + ); } #createContainerElement() { @@ -133,66 +133,44 @@ export class UmbModalHandlerClass { + this.#removeInnerElement(); + if (manifest) { + const innerElement = await this.#createInnerElement(manifest); + if (innerElement) { + this.#appendInnerElement(innerElement); + } + } + }, + '_observeModalExtension' + ); + } + } + + async #createInnerElement(manifest: ManifestModal) { // TODO: add inner fallback element if no extension element is found const innerElement = (await createExtensionElement(manifest)) as any; if (innerElement) { - innerElement.data = data; - //innerElement.observable = this.#dataObservable; - innerElement.modalHandler = this; + innerElement.data = this.data; + innerElement.modalContext = this; innerElement.manifest = manifest; } return innerElement; } - // 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(); - } - - public reject() { - this.modalElement.close(); - } - - public onSubmit(): Promise { - return this._submitPromise; - } - - /* TODO: modals being part of the extension registry now means that a modal element can change over time. - It makes this code a bit more complex. The main idea is to have the element as part of the modalHandler so it is possible to dispatch events from within the modal element to the one that opened it. - Now when the element is an observable it makes it more complex because this host needs to subscribe to updates to the element, instead of just having a reference to it. - If we find a better generic solution to communicate between the modal and the implementor, then we can remove the element as part of the modalHandler. */ - #observeModal(modalAlias: string, data?: ModalData) { - if (this.host) { - new UmbObserverController( - this.host, - umbExtensionsRegistry.getByTypeAndAlias('modal', modalAlias), - async (manifest) => { - if (manifest) { - const innerElement = await this.#createInnerElement(manifest, data); - if (innerElement) { - this.#appendInnerElement(innerElement); - return; - } - } - this.#removeInnerElement(); - } - ); - } - } - #appendInnerElement(element: HTMLElement) { this.#modalRouterElement.appendChild(element); - /*this.#modalRouterElement.routes = [ - { - path: '', - component: element, - }, - ]; - this.#modalRouterElement.render();*/ this.#innerElement.next(element); } @@ -204,8 +182,34 @@ export class UmbModalHandlerClass { + return this.#submitPromise; } } + +export const UMB_MODAL_CONTEXT_TOKEN = new UmbContextToken('UmbModalContext'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-manager.context.ts similarity index 57% rename from src/Umbraco.Web.UI.Client/src/packages/core/modal/modal.context.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-manager.context.ts index d3dd5cadec..97f623d798 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-manager.context.ts @@ -1,5 +1,5 @@ -import { UmbModalHandler, UmbModalHandlerClass } from './modal-handler.js'; import type { UmbModalToken } from './token/modal-token.js'; +import { UmbModalContext, UmbModalContextClass } from './index.js'; import type { IRouterSlot } from '@umbraco-cms/backoffice/external/router-slot'; import type { UUIModalSidebarSize } from '@umbraco-cms/backoffice/external/uui'; import { BehaviorSubject } from '@umbraco-cms/backoffice/external/rxjs'; @@ -15,12 +15,10 @@ export interface UmbModalConfig { size?: UUIModalSidebarSize; } -// 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 { +export class UmbModalManagerContext { 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: UmbControllerHostElement) { @@ -30,10 +28,12 @@ export class UmbModalContext { /** * Opens a modal or sidebar modal * @public - * @param {(string | HTMLElement)} element - * @param {UmbModalOptions} [options] + * @param {(string | UmbModalToken)} modalAlias + * @param {ModalData} data + * @param {UmbModalConfig} config + * @param {IRouterSlot | null} router * @return {*} {UmbModalHandler} - * @memberof UmbModalContext + * @memberof UmbModalManagerContext */ public open( modalAlias: string | UmbModalToken, @@ -41,30 +41,29 @@ export class UmbModalContext { config?: UmbModalConfig, router: IRouterSlot | null = null ) { - const modalHandler = new UmbModalHandlerClass( + const modalContext = new UmbModalContextClass( this.host, router, modalAlias, data, config - ) as unknown as UmbModalHandler; + ) as unknown as UmbModalContext; - modalHandler.modalElement.addEventListener('close-end', () => this.#onCloseEnd(modalHandler)); + modalContext.modalElement.addEventListener('close-end', () => this.#onCloseEnd(modalContext)); this.#modals.next( - appendToFrozenArray(this.#modals.getValue(), modalHandler, (entry) => entry.key === modalHandler.key) + appendToFrozenArray(this.#modals.getValue(), modalContext, (entry) => entry.key === modalContext.key) ); - return modalHandler; + return modalContext; } /** * Closes a modal or sidebar modal * @private * @param {string} key - * @memberof UmbModalContext + * @memberof UmbModalManagerContext */ public close(key: string) { - console.log('close', key, this.#modals); const modal = this.#modals.getValue().find((modal) => modal.key === key); if (modal) { modal.reject(); @@ -78,13 +77,13 @@ export class UmbModalContext { /** * Handles the close-end event * @private - * @param {UmbModalHandler} modalHandler - * @memberof UmbModalContext + * @param {UmbModalContext} modalContext + * @memberof UmbModalManagerContext */ - #onCloseEnd(modalHandler: UmbModalHandler) { - modalHandler.modalElement.removeEventListener('close-end', () => this.#onCloseEnd(modalHandler)); - this.#remove(modalHandler.key); + #onCloseEnd(modalContext: UmbModalContext) { + modalContext.modalElement.removeEventListener('close-end', () => this.#onCloseEnd(modalContext)); + this.#remove(modalContext.key); } } -export const UMB_MODAL_CONTEXT_TOKEN = new UmbContextToken('UmbModalContext'); +export const UMB_MODAL_MANAGER_CONTEXT_TOKEN = new UmbContextToken('UmbModalManagerContext'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.controller.ts index 551cd0af04..88fd59ce9c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.controller.ts @@ -1,7 +1,7 @@ // TODO: Be aware here we import a class from src! import { UmbModalRouteRegistration } from './modal-route-registration.js'; import { UmbModalToken } from './token/index.js'; -import { UmbModalConfig } from './modal.context.js'; +import { UmbModalConfig } from './modal-manager.context.js'; import { UMB_ROUTE_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/router'; import type { UmbControllerHostElement, UmbControllerInterface } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.ts index d9a17ce870..5a09f9dd06 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/modal-route-registration.ts @@ -1,5 +1,5 @@ -import { UmbModalHandler } from './modal-handler.js'; -import { UmbModalConfig, UmbModalContext } from './modal.context.js'; +import { UmbModalContext } from './modal-context.js'; +import { UmbModalConfig, UmbModalManagerContext } from './modal-manager.context.js'; import { UmbModalToken } from './token/modal-token.js'; import type { IRouterSlot } from '@umbraco-cms/backoffice/external/router-slot'; import { encodeFolderName } from '@umbraco-cms/backoffice/router'; @@ -18,7 +18,7 @@ export class UmbModalRouteRegistration void; #onRejectCallback?: () => void; - #modalHandler: UmbModalHandler | undefined; + #modalContext: UmbModalContext | undefined; #routeBuilder?: UmbModalRouteBuilder; #urlBuilderCallback: ((urlBuilder: UmbModalRouteBuilder) => void) | undefined; @@ -62,20 +62,20 @@ export class UmbModalRouteRegistration void) { @@ -102,22 +102,22 @@ export class UmbModalRouteRegistration { this.#onSubmitCallback?.(data); - this.#modalHandler = undefined; + this.#modalContext = undefined; }; #onReject = () => { this.#onRejectCallback?.(); - this.#modalHandler = undefined; + this.#modalContext = undefined; }; - routeSetup(router: IRouterSlot, modalContext: UmbModalContext, params: Params) { + routeSetup(router: IRouterSlot, modalContext: UmbModalManagerContext, params: Params) { // If already open, don't do anything: if (this.active) return; const modalData = this.#onSetupCallback ? this.#onSetupCallback(params) : undefined; if (modalData !== false) { - this.#modalHandler = modalContext.open(this.#modalAlias, modalData, this.modalConfig, router); - this.#modalHandler.onSubmit().then(this.#onSubmit, this.#onReject); - return this.#modalHandler; + this.#modalContext = modalContext.open(this.#modalAlias, modalData, this.modalConfig, router); + this.#modalContext.onSubmit().then(this.#onSubmit, this.#onReject); + return this.#modalContext; } return null; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/data-type-picker-flow-data-type-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/data-type-picker-flow-data-type-picker-modal.token.ts new file mode 100644 index 0000000000..4c21b1c8b1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/data-type-picker-flow-data-type-picker-modal.token.ts @@ -0,0 +1,18 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbDataTypePickerFlowDataTypePickerModalData { + propertyEditorUiAlias: string; +} + +export type UmbDataTypePickerFlowDataTypePickerModalResult = { + dataTypeId?: string; + createNewWithPropertyEditorUiAlias?: string; +}; + +export const UMB_DATA_TYPE_PICKER_FLOW_DATA_TYPE_PICKER_MODAL = new UmbModalToken< + UmbDataTypePickerFlowDataTypePickerModalData, + UmbDataTypePickerFlowDataTypePickerModalResult +>('Umb.Modal.DataTypePickerFlowDataTypePicker', { + type: 'sidebar', + size: 'small', +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts index e7b1cd82c9..0c5dfd5cb9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/index.ts @@ -29,4 +29,6 @@ export * from './folder-modal.token.js'; export * from './partial-view-picker-modal.token.js'; export * from './dictionary-item-picker-modal.token.js'; export * from './data-type-picker-modal.token.js'; +export * from './workspace-modal.token.js'; export * from './data-type-picker-flow-modal.token.js'; +export * from './data-type-picker-flow-data-type-picker-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts index 0e7328b277..c8c59e8b45 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/modal-token.ts @@ -1,4 +1,4 @@ -import { UmbModalConfig } from '../modal.context.js'; +import { UmbModalConfig } from '../modal-manager.context.js'; export class UmbModalToken { /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/property-editor-ui-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/property-editor-ui-picker-modal.token.ts index 9bff24f2fe..8cdbd227ac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/property-editor-ui-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/property-editor-ui-picker-modal.token.ts @@ -12,7 +12,7 @@ export type UmbPropertyEditorUIPickerModalResult = { export const UMB_PROPERTY_EDITOR_UI_PICKER_MODAL = new UmbModalToken< UmbPropertyEditorUIPickerModalData, UmbPropertyEditorUIPickerModalResult ->('Umb.Modal.PropertyEditorUIPicker', { +>('Umb.Modal.PropertyEditorUiPicker', { type: 'sidebar', size: 'small', }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/workspace-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/workspace-modal.token.ts new file mode 100644 index 0000000000..46523ee4b1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/token/workspace-modal.token.ts @@ -0,0 +1,16 @@ +import { CreateDataTypeRequestModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbWorkspaceData { + entityType: string; + preset: Partial; +} + +export type UmbWorkspaceResult = { + id: string; +}; + +export const UMB_WORKSPACE_MODAL = new UmbModalToken('Umb.Modal.Workspace', { + type: 'sidebar', + size: 'large', +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts index 2f6f163fe2..b10586a5de 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts @@ -2,8 +2,8 @@ import { UmbItemRepository, UmbRepositoryItemsManager } from '@umbraco-cms/backo import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UMB_CONFIRM_MODAL, - UMB_MODAL_CONTEXT_TOKEN, - UmbModalContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UmbModalManagerContext, UmbModalToken, UmbPickerModalData, } from '@umbraco-cms/backoffice/modal'; @@ -17,7 +17,7 @@ export class UmbPickerInputContext repository?: UmbItemRepository; #getUnique: (entry: ItemType) => string | undefined; - public modalContext?: UmbModalContext; + public modalManager?: UmbModalManagerContext; public pickableFilter?: (item: ItemType) => boolean = () => true; @@ -50,8 +50,8 @@ export class UmbPickerInputContext this.#init = Promise.all([ this.#itemManager.init, - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this.modalContext = instance; + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this.modalManager = instance; }).asPromise(), ]); } @@ -66,16 +66,16 @@ export class UmbPickerInputContext // TODO: If modalAlias is a ModalToken, then via TS, we should get the correct type for pickerData. Otherwise fallback to unknown. openPicker(pickerData?: Partial>) { - if (!this.modalContext) throw new Error('Modal context is not initialized'); + if (!this.modalManager) throw new Error('Modal manager context is not initialized'); - const modalHandler = this.modalContext.open(this.modalAlias, { + const modalContext = this.modalManager.open(this.modalAlias, { multiple: this.max === 1 ? false : true, selection: [...this.getSelection()], pickableFilter: this.pickableFilter, ...pickerData, }); - modalHandler?.onSubmit().then(({ selection }: any) => { + modalContext?.onSubmit().then(({ selection }: any) => { this.setSelection(selection); this.host.dispatchEvent(new UmbChangeEvent()); // TODO: we only want to request items that are not already in the selectedItems array @@ -90,14 +90,14 @@ export class UmbPickerInputContext const item = this.#itemManager.getItems().find((item) => this.#getUnique(item) === unique); if (!item) throw new Error('Could not find item with unique: ' + unique); - const modalHandler = this.modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this.modalManager?.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(); + await modalContext?.onSubmit(); this.#removeItem(unique); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts index f44416d188..cbe44fae8a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editors/uis/icon-picker/property-editor-ui-icon-picker.element.ts @@ -1,7 +1,11 @@ -import { html , customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { UmbPropertyEditorExtensionElement } from '@umbraco-cms/backoffice/extension-registry'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_ICON_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_ICON_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import type { UmbDataTypePropertyCollection } from '@umbraco-cms/backoffice/components'; @@ -16,11 +20,11 @@ export class UmbPropertyEditorUIIconPickerElement extends UmbLitElement implemen @property({ type: Array, attribute: false }) public config?: UmbDataTypePropertyCollection; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/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/packages/core/property-editors/uis/multiple-text-string/input-multiple-text-string-item/input-multiple-text-string-item.element.ts index 71dd28f03d..c3468f1bac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/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/packages/core/property-editors/uis/multiple-text-string/input-multiple-text-string-item/input-multiple-text-string-item.element.ts @@ -1,6 +1,10 @@ -import { css, html, nothing , customElement, property, query } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, nothing, customElement, property, query } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles, FormControlMixin, UUIInputElement, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_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'; @@ -30,25 +34,25 @@ export class UmbInputMultipleTextStringItemElement extends FormControlMixin(UmbL @query('#input') protected _input?: UUIInputElement; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } #onDelete() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: `Delete ${this.value || 'item'}`, content: 'Are you sure you want to delete this item?', color: 'danger', confirmLabel: 'Delete', }); - modalHandler?.onSubmit().then(() => { + modalContext?.onSubmit().then(() => { this.dispatchEvent(new UmbDeleteEvent()); }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/index.ts index ae6add6c58..07497983cb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/index.ts @@ -2,6 +2,7 @@ export * from './workspace-action/index.js'; export * from './workspace-action-menu/index.js'; export * from './workspace-editor/index.js'; export * from './workspace-footer/index.js'; +export * from './workspace-modal/index.js'; export * from './workspace-context/index.js'; export * from './workspace-variant/index.js'; export * from './workspace-split-view-manager.class.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/manifests.ts new file mode 100644 index 0000000000..0f7b8c89ac --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/manifests.ts @@ -0,0 +1,3 @@ +import { manifests as workspaceModals } from './workspace-modal/manifests.js'; + +export const manifests = [...workspaceModals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-context/workspace-context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-context/workspace-context.ts index 0362130fe2..05d79d904b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-context/workspace-context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-context/workspace-context.ts @@ -1,9 +1,10 @@ import { UmbEntityWorkspaceContextInterface } from './workspace-entity-context.interface.js'; -import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; +import { UmbContextConsumerController, UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbEntityBase } from '@umbraco-cms/backoffice/models'; import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; +import { UMB_MODAL_CONTEXT_TOKEN, UmbModalContext } from '@umbraco-cms/backoffice/modal'; /* @@ -13,8 +14,11 @@ If so we need to align on a interface that all of these implements. otherwise co export abstract class UmbWorkspaceContext implements UmbEntityWorkspaceContextInterface { - public host: UmbControllerHostElement; - public repository: T; + public readonly host: UmbControllerHostElement; + public readonly repository: T; + + // TODO: We could make a base type for workspace modal data, and use this here: As well as a base for the result, to make sure we always include the unique. + public readonly modalContext?: UmbModalContext<{ preset: object }>; #isNew = new UmbBooleanState(undefined); isNew = this.#isNew.asObservable(); @@ -23,6 +27,9 @@ export abstract class UmbWorkspaceContext this.host = host; this.repository = repository; new UmbContextProviderController(host, UMB_ENTITY_WORKSPACE_CONTEXT, this); + new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (context) => { + (this.modalContext as UmbModalContext) = context; + }); } getIsNew() { @@ -33,6 +40,19 @@ export abstract class UmbWorkspaceContext this.#isNew.next(isNew); } + protected saveComplete(data: EntityType) { + if (this.modalContext) { + this.submitModal(data); + } else { + // No need to have UI changing to "not new" if we are in a modal. + this.setIsNew(false); + } + } + + protected submitModal(data: EntityType) { + this.modalContext?.submit(data); + } + 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; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-footer/workspace-footer.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-footer/workspace-footer.element.ts index 49ea30ac3d..dd6c99aa09 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-footer/workspace-footer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-footer/workspace-footer.element.ts @@ -1,8 +1,9 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { css, html , customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import type { ManifestWorkspaceAction } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_MODAL_CONTEXT_TOKEN, UmbModalContext } from '@umbraco-cms/backoffice/modal'; /** * @element umb-workspace-footer @@ -17,6 +18,7 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-workspace-footer') export class UmbWorkspaceFooterLayoutElement extends UmbLitElement { private _alias = ''; + /** * Alias of the workspace. The Layout will render the workspace actions that are registered for this workspace alias. * @public @@ -36,12 +38,31 @@ export class UmbWorkspaceFooterLayoutElement extends UmbLitElement { } } + @state() + _withinModal = false; + + #modalContext?: UmbModalContext; + + constructor() { + super(); + this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (context) => { + this.#modalContext = context; + }); + } + + private _onClose = () => { + this.#modalContext?.reject(); + }; + // TODO: Some event/callback from umb-extension-slot that can be utilized to hide the footer, if empty. render() { return html` + ${this.#modalContext + ? html`` + : ''} import('./workspace-modal.element.js'), +}; + +export const manifests = [workspaceModal]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-modal/workspace-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-modal/workspace-modal.element.ts new file mode 100644 index 0000000000..02dff6e98f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace-modal/workspace-modal.element.ts @@ -0,0 +1,36 @@ +import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; +import { css, CSSResultGroup, html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbWorkspaceData } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; + +@customElement('umb-workspace-modal') +export class UmbWorkspaceModalElement extends UmbLitElement { + @property() + data?: UmbWorkspaceData; + + /** + * TODO: Consider if this binding and events integration is the right for communicating back the modal handler. Or if we should go with some Context API. like a Modal Context API. + * + */ + render() { + return html``; + } + + static styles: CSSResultGroup = [ + UUITextStyles, + css` + :host { + display: block; + height: 100%; + } + `, + ]; +} + +export default UmbWorkspaceModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-workspace-modal': UmbWorkspaceModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace.element.ts index 3d1eb0a531..d6ed14cf62 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/workspace.element.ts @@ -1,5 +1,5 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { css, html, nothing , customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { ManifestWorkspace } from '@umbraco-cms/backoffice/extension-registry'; @@ -9,7 +9,7 @@ export class UmbWorkspaceElement extends UmbLitElement { entityType = ''; render() { - if (!this.entityType) nothing; + if (!this.entityType) return nothing; return html` manifest.meta.entityType === this.entityType}>`; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts index 69feeae261..44274f5bed 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/dashboards/redirect-management/dashboard-redirect-management.element.ts @@ -5,7 +5,11 @@ import { UUIPaginationEvent, } from '@umbraco-cms/backoffice/external/uui'; import { css, html, nothing, customElement, state, query, property } from '@umbraco-cms/backoffice/external/lit'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { RedirectManagementResource, @@ -43,11 +47,11 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { @query('uui-pagination') private _pagination?: UUIPaginationElement; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (_instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (_instance) => { this._modalContext = _instance; }); } @@ -64,7 +68,7 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { } private _removeRedirectHandler(data: RedirectUrlResponseModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Delete', content: html`
@@ -77,7 +81,7 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { color: 'danger', confirmLabel: 'Delete', }); - modalHandler?.onSubmit().then(() => { + modalContext?.onSubmit().then(() => { this._removeRedirect(data); }); } @@ -94,13 +98,13 @@ export class UmbDashboardRedirectManagementElement extends UmbLitElement { } private _disableRedirectHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Disable URL tracker', content: html`Are you sure you want to disable the URL tracker?`, color: 'danger', confirmLabel: 'Disable', }); - modalHandler?.onSubmit().then(() => { + modalContext?.onSubmit().then(() => { this._toggleRedirect(); }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type-picker/input-document-type-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type-picker/input-document-type-picker.element.ts index 0113e7f448..3753a17089 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type-picker/input-document-type-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/components/input-document-type-picker/input-document-type-picker.element.ts @@ -6,8 +6,8 @@ import { css, html, nothing, ifDefined, customElement, property, state } from '@ import { UUITextStyles, FormControlMixin } from '@umbraco-cms/backoffice/external/uui'; import { DocumentTypeResponseModel, EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { - UmbModalContext, - UMB_MODAL_CONTEXT_TOKEN, + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_CONFIRM_MODAL, UMB_DOCUMENT_TYPE_PICKER_MODAL, } from '@umbraco-cms/backoffice/modal'; @@ -38,7 +38,7 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl @state() private _items?: Array; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; private _documentTypeStore?: UmbDocumentTypeTreeStore; private _pickedItemsObserver?: UmbObserverController; @@ -48,7 +48,7 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl this._documentTypeStore = instance; this._observePickedDocuments(); }); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -70,25 +70,25 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl 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, { + const modalContext = this._modalContext?.open(UMB_DOCUMENT_TYPE_PICKER_MODAL, { multiple: true, selection: [...this._selectedIds], }); - modalHandler?.onSubmit().then(({ selection }: any) => { + modalContext?.onSubmit().then(({ selection }: any) => { this._setSelection(selection); }); } private async _removeItem(item: DocumentTypeResponseModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = 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(); + await modalContext?.onSubmit(); const newSelection = this._selectedIds.filter((value) => value !== item.id); this._setSelection(newSelection); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/create.action.ts index 4a4a74014a..5546938f8f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/create.action.ts @@ -2,25 +2,25 @@ import { UmbDocumentTypeRepository } from '../../repository/document-type.reposi import { UMB_DOCUMENT_TYPE_CREATE_OPTIONS_MODAL } from './modal/index.js'; import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbModalManagerContext, UMB_MODAL_MANAGER_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; export class UmbCreateDataTypeEntityAction extends UmbEntityActionBase { - #modalContext?: UmbModalContext; + #modalManagerContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this.#modalContext = instance; + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this.#modalManagerContext = instance; }); } async execute() { - if (!this.#modalContext) throw new Error('Modal context is not available'); + if (!this.#modalManagerContext) throw new Error('Modal manager context is not available'); if (!this.repository) throw new Error('Repository is not available'); - this.#modalContext?.open(UMB_DOCUMENT_TYPE_CREATE_OPTIONS_MODAL, { + this.#modalManagerContext?.open(UMB_DOCUMENT_TYPE_CREATE_OPTIONS_MODAL, { parentKey: this.unique, }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/modal/document-type-create-options-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/modal/document-type-create-options-modal.element.ts index 574a3fbe4b..96c8ea2fac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/modal/document-type-create-options-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/entity-actions/create/modal/document-type-create-options-modal.element.ts @@ -3,26 +3,26 @@ import { UmbDocumentTypeCreateOptionsModalData } from './index.js'; import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { + UmbModalManagerContext, UmbModalContext, - UmbModalHandler, UMB_FOLDER_MODAL, - UMB_MODAL_CONTEXT_TOKEN, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-document-type-create-options-modal') export class UmbDataTypeCreateOptionsModalElement extends UmbLitElement { @property({ attribute: false }) - modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; @property({ type: Object }) data?: UmbDocumentTypeCreateOptionsModalData; - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -32,16 +32,16 @@ export class UmbDataTypeCreateOptionsModalElement extends UmbLitElement { const folderModalHandler = this.#modalContext?.open(UMB_FOLDER_MODAL, { repositoryAlias: DOCUMENT_TYPE_REPOSITORY_ALIAS, }); - folderModalHandler?.onSubmit().then(() => this.modalHandler?.submit()); + folderModalHandler?.onSubmit().then(() => this.modalContext?.submit()); } // close the modal when navigating to data type #onNavigate() { - this.modalHandler?.submit(); + this.modalContext?.submit(); } #onCancel() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/allowed-document-types/allowed-document-types-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/allowed-document-types/allowed-document-types-modal.element.ts index 34019ecbf8..ec849a09f3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/allowed-document-types/allowed-document-types-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/modals/allowed-document-types/allowed-document-types-modal.element.ts @@ -44,7 +44,7 @@ export class UmbAllowedDocumentTypesModalElement extends UmbModalBaseElement< } private _handleCancel() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } #onClick(event: PointerEvent) { @@ -52,7 +52,7 @@ export class UmbAllowedDocumentTypesModalElement extends UmbModalBaseElement< 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 }); + this.modalContext?.submit({ documentTypeKey }); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts index b9e423ee7e..2a9a386c38 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts @@ -2,7 +2,11 @@ import { UmbDocumentTypeWorkspaceContext } from './document-type-workspace.conte import { UUIInputElement, UUIInputEvent, UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_ICON_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_ICON_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; @customElement('umb-document-type-workspace-editor') export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement { @@ -21,7 +25,7 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement { @state() private _alias?: string; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); @@ -31,7 +35,7 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement { this.#observeDocumentType(); }); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -67,12 +71,12 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement { } private async _handleIconClick() { - const modalHandler = this._modalContext?.open(UMB_ICON_PICKER_MODAL, { + const modalContext = this._modalContext?.open(UMB_ICON_PICKER_MODAL, { icon: this._icon, color: this._iconColorAlias, }); - modalHandler?.onSubmit().then((saved) => { + modalContext?.onSubmit().then((saved) => { if (saved.icon) this.#workspaceContext?.setIcon(saved.icon); // TODO: save color ALIAS as well }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/views/design/document-type-workspace-view-edit-properties.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/views/design/document-type-workspace-view-edit-properties.element.ts index 5967b66af0..45fcdb1a6c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/views/design/document-type-workspace-view-edit-properties.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/views/design/document-type-workspace-view-edit-properties.element.ts @@ -1,5 +1,5 @@ import { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context.js'; -import { css, html , customElement, property, state , repeat , ifDefined } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, property, state, repeat, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { UmbContentTypePropertyStructureHelper, PropertyContainerTypes } from '@umbraco-cms/backoffice/content-type'; import { UmbSorterController, UmbSorterConfig } from '@umbraco-cms/backoffice/sorter'; @@ -8,7 +8,7 @@ import { DocumentTypePropertyTypeResponseModel, PropertyTypeResponseModelBaseModel, } from '@umbraco-cms/backoffice/backend-api'; -import { UMB_MODAL_CONTEXT_TOKEN, UMB_PROPERTY_SETTINGS_MODAL } from '@umbraco-cms/backoffice/modal'; +import { UMB_MODAL_MANAGER_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; import './document-type-workspace-view-edit-property.element.js'; import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; const SORTER_CONFIG: UmbSorterConfig = { @@ -80,7 +80,7 @@ export class UmbDocumentTypeWorkspaceViewEditPropertiesElement extends UmbLitEle @state() _propertyStructure: Array = []; - #modalContext?: typeof UMB_MODAL_CONTEXT_TOKEN.TYPE; + #modalContext?: typeof UMB_MODAL_MANAGER_CONTEXT_TOKEN.TYPE; constructor() { super(); @@ -90,7 +90,7 @@ export class UmbDocumentTypeWorkspaceViewEditPropertiesElement extends UmbLitEle (workspaceContext as UmbDocumentTypeWorkspaceContext).structure ); }); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => (this.#modalContext = instance)); + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => (this.#modalContext = instance)); this.observe(this._propertyStructureHelper.propertyStructure, (propertyStructure) => { this._propertyStructure = propertyStructure; this.#propertySorter.setModel(this._propertyStructure); @@ -107,9 +107,9 @@ export class UmbDocumentTypeWorkspaceViewEditPropertiesElement extends UmbLitEle console.log('property id:', property.id!, property); // TODO: route modal.. - const modalHandler = this.#modalContext?.open(UMB_PROPERTY_SETTINGS_MODAL); + const modalContext = this.#modalContext?.open(UMB_PROPERTY_SETTINGS_MODAL); - modalHandler?.onSubmit().then((result) => { + modalContext?.onSubmit().then((result) => { console.log(result); }); */ diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-picker/input-document-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-picker/input-document-picker.element.ts index db3992298f..50b1ae9836 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-picker/input-document-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document-picker/input-document-picker.element.ts @@ -3,8 +3,8 @@ import type { UmbDocumentTreeStore } from '../../repository/document.tree.store. import { css, html, nothing, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles, FormControlMixin } from '@umbraco-cms/backoffice/external/uui'; import { - UmbModalContext, - UMB_MODAL_CONTEXT_TOKEN, + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_CONFIRM_MODAL, UMB_DOCUMENT_PICKER_MODAL, } from '@umbraco-cms/backoffice/modal'; @@ -71,7 +71,7 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen @state() private _items?: Array; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; private _documentStore?: UmbDocumentTreeStore; private _pickedItemsObserver?: UmbObserverController; @@ -93,7 +93,7 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen this._documentStore = instance; this._observePickedDocuments(); }); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -115,25 +115,25 @@ export class UmbInputDocumentPickerElement extends FormControlMixin(UmbLitElemen 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_PICKER_MODAL, { + const modalContext = this._modalContext?.open(UMB_DOCUMENT_PICKER_MODAL, { multiple: this.max === 1 ? false : true, selection: [...this._selectedIds], }); - modalHandler?.onSubmit().then(({ selection }: any) => { + modalContext?.onSubmit().then(({ selection }: any) => { this._setSelection(selection); }); } private async _removeItem(item: EntityTreeItemResponseModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = 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(); + await modalContext?.onSubmit(); const newSelection = this._selectedIds.filter((value) => value !== item.id); this._setSelection(newSelection); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts index 8bf7982dc8..331aeea40d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts @@ -2,19 +2,19 @@ import type { UmbDocumentRepository } from '../../repository/document.repository import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { - UmbModalContext, - UMB_MODAL_CONTEXT_TOKEN, + UmbModalManagerContext, + UMB_MODAL_MANAGER_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; + #modalContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -45,12 +45,12 @@ export class UmbCreateDocumentEntityAction extends UmbEntityActionBase { - extensionRegistry.registerMany(manifests); -}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/umbraco-package.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/umbraco-package.ts index a0b11b8baf..260460b442 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/umbraco-package.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/umbraco-package.ts @@ -1,9 +1,9 @@ export const name = 'Umbraco.Core.DocumentManagement'; export const extensions = [ { - name: 'Document Management Entry Point', - alias: 'Umb.EntryPoint.DocumentManagement', - type: 'entryPoint', - loader: () => import('./package-entry-point.js'), + name: 'Document Management Bundle', + alias: 'Umb.Bundle.DocumentManagement', + type: 'bundle', + loader: () => import('./manifests.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media-picker/input-media-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media-picker/input-media-picker.element.ts index 9822455abe..a7e10234b7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media-picker/input-media-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/components/input-media-picker/input-media-picker.element.ts @@ -2,8 +2,8 @@ import { UmbMediaRepository } from '../../repository/media.repository.js'; import { css, html, nothing, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles, FormControlMixin } from '@umbraco-cms/backoffice/external/uui'; import { - UmbModalContext, - UMB_MODAL_CONTEXT_TOKEN, + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_CONFIRM_MODAL, UMB_MEDIA_TREE_PICKER_MODAL, } from '@umbraco-cms/backoffice/modal'; @@ -70,7 +70,7 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) @state() private _items?: Array; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; private _pickedItemsObserver?: UmbObserverController; private _repository = new UmbMediaRepository(this); @@ -88,7 +88,7 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) () => !!this.max && this._selectedIds.length > this.max ); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -117,25 +117,25 @@ export class UmbInputMediaPickerElement extends FormControlMixin(UmbLitElement) 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_MEDIA_TREE_PICKER_MODAL, { + const modalContext = this._modalContext?.open(UMB_MEDIA_TREE_PICKER_MODAL, { multiple: this.max === 1 ? false : true, selection: [...this._selectedIds], }); - modalHandler?.onSubmit().then(({ selection }: any) => { + modalContext?.onSubmit().then(({ selection }: any) => { this._setSelection(selection); }); } private _removeItem(item: EntityTreeItemResponseModel) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { color: 'danger', headline: `Remove ${item.name}?`, content: 'Are you sure you want to remove this item', confirmLabel: 'Remove', }); - modalHandler?.onSubmit().then(() => { + modalContext?.onSubmit().then(() => { const newSelection = this._selectedIds.filter((value) => value !== item.id); this._setSelection(newSelection); }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move/move.action.ts index 7cae823031..9f71ba5fa1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move/move.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/move/move.action.ts @@ -2,27 +2,31 @@ import type { UmbMediaRepository } from '../../repository/media.repository.js'; import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_MEDIA_TREE_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_MEDIA_TREE_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase { - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); - new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + new UmbContextConsumerController(host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } async execute() { // TODO: the picker should be single picker by default - const modalHandler = this.#modalContext?.open(UMB_MEDIA_TREE_PICKER_MODAL, { + const modalContext = this.#modalContext?.open(UMB_MEDIA_TREE_PICKER_MODAL, { selection: [], multiple: false, }); - if (modalHandler) { - const { selection } = await modalHandler.onSubmit(); + if (modalContext) { + const { selection } = await modalContext.onSubmit(); const destination = selection[0]; await this.repository?.move(this.selection, destination); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/trash.action.ts index 9b2f10d9d9..e059b95969 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/trash.action.ts @@ -3,15 +3,19 @@ import { html } from '@umbraco-cms/backoffice/external/lit'; import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; export class UmbMediaTrashEntityBulkAction extends UmbEntityBulkActionBase { - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) { super(host, repositoryAlias, selection); - new UmbContextConsumerController(host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { + new UmbContextConsumerController(host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -25,7 +29,7 @@ export class UmbMediaTrashEntityBulkAction extends UmbEntityBulkActionBase import('./index.js'), + loader: () => import('./package-entry-point.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/package-entry-point.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/package-entry-point.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/umbraco-package.ts b/src/Umbraco.Web.UI.Client/src/packages/members/umbraco-package.ts index c4ce05c45a..c3376f3876 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/umbraco-package.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/umbraco-package.ts @@ -4,6 +4,6 @@ export const extensions = [ name: 'Member Management Entry Point', alias: 'Umb.EntryPoint.MemberManagement', type: 'entryPoint', - loader: () => import('./index.js'), + loader: () => import('./package-entry-point.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/index.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-entry-point.ts similarity index 87% rename from src/Umbraco.Web.UI.Client/src/packages/packages/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/packages/package-entry-point.ts index 34d49d9576..01a54b2026 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-entry-point.ts @@ -1,4 +1,4 @@ -import { manifests as repositoryManifests } from './repository/manifests.js'; +import { manifests as repositoryManifests } from './package/repository/manifests.js'; import { manifests as packageBuilderManifests } from './package-builder/manifests.js'; import { manifests as packageRepoManifests } from './package-repo/manifests.js'; import { manifests as packageSectionManifests } from './package-section/manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/packages-created-overview.element.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/packages-created-overview.element.ts index 66e6c6e32a..cfd9965b0e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/packages-created-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/created/packages-created-overview.element.ts @@ -3,7 +3,11 @@ import { UUIPaginationEvent } from '@umbraco-cms/backoffice/external/uui'; 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'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; @customElement('umb-packages-created-overview') export class UmbPackagesCreatedOverviewElement extends UmbLitElement { @@ -21,7 +25,7 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { @state() private _total?: number; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); @@ -31,7 +35,7 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { super.connectedCallback(); this.#getPackages(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -104,14 +108,14 @@ export class UmbPackagesCreatedOverviewElement extends UmbLitElement { async #deletePackage(p: PackageDefinitionResponseModel) { if (!p.id) return; - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { color: 'danger', headline: `Remove ${p.name}?`, content: 'Are you sure you want to delete this package', confirmLabel: 'Delete', }); - await modalHandler?.onSubmit(); + await modalContext?.onSubmit(); const { error } = await tryExecuteAndNotify(this, PackageResource.deletePackageCreatedById({ id: p.id })); if (error) return; diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts index d3af6e67c8..1f1368c421 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view-item.element.ts @@ -1,7 +1,11 @@ -import { html, css, nothing , ifDefined , customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { html, css, nothing, ifDefined, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UUIButtonState } from '@umbraco-cms/backoffice/external/uui'; import { map } from '@umbraco-cms/backoffice/external/rxjs'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api'; import { ManifestPackageView, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -40,7 +44,7 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement { private _packageView?: ManifestPackageView; #notificationContext?: UmbNotificationContext; - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor() { super(); @@ -48,7 +52,7 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement { this.consumeContext(UMB_NOTIFICATION_CONTEXT_TOKEN, (instance) => { this.#notificationContext = instance; }); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -73,14 +77,14 @@ export class UmbInstalledPackagesSectionViewItemElement extends UmbLitElement { async _onMigration() { if (!this.name) return; - const modalHandler = this.#modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = 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}`, confirmLabel: 'Run migrations', }); - await modalHandler?.onSubmit(); + await modalContext?.onSubmit(); this._migrationButtonState = 'waiting'; const { error } = await tryExecuteAndNotify( diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts index f069ad1966..6d72e50dcc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package-section/views/installed/installed-packages-section-view.element.ts @@ -1,4 +1,4 @@ -import { UmbPackageRepository } from '../../../repository/package.repository.js'; +import { UmbPackageRepository } from '../../../package/repository/package.repository.js'; import type { UmbPackageWithMigrationStatus } from '../../../types.js'; import { html, css, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { combineLatest } from '@umbraco-cms/backoffice/external/rxjs'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package/index.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/index.ts new file mode 100644 index 0000000000..3d76f338dd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package/index.ts @@ -0,0 +1 @@ +export * from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/index.ts new file mode 100644 index 0000000000..437143950f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/index.ts @@ -0,0 +1 @@ +export * from './package.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/packages/repository/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/repository/package.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/package.repository.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/packages/repository/package.repository.ts rename to src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/package.repository.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/repository/package.store.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/package.store.ts similarity index 97% rename from src/Umbraco.Web.UI.Client/src/packages/packages/repository/package.store.ts rename to src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/package.store.ts index f3292bf5ee..3b6a382bf6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/repository/package.store.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/package.store.ts @@ -1,4 +1,4 @@ -import type { UmbPackage } from '../types.js'; +import type { UmbPackage } from '../../types.js'; import { ReplaySubject } from '@umbraco-cms/backoffice/external/rxjs'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/repository/server-extension.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/server-extension.controller.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/packages/repository/server-extension.controller.ts rename to src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/server-extension.controller.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/repository/sources/package.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/packages/repository/sources/package.server.data.ts rename to src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/umbraco-package.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/umbraco-package.ts index c7d6b9a313..156094f0c2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/umbraco-package.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/umbraco-package.ts @@ -4,6 +4,6 @@ export const extensions = [ name: 'Package Management Entry Point', alias: 'Umb.EntryPoint.PackageManagement', type: 'entryPoint', - loader: () => import('./index.js'), + loader: () => import('./package-entry-point.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-settings.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-settings.element.ts index f6f75bf486..8d68b1db05 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-settings.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-settings.element.ts @@ -1,4 +1,4 @@ -import { html, css , customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { html, css, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { UmbCreateDocumentModalResultData, UmbExamineFieldsSettingsModalData } from '@umbraco-cms/backoffice/modal'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; @@ -12,7 +12,7 @@ export class UmbExamineFieldsSettingsModalElement extends UmbModalBaseElement< private _fields?: UmbExamineFieldsSettingsModalData; private _handleClose() { - this.modalHandler?.submit({ fields: this._fields }); + this.modalContext?.submit({ fields: this._fields }); } disconnectedCallback(): void { diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-viewer.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-viewer.element.ts index 456ccf5578..44f55bf86a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-viewer.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/modal-views/fields-viewer.element.ts @@ -1,4 +1,4 @@ -import { html, css, nothing , customElement } from '@umbraco-cms/backoffice/external/lit'; +import { html, css, nothing, customElement } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; import type { SearchResultResponseModel } from '@umbraco-cms/backoffice/backend-api'; @@ -8,7 +8,7 @@ export class UmbModalElementFieldsViewerElement extends UmbModalBaseElement< SearchResultResponseModel & { name: string } > { private _handleClose() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-indexers.ts b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-indexers.ts index bb89ff057f..e89a887d15 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-indexers.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-indexers.ts @@ -1,6 +1,10 @@ import { UUITextStyles, UUIButtonState } from '@umbraco-cms/backoffice/external/uui'; import { css, html, nothing, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_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'; @@ -21,12 +25,12 @@ export class UmbDashboardExamineIndexElement extends UmbLitElement { @state() private _loading = true; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (_instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (_instance) => { this._modalContext = _instance; }); @@ -49,7 +53,7 @@ export class UmbDashboardExamineIndexElement extends UmbLitElement { } private async _onRebuildHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: `Rebuild ${this.indexName}`, content: html` This will cause the index to be rebuilt.
@@ -60,7 +64,7 @@ export class UmbDashboardExamineIndexElement extends UmbLitElement { color: 'danger', confirmLabel: 'Rebuild', }); - modalHandler?.onSubmit().then(() => { + modalContext?.onSubmit().then(() => { this._rebuild(); }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-searchers.ts b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-searchers.ts index 20c202422d..dd55a42d20 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-searchers.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/examine-management-dashboard/views/section-view-examine-searchers.ts @@ -1,8 +1,8 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { css, html, nothing , customElement, state, query, property } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, nothing, customElement, state, query, property } from '@umbraco-cms/backoffice/external/lit'; import { - UmbModalContext, - UMB_MODAL_CONTEXT_TOKEN, + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_EXAMINE_FIELDS_SETTINGS_MODAL, } from '@umbraco-cms/backoffice/modal'; import { @@ -23,7 +23,7 @@ interface ExposedSearchResultField { @customElement('umb-dashboard-examine-searcher') export class UmbDashboardExamineSearcherElement extends UmbLitElement { - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; @property() searcherName!: string; @@ -42,7 +42,7 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement { constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -97,10 +97,10 @@ export class UmbDashboardExamineSearcherElement extends UmbLitElement { } private _onFieldFilterClick() { - const modalHandler = this._modalContext?.open(UMB_EXAMINE_FIELDS_SETTINGS_MODAL, { + const modalContext = this._modalContext?.open(UMB_EXAMINE_FIELDS_SETTINGS_MODAL, { ...this._exposedFields, }); - modalHandler?.onSubmit().then(({ fields } = {}) => { + modalContext?.onSubmit().then(({ fields } = {}) => { if (!fields) return; this._exposedFields = fields; }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts b/src/Umbraco.Web.UI.Client/src/packages/search/package-entry-point.ts similarity index 78% rename from src/Umbraco.Web.UI.Client/src/packages/search/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/search/package-entry-point.ts index bc3f48d352..2e31400609 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/package-entry-point.ts @@ -1,4 +1,4 @@ -import { manifests as searchManifests } from '../search/manifests.js'; +import { manifests as searchManifests } from './manifests.js'; import type { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/umb-search-header-app.element.ts b/src/Umbraco.Web.UI.Client/src/packages/search/umb-search-header-app.element.ts index 029422fc60..c0c567112f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/umb-search-header-app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/umb-search-header-app.element.ts @@ -1,16 +1,16 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { css, CSSResultGroup, html , customElement } from '@umbraco-cms/backoffice/external/lit'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { css, CSSResultGroup, html, customElement } from '@umbraco-cms/backoffice/external/lit'; +import { UmbModalManagerContext, UMB_MODAL_MANAGER_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @customElement('umb-search-header-app') export class UmbSearchHeaderAppElement extends UmbLitElement { - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (_instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (_instance) => { this._modalContext = _instance; }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/umbraco-package.ts b/src/Umbraco.Web.UI.Client/src/packages/search/umbraco-package.ts index cc195e5790..a58633ae59 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/umbraco-package.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/umbraco-package.ts @@ -4,6 +4,6 @@ export const extensions = [ name: 'Search Entry Point', alias: 'Umb.EntryPoint.Search', type: 'entryPoint', - loader: () => import('./index.js'), + loader: () => import('./package-entry-point.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/dashboards/published-status/dashboard-published-status.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/dashboards/published-status/dashboard-published-status.element.ts index d059a34dad..2471c4a92f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/dashboards/published-status/dashboard-published-status.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/dashboards/published-status/dashboard-published-status.element.ts @@ -1,6 +1,10 @@ import { UUIButtonState, UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_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'; @@ -22,12 +26,12 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { @state() private _buttonStateCollect: UUIButtonState = undefined; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -66,13 +70,13 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { } } private async _onReloadCacheHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Reload', content: html` Trigger a in-memory and local file cache reload on all servers. `, color: 'danger', confirmLabel: 'Continue', }); - modalHandler?.onSubmit().then(() => { + modalContext?.onSubmit().then(() => { this._reloadMemoryCache(); }); } @@ -89,13 +93,13 @@ export class UmbDashboardPublishedStatusElement extends UmbLitElement { } private async _onRebuildCacheHandler() { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContex = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Rebuild', content: html` Rebuild content in cmsContentNu database table. Expensive.`, color: 'danger', confirmLabel: 'Continue', }); - modalHandler?.onSubmit().then(() => { + modalContex?.onSubmit().then(() => { this._rebuildDatabaseCache(); }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/copy/copy.action.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/copy/copy.action.ts index 2c1caf46f3..0e5bb55c0a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/copy/copy.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/copy/copy.action.ts @@ -1,27 +1,31 @@ import { UmbDataTypeRepository } from '../../repository/data-type.repository.js'; import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_DATA_TYPE_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_DATA_TYPE_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; // TODO: investigate what we need to make a generic copy action export class UmbCopyDataTypeEntityAction extends UmbEntityActionBase { - #modalContext?: UmbModalContext; + #modalManagerContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this.#modalContext = instance; + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this.#modalManagerContext = instance; }); } async execute() { - if (!this.#modalContext) throw new Error('Modal context is not available'); + if (!this.#modalManagerContext) throw new Error('Modal manager context is not available'); if (!this.repository) throw new Error('Repository is not available'); - const modalHandler = this.#modalContext?.open(UMB_DATA_TYPE_PICKER_MODAL); - const { selection } = await modalHandler.onSubmit(); + const modalContext = this.#modalManagerContext?.open(UMB_DATA_TYPE_PICKER_MODAL); + const { selection } = await modalContext.onSubmit(); await this.repository.copy(this.unique, selection[0]); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/create.action.ts index 64008eb5e7..730475c6b1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/create.action.ts @@ -2,25 +2,25 @@ import { UmbDataTypeRepository } from '../../repository/data-type.repository.js' import { UMB_DATA_TYPE_CREATE_OPTIONS_MODAL } from './modal/index.js'; import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; +import { UmbModalManagerContext, UMB_MODAL_MANAGER_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/modal'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; export class UmbCreateDataTypeEntityAction extends UmbEntityActionBase { - #modalContext?: UmbModalContext; + #modalManagerContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this.#modalContext = instance; + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this.#modalManagerContext = instance; }); } async execute() { - if (!this.#modalContext) throw new Error('Modal context is not available'); + if (!this.#modalManagerContext) throw new Error('Modal manager context is not available'); if (!this.repository) throw new Error('Repository is not available'); - this.#modalContext?.open(UMB_DATA_TYPE_CREATE_OPTIONS_MODAL, { + this.#modalManagerContext?.open(UMB_DATA_TYPE_CREATE_OPTIONS_MODAL, { parentKey: this.unique, }); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/modal/data-type-create-options-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/modal/data-type-create-options-modal.element.ts index 857fd0fe49..708eff59ac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/modal/data-type-create-options-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/create/modal/data-type-create-options-modal.element.ts @@ -1,28 +1,28 @@ import { DATA_TYPE_REPOSITORY_ALIAS } from '../../../repository/manifests.js'; import { UmbDataTypeCreateOptionsModalData } from './index.js'; -import { html , customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { + UmbModalManagerContext, UmbModalContext, - UmbModalHandler, UMB_FOLDER_MODAL, - UMB_MODAL_CONTEXT_TOKEN, + UMB_MODAL_MANAGER_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 { @property({ attribute: false }) - modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; @property({ type: Object }) data?: UmbDataTypeCreateOptionsModalData; - #modalContext?: UmbModalContext; + #modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this.#modalContext = instance; }); } @@ -32,16 +32,16 @@ export class UmbDataTypeCreateOptionsModalElement extends UmbLitElement { const folderModalHandler = this.#modalContext?.open(UMB_FOLDER_MODAL, { repositoryAlias: DATA_TYPE_REPOSITORY_ALIAS, }); - folderModalHandler?.onSubmit().then(() => this.modalHandler?.submit()); + folderModalHandler?.onSubmit().then(() => this.modalContext?.submit()); } // close the modal when navigating to data type #onNavigate() { - this.modalHandler?.submit(); + this.modalContext?.submit(); } #onCancel() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/move/move.action.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/move/move.action.ts index 30f6f4a5c1..c71fba2fbf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/move/move.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/entity-actions/move/move.action.ts @@ -1,27 +1,31 @@ import { UmbDataTypeRepository } from '../../repository/data-type.repository.js'; import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_DATA_TYPE_PICKER_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_DATA_TYPE_PICKER_MODAL, +} from '@umbraco-cms/backoffice/modal'; import { UmbContextConsumerController } from '@umbraco-cms/backoffice/context-api'; // TODO: investigate what we need to make a generic move action export class UmbMoveDataTypeEntityAction extends UmbEntityActionBase { - #modalContext?: UmbModalContext; + #modalManagerContext?: UmbModalManagerContext; constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) { super(host, repositoryAlias, unique); - new UmbContextConsumerController(this.host, UMB_MODAL_CONTEXT_TOKEN, (instance) => { - this.#modalContext = instance; + new UmbContextConsumerController(this.host, UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this.#modalManagerContext = instance; }); } async execute() { - if (!this.#modalContext) throw new Error('Modal context is not available'); + if (!this.#modalManagerContext) throw new Error('Modal manager context is not available'); if (!this.repository) throw new Error('Repository is not available'); - const modalHandler = this.#modalContext?.open(UMB_DATA_TYPE_PICKER_MODAL); - const { selection } = await modalHandler.onSubmit(); + const modalContext = this.#modalManagerContext?.open(UMB_DATA_TYPE_PICKER_MODAL); + const { selection } = await modalContext.onSubmit(); await this.repository.move(this.unique, selection[0]); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.ts new file mode 100644 index 0000000000..8b056368a7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.ts @@ -0,0 +1,190 @@ +import { UmbDataTypeRepository } from '../../repository/data-type.repository.js'; +import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit'; +import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; +import { + UmbModalContext, + UmbDataTypePickerFlowDataTypePickerModalData, + UmbDataTypePickerFlowDataTypePickerModalResult, +} from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { FolderTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +@customElement('umb-data-type-picker-flow-data-type-picker-modal') +export class UmbDataTypePickerFlowDataTypePickerModalElement extends UmbLitElement { + @property({ type: Object }) + data?: UmbDataTypePickerFlowDataTypePickerModalData; + + @state() + private _dataTypes?: Array; + + private _propertyEditorUiAlias!: string; + + connectedCallback(): void { + super.connectedCallback(); + + if (!this.data) return; + + this._propertyEditorUiAlias = this.data.propertyEditorUiAlias; + + this._observeDataTypesOf(this._propertyEditorUiAlias); + } + + private async _observeDataTypesOf(propertyEditorUiAlias: string) { + if (!this.data) return; + + const dataTypeRepository = new UmbDataTypeRepository(this); + + // TODO: This is a hack to get the data types of a property editor ui alias. + // TODO: Make sure filtering works data-type that does not have a property editor ui, but should be using the default property editor UI for those. + // TODO: make an end-point just retrieving the data types using a given property editor ui alias. + const { data } = await dataTypeRepository.requestRootTreeItems(); + + if (!data) return; + + await Promise.all( + data.items.map((item) => { + if (item.id) { + return dataTypeRepository.requestById(item.id); + } + return Promise.resolve(); + }) + ); + + // TODO: Use the asObservable from above onces end-point has been made. + const source = await dataTypeRepository.byPropertyEditorUiAlias(propertyEditorUiAlias); + this.observe(source, (dataTypes) => { + this._dataTypes = dataTypes; + }); + } + + private _handleClick(dataType: FolderTreeItemResponseModel) { + if (dataType.id) { + this.modalContext?.submit({ dataTypeId: dataType.id }); + } + } + + private _handleCreate() { + this.modalContext?.submit({ createNewWithPropertyEditorUiAlias: this._propertyEditorUiAlias }); + } + + private _close() { + this.modalContext?.reject(); + } + + @property({ attribute: false }) + modalContext?: UmbModalContext< + UmbDataTypePickerFlowDataTypePickerModalData, + UmbDataTypePickerFlowDataTypePickerModalResult + >; + + render() { + return html` + + ${this._renderDataTypes()} ${this._renderCreate()} +
+ +
+
+ `; + } + + private _renderDataTypes() { + return html`
    + ${this._dataTypes + ? repeat( + this._dataTypes, + (dataType) => dataType.id, + (dataType) => + dataType.id + ? html`
  • + +
  • ` + : '' + ) + : ''} +
`; + } + private _renderCreate() { + return html`
  • + +
  • `; + } + + static styles = [ + UUITextStyles, + css` + #filter { + width: 100%; + margin-bottom: var(--uui-size-space-4); + } + + #filter-icon { + padding-left: var(--uui-size-space-2); + } + + #item-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); + margin: 0; + padding: 0; + grid-gap: var(--uui-size-space-4); + } + + #item-grid .item { + display: flex; + align-items: flex-start; + justify-content: center; + list-style: none; + height: 100%; + border: 1px solid transparent; + border-radius: var(--uui-border-radius); + } + + #item-grid .item:hover { + background: var(--uui-color-surface-emphasis); + color: var(--uui-color-interactive-emphasis); + cursor: pointer; + } + + #item-grid .item[selected] button { + background: var(--uui-color-selected); + color: var(--uui-color-selected-contrast); + } + + #item-grid .item button { + background: none; + border: none; + cursor: pointer; + padding: var(--uui-size-space-3); + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + font-size: 0.8rem; + height: 100%; + width: 100%; + color: var(--uui-color-interactive); + border-radius: var(--uui-border-radius); + } + + #item-grid .item .icon { + font-size: 2em; + margin-bottom: var(--uui-size-space-2); + } + `, + ]; +} + +export default UmbDataTypePickerFlowDataTypePickerModalElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-data-type-picker-flow-data-type-picker-modal': UmbDataTypePickerFlowDataTypePickerModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts index 31936de95b..921973d43d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-modal.element.ts @@ -4,9 +4,13 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { groupBy } from '@umbraco-cms/backoffice/external/lodash'; import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { - UmbPropertyEditorUIPickerModalData, - UmbPropertyEditorUIPickerModalResult, - UmbModalHandler, + UMB_DATA_TYPE_PICKER_FLOW_DATA_TYPE_PICKER_MODAL, + UMB_WORKSPACE_MODAL, + UmbDataTypePickerFlowModalData, + UmbDataTypePickerFlowModalResult, + UmbModalContext, + UmbModalRouteBuilder, + UmbModalRouteRegistrationController, } from '@umbraco-cms/backoffice/modal'; import { ManifestPropertyEditorUi, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -18,18 +22,18 @@ interface GroupedItems { @customElement('umb-data-type-picker-flow-modal') export class UmbDataTypePickerFlowModalElement extends UmbLitElement { @property({ attribute: false }) - modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; @property({ type: Object }) - public get data(): UmbPropertyEditorUIPickerModalData | undefined { + public get data(): UmbDataTypePickerFlowModalData | undefined { return this._data; } - public set data(value: UmbPropertyEditorUIPickerModalData | undefined) { + public set data(value: UmbDataTypePickerFlowModalData | undefined) { this._data = value; this._selection = this.data?.selection ?? []; this._submitLabel = this.data?.submitLabel ?? this._submitLabel; } - private _data?: UmbPropertyEditorUIPickerModalData | undefined; + private _data?: UmbDataTypePickerFlowModalData | undefined; @state() private _groupedDataTypes?: GroupedItems; @@ -43,18 +47,59 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement { @state() private _submitLabel = 'Select'; + @state() + private _dataTypePickerModalRouteBuilder?: UmbModalRouteBuilder; + + private _createDataTypeModal: UmbModalRouteRegistrationController; + #repository; #dataTypes: Array = []; #propertyEditorUIs: Array = []; #currentFilterQuery = ''; + //UMB_DATA_TYPE_PICKER_FLOW_UI_PICKER_MODAL; + constructor() { super(); this.#repository = new UmbDataTypeRepository(this); + new UmbModalRouteRegistrationController(this, UMB_DATA_TYPE_PICKER_FLOW_DATA_TYPE_PICKER_MODAL) + .addAdditionalPath(':uiAlias') + .onSetup((routingInfo) => { + return { + propertyEditorUiAlias: routingInfo.uiAlias, + }; + }) + .onSubmit((submitData) => { + if (submitData.dataTypeId) { + this._select(submitData.dataTypeId); + } else if (submitData.createNewWithPropertyEditorUiAlias) { + this._createDataType(submitData.createNewWithPropertyEditorUiAlias); + } + }) + .observeRouteBuilder((routeBuilder) => { + this._dataTypePickerModalRouteBuilder = routeBuilder; + this.requestUpdate('_dataTypePickerModalRouteBuilder'); + }); + + this._createDataTypeModal = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(':uiAlias') + .onSetup((params) => { + return { entityType: 'data-type', preset: { propertyEditorUiAlias: params.uiAlias } }; + }) + .onSubmit((submitData) => { + console.log('submitData', submitData); + }); + this.#init(); } + private _createDataType(propertyEditorUiAlias: string) { + // TODO: Could be nice with a more pretty way to prepend to the URL: + // Open create modal: + this._createDataTypeModal.open({ uiAlias: propertyEditorUiAlias }, 'create/null'); + } + async #init() { // TODO: Get ALL items, or traverse the structure aka. multiple recursive calls. this.observe( @@ -72,10 +117,6 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement { }); } - private _handleUIClick(propertyEditorUi: ManifestPropertyEditorUi) { - alert('To BE DONE.'); - } - private _handleDataTypeClick(dataType: EntityTreeItemResponseModel) { if (dataType.id) { this._select(dataType.id); @@ -116,11 +157,11 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement { } private _close() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } private _submit() { - this.modalHandler?.submit({ selection: this._selection }); + this.modalContext?.submit({ selection: this._selection }); } render() { @@ -191,16 +232,20 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement { private _renderGroupUIs(uis: Array) { return html`
      - ${repeat( - uis, - (propertyEditorUI) => propertyEditorUI.alias, - (propertyEditorUI) => html`
    • - -
    • ` - )} + ${this._dataTypePickerModalRouteBuilder + ? repeat( + uis, + (propertyEditorUI) => propertyEditorUI.alias, + (propertyEditorUI) => html`
    • + + + ${propertyEditorUI.meta.label || propertyEditorUI.name} + +
    • ` + ) + : ''}
    `; } @@ -240,21 +285,8 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement { cursor: pointer; } - #item-grid .item[selected] button { - background: var(--uui-color-selected); - color: var(--uui-color-selected-contrast); - } - - #item-grid .item button { - background: none; - border: none; - cursor: pointer; + #item-grid .item uui-button { padding: var(--uui-size-space-3); - display: flex; - align-items: center; - flex-direction: column; - justify-content: center; - font-size: 0.8rem; height: 100%; width: 100%; color: var(--uui-color-interactive); diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-modal.stories.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-modal.stories.ts deleted file mode 100644 index 8e8e70e5c6..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/data-type-picker-flow/data-type-picker-flow-modal.stories.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Meta, Story } from '@storybook/web-components'; -import type { UmbDataTypePickerFlowModalElement } from './data-type-picker-flow-modal.element.js'; -import { html } from '@umbraco-cms/backoffice/external/lit'; -import type { UmbPropertyEditorUIPickerModalData } from '@umbraco-cms/backoffice/modal'; - -import './data-type-picker-flow-modal.element.js'; -import '../../../../core/components/body-layout/body-layout.element.js'; - -export default { - title: 'API/Modals/Layouts/Data Type Picker Flow', - component: 'umb-data-type-picker-flow-modal', - id: 'umb-data-type-picker-flow-modal', -} as Meta; - -const data: UmbPropertyEditorUIPickerModalData = { selection: [] }; - -export const Overview: Story = () => html` - -`; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/manifests.ts index f1fb7f9987..7abab6de4a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/manifests.ts @@ -3,7 +3,7 @@ import type { ManifestModal } from '@umbraco-cms/backoffice/extension-registry'; const modals: Array = [ { type: 'modal', - alias: 'Umb.Modal.PropertyEditorUIPicker', + alias: 'Umb.Modal.PropertyEditorUiPicker', name: 'Property Editor UI Picker Modal', loader: () => import('./property-editor-ui-picker/property-editor-ui-picker-modal.element.js'), }, @@ -13,6 +13,12 @@ const modals: Array = [ name: 'Data Type Picker Flow Modal', loader: () => import('./data-type-picker-flow/data-type-picker-flow-modal.element.js'), }, + { + type: 'modal', + alias: 'Umb.Modal.DataTypePickerFlowDataTypePicker', + name: 'Data Type Picker Flow UI Picker Modal', + loader: () => import('./data-type-picker-flow/data-type-picker-flow-data-type-picker-modal.element.js'), + }, ]; export const manifests = [...modals]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts index 29f67cf412..16c4dff594 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/modals/property-editor-ui-picker/property-editor-ui-picker-modal.element.ts @@ -5,7 +5,7 @@ import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { UmbPropertyEditorUIPickerModalData, UmbPropertyEditorUIPickerModalResult, - UmbModalHandler, + UmbModalContext, } from '@umbraco-cms/backoffice/modal'; import { ManifestPropertyEditorUi, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -30,6 +30,9 @@ export class UmbPropertyEditorUIPickerModalElement extends UmbLitElement { @state() private _submitLabel = 'Select'; + @property({ attribute: false }) + modalContext?: UmbModalContext; + connectedCallback(): void { super.connectedCallback(); @@ -72,14 +75,11 @@ export class UmbPropertyEditorUIPickerModalElement extends UmbLitElement { } private _close() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } - @property({ attribute: false }) - modalHandler?: UmbModalHandler; - private _submit() { - this.modalHandler?.submit({ selection: this._selection }); + this.modalContext?.submit({ selection: this._selection }); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.repository.ts index aa5d7b81fe..959ba64508 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.repository.ts @@ -71,6 +71,7 @@ export class UmbDataTypeRepository this.#moveSource = new UmbDataTypeMoveServerDataSource(this.#host); this.#copySource = new UmbDataTypeCopyServerDataSource(this.#host); + // TODO: Make a method that takes the controllers and returns a promise, just to simplify this: this.#init = Promise.all([ new UmbContextConsumerController(this.#host, UMB_DATA_TYPE_STORE_CONTEXT_TOKEN, (instance) => { this.#detailStore = instance; @@ -187,6 +188,12 @@ export class UmbDataTypeRepository return this.#detailStore!.byId(id); } + async byPropertyEditorUiAlias(propertyEditorUiAlias: string) { + if (!propertyEditorUiAlias) throw new Error('propertyEditorUiAlias is missing'); + await this.#init; + return this.#detailStore!.withPropertyEditorUiAlias(propertyEditorUiAlias); + } + async create(dataType: CreateDataTypeRequestModel) { if (!dataType) throw new Error('Data Type is missing'); if (!dataType.id) throw new Error('Data Type id is missing'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.store.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.store.ts index 76e2c0e20c..fb7fb3249e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.store.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/repository/data-type.store.ts @@ -52,4 +52,11 @@ export class UmbDataTypeStore extends UmbStoreBase { remove(uniques: Array) { this._data.remove(uniques); } + + withPropertyEditorUiAlias(propertyEditorUiAlias: string) { + // TODO: Use a model for the data-type tree items: ^^Most likely it should be parsed to the UmbEntityTreeStore as a generic type. + return this._data.getObservablePart((items) => + items.filter((item) => (item as any).propertyEditorUiAlias === propertyEditorUiAlias) + ); + } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace-editor.element.ts index 0fdd38475d..f0a8179dd6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace-editor.element.ts @@ -23,10 +23,29 @@ export class UmbDataTypeWorkspaceEditorElement extends UmbLitElement { this.consumeContext(UMB_ENTITY_WORKSPACE_CONTEXT, (workspaceContext) => { this.#workspaceContext = workspaceContext as UmbDataTypeWorkspaceContext; + this.#observeIsNew(); this.#observeName(); }); } + // TODO: invent some general way for all workspaces, with a name?, to put focus on the name when new. + #observeIsNew() { + if (!this.#workspaceContext) return; + this.observe( + this.#workspaceContext.isNew, + (isNew) => { + if (isNew) { + // TODO: Make a general way to put focus on a input in a modal. (also make sure it only happens if its the top-most-modal.) + requestAnimationFrame(() => { + (this.shadowRoot!.querySelector('#nameInput') as HTMLElement).focus(); + }); + } + this.removeControllerByUnique('_observeIsNew'); + }, + '_observeIsNew' + ); + } + #observeName() { if (!this.#workspaceContext) return; this.observe(this.#workspaceContext.name, (dataTypeName) => { @@ -50,7 +69,7 @@ export class UmbDataTypeWorkspaceEditorElement extends UmbLitElement { render() { return html` - + `; } @@ -64,7 +83,7 @@ export class UmbDataTypeWorkspaceEditorElement extends UmbLitElement { height: 100%; } - #header { + #nameInput { /* TODO: can this be applied from layout slot CSS? */ margin: 0 var(--uui-size-layout-1); flex: 1 1 auto; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.context.ts index e56e1bc889..dc0e25b629 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.context.ts @@ -28,7 +28,10 @@ export class UmbDataTypeWorkspaceContext } async createScaffold(parentId: string | null) { - const { data } = await this.repository.createScaffold(parentId); + let { data } = await this.repository.createScaffold(parentId); + if (this.modalContext) { + data = { ...data, ...this.modalContext.data.preset }; + } this.setIsNew(true); // 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. @@ -80,8 +83,8 @@ export class UmbDataTypeWorkspaceContext } else { await this.repository.save(this.#data.value.id, this.#data.value); } - // If it went well, then its not new anymore?. - this.setIsNew(false); + + this.saveComplete(this.#data.value); } async delete(id: string) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.element.ts index 807a60aa58..2bda82db04 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/data-type-workspace.element.ts @@ -1,6 +1,6 @@ import { UmbDataTypeWorkspaceContext } from './data-type-workspace.context.js'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement } from '@umbraco-cms/backoffice/external/lit'; import type { UmbRoute } from '@umbraco-cms/backoffice/router'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -12,8 +12,7 @@ export class UmbDataTypeWorkspaceElement extends UmbLitElement { #element = document.createElement('umb-data-type-workspace-editor'); - @state() - _routes: UmbRoute[] = [ + private _routes: UmbRoute[] = [ { path: 'create/:parentId', component: () => this.#element, @@ -36,7 +35,7 @@ export class UmbDataTypeWorkspaceElement extends UmbLitElement { return html``; } - static styles = [UUITextStyles, css``]; + static styles = [UUITextStyles]; } export default UmbDataTypeWorkspaceElement; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/manifests.ts index 6732de2659..a1d3852160 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/manifests.ts @@ -1,5 +1,6 @@ import { UmbSaveWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; import type { + ManifestModal, ManifestWorkspace, ManifestWorkspaceAction, ManifestWorkspaceEditorView, diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/views/details/data-type-details-workspace-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/views/details/data-type-details-workspace-view.element.ts index e166ab65d6..8dfb150e23 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/views/details/data-type-details-workspace-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/data-types/workspace/views/details/data-type-details-workspace-view.element.ts @@ -3,8 +3,8 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UMB_ENTITY_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; import { - UmbModalContext, - UMB_MODAL_CONTEXT_TOKEN, + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_PROPERTY_EDITOR_UI_PICKER_MODAL, } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; @@ -38,12 +38,12 @@ export class UmbDataTypeDetailsWorkspaceViewEditElement private _data: Array = []; private _workspaceContext?: UmbDataTypeWorkspaceContext; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); @@ -128,11 +128,11 @@ export class UmbDataTypeDetailsWorkspaceViewEditElement private _openPropertyEditorUIPicker() { if (!this._dataType) return; - const modalHandler = this._modalContext?.open(UMB_PROPERTY_EDITOR_UI_PICKER_MODAL, { + const modalContext = this._modalContext?.open(UMB_PROPERTY_EDITOR_UI_PICKER_MODAL, { selection: this._propertyEditorUiAlias ? [this._propertyEditorUiAlias] : [], }); - modalHandler?.onSubmit().then(({ selection }) => { + modalContext?.onSubmit().then(({ selection }) => { this._selectPropertyEditorUI(selection[0]); }); } @@ -197,6 +197,11 @@ export class UmbDataTypeDetailsWorkspaceViewEditElement css` :host { display: block; + margin: var(--uui-size-layout-1); + padding-bottom: var(--uui-size-layout-1); + } + + uui-box { padding: var(--uui-size-layout-1); } `, diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/extensions/workspace/extension-root-workspace.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/extensions/workspace/extension-root-workspace.element.ts index e82d909b07..488f8e6788 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/extensions/workspace/extension-root-workspace.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/extensions/workspace/extension-root-workspace.element.ts @@ -1,22 +1,26 @@ -import { css, html , customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { map } from '@umbraco-cms/backoffice/external/rxjs'; import { isManifestElementNameType } from '@umbraco-cms/backoffice/extension-api'; import { ManifestTypes, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; -import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN, UMB_CONFIRM_MODAL } from '@umbraco-cms/backoffice/modal'; +import { + UmbModalManagerContext, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UMB_CONFIRM_MODAL, +} from '@umbraco-cms/backoffice/modal'; @customElement('umb-extension-root-workspace') export class UmbExtensionRootWorkspaceElement extends UmbLitElement { @state() private _extensions?: Array = undefined; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; connectedCallback(): void { super.connectedCallback(); this._observeExtensions(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -43,14 +47,14 @@ export class UmbExtensionRootWorkspaceElement extends UmbLitElement { } async #removeExtension(extension: ManifestTypes) { - const modalHandler = this._modalContext?.open(UMB_CONFIRM_MODAL, { + const modalContext = this._modalContext?.open(UMB_CONFIRM_MODAL, { headline: 'Unload extension', confirmLabel: 'Unload', content: html`

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

    `, color: 'danger', }); - await modalHandler?.onSubmit(); + await modalContext?.onSubmit(); umbExtensionsRegistry.unregister(extension.alias); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/index.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/index.ts deleted file mode 100644 index 027b561e24..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import './cultures/components/index.js'; -import './languages/components/index.js'; - -export * from './manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/languages/index.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/languages/index.ts index a990356c4d..2cc9965ab1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/languages/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/languages/index.ts @@ -2,3 +2,5 @@ import './components/index.js'; export const LANGUAGE_ROOT_ENTITY_TYPE = 'language-root'; export const LANGUAGE_ENTITY_TYPE = 'language'; + +export * from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts index bf848d06ad..5e22af8afa 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts @@ -1,6 +1,6 @@ import { UmbLanguageRepository } from '../../repository/language.repository.js'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { css, html , customElement, state , repeat } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; import { LanguageResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbSelectionManagerBase } from '@umbraco-cms/backoffice/utils'; @@ -37,11 +37,11 @@ export class UmbLanguagePickerModalElement extends UmbModalBaseElement< } #submit() { - this.modalHandler?.submit({ selection: this.#selectionManager.getSelection() }); + this.modalContext?.submit({ selection: this.#selectionManager.getSelection() }); } #close() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/languages/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/languages/repository/index.ts new file mode 100644 index 0000000000..ca367b38f3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/languages/repository/index.ts @@ -0,0 +1 @@ +export * from './language.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input-modal.element.ts index e19cf76c42..1970cd7b38 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input-modal.element.ts @@ -1,5 +1,5 @@ -import { html, css , customElement, query, state } from '@umbraco-cms/backoffice/external/lit'; -import { UUITextStyles , UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; +import { html, css, customElement, query, state } from '@umbraco-cms/backoffice/external/lit'; +import { UUITextStyles, UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; import { SavedLogSearchPresenationBaseModel } from '@umbraco-cms/backoffice/backend-api'; @@ -12,11 +12,11 @@ export default class UmbLogViewerSaveSearchModalElement extends UmbModalBaseElem private _input!: UUIInputElement; private _handleClose() { - this.modalHandler?.reject(); + this.modalContext?.reject(); } private _handleSubmit() { - this.modalHandler?.submit({ name: this._input.value as string, query: this.data?.query }); + this.modalContext?.submit({ name: this._input.value as string, query: this.data?.query }); } @state() diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts index c445fc2c65..f866e2b1fe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/logviewer/workspace/views/search/components/log-viewer-search-input.element.ts @@ -1,14 +1,20 @@ import { UmbLogViewerWorkspaceContext, UMB_APP_LOG_VIEWER_CONTEXT_TOKEN } from '../../../logviewer.context.js'; -import { UUIButtonElement, UUIInputElement, UUIPopoverElement, UUISymbolExpandElement , UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; -import { css, html , customElement, query, state } from '@umbraco-cms/backoffice/external/lit'; +import { + UUIButtonElement, + UUIInputElement, + UUIPopoverElement, + UUISymbolExpandElement, + UUITextStyles, +} from '@umbraco-cms/backoffice/external/uui'; +import { css, html, customElement, query, state } from '@umbraco-cms/backoffice/external/lit'; import { Subject, debounceTime, tap } from '@umbraco-cms/backoffice/external/rxjs'; import { SavedLogSearchResponseModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { query as getQuery, path, toQueryString } from '@umbraco-cms/backoffice/router'; import { - UMB_MODAL_CONTEXT_TOKEN, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UmbModalManagerContext, UmbModalContext, - UmbModalHandler, UmbModalToken, } from '@umbraco-cms/backoffice/modal'; @@ -49,7 +55,7 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { #logViewerContext?: UmbLogViewerWorkspaceContext; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; constructor() { super(); @@ -59,7 +65,7 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { this.#logViewerContext?.getSavedSearches(); }); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); @@ -128,7 +134,7 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { this.#logViewerContext?.setFilterExpression(''); } - #modalHandler?: UmbModalHandler; + modalContext?: UmbModalContext; #saveSearch(savedSearch: SavedLogSearchResponseModel) { this.#logViewerContext?.saveSearch(savedSearch); @@ -139,8 +145,8 @@ export class UmbLogViewerSearchInputElement extends UmbLitElement { } #openSaveSearchDialog() { - this.#modalHandler = this._modalContext?.open(UMB_LOG_VIEWER_SAVE_SEARCH_MODAL, { query: this._inputQuery }); - this.#modalHandler?.onSubmit().then((savedSearch) => { + this.modalContext = this._modalContext?.open(UMB_LOG_VIEWER_SAVE_SEARCH_MODAL, { query: this._inputQuery }); + this.modalContext?.onSubmit().then((savedSearch) => { if (savedSearch) { this.#saveSearch(savedSearch); this._isQuerySaved = true; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/relation-types/index.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/relation-types/index.ts new file mode 100644 index 0000000000..6dcbad91fa --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/relation-types/index.ts @@ -0,0 +1 @@ +export * from './repository'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/settings/relation-types/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/settings/relation-types/repository/index.ts new file mode 100644 index 0000000000..e32cef78db --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/settings/relation-types/repository/index.ts @@ -0,0 +1 @@ +export * from './relation-type.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tags/index.ts b/src/Umbraco.Web.UI.Client/src/packages/tags/index.ts index fa1b7ed38d..37dd11a7dd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tags/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tags/index.ts @@ -1,11 +1 @@ -import { manifests as repositoryManifests } from './repository/manifests.js'; -import { manifests as propertyEditorManifests } from './property-editors/manifests.js'; -import { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api'; - -import './components/index.js'; - -export const manifests = [...repositoryManifests, ...propertyEditorManifests]; - -export const onInit: UmbEntryPointOnInit = (host, extensionRegistry) => { - extensionRegistry.registerMany(manifests); -}; +export * from './repository/'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tags/package-entry-point.ts b/src/Umbraco.Web.UI.Client/src/packages/tags/package-entry-point.ts new file mode 100644 index 0000000000..fa1b7ed38d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/tags/package-entry-point.ts @@ -0,0 +1,11 @@ +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { manifests as propertyEditorManifests } from './property-editors/manifests.js'; +import { UmbEntryPointOnInit } from '@umbraco-cms/backoffice/extension-api'; + +import './components/index.js'; + +export const manifests = [...repositoryManifests, ...propertyEditorManifests]; + +export const onInit: UmbEntryPointOnInit = (host, extensionRegistry) => { + extensionRegistry.registerMany(manifests); +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tags/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/tags/repository/index.ts new file mode 100644 index 0000000000..4e001da49d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/tags/repository/index.ts @@ -0,0 +1 @@ +export * from './tag.repository.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tags/umbraco-package.ts b/src/Umbraco.Web.UI.Client/src/packages/tags/umbraco-package.ts index 13f9a1d86e..584495cc16 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tags/umbraco-package.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tags/umbraco-package.ts @@ -5,6 +5,6 @@ export const extensions = [ name: 'Tags Management Entry Point', alias: 'Umb.EntryPoint.TagsManagement', type: 'entryPoint', - loader: () => import('./index.js'), + loader: () => import('./package-entry-point.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.element.ts index 47f37c3de9..d74d7fa607 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/code-editor/code-editor.element.ts @@ -1,7 +1,7 @@ -import { UMB_THEME_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/themes'; import { UmbCodeEditorController } from './code-editor.controller.js'; import type { CodeEditorLanguage, CodeEditorSearchOptions, UmbCodeEditorHost } from './code-editor.model.js'; import { CodeEditorTheme } from './code-editor.model.js'; +import { UMB_THEME_CONTEXT_TOKEN } from '@umbraco-cms/backoffice/themes'; import { monacoEditorStyles, monacoJumpingCursorHack } from '@umbraco-cms/backoffice/external/monaco-editor'; import { css, diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/components/insert-menu/templating-insert-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/components/insert-menu/templating-insert-menu.element.ts index 87f5246c9b..74f96512fa 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/components/insert-menu/templating-insert-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/components/insert-menu/templating-insert-menu.element.ts @@ -6,15 +6,15 @@ import { CodeSnippetType, UMB_MODAL_TEMPLATING_INSERT_FIELD_SIDEBAR_MODAL, } from '../../modals/insert-choose-type-sidebar.element.js'; -import { customElement, property , css, html } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, property, css, html } from '@umbraco-cms/backoffice/external/lit'; import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { UMB_DICTIONARY_ITEM_PICKER_MODAL, - UMB_MODAL_CONTEXT_TOKEN, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, UMB_PARTIAL_VIEW_PICKER_MODAL, UmbDictionaryItemPickerModalResult, + UmbModalManagerContext, UmbModalContext, - UmbModalHandler, UmbModalToken, UmbPartialViewPickerModalResult, } from '@umbraco-cms/backoffice/modal'; @@ -33,15 +33,15 @@ export class UmbTemplatingInsertMenuElement extends UmbLitElement { @property() value = ''; - private _modalContext?: UmbModalContext; + private _modalContext?: UmbModalManagerContext; - #openModal?: UmbModalHandler; + #openModal?: UmbModalContext; #dictionaryRepository = new UmbDictionaryRepository(this); constructor() { super(); - this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { this._modalContext = instance; }); } @@ -143,8 +143,8 @@ export class UmbTemplatingInsertMenuElement extends UmbLitElement { id="insert-button" label="open insert menu">
      -