From ef668ad3f88b6a19b1bf3b136b43612f8169409c Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:14:55 +0200 Subject: [PATCH 001/170] feat: add bundling for the 'tiny-mce' package --- package-lock.json | 6 ++++++ package.json | 1 + src/packages/tiny-mce/package.json | 8 ++++++++ src/packages/tiny-mce/vite.config.ts | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 src/packages/tiny-mce/package.json create mode 100644 src/packages/tiny-mce/vite.config.ts diff --git a/package-lock.json b/package-lock.json index 5a1f3cde7f..7926cf8773 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "./src/packages/property-editors", "./src/packages/tags", "./src/packages/templating", + "./src/packages/tiny-mce", "./src/packages/umbraco-news", "./src/packages/user", "./src/packages/webhook" @@ -7407,6 +7408,10 @@ "resolved": "src/packages/templating", "link": true }, + "node_modules/@umbraco-backoffice/tiny-mce": { + "resolved": "src/packages/tiny-mce", + "link": true + }, "node_modules/@umbraco-backoffice/umbraco-news": { "resolved": "src/packages/umbraco-news", "link": true @@ -21733,6 +21738,7 @@ "src/packages/templating": { "name": "@umbraco-backoffice/templating" }, + "src/packages/tiny-mce": {}, "src/packages/umbraco-news": { "name": "@umbraco-backoffice/umbraco-news" }, diff --git a/package.json b/package.json index 1d62ade7fe..a2f9bb6075 100644 --- a/package.json +++ b/package.json @@ -142,6 +142,7 @@ "./src/packages/property-editors", "./src/packages/tags", "./src/packages/templating", + "./src/packages/tiny-mce", "./src/packages/umbraco-news", "./src/packages/user", "./src/packages/webhook" diff --git a/src/packages/tiny-mce/package.json b/src/packages/tiny-mce/package.json new file mode 100644 index 0000000000..6362dc5347 --- /dev/null +++ b/src/packages/tiny-mce/package.json @@ -0,0 +1,8 @@ +{ + "name": "@umbraco-backoffice/tiny-mce", + "private": true, + "type": "module", + "scripts": { + "build": "vite build" + } +} diff --git a/src/packages/tiny-mce/vite.config.ts b/src/packages/tiny-mce/vite.config.ts new file mode 100644 index 0000000000..72556d1777 --- /dev/null +++ b/src/packages/tiny-mce/vite.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'vite'; +import { rmSync } from 'fs'; +import { getDefaultConfig } from '../../vite-config-base'; + +const dist = '../../../dist-cms/packages/tiny-mce'; + +// delete the unbundled dist folder +rmSync(dist, { recursive: true, force: true }); + +export default defineConfig({ + ...getDefaultConfig({ + dist, + entry: { + index: 'index.ts', + 'umbraco-package': 'umbraco-package.ts', + manifests: 'manifests.ts', + }, + }), +}); From 1fd3b667171945def605e6bc9ba5a481079a893a Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:29:47 +0200 Subject: [PATCH 002/170] update lockfile --- package-lock.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 6fddbdbd5c..0c8211ee8a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21746,7 +21746,9 @@ "src/packages/templating": { "name": "@umbraco-backoffice/templating" }, - "src/packages/tiny-mce": {}, + "src/packages/tiny-mce": { + "name": "@umbraco-backoffice/tiny-mce" + }, "src/packages/umbraco-news": { "name": "@umbraco-backoffice/umbraco-news" }, From 1b35768e26029f62a9bccdc15dff33c58c3b417c Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:37:31 +0200 Subject: [PATCH 003/170] add fallback for tinymce --- .../core/localization/registry/localization.registry.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/packages/core/localization/registry/localization.registry.ts b/src/packages/core/localization/registry/localization.registry.ts index f2b5e98a4e..89174aecfd 100644 --- a/src/packages/core/localization/registry/localization.registry.ts +++ b/src/packages/core/localization/registry/localization.registry.ts @@ -1,8 +1,8 @@ -import type { +import { UmbLocalizationSetBase, UmbLocalizationDictionary, - UmbLocalizationFlatDictionary, -} from '@umbraco-cms/backoffice/localization-api'; + UmbLocalizationFlatDictionary, UMB_DEFAULT_LOCALIZATION_CULTURE +} from "@umbraco-cms/backoffice/localization-api"; import { umbLocalizationManager } from '@umbraco-cms/backoffice/localization-api'; import type { ManifestLocalization, UmbBackofficeExtensionRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; @@ -36,7 +36,7 @@ export class UmbLocalizationRegistry { constructor(extensionRegistry: UmbBackofficeExtensionRegistry) { combineLatest([this.currentLanguage, extensionRegistry.byType('localization')]).subscribe( async ([currentLanguage, extensions]) => { - const locale = new Intl.Locale(currentLanguage); + const locale = new Intl.Locale(!!currentLanguage ? currentLanguage : UMB_DEFAULT_LOCALIZATION_CULTURE); const filteredExt = extensions.filter( (ext) => ext.meta.culture.toLowerCase() === locale.baseName.toLowerCase() || From c11ac805e5d8c7fda7c3a32eac8ac22a52ed4b6d Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:44:47 +0200 Subject: [PATCH 004/170] chore: linting --- .../core/localization/registry/localization.registry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/localization/registry/localization.registry.ts b/src/packages/core/localization/registry/localization.registry.ts index 89174aecfd..d63cdce44b 100644 --- a/src/packages/core/localization/registry/localization.registry.ts +++ b/src/packages/core/localization/registry/localization.registry.ts @@ -36,7 +36,7 @@ export class UmbLocalizationRegistry { constructor(extensionRegistry: UmbBackofficeExtensionRegistry) { combineLatest([this.currentLanguage, extensionRegistry.byType('localization')]).subscribe( async ([currentLanguage, extensions]) => { - const locale = new Intl.Locale(!!currentLanguage ? currentLanguage : UMB_DEFAULT_LOCALIZATION_CULTURE); + const locale = new Intl.Locale(currentLanguage ? currentLanguage : UMB_DEFAULT_LOCALIZATION_CULTURE); const filteredExt = extensions.filter( (ext) => ext.meta.culture.toLowerCase() === locale.baseName.toLowerCase() || From d90c891a8d948eb958cc954c93bce9e3613df40d Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:45:22 +0200 Subject: [PATCH 005/170] chore: linting --- .../core/localization/registry/localization.registry.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/packages/core/localization/registry/localization.registry.ts b/src/packages/core/localization/registry/localization.registry.ts index d63cdce44b..60ac072049 100644 --- a/src/packages/core/localization/registry/localization.registry.ts +++ b/src/packages/core/localization/registry/localization.registry.ts @@ -1,7 +1,8 @@ import { - UmbLocalizationSetBase, - UmbLocalizationDictionary, - UmbLocalizationFlatDictionary, UMB_DEFAULT_LOCALIZATION_CULTURE + type UmbLocalizationSetBase, + type UmbLocalizationDictionary, + type UmbLocalizationFlatDictionary, + UMB_DEFAULT_LOCALIZATION_CULTURE } from "@umbraco-cms/backoffice/localization-api"; import { umbLocalizationManager } from '@umbraco-cms/backoffice/localization-api'; import type { ManifestLocalization, UmbBackofficeExtensionRegistry } from '@umbraco-cms/backoffice/extension-registry'; From 1148f85ff63dd65be1c0b6a3586faf2098abeceb Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:50:11 +0200 Subject: [PATCH 006/170] fix: move assignment to state --- .../core/localization/registry/localization.registry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/core/localization/registry/localization.registry.ts b/src/packages/core/localization/registry/localization.registry.ts index 60ac072049..cc755ebd24 100644 --- a/src/packages/core/localization/registry/localization.registry.ts +++ b/src/packages/core/localization/registry/localization.registry.ts @@ -22,7 +22,7 @@ function addOrUpdateDictionary( } export class UmbLocalizationRegistry { - #currentLanguage = new UmbStringState(document.documentElement.lang ?? 'en-us'); + #currentLanguage = new UmbStringState(document.documentElement.lang !== '' ? document.documentElement.lang : UMB_DEFAULT_LOCALIZATION_CULTURE); readonly currentLanguage = this.#currentLanguage.asObservable(); #loadedExtAliases: Array = []; @@ -37,7 +37,7 @@ export class UmbLocalizationRegistry { constructor(extensionRegistry: UmbBackofficeExtensionRegistry) { combineLatest([this.currentLanguage, extensionRegistry.byType('localization')]).subscribe( async ([currentLanguage, extensions]) => { - const locale = new Intl.Locale(currentLanguage ? currentLanguage : UMB_DEFAULT_LOCALIZATION_CULTURE); + const locale = new Intl.Locale(currentLanguage); const filteredExt = extensions.filter( (ext) => ext.meta.culture.toLowerCase() === locale.baseName.toLowerCase() || From 9bb31d7feba231ef6beacd86fedebf8f5f71e93c Mon Sep 17 00:00:00 2001 From: Markus Johansson Date: Sat, 27 Jul 2024 15:55:00 +0200 Subject: [PATCH 007/170] Added example of modal route with issue --- examples/modal-routed/dashboard.element.ts | 72 +++++++++++++++++++ examples/modal-routed/dashboard2.element.ts | 36 ++++++++++ examples/modal-routed/index.ts | 48 +++++++++++++ .../modal-routed/modal/example-modal-token.ts | 15 ++++ .../modal/example-modal.element.ts | 66 +++++++++++++++++ .../steps/example-modal-step1.element.ts | 31 ++++++++ .../steps/example-modal-step2.element.ts | 31 ++++++++ examples/modal-routed/tabs/tab1.element.ts | 41 +++++++++++ examples/modal-routed/tabs/tab2.element.ts | 59 +++++++++++++++ 9 files changed, 399 insertions(+) create mode 100644 examples/modal-routed/dashboard.element.ts create mode 100644 examples/modal-routed/dashboard2.element.ts create mode 100644 examples/modal-routed/index.ts create mode 100644 examples/modal-routed/modal/example-modal-token.ts create mode 100644 examples/modal-routed/modal/example-modal.element.ts create mode 100644 examples/modal-routed/modal/steps/example-modal-step1.element.ts create mode 100644 examples/modal-routed/modal/steps/example-modal-step2.element.ts create mode 100644 examples/modal-routed/tabs/tab1.element.ts create mode 100644 examples/modal-routed/tabs/tab2.element.ts diff --git a/examples/modal-routed/dashboard.element.ts b/examples/modal-routed/dashboard.element.ts new file mode 100644 index 0000000000..b7d8714b7d --- /dev/null +++ b/examples/modal-routed/dashboard.element.ts @@ -0,0 +1,72 @@ +import { css, html, LitElement } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UmbModalRouteRegistrationController, UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; +import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token'; + +@customElement('umb-dashboard') +export class UmbDashboardElement extends UmbElementMixin(LitElement) { + + #workspaceModal?: UmbModalRouteRegistrationController; + + @state() + private _routes: UmbRoute[] = [ + { + path: `/tab1`, + component: () => import('./tabs/tab1.element.js'), + setup: (component, info) => { + }, + }, + { + path: `/tab2`, + component: () => import('./tabs/tab2.element.js'), + setup: (component, info) => { + }, + }, + { + path: '', + redirectTo: 'tab1', + }, + ]; + + /** + * + */ + constructor() { + super(); + console.log('modal element loaded'); + } + + override render() { + return html` +
+ umb-example modal + +
+ { + console.log('modal routes init'); + }} + @change=${(event: UmbRouterSlotChangeEvent) => { + console.log('modal routes change'); + }}> +
+ `; + } + + static override styles = [UmbTextStyles, css``]; +} + +export default UmbDashboardElement + +declare global { + interface HTMLElementTagNameMap { + 'umb-dashboard': UmbDashboardElement; + } +} diff --git a/examples/modal-routed/dashboard2.element.ts b/examples/modal-routed/dashboard2.element.ts new file mode 100644 index 0000000000..cd08bae781 --- /dev/null +++ b/examples/modal-routed/dashboard2.element.ts @@ -0,0 +1,36 @@ +import { css, html, LitElement } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token'; + +@customElement('umb-dashboard2') +export class UmbDashboard2Element extends UmbElementMixin(LitElement) { + + constructor() { + super(); + } + + override render() { + return html` +
+

Link to modal route

+

This page only shows how to link to the routed modal that is placed on a tab on the "Modal Dashboard". Clicking this link will not load the slots inside the modal, however, going to the "Modal Dashboard", clicking on tab 2 and opening the modal from there will work.

+ Open Modal Route +
+ ` + + } + + static override styles = [UmbTextStyles, css``]; +} + +export default UmbDashboard2Element + +declare global { + interface HTMLElementTagNameMap { + 'umb-dashboard2': UmbDashboard2Element; + } +} diff --git a/examples/modal-routed/index.ts b/examples/modal-routed/index.ts new file mode 100644 index 0000000000..21a3f2085e --- /dev/null +++ b/examples/modal-routed/index.ts @@ -0,0 +1,48 @@ +import { ManifestDashboard, ManifestModal, ManifestSection } from '@umbraco-cms/backoffice/extension-registry'; + +// const section : ManifestSection = { +// type: "section", +// alias: 'demo.section', +// name: "Demo Section", +// meta: { +// label: "Demo", +// pathname: "demo" +// } +// } + +let dashboard : ManifestDashboard = { + type: 'dashboard', + name: 'Example Modal Dashboard', + alias: 'example.dashboard.dataset', + element: () => import('./dashboard.element.js'), + weight: 15000, + meta: { + label: 'Modal Dashboard', + pathname: 'example', + }, +}; + +let dashboard2 : ManifestDashboard = { + type: 'dashboard', + name: 'Example Modal Dashboard2', + alias: 'example.dashboard.dataset2', + element: () => import('./dashboard2.element.js'), + weight: 15001, + meta: { + label: 'Link Dashboard', + pathname: 'example-2', + }, +}; + +const modal : ManifestModal = { + type: 'modal', + name: 'Example Modal', + alias: 'example.routed.modal', + element : () => import('./modal/example-modal.element.js'), +}; + +export const manifests = [ + dashboard, + dashboard2, + modal +]; diff --git a/examples/modal-routed/modal/example-modal-token.ts b/examples/modal-routed/modal/example-modal-token.ts new file mode 100644 index 0000000000..0668cd9993 --- /dev/null +++ b/examples/modal-routed/modal/example-modal-token.ts @@ -0,0 +1,15 @@ +import { UmbModalToken } from "@umbraco-cms/backoffice/modal"; + +export type Data = {} +export type RetData = {} + +export const EXAMPLE_ROUTED_MODAL = new UmbModalToken< +Data, +RetData +>('example.routed.modal', // this needs to match the alias of the modal registered in manifest.ts +{ + modal : { + type : 'dialog', + size : 'full' + } +}); diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts new file mode 100644 index 0000000000..25992faf05 --- /dev/null +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -0,0 +1,66 @@ +import { css, html, LitElement } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; + +@customElement('umb-example-modal') +export class UmbExampleModal extends UmbModalBaseElement { + + @state() + private _routes: UmbRoute[] = [ + { + path: `/overview`, + component: () => import('./steps/example-modal-step1.element.js'), + setup: (component, info) => { + }, + }, + { + path: `/details`, + component: () => import('./steps/example-modal-step2.element.js'), + setup: (component, info) => { + }, + }, + { + path: '', + redirectTo: 'overview', + }, + ]; + + /** + * + */ + constructor() { + super(); + console.log('modal element loaded'); + } + + override render() { + return html` +
+ umb-example modal +
+ { + console.log('modal routes init'); + }} + @change=${(event: UmbRouterSlotChangeEvent) => { + console.log('modal routes change'); + }}> +
+ `; + } + + static override styles = [UmbTextStyles, css``]; +} + +export default UmbExampleModal; + +declare global { + interface HTMLElementTagNameMap { + 'umb-example-modal': UmbExampleModal; + } +} diff --git a/examples/modal-routed/modal/steps/example-modal-step1.element.ts b/examples/modal-routed/modal/steps/example-modal-step1.element.ts new file mode 100644 index 0000000000..35f39147fd --- /dev/null +++ b/examples/modal-routed/modal/steps/example-modal-step1.element.ts @@ -0,0 +1,31 @@ +import { css, html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; + +@customElement('umb-example-modal-step1') +export class UmbExampleModalStep1 extends UmbModalBaseElement { + + override render() { + return html` +
+ example modal step1 + + +
+ `; + } + + static override styles = [UmbTextStyles, css``]; +} + +export default UmbExampleModalStep1; + +declare global { + interface HTMLElementTagNameMap { + 'umb-example-modal-step1': UmbExampleModalStep1; + } +} diff --git a/examples/modal-routed/modal/steps/example-modal-step2.element.ts b/examples/modal-routed/modal/steps/example-modal-step2.element.ts new file mode 100644 index 0000000000..32dadca5b8 --- /dev/null +++ b/examples/modal-routed/modal/steps/example-modal-step2.element.ts @@ -0,0 +1,31 @@ +import { css, html, LitElement } from 'lit'; +import { customElement } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; + +@customElement('umb-example-modal-step2') +export class UmbExampleModalStep2 extends UmbModalBaseElement { + + override render() { + return html` +
+ example modal step1 + + +
+ `; + } + + static override styles = [UmbTextStyles, css``]; +} + +export default UmbExampleModalStep2; + +declare global { + interface HTMLElementTagNameMap { + 'umb-example-modal-step2': UmbExampleModalStep2; + } +} diff --git a/examples/modal-routed/tabs/tab1.element.ts b/examples/modal-routed/tabs/tab1.element.ts new file mode 100644 index 0000000000..1c361976a0 --- /dev/null +++ b/examples/modal-routed/tabs/tab1.element.ts @@ -0,0 +1,41 @@ +import { css, html, LitElement } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token'; + +@customElement('umb-dashboard-tab1') +export class UmbDashboardTab1Element extends UmbElementMixin(LitElement) { + + #workspaceModal?: UmbModalRouteRegistrationController; + + @state() + _editLinkPath?: string; + + constructor() { + super(); + + } + + override render() { + return html` +
+

tab 1

+ +
+ ` + + } + + static override styles = [UmbTextStyles, css``]; +} + +export default UmbDashboardTab1Element + +declare global { + interface UmbDashboardTab1Element { + 'umb-dashboard-tab1': UmbDashboardTab1Element; + } +} diff --git a/examples/modal-routed/tabs/tab2.element.ts b/examples/modal-routed/tabs/tab2.element.ts new file mode 100644 index 0000000000..85c761a461 --- /dev/null +++ b/examples/modal-routed/tabs/tab2.element.ts @@ -0,0 +1,59 @@ +import { css, html, LitElement } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { EXAMPLE_ROUTED_MODAL } from './../modal/example-modal-token'; + +@customElement('umb-dashboard-tab2') +export class UmbDashboardTab2Element extends UmbElementMixin(LitElement) { + + #workspaceModal?: UmbModalRouteRegistrationController; + + @state() + _editLinkPath?: string; + + constructor() { + super(); + + // Using workspace modal context + this.#workspaceModal?.destroy(); + this.#workspaceModal = new UmbModalRouteRegistrationController(this, EXAMPLE_ROUTED_MODAL) + .addAdditionalPath('view/:entityKey') + .onSetup(() => { + return { + data: {}, + value: {} + }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editLinkPath = routeBuilder({entityKey : 'abc123'}); + }); + } + + override render() { + return html` +
+

tab 2

+

This element hosts the UmbModalRouteRegistrationController

+ + Open modal +
+ + Path: ${this._editLinkPath} +
+ ` + + } + + static override styles = [UmbTextStyles, css``]; +} + +export default UmbDashboardTab2Element + +declare global { + interface UmbDashboardTab2Element { + 'umb-dashboard-tab2': UmbDashboardTab2Element; + } +} From e474e72c611f58d2f791a346dc8844a324f2c60f Mon Sep 17 00:00:00 2001 From: Markus Johansson Date: Sat, 27 Jul 2024 16:43:43 +0200 Subject: [PATCH 008/170] #16834 potential fix for um-router-slot --- examples/modal-routed/dashboard.element.ts | 2 +- .../modal/example-modal.element.ts | 49 ++++++++++++------- .../core/router/router-slot.element.ts | 4 ++ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/examples/modal-routed/dashboard.element.ts b/examples/modal-routed/dashboard.element.ts index b7d8714b7d..add1ec69de 100644 --- a/examples/modal-routed/dashboard.element.ts +++ b/examples/modal-routed/dashboard.element.ts @@ -51,7 +51,7 @@ export class UmbDashboardElement extends UmbElementMixin(LitElement) { { - console.log('modal routes init'); + console.log('tab routes init'); }} @change=${(event: UmbRouterSlotChangeEvent) => { console.log('modal routes change'); diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index 25992faf05..a36ba43bc5 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -11,22 +11,7 @@ export class UmbExampleModal extends UmbModalBaseElement { @state() private _routes: UmbRoute[] = [ - { - path: `/overview`, - component: () => import('./steps/example-modal-step1.element.js'), - setup: (component, info) => { - }, - }, - { - path: `/details`, - component: () => import('./steps/example-modal-step2.element.js'), - setup: (component, info) => { - }, - }, - { - path: '', - redirectTo: 'overview', - }, + ]; /** @@ -37,6 +22,36 @@ export class UmbExampleModal extends UmbModalBaseElement { console.log('modal element loaded'); } + override connectedCallback(): void { + super.connectedCallback(); + this._routes = [{ + path: `/overview`, + component: () => import('./steps/example-modal-step1.element.js'), + setup: (component, info) => { + }, + }, + { + path: `/details`, + component: () => import('./steps/example-modal-step2.element.js'), + setup: (component, info) => { + }, + }, + { + path: '', + redirectTo: 'overview', + }, + { + path: '', + redirectTo: 'test', + } +]; + + setTimeout(()=>{ + //this._routes = [this._routes[0],this._routes[1],this._routes[2]] + },20); + + } + override render() { return html`
@@ -45,7 +60,7 @@ export class UmbExampleModal extends UmbModalBaseElement { { - console.log('modal routes init'); + console.log('modal route init fired'); }} @change=${(event: UmbRouterSlotChangeEvent) => { console.log('modal routes change'); diff --git a/src/packages/core/router/router-slot.element.ts b/src/packages/core/router/router-slot.element.ts index ae9f336236..2ca1edb543 100644 --- a/src/packages/core/router/router-slot.element.ts +++ b/src/packages/core/router/router-slot.element.ts @@ -97,6 +97,10 @@ export class UmbRouterSlotElement extends UmbLitElement { this._routerPath = this._constructAbsoluteRouterPath(); this.#routeContext._internal_routerGotBasePath(this._routerPath); this.dispatchEvent(new UmbRouterSlotInitEvent()); + const newActiveLocalPath = this._constructLocalRouterPath(); + if (this._activeLocalPath !== newActiveLocalPath) { + this.#router.routes = [...this.#router.routes]; + } } protected _updateRouterPath() { From e8a65c8f0cb4f4cbc754e378d816bb19e7932a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Aug 2024 10:19:24 +0200 Subject: [PATCH 009/170] clean up --- examples/modal-routed/dashboard.element.ts | 67 ++++++++---------- examples/modal-routed/dashboard2.element.ts | 38 +++++----- .../modal/example-modal.element.ts | 70 ++++++++----------- .../steps/example-modal-step1.element.ts | 15 +--- .../steps/example-modal-step2.element.ts | 17 +---- 5 files changed, 85 insertions(+), 122 deletions(-) diff --git a/examples/modal-routed/dashboard.element.ts b/examples/modal-routed/dashboard.element.ts index add1ec69de..a4b1cd73d1 100644 --- a/examples/modal-routed/dashboard.element.ts +++ b/examples/modal-routed/dashboard.element.ts @@ -1,35 +1,30 @@ -import { css, html, LitElement } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { css, html, LitElement, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; -import { UmbModalRouteRegistrationController, UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; -import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token'; +import type { + UmbModalRouteRegistrationController, + UmbRoute, + UmbRouterSlotChangeEvent, + UmbRouterSlotInitEvent, +} from '@umbraco-cms/backoffice/router'; @customElement('umb-dashboard') export class UmbDashboardElement extends UmbElementMixin(LitElement) { - - #workspaceModal?: UmbModalRouteRegistrationController; - - @state() - private _routes: UmbRoute[] = [ - { - path: `/tab1`, - component: () => import('./tabs/tab1.element.js'), - setup: (component, info) => { - }, - }, - { - path: `/tab2`, - component: () => import('./tabs/tab2.element.js'), - setup: (component, info) => { - }, - }, - { - path: '', - redirectTo: 'tab1', - }, - ]; + @state() + private _routes: UmbRoute[] = [ + { + path: `/tab1`, + component: () => import('./tabs/tab1.element.js'), + }, + { + path: `/tab2`, + component: () => import('./tabs/tab2.element.js'), + }, + { + path: '', + redirectTo: 'tab1', + }, + ]; /** * @@ -47,15 +42,15 @@ export class UmbDashboardElement extends UmbElementMixin(LitElement) {
  • Tab 1
  • Tab 2 (with modal)
  • -
    +
    { - console.log('tab routes init'); - }} - @change=${(event: UmbRouterSlotChangeEvent) => { - console.log('modal routes change'); - }}> + .routes=${this._routes} + @init=${(event: UmbRouterSlotInitEvent) => { + console.log('tab routes init', event); + }} + @change=${(event: UmbRouterSlotChangeEvent) => { + console.log('modal routes change', event); + }}>
    `; } @@ -63,7 +58,7 @@ export class UmbDashboardElement extends UmbElementMixin(LitElement) { static override styles = [UmbTextStyles, css``]; } -export default UmbDashboardElement +export default UmbDashboardElement; declare global { interface HTMLElementTagNameMap { diff --git a/examples/modal-routed/dashboard2.element.ts b/examples/modal-routed/dashboard2.element.ts index cd08bae781..aedf64759c 100644 --- a/examples/modal-routed/dashboard2.element.ts +++ b/examples/modal-routed/dashboard2.element.ts @@ -1,33 +1,33 @@ -import { css, html, LitElement } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { css, html, LitElement, customElement } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; -import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; -import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token'; @customElement('umb-dashboard2') export class UmbDashboard2Element extends UmbElementMixin(LitElement) { - - constructor() { - super(); + constructor() { + super(); } - override render() { - return html` -
    -

    Link to modal route

    -

    This page only shows how to link to the routed modal that is placed on a tab on the "Modal Dashboard". Clicking this link will not load the slots inside the modal, however, going to the "Modal Dashboard", clicking on tab 2 and opening the modal from there will work.

    - Open Modal Route -
    - ` - - } + override render() { + return html` +
    +

    Link to modal route

    +

    + This page only shows how to link to the routed modal that is placed on a tab on the "Modal Dashboard". + Clicking this link will not load the slots inside the modal, however, going to the "Modal Dashboard", clicking + on tab 2 and opening the modal from there will work. +

    + Open Modal Route +
    + `; + } static override styles = [UmbTextStyles, css``]; } -export default UmbDashboard2Element +export default UmbDashboard2Element; declare global { interface HTMLElementTagNameMap { diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index a36ba43bc5..a0d71b8ff4 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -1,18 +1,12 @@ -import { css, html, LitElement } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -import { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; +import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; @customElement('umb-example-modal') export class UmbExampleModal extends UmbModalBaseElement { - @state() - private _routes: UmbRoute[] = [ - - ]; + private _routes: UmbRoute[] = []; /** * @@ -24,47 +18,43 @@ export class UmbExampleModal extends UmbModalBaseElement { override connectedCallback(): void { super.connectedCallback(); - this._routes = [{ - path: `/overview`, - component: () => import('./steps/example-modal-step1.element.js'), - setup: (component, info) => { + this._routes = [ + { + path: `/overview`, + component: () => import('./steps/example-modal-step1.element.js'), }, - }, - { - path: `/details`, - component: () => import('./steps/example-modal-step2.element.js'), - setup: (component, info) => { + { + path: `/details`, + component: () => import('./steps/example-modal-step2.element.js'), }, - }, - { - path: '', - redirectTo: 'overview', - }, - { - path: '', - redirectTo: 'test', - } -]; - - setTimeout(()=>{ - //this._routes = [this._routes[0],this._routes[1],this._routes[2]] - },20); + { + path: '', + redirectTo: 'overview', + }, + { + path: '', + redirectTo: 'test', + }, + ]; + setTimeout(() => { + //this._routes = [this._routes[0],this._routes[1],this._routes[2]] + }, 20); } override render() { return html`
    umb-example modal -
    +
    { - console.log('modal route init fired'); - }} - @change=${(event: UmbRouterSlotChangeEvent) => { - console.log('modal routes change'); - }}> + .routes=${this._routes} + @init=${(event: UmbRouterSlotInitEvent) => { + console.log('modal route init fired', event); + }} + @change=${(event: UmbRouterSlotChangeEvent) => { + console.log('modal routes change', event); + }}>
    `; } diff --git a/examples/modal-routed/modal/steps/example-modal-step1.element.ts b/examples/modal-routed/modal/steps/example-modal-step1.element.ts index 35f39147fd..9098546e6a 100644 --- a/examples/modal-routed/modal/steps/example-modal-step1.element.ts +++ b/examples/modal-routed/modal/steps/example-modal-step1.element.ts @@ -1,22 +1,11 @@ -import { css, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { css, html, customElement } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; @customElement('umb-example-modal-step1') export class UmbExampleModalStep1 extends UmbModalBaseElement { - override render() { - return html` -
    - example modal step1 - - -
    - `; + return html`
    example modal step1
    `; } static override styles = [UmbTextStyles, css``]; diff --git a/examples/modal-routed/modal/steps/example-modal-step2.element.ts b/examples/modal-routed/modal/steps/example-modal-step2.element.ts index 32dadca5b8..c6a9f6a5d5 100644 --- a/examples/modal-routed/modal/steps/example-modal-step2.element.ts +++ b/examples/modal-routed/modal/steps/example-modal-step2.element.ts @@ -1,25 +1,14 @@ -import { css, html, LitElement } from 'lit'; -import { customElement } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { html, customElement } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -import { UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; @customElement('umb-example-modal-step2') export class UmbExampleModalStep2 extends UmbModalBaseElement { - override render() { - return html` -
    - example modal step1 - - -
    - `; + return html`
    example modal step1
    `; } - static override styles = [UmbTextStyles, css``]; + static override styles = [UmbTextStyles]; } export default UmbExampleModalStep2; From 054cf53076718a28e1c60e972dd205eb0b74815b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Aug 2024 10:20:56 +0200 Subject: [PATCH 010/170] more clean up --- examples/modal-routed/dashboard.element.ts | 7 +-- examples/modal-routed/tabs/tab1.element.ts | 36 +++++------- examples/modal-routed/tabs/tab2.element.ts | 68 ++++++++++------------ 3 files changed, 46 insertions(+), 65 deletions(-) diff --git a/examples/modal-routed/dashboard.element.ts b/examples/modal-routed/dashboard.element.ts index a4b1cd73d1..6fcae676ba 100644 --- a/examples/modal-routed/dashboard.element.ts +++ b/examples/modal-routed/dashboard.element.ts @@ -1,12 +1,7 @@ import { css, html, LitElement, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; -import type { - UmbModalRouteRegistrationController, - UmbRoute, - UmbRouterSlotChangeEvent, - UmbRouterSlotInitEvent, -} from '@umbraco-cms/backoffice/router'; +import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; @customElement('umb-dashboard') export class UmbDashboardElement extends UmbElementMixin(LitElement) { diff --git a/examples/modal-routed/tabs/tab1.element.ts b/examples/modal-routed/tabs/tab1.element.ts index 1c361976a0..463b31824e 100644 --- a/examples/modal-routed/tabs/tab1.element.ts +++ b/examples/modal-routed/tabs/tab1.element.ts @@ -1,38 +1,28 @@ -import { css, html, LitElement } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { css, html, LitElement, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; -import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; -import { EXAMPLE_ROUTED_MODAL } from './modal/example-modal-token'; @customElement('umb-dashboard-tab1') export class UmbDashboardTab1Element extends UmbElementMixin(LitElement) { - - #workspaceModal?: UmbModalRouteRegistrationController; - - @state() + @state() _editLinkPath?: string; - constructor() { - super(); - - } - - override render() { - return html` -
    -

    tab 1

    - -
    - ` + constructor() { + super(); + } - } + override render() { + return html` +
    +

    tab 1

    +
    + `; + } static override styles = [UmbTextStyles, css``]; } -export default UmbDashboardTab1Element +export default UmbDashboardTab1Element; declare global { interface UmbDashboardTab1Element { diff --git a/examples/modal-routed/tabs/tab2.element.ts b/examples/modal-routed/tabs/tab2.element.ts index 85c761a461..11799d01b0 100644 --- a/examples/modal-routed/tabs/tab2.element.ts +++ b/examples/modal-routed/tabs/tab2.element.ts @@ -1,56 +1,52 @@ -import { css, html, LitElement } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { EXAMPLE_ROUTED_MODAL } from '../modal/example-modal-token.js'; +import { css, html, LitElement, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; -import { EXAMPLE_ROUTED_MODAL } from './../modal/example-modal-token'; @customElement('umb-dashboard-tab2') export class UmbDashboardTab2Element extends UmbElementMixin(LitElement) { - #workspaceModal?: UmbModalRouteRegistrationController; - @state() + @state() _editLinkPath?: string; - constructor() { - super(); - - // Using workspace modal context - this.#workspaceModal?.destroy(); - this.#workspaceModal = new UmbModalRouteRegistrationController(this, EXAMPLE_ROUTED_MODAL) - .addAdditionalPath('view/:entityKey') - .onSetup(() => { - return { - data: {}, - value: {} - }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editLinkPath = routeBuilder({entityKey : 'abc123'}); - }); - } - - override render() { - return html` -
    -

    tab 2

    -

    This element hosts the UmbModalRouteRegistrationController

    + constructor() { + super(); + + // Using workspace modal context + this.#workspaceModal?.destroy(); + this.#workspaceModal = new UmbModalRouteRegistrationController(this, EXAMPLE_ROUTED_MODAL) + .addAdditionalPath('view/:entityKey') + .onSetup(() => { + return { + data: {}, + value: {}, + }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editLinkPath = routeBuilder({ entityKey: 'abc123' }); + }); + } - Open modal -
    + override render() { + return html` +
    +

    tab 2

    +

    This element hosts the UmbModalRouteRegistrationController

    - Path: ${this._editLinkPath} -
    - ` + Open modal +
    - } + Path: ${this._editLinkPath} +
    + `; + } static override styles = [UmbTextStyles, css``]; } -export default UmbDashboardTab2Element +export default UmbDashboardTab2Element; declare global { interface UmbDashboardTab2Element { From 6f8a9ab573e6fc0728cf35ffda1338f0bd345735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Aug 2024 10:21:28 +0200 Subject: [PATCH 011/170] remove test route --- examples/modal-routed/modal/example-modal.element.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index a0d71b8ff4..312f9a8013 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -31,10 +31,6 @@ export class UmbExampleModal extends UmbModalBaseElement { path: '', redirectTo: 'overview', }, - { - path: '', - redirectTo: 'test', - }, ]; setTimeout(() => { From 0a00aad2908c2e727a03bcc712ec40da2058a0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Aug 2024 10:21:43 +0200 Subject: [PATCH 012/170] remove timeout --- examples/modal-routed/modal/example-modal.element.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index 312f9a8013..8b0f4ad60e 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -32,10 +32,6 @@ export class UmbExampleModal extends UmbModalBaseElement { redirectTo: 'overview', }, ]; - - setTimeout(() => { - //this._routes = [this._routes[0],this._routes[1],this._routes[2]] - }, 20); } override render() { From cc2af6217a01e054028cb79a652d6939462f182b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Aug 2024 10:25:19 +0200 Subject: [PATCH 013/170] prettier --- .../modal-routed/modal/example-modal-token.ts | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/modal-routed/modal/example-modal-token.ts b/examples/modal-routed/modal/example-modal-token.ts index 0668cd9993..e9092a0b32 100644 --- a/examples/modal-routed/modal/example-modal-token.ts +++ b/examples/modal-routed/modal/example-modal-token.ts @@ -1,15 +1,14 @@ -import { UmbModalToken } from "@umbraco-cms/backoffice/modal"; +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; -export type Data = {} -export type RetData = {} +export type Data = object; +export type RetData = object; -export const EXAMPLE_ROUTED_MODAL = new UmbModalToken< -Data, -RetData ->('example.routed.modal', // this needs to match the alias of the modal registered in manifest.ts -{ - modal : { - type : 'dialog', - size : 'full' - } -}); +export const EXAMPLE_ROUTED_MODAL = new UmbModalToken( + 'example.routed.modal', // this needs to match the alias of the modal registered in manifest.ts + { + modal: { + type: 'dialog', + size: 'full', + }, + }, +); From f4cdd57f5b8d8a38eb2dd17dc78fdd0e12b275ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Aug 2024 10:29:39 +0200 Subject: [PATCH 014/170] more corrections --- examples/modal-routed/index.ts | 22 ++++++++----------- .../modal-routed/modal/example-modal-token.ts | 1 - .../modal/example-modal.element.ts | 4 ++-- .../steps/example-modal-step2.element.ts | 2 +- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/examples/modal-routed/index.ts b/examples/modal-routed/index.ts index 21a3f2085e..5aca09fe79 100644 --- a/examples/modal-routed/index.ts +++ b/examples/modal-routed/index.ts @@ -1,4 +1,4 @@ -import { ManifestDashboard, ManifestModal, ManifestSection } from '@umbraco-cms/backoffice/extension-registry'; +import type { ManifestDashboard, ManifestModal } from '@umbraco-cms/backoffice/extension-registry'; // const section : ManifestSection = { // type: "section", @@ -10,7 +10,7 @@ import { ManifestDashboard, ManifestModal, ManifestSection } from '@umbraco-cms/ // } // } -let dashboard : ManifestDashboard = { +const dashboard: ManifestDashboard = { type: 'dashboard', name: 'Example Modal Dashboard', alias: 'example.dashboard.dataset', @@ -22,7 +22,7 @@ let dashboard : ManifestDashboard = { }, }; -let dashboard2 : ManifestDashboard = { +const dashboard2: ManifestDashboard = { type: 'dashboard', name: 'Example Modal Dashboard2', alias: 'example.dashboard.dataset2', @@ -34,15 +34,11 @@ let dashboard2 : ManifestDashboard = { }, }; -const modal : ManifestModal = { - type: 'modal', - name: 'Example Modal', - alias: 'example.routed.modal', - element : () => import('./modal/example-modal.element.js'), +const modal: ManifestModal = { + type: 'modal', + name: 'Example Modal', + alias: 'example.routed.modal', + element: () => import('./modal/example-modal.element.js'), }; -export const manifests = [ - dashboard, - dashboard2, - modal -]; +export const manifests = [dashboard, dashboard2, modal]; diff --git a/examples/modal-routed/modal/example-modal-token.ts b/examples/modal-routed/modal/example-modal-token.ts index e9092a0b32..b44e2f4ae9 100644 --- a/examples/modal-routed/modal/example-modal-token.ts +++ b/examples/modal-routed/modal/example-modal-token.ts @@ -8,7 +8,6 @@ export const EXAMPLE_ROUTED_MODAL = new UmbModalToken( { modal: { type: 'dialog', - size: 'full', }, }, ); diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index 8b0f4ad60e..df982abe9e 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -20,11 +20,11 @@ export class UmbExampleModal extends UmbModalBaseElement { super.connectedCallback(); this._routes = [ { - path: `/overview`, + path: `overview`, component: () => import('./steps/example-modal-step1.element.js'), }, { - path: `/details`, + path: `details`, component: () => import('./steps/example-modal-step2.element.js'), }, { diff --git a/examples/modal-routed/modal/steps/example-modal-step2.element.ts b/examples/modal-routed/modal/steps/example-modal-step2.element.ts index c6a9f6a5d5..ea5c711b25 100644 --- a/examples/modal-routed/modal/steps/example-modal-step2.element.ts +++ b/examples/modal-routed/modal/steps/example-modal-step2.element.ts @@ -5,7 +5,7 @@ import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; @customElement('umb-example-modal-step2') export class UmbExampleModalStep2 extends UmbModalBaseElement { override render() { - return html`
    example modal step1
    `; + return html`
    example modal step2
    `; } static override styles = [UmbTextStyles]; From 13bceb0a2738b91e1f090612a1ab35e3e7944ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 6 Aug 2024 10:32:11 +0200 Subject: [PATCH 015/170] note --- examples/modal-routed/modal/example-modal.element.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index df982abe9e..453935be03 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -27,10 +27,11 @@ export class UmbExampleModal extends UmbModalBaseElement { path: `details`, component: () => import('./steps/example-modal-step2.element.js'), }, - { + // NL: There is a problem with this one, but there is more problems as the modal does not close when navigating the browser history. + /*{ path: '', redirectTo: 'overview', - }, + },*/ ]; } From 9ec20e96eb8da4bd474e97118188bb746d82d771 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 7 Oct 2024 09:50:00 +0200 Subject: [PATCH 016/170] wip --- .../entity-detail-workspace-base.ts | 6 ++- .../tree/folder/collection/constants.ts | 2 + .../folder-collection.repository.ts | 43 +++++++++++++++++++ .../tree/folder/collection/manifests.ts | 22 ++++++++++ .../tree/folder/collection/types.ts | 6 +++ .../tree/folder/collection/views/manifests.ts | 25 +++++++++++ .../document-types/tree/folder/manifests.ts | 6 ++- .../tree/folder/workspace/manifests.ts | 19 ++++++++ 8 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/packages/documents/document-types/tree/folder/collection/constants.ts create mode 100644 src/packages/documents/document-types/tree/folder/collection/folder-collection.repository.ts create mode 100644 src/packages/documents/document-types/tree/folder/collection/manifests.ts create mode 100644 src/packages/documents/document-types/tree/folder/collection/types.ts create mode 100644 src/packages/documents/document-types/tree/folder/collection/views/manifests.ts diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 4a85b64773..bf32dcf75c 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -2,7 +2,7 @@ import { UmbSubmittableWorkspaceContextBase } from '../submittable/index.js'; import { UmbEntityWorkspaceDataManager } from '../entity/entity-workspace-data-manager.js'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbEntityModel, UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; +import { UmbEntityContext, type UmbEntityModel, type UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; import { UMB_DISCARD_CHANGES_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import { @@ -41,6 +41,8 @@ export abstract class UmbEntityDetailWorkspaceContextBase< public readonly entityType = this._data.createObservablePartOfCurrent((data) => data?.entityType); public readonly unique = this._data.createObservablePartOfCurrent((data) => data?.unique); + #entityContext = new UmbEntityContext(this); + protected _getDataPromise?: Promise; protected _detailRepository?: DetailRepositoryType; @@ -65,6 +67,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< constructor(host: UmbControllerHost, args: UmbEntityWorkspaceContextArgs) { super(host, args.workspaceAlias); this.#entityType = args.entityType; + this.#entityContext.setEntityType(this.#entityType); window.addEventListener('willchangestate', this.#onWillNavigate); this.#observeRepository(args.detailRepositoryAlias); } @@ -82,6 +85,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< } async load(unique: string) { + this.#entityContext.setUnique(unique); await this.#init; this.resetState(); this._getDataPromise = this._detailRepository!.requestByUnique(unique); diff --git a/src/packages/documents/document-types/tree/folder/collection/constants.ts b/src/packages/documents/document-types/tree/folder/collection/constants.ts new file mode 100644 index 0000000000..2acb88dc1e --- /dev/null +++ b/src/packages/documents/document-types/tree/folder/collection/constants.ts @@ -0,0 +1,2 @@ +export const UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType.Folder.Collection'; +export const UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS = 'Umb.Collection.DocumentType.Folder.'; diff --git a/src/packages/documents/document-types/tree/folder/collection/folder-collection.repository.ts b/src/packages/documents/document-types/tree/folder/collection/folder-collection.repository.ts new file mode 100644 index 0000000000..38dd65b799 --- /dev/null +++ b/src/packages/documents/document-types/tree/folder/collection/folder-collection.repository.ts @@ -0,0 +1,43 @@ +import { UmbDocumentTypeTreeRepository } from '../../document-type-tree.repository.js'; +import type { UmbCollectionFilterModel, UmbCollectionRepository } from '@umbraco-cms/backoffice/collection'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UMB_ENTITY_CONTEXT, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; + +export class UmbDocumentTypeFolderCollectionRepository extends UmbRepositoryBase implements UmbCollectionRepository { + #treeRepository = new UmbDocumentTypeTreeRepository(this); + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_ENTITY_CONTEXT, (entityContext) => { + console.log(entityContext); + }); + } + + async requestCollection(filter: UmbCollectionFilterModel) { + const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); + if (!entityContext) throw new Error('Entity context not found'); + + const entityType = entityContext.getEntityType(); + const unique = entityContext.getUnique(); + + if (!entityType) throw new Error('Entity type not found'); + if (unique === undefined) throw new Error('Unique not found'); + + const parent: UmbEntityModel = { entityType, unique }; + + if (parent.unique === null) { + return this.#treeRepository.requestTreeRootItems({ skip: filter.skip, take: filter.take }); + } else { + return this.#treeRepository.requestTreeItemsOf({ parent, skip: filter.skip, take: filter.take }); + } + } + + override destroy(): void { + this.#treeRepository.destroy(); + super.destroy(); + } +} + +export { UmbDocumentTypeFolderCollectionRepository as api }; diff --git a/src/packages/documents/document-types/tree/folder/collection/manifests.ts b/src/packages/documents/document-types/tree/folder/collection/manifests.ts new file mode 100644 index 0000000000..c80dc7f968 --- /dev/null +++ b/src/packages/documents/document-types/tree/folder/collection/manifests.ts @@ -0,0 +1,22 @@ +import { + UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS, + UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS, +} from './constants.js'; + +export const manifests: Array = [ + { + type: 'collection', + kind: 'default', + alias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS, + name: 'Document Type Folder Collection', + meta: { + repositoryAlias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS, + }, + }, + { + type: 'repository', + alias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS, + name: 'Document Type Folder Collection Repository', + api: () => import('./folder-collection.repository.js'), + }, +]; diff --git a/src/packages/documents/document-types/tree/folder/collection/types.ts b/src/packages/documents/document-types/tree/folder/collection/types.ts new file mode 100644 index 0000000000..1409f4767a --- /dev/null +++ b/src/packages/documents/document-types/tree/folder/collection/types.ts @@ -0,0 +1,6 @@ +import type { UmbCollectionFilterModel } from '@umbraco-cms/backoffice/collection'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; + +export interface UmbFolderCollectionFilterModel extends UmbCollectionFilterModel { + parent: UmbEntityModel; +} diff --git a/src/packages/documents/document-types/tree/folder/collection/views/manifests.ts b/src/packages/documents/document-types/tree/folder/collection/views/manifests.ts new file mode 100644 index 0000000000..7c63b8a72b --- /dev/null +++ b/src/packages/documents/document-types/tree/folder/collection/views/manifests.ts @@ -0,0 +1,25 @@ +import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; + +export const UMB_DOCUMENT_GRID_COLLECTION_VIEW_ALIAS = 'Umb.CollectionView.Document.Grid'; +export const UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS = 'Umb.CollectionView.Document.Table'; + +export const manifests: Array = [ + { + type: 'collectionView', + alias: UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS, + name: 'Document Table Collection View', + element: () => import('./table/document-table-collection-view.element.js'), + weight: 300, + meta: { + label: 'Table', + icon: 'icon-list', + pathName: 'table', + }, + conditions: [ + { + alias: UMB_COLLECTION_ALIAS_CONDITION, + match: 'Umb.Collection.Document', + }, + ], + }, +]; diff --git a/src/packages/documents/document-types/tree/folder/manifests.ts b/src/packages/documents/document-types/tree/folder/manifests.ts index 9715c8438e..2cd9539fa0 100644 --- a/src/packages/documents/document-types/tree/folder/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/manifests.ts @@ -1,7 +1,8 @@ import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../entity.js'; -import { UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS } from './repository/constants.js'; -import { manifests as workspaceManifests } from './workspace/manifests.js'; +import { manifests as collectionManifests } from './collection/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; +import { manifests as workspaceManifests } from './workspace/manifests.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS } from './repository/constants.js'; export const manifests: Array = [ { @@ -24,6 +25,7 @@ export const manifests: Array = [ folderRepositoryAlias: UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS, }, }, + ...collectionManifests, ...repositoryManifests, ...workspaceManifests, ]; diff --git a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts index 52c211ec2f..9ec081e186 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts @@ -1,4 +1,5 @@ import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS } from '../collection/constants.js'; import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; @@ -13,6 +14,24 @@ export const manifests: Array = [ entityType: UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, }, }, + { + type: 'workspaceView', + kind: 'collection', + alias: 'Umb.WorkspaceView.DocumentType.Folder.Collection', + name: 'Document Type Folder Collection Workspace View', + meta: { + label: '#general_design', + pathname: 'design', + icon: 'icon-member-dashed-line', + collectionAlias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS, + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS, + }, + ], + }, { type: 'workspaceAction', kind: 'default', From 87b75860ee9be7f60775bdb99d2cb44cccce3c43 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 9 Oct 2024 16:11:05 +0200 Subject: [PATCH 017/170] wip render tree item children in collection --- .../tree/folder/collection/constants.ts | 2 - .../tree/folder/collection/manifests.ts | 22 ----- .../tree/folder/collection/views/manifests.ts | 25 ------ .../document-types/tree/folder/manifests.ts | 2 +- .../tree/folder/workspace/manifests.ts | 4 +- .../constants.ts | 3 + ...ee-item-children-collection.repository.ts} | 9 +- .../manifests.ts | 24 ++++++ .../types.ts | 2 +- .../views/manifests.ts | 23 ++++++ .../views/table.element.ts | 82 +++++++++++++++++++ 11 files changed, 142 insertions(+), 56 deletions(-) delete mode 100644 src/packages/documents/document-types/tree/folder/collection/constants.ts delete mode 100644 src/packages/documents/document-types/tree/folder/collection/manifests.ts delete mode 100644 src/packages/documents/document-types/tree/folder/collection/views/manifests.ts create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts rename src/packages/documents/document-types/tree/{folder/collection/folder-collection.repository.ts => tree-item-children-collection/document-type-tree-item-children-collection.repository.ts} (82%) create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts rename src/packages/documents/document-types/tree/{folder/collection => tree-item-children-collection}/types.ts (63%) create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts diff --git a/src/packages/documents/document-types/tree/folder/collection/constants.ts b/src/packages/documents/document-types/tree/folder/collection/constants.ts deleted file mode 100644 index 2acb88dc1e..0000000000 --- a/src/packages/documents/document-types/tree/folder/collection/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType.Folder.Collection'; -export const UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS = 'Umb.Collection.DocumentType.Folder.'; diff --git a/src/packages/documents/document-types/tree/folder/collection/manifests.ts b/src/packages/documents/document-types/tree/folder/collection/manifests.ts deleted file mode 100644 index c80dc7f968..0000000000 --- a/src/packages/documents/document-types/tree/folder/collection/manifests.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { - UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS, - UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS, -} from './constants.js'; - -export const manifests: Array = [ - { - type: 'collection', - kind: 'default', - alias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS, - name: 'Document Type Folder Collection', - meta: { - repositoryAlias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS, - }, - }, - { - type: 'repository', - alias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_REPOSITORY_ALIAS, - name: 'Document Type Folder Collection Repository', - api: () => import('./folder-collection.repository.js'), - }, -]; diff --git a/src/packages/documents/document-types/tree/folder/collection/views/manifests.ts b/src/packages/documents/document-types/tree/folder/collection/views/manifests.ts deleted file mode 100644 index 7c63b8a72b..0000000000 --- a/src/packages/documents/document-types/tree/folder/collection/views/manifests.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; - -export const UMB_DOCUMENT_GRID_COLLECTION_VIEW_ALIAS = 'Umb.CollectionView.Document.Grid'; -export const UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS = 'Umb.CollectionView.Document.Table'; - -export const manifests: Array = [ - { - type: 'collectionView', - alias: UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS, - name: 'Document Table Collection View', - element: () => import('./table/document-table-collection-view.element.js'), - weight: 300, - meta: { - label: 'Table', - icon: 'icon-list', - pathName: 'table', - }, - conditions: [ - { - alias: UMB_COLLECTION_ALIAS_CONDITION, - match: 'Umb.Collection.Document', - }, - ], - }, -]; diff --git a/src/packages/documents/document-types/tree/folder/manifests.ts b/src/packages/documents/document-types/tree/folder/manifests.ts index 2cd9539fa0..e22ac7c538 100644 --- a/src/packages/documents/document-types/tree/folder/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/manifests.ts @@ -1,5 +1,5 @@ import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../entity.js'; -import { manifests as collectionManifests } from './collection/manifests.js'; +import { manifests as collectionManifests } from '../tree-item-children-collection/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; import { UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS } from './repository/constants.js'; diff --git a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts index 9ec081e186..8b1109ef05 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts @@ -1,5 +1,5 @@ import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; -import { UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS } from '../collection/constants.js'; +import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from '../../tree-item-children-collection/constants.js'; import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; @@ -23,7 +23,7 @@ export const manifests: Array = [ label: '#general_design', pathname: 'design', icon: 'icon-member-dashed-line', - collectionAlias: UMB_DOCUMENT_TYPE_FOLDER_COLLECTION_ALIAS, + collectionAlias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS, }, conditions: [ { diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts new file mode 100644 index 0000000000..800c987d78 --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts @@ -0,0 +1,3 @@ +export const UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS = 'Umb.Collection.DocumentType.TreeItemChildren'; +export const UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS = + 'Umb.Repository.DocumentType.TreeItemChildrenCollection'; diff --git a/src/packages/documents/document-types/tree/folder/collection/folder-collection.repository.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/document-type-tree-item-children-collection.repository.ts similarity index 82% rename from src/packages/documents/document-types/tree/folder/collection/folder-collection.repository.ts rename to src/packages/documents/document-types/tree/tree-item-children-collection/document-type-tree-item-children-collection.repository.ts index 38dd65b799..a23282f427 100644 --- a/src/packages/documents/document-types/tree/folder/collection/folder-collection.repository.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/document-type-tree-item-children-collection.repository.ts @@ -1,10 +1,13 @@ -import { UmbDocumentTypeTreeRepository } from '../../document-type-tree.repository.js'; +import { UmbDocumentTypeTreeRepository } from '../document-type-tree.repository.js'; import type { UmbCollectionFilterModel, UmbCollectionRepository } from '@umbraco-cms/backoffice/collection'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_ENTITY_CONTEXT, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -export class UmbDocumentTypeFolderCollectionRepository extends UmbRepositoryBase implements UmbCollectionRepository { +export class UmbDocumentTypeTreeItemChildrenCollectionRepository + extends UmbRepositoryBase + implements UmbCollectionRepository +{ #treeRepository = new UmbDocumentTypeTreeRepository(this); constructor(host: UmbControllerHost) { @@ -40,4 +43,4 @@ export class UmbDocumentTypeFolderCollectionRepository extends UmbRepositoryBase } } -export { UmbDocumentTypeFolderCollectionRepository as api }; +export { UmbDocumentTypeTreeItemChildrenCollectionRepository as api }; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts new file mode 100644 index 0000000000..2c7e7991ed --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts @@ -0,0 +1,24 @@ +import { + UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS, + UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS, +} from './constants.js'; +import { manifests as viewManifests } from './views/manifests.js'; + +export const manifests: Array = [ + { + type: 'collection', + kind: 'default', + alias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS, + name: 'Document Type Tree Item Children Collection', + meta: { + repositoryAlias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS, + }, + }, + { + type: 'repository', + alias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS, + name: 'Document Type Tree Item Children Collection Repository', + api: () => import('./document-type-tree-item-children-collection.repository.js'), + }, + ...viewManifests, +]; diff --git a/src/packages/documents/document-types/tree/folder/collection/types.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/types.ts similarity index 63% rename from src/packages/documents/document-types/tree/folder/collection/types.ts rename to src/packages/documents/document-types/tree/tree-item-children-collection/types.ts index 1409f4767a..a45264779f 100644 --- a/src/packages/documents/document-types/tree/folder/collection/types.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/types.ts @@ -1,6 +1,6 @@ import type { UmbCollectionFilterModel } from '@umbraco-cms/backoffice/collection'; import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -export interface UmbFolderCollectionFilterModel extends UmbCollectionFilterModel { +export interface UmbDocumentTypeTreeItemChildrenCollectionFilterModel extends UmbCollectionFilterModel { parent: UmbEntityModel; } diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts new file mode 100644 index 0000000000..8b8cc044f7 --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts @@ -0,0 +1,23 @@ +import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from '../constants.js'; +import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; + +export const manifests: Array = [ + { + type: 'collectionView', + alias: 'Umb.CollectionView.DocumentType.Folder.Table', + name: 'Document Type Folder Children Table Collection View', + element: () => import('./table.element.js'), + weight: 300, + meta: { + label: 'Table', + icon: 'icon-list', + pathName: 'table', + }, + conditions: [ + { + alias: UMB_COLLECTION_ALIAS_CONDITION, + match: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS, + }, + ], + }, +]; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts new file mode 100644 index 0000000000..7a55c757d2 --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts @@ -0,0 +1,82 @@ +import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; +import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; +import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; +import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbTreeItemModel } from '@umbraco-cms/backoffice/tree'; + +const elementName = 'umb-tree-item-children-table-collection-view'; +@customElement(elementName) +export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement { + @state() + private _tableConfig: UmbTableConfig = { + allowSelection: false, + }; + + @state() + private _tableColumns: Array = [ + { + name: 'Name', + alias: 'name', + }, + ]; + + @state() + private _tableItems: Array = []; + + #collectionContext?: UmbDefaultCollectionContext; + + constructor() { + super(); + + this.consumeContext(UMB_COLLECTION_CONTEXT, (instance) => { + this.#collectionContext = instance; + this.#observeCollectionItems(); + }); + } + + #observeCollectionItems() { + if (!this.#collectionContext) return; + this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver'); + } + + #createTableItems(item: Array) { + this._tableItems = item.map((item) => { + return { + id: item.unique, + icon: item.isFolder && !item.icon ? 'icon-folder' : item.icon, + data: [ + { + columnAlias: 'name', + value: item.name, + }, + ], + }; + }); + } + + override render() { + return html` + + `; + } + + static override styles = [ + UmbTextStyles, + css` + :host { + display: flex; + flex-direction: column; + } + `, + ]; +} + +export default UmbTreeItemChildrenTableCollectionViewElement; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbTreeItemChildrenTableCollectionViewElement; + } +} From 5bb88eaa36fa88a02dc88ffcbc226ec6ee137fb0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 9 Oct 2024 17:37:33 +0200 Subject: [PATCH 018/170] split workspace into folders --- .../input-document-type.element.ts | 2 +- .../document-types/tree/manifests.ts | 10 -- .../workspace/document-type-root/manifests.ts | 14 +++ .../workspace/document-type/constants.ts | 1 + .../document-type-workspace-editor.element.ts | 0 .../document-type-workspace.context-token.ts | 0 .../document-type-workspace.context.ts | 8 +- .../document-type-workspace.modal-token.ts | 2 +- .../workspace/document-type/index.ts | 3 + .../workspace/document-type/manifests.ts | 106 +++++++++++++++++ ...nt-type-workspace-view-settings.element.ts | 0 ...t-type-workspace-view-structure.element.ts | 2 +- ...t-type-workspace-view-templates.element.ts | 0 .../document-types/workspace/index.ts | 3 +- .../document-types/workspace/manifests.ts | 109 +----------------- 15 files changed, 135 insertions(+), 125 deletions(-) create mode 100644 src/packages/documents/document-types/workspace/document-type-root/manifests.ts create mode 100644 src/packages/documents/document-types/workspace/document-type/constants.ts rename src/packages/documents/document-types/workspace/{ => document-type}/document-type-workspace-editor.element.ts (100%) rename src/packages/documents/document-types/workspace/{ => document-type}/document-type-workspace.context-token.ts (100%) rename src/packages/documents/document-types/workspace/{ => document-type}/document-type-workspace.context.ts (97%) rename src/packages/documents/document-types/workspace/{ => document-type}/document-type-workspace.modal-token.ts (93%) create mode 100644 src/packages/documents/document-types/workspace/document-type/index.ts create mode 100644 src/packages/documents/document-types/workspace/document-type/manifests.ts rename src/packages/documents/document-types/workspace/{ => document-type}/views/settings/document-type-workspace-view-settings.element.ts (100%) rename src/packages/documents/document-types/workspace/{ => document-type}/views/structure/document-type-workspace-view-structure.element.ts (97%) rename src/packages/documents/document-types/workspace/{ => document-type}/views/templates/document-type-workspace-view-templates.element.ts (100%) diff --git a/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts b/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts index de53c7122e..f7bc27eead 100644 --- a/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts +++ b/src/packages/documents/document-types/components/input-document-type/input-document-type.element.ts @@ -1,5 +1,5 @@ import type { UmbDocumentTypeItemModel } from '../../repository/index.js'; -import { UMB_DOCUMENT_TYPE_WORKSPACE_MODAL } from '../../workspace/document-type-workspace.modal-token.js'; +import { UMB_DOCUMENT_TYPE_WORKSPACE_MODAL } from '../../workspace/document-type/document-type-workspace.modal-token.js'; import type { UmbDocumentTypeTreeItemModel } from '../../tree/types.js'; import { UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN } from '../../paths.js'; import { UmbDocumentTypePickerInputContext } from './input-document-type.context.js'; diff --git a/src/packages/documents/document-types/tree/manifests.ts b/src/packages/documents/document-types/tree/manifests.ts index 40f1ed4830..4ff98fac57 100644 --- a/src/packages/documents/document-types/tree/manifests.ts +++ b/src/packages/documents/document-types/tree/manifests.ts @@ -44,16 +44,6 @@ export const manifests: Array = [ UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, ], }, - { - type: 'workspace', - kind: 'default', - alias: 'Umb.Workspace.DocumentType.Root', - name: 'Document Type Root Workspace', - meta: { - entityType: UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, - headline: '#treeHeaders_documentTypes', - }, - }, ...folderManifests, ...reloadManifests, ]; diff --git a/src/packages/documents/document-types/workspace/document-type-root/manifests.ts b/src/packages/documents/document-types/workspace/document-type-root/manifests.ts new file mode 100644 index 0000000000..c61b55778a --- /dev/null +++ b/src/packages/documents/document-types/workspace/document-type-root/manifests.ts @@ -0,0 +1,14 @@ +import { UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from '../../entity.js'; + +export const manifests: Array = [ + { + type: 'workspace', + kind: 'default', + alias: 'Umb.Workspace.DocumentType.Root', + name: 'Document Type Root Workspace', + meta: { + entityType: UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, + headline: '#treeHeaders_documentTypes', + }, + }, +]; diff --git a/src/packages/documents/document-types/workspace/document-type/constants.ts b/src/packages/documents/document-types/workspace/document-type/constants.ts new file mode 100644 index 0000000000..6592bb27dd --- /dev/null +++ b/src/packages/documents/document-types/workspace/document-type/constants.ts @@ -0,0 +1 @@ +export const UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.DocumentType'; diff --git a/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts b/src/packages/documents/document-types/workspace/document-type/document-type-workspace-editor.element.ts similarity index 100% rename from src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts rename to src/packages/documents/document-types/workspace/document-type/document-type-workspace-editor.element.ts diff --git a/src/packages/documents/document-types/workspace/document-type-workspace.context-token.ts b/src/packages/documents/document-types/workspace/document-type/document-type-workspace.context-token.ts similarity index 100% rename from src/packages/documents/document-types/workspace/document-type-workspace.context-token.ts rename to src/packages/documents/document-types/workspace/document-type/document-type-workspace.context-token.ts diff --git a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/packages/documents/document-types/workspace/document-type/document-type-workspace.context.ts similarity index 97% rename from src/packages/documents/document-types/workspace/document-type-workspace.context.ts rename to src/packages/documents/document-types/workspace/document-type/document-type-workspace.context.ts index e1791d7ec0..a47b5c868b 100644 --- a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts +++ b/src/packages/documents/document-types/workspace/document-type/document-type-workspace.context.ts @@ -4,10 +4,10 @@ import { UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PRESET_TEMPLATE, UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN, type UmbCreateDocumentTypeWorkspacePresetType, -} from '../paths.js'; -import type { UmbDocumentTypeDetailModel } from '../types.js'; -import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js'; -import { UmbDocumentTypeDetailRepository } from '../repository/detail/document-type-detail.repository.js'; +} from '../../paths.js'; +import type { UmbDocumentTypeDetailModel } from '../../types.js'; +import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../entity.js'; +import { UmbDocumentTypeDetailRepository } from '../../repository/detail/document-type-detail.repository.js'; import { UmbDocumentTypeWorkspaceEditorElement } from './document-type-workspace-editor.element.js'; import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type'; import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; diff --git a/src/packages/documents/document-types/workspace/document-type-workspace.modal-token.ts b/src/packages/documents/document-types/workspace/document-type/document-type-workspace.modal-token.ts similarity index 93% rename from src/packages/documents/document-types/workspace/document-type-workspace.modal-token.ts rename to src/packages/documents/document-types/workspace/document-type/document-type-workspace.modal-token.ts index 46162c38e0..e30cbcfd61 100644 --- a/src/packages/documents/document-types/workspace/document-type-workspace.modal-token.ts +++ b/src/packages/documents/document-types/workspace/document-type/document-type-workspace.modal-token.ts @@ -1,4 +1,4 @@ -import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../entity.js'; +import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../entity.js'; import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import type { UmbDeepPartialObject } from '@umbraco-cms/backoffice/utils'; diff --git a/src/packages/documents/document-types/workspace/document-type/index.ts b/src/packages/documents/document-types/workspace/document-type/index.ts new file mode 100644 index 0000000000..5232133b80 --- /dev/null +++ b/src/packages/documents/document-types/workspace/document-type/index.ts @@ -0,0 +1,3 @@ +export * from './document-type-workspace.context-token.js'; +export * from './document-type-workspace.modal-token.js'; +export * from './constants.js'; diff --git a/src/packages/documents/document-types/workspace/document-type/manifests.ts b/src/packages/documents/document-types/workspace/document-type/manifests.ts new file mode 100644 index 0000000000..81b4a8d3d3 --- /dev/null +++ b/src/packages/documents/document-types/workspace/document-type/manifests.ts @@ -0,0 +1,106 @@ +import { UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../../repository/composition/index.js'; +import { UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS } from './constants.js'; +import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; + +export const manifests: Array = [ + { + type: 'workspace', + kind: 'routable', + alias: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, + name: 'Document Type Workspace', + api: () => import('./document-type-workspace.context.js'), + meta: { + entityType: 'document-type', + }, + }, + { + type: 'workspaceView', + kind: 'contentTypeDesignEditor', + alias: 'Umb.WorkspaceView.DocumentType.Design', + name: 'Document Type Workspace Design View', + meta: { + label: '#general_design', + pathname: 'design', + icon: 'icon-document-dashed-line', + compositionRepositoryAlias: UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS, + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, + }, + ], + }, + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.DocumentType.Structure', + name: 'Document Type Workspace Structure View', + element: () => import('./views/structure/document-type-workspace-view-structure.element.js'), + weight: 800, + meta: { + label: '#contentTypeEditor_structure', + pathname: 'structure', + icon: 'icon-mindmap', + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, + }, + ], + }, + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.DocumentType.Settings', + name: 'Document Type Workspace Settings View', + element: () => import('./views/settings/document-type-workspace-view-settings.element.js'), + weight: 600, + meta: { + label: '#general_settings', + pathname: 'settings', + icon: 'icon-settings', + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, + }, + ], + }, + { + type: 'workspaceView', + alias: 'Umb.WorkspaceView.DocumentType.Templates', + name: 'Document Type Workspace Templates View', + element: () => import('./views/templates/document-type-workspace-view-templates.element.js'), + weight: 400, + meta: { + label: '#treeHeaders_templates', + pathname: 'templates', + icon: 'icon-layout', + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, + }, + ], + }, + { + type: 'workspaceAction', + kind: 'default', + alias: 'Umb.WorkspaceAction.DocumentType.Save', + name: 'Save Document Type Workspace Action', + api: UmbSubmitWorkspaceAction, + meta: { + label: '#buttons_save', + look: 'primary', + color: 'positive', + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, + }, + ], + }, +]; diff --git a/src/packages/documents/document-types/workspace/views/settings/document-type-workspace-view-settings.element.ts b/src/packages/documents/document-types/workspace/document-type/views/settings/document-type-workspace-view-settings.element.ts similarity index 100% rename from src/packages/documents/document-types/workspace/views/settings/document-type-workspace-view-settings.element.ts rename to src/packages/documents/document-types/workspace/document-type/views/settings/document-type-workspace-view-settings.element.ts diff --git a/src/packages/documents/document-types/workspace/views/structure/document-type-workspace-view-structure.element.ts b/src/packages/documents/document-types/workspace/document-type/views/structure/document-type-workspace-view-structure.element.ts similarity index 97% rename from src/packages/documents/document-types/workspace/views/structure/document-type-workspace-view-structure.element.ts rename to src/packages/documents/document-types/workspace/document-type/views/structure/document-type-workspace-view-structure.element.ts index 0a490ea644..5edd8d234d 100644 --- a/src/packages/documents/document-types/workspace/views/structure/document-type-workspace-view-structure.element.ts +++ b/src/packages/documents/document-types/workspace/document-type/views/structure/document-type-workspace-view-structure.element.ts @@ -1,5 +1,5 @@ import type { UmbDocumentTypeWorkspaceContext } from '../../document-type-workspace.context.js'; -import type { UmbInputDocumentTypeElement } from '../../../components/input-document-type/input-document-type.element.js'; +import type { UmbInputDocumentTypeElement } from '../../../../components/input-document-type/input-document-type.element.js'; import { UMB_DOCUMENT_TYPE_WORKSPACE_CONTEXT } from '../../document-type-workspace.context-token.js'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; diff --git a/src/packages/documents/document-types/workspace/views/templates/document-type-workspace-view-templates.element.ts b/src/packages/documents/document-types/workspace/document-type/views/templates/document-type-workspace-view-templates.element.ts similarity index 100% rename from src/packages/documents/document-types/workspace/views/templates/document-type-workspace-view-templates.element.ts rename to src/packages/documents/document-types/workspace/document-type/views/templates/document-type-workspace-view-templates.element.ts diff --git a/src/packages/documents/document-types/workspace/index.ts b/src/packages/documents/document-types/workspace/index.ts index cf7ab5393f..7aa5441487 100644 --- a/src/packages/documents/document-types/workspace/index.ts +++ b/src/packages/documents/document-types/workspace/index.ts @@ -1,2 +1 @@ -export * from './document-type-workspace.context-token.js'; -export * from './document-type-workspace.modal-token.js'; +export * from './document-type/index.js'; diff --git a/src/packages/documents/document-types/workspace/manifests.ts b/src/packages/documents/document-types/workspace/manifests.ts index f4230143a2..8d1f79b665 100644 --- a/src/packages/documents/document-types/workspace/manifests.ts +++ b/src/packages/documents/document-types/workspace/manifests.ts @@ -1,107 +1,4 @@ -import { UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../repository/composition/index.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { manifests as documentTypeManifests } from './document-type/manifests.js'; +import { manifests as documentTypeRootManifests } from './document-type-root/manifests.js'; -export const UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.DocumentType'; - -export const manifests: Array = [ - { - type: 'workspace', - kind: 'routable', - alias: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, - name: 'Document Type Workspace', - api: () => import('./document-type-workspace.context.js'), - meta: { - entityType: 'document-type', - }, - }, - { - type: 'workspaceView', - kind: 'contentTypeDesignEditor', - alias: 'Umb.WorkspaceView.DocumentType.Design', - name: 'Document Type Workspace Design View', - meta: { - label: '#general_design', - pathname: 'design', - icon: 'icon-document-dashed-line', - compositionRepositoryAlias: UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS, - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, - }, - ], - }, - { - type: 'workspaceView', - alias: 'Umb.WorkspaceView.DocumentType.Structure', - name: 'Document Type Workspace Structure View', - element: () => import('./views/structure/document-type-workspace-view-structure.element.js'), - weight: 800, - meta: { - label: '#contentTypeEditor_structure', - pathname: 'structure', - icon: 'icon-mindmap', - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, - }, - ], - }, - { - type: 'workspaceView', - alias: 'Umb.WorkspaceView.DocumentType.Settings', - name: 'Document Type Workspace Settings View', - element: () => import('./views/settings/document-type-workspace-view-settings.element.js'), - weight: 600, - meta: { - label: '#general_settings', - pathname: 'settings', - icon: 'icon-settings', - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, - }, - ], - }, - { - type: 'workspaceView', - alias: 'Umb.WorkspaceView.DocumentType.Templates', - name: 'Document Type Workspace Templates View', - element: () => import('./views/templates/document-type-workspace-view-templates.element.js'), - weight: 400, - meta: { - label: '#treeHeaders_templates', - pathname: 'templates', - icon: 'icon-layout', - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, - }, - ], - }, - { - type: 'workspaceAction', - kind: 'default', - alias: 'Umb.WorkspaceAction.DocumentType.Save', - name: 'Save Document Type Workspace Action', - api: UmbSubmitWorkspaceAction, - meta: { - label: '#buttons_save', - look: 'primary', - color: 'positive', - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, - }, - ], - }, -]; +export const manifests: Array = [...documentTypeManifests, ...documentTypeRootManifests]; From c771b187f952f2288ccd2e75b13a0bb05e0b48ff Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 9 Oct 2024 18:20:18 +0200 Subject: [PATCH 019/170] export consts + temp conditions for testing purposes --- .../tree/folder/workspace/index.ts | 1 + .../tree/folder/workspace/manifests.ts | 19 ----------------- .../documents/document-types/tree/index.ts | 3 ++- .../document-types/tree/manifests.ts | 21 +++++++++++++++++++ .../tree-item-children-collection/index.ts | 1 + .../workspace/document-type-root/constants.ts | 1 + .../workspace/document-type-root/index.ts | 1 + 7 files changed, 27 insertions(+), 20 deletions(-) create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/index.ts create mode 100644 src/packages/documents/document-types/workspace/document-type-root/constants.ts create mode 100644 src/packages/documents/document-types/workspace/document-type-root/index.ts diff --git a/src/packages/documents/document-types/tree/folder/workspace/index.ts b/src/packages/documents/document-types/tree/folder/workspace/index.ts index e69de29bb2..4f07201dcf 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/index.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/index.ts @@ -0,0 +1 @@ +export * from './constants.js'; diff --git a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts index 8b1109ef05..52c211ec2f 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts @@ -1,5 +1,4 @@ import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; -import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from '../../tree-item-children-collection/constants.js'; import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; @@ -14,24 +13,6 @@ export const manifests: Array = [ entityType: UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, }, }, - { - type: 'workspaceView', - kind: 'collection', - alias: 'Umb.WorkspaceView.DocumentType.Folder.Collection', - name: 'Document Type Folder Collection Workspace View', - meta: { - label: '#general_design', - pathname: 'design', - icon: 'icon-member-dashed-line', - collectionAlias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS, - }, - conditions: [ - { - alias: 'Umb.Condition.WorkspaceAlias', - match: UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS, - }, - ], - }, { type: 'workspaceAction', kind: 'default', diff --git a/src/packages/documents/document-types/tree/index.ts b/src/packages/documents/document-types/tree/index.ts index f2f1e85a61..4c002c1c02 100644 --- a/src/packages/documents/document-types/tree/index.ts +++ b/src/packages/documents/document-types/tree/index.ts @@ -1,3 +1,4 @@ export { UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT } from './document-type.tree.store.context-token.js'; -export { UMB_DOCUMENT_TYPE_TREE_REPOSITORY_ALIAS, UMB_DOCUMENT_TYPE_TREE_ALIAS } from './constants.js'; +export * from './constants.js'; export * from './folder/index.js'; +export * from './tree-item-children-collection/index.js'; diff --git a/src/packages/documents/document-types/tree/manifests.ts b/src/packages/documents/document-types/tree/manifests.ts index 4ff98fac57..497519bcd3 100644 --- a/src/packages/documents/document-types/tree/manifests.ts +++ b/src/packages/documents/document-types/tree/manifests.ts @@ -3,13 +3,16 @@ import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, } from '../entity.js'; +import { UMB_DOCUMENT_TYPE_ROOT_WORKSPACE_ALIAS } from '../workspace/document-type-root/index.js'; import { UMB_DOCUMENT_TYPE_TREE_ALIAS, UMB_DOCUMENT_TYPE_TREE_REPOSITORY_ALIAS, UMB_DOCUMENT_TYPE_TREE_STORE_ALIAS, } from './constants.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './folder/index.js'; import { manifests as folderManifests } from './folder/manifests.js'; import { manifests as reloadManifests } from './reload-tree-item-children/manifests.js'; +import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './tree-item-children-collection/index.js'; export const manifests: Array = [ { @@ -44,6 +47,24 @@ export const manifests: Array = [ UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, ], }, + { + type: 'workspaceView', + kind: 'collection', + alias: 'Umb.WorkspaceView.DocumentType.TreeItemChildrenCollection', + name: 'Document Type Tree Item Children Collection Workspace View', + meta: { + label: '#general_design', + pathname: 'design', + icon: 'icon-member-dashed-line', + collectionAlias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS, + }, + conditions: [ + { + alias: 'Umb.Condition.WorkspaceAlias', + oneOf: [UMB_DOCUMENT_TYPE_ROOT_WORKSPACE_ALIAS, UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS], + }, + ], + }, ...folderManifests, ...reloadManifests, ]; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts new file mode 100644 index 0000000000..4f07201dcf --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts @@ -0,0 +1 @@ +export * from './constants.js'; diff --git a/src/packages/documents/document-types/workspace/document-type-root/constants.ts b/src/packages/documents/document-types/workspace/document-type-root/constants.ts new file mode 100644 index 0000000000..494ee8fb32 --- /dev/null +++ b/src/packages/documents/document-types/workspace/document-type-root/constants.ts @@ -0,0 +1 @@ +export const UMB_DOCUMENT_TYPE_ROOT_WORKSPACE_ALIAS = 'Umb.Workspace.DocumentType.Root'; diff --git a/src/packages/documents/document-types/workspace/document-type-root/index.ts b/src/packages/documents/document-types/workspace/document-type-root/index.ts new file mode 100644 index 0000000000..4f07201dcf --- /dev/null +++ b/src/packages/documents/document-types/workspace/document-type-root/index.ts @@ -0,0 +1 @@ +export * from './constants.js'; From 9fcf2beb5f6a28431fe4d59c81cadfcd07e32c4a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 10 Oct 2024 10:48:48 +0200 Subject: [PATCH 020/170] don't make pagination take up space --- .../components/pagination/collection-pagination.element.ts | 4 ++++ .../core/collection/default/collection-default.element.ts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/packages/core/collection/components/pagination/collection-pagination.element.ts b/src/packages/core/collection/components/pagination/collection-pagination.element.ts index 7ee0688115..8bd77abf64 100644 --- a/src/packages/core/collection/components/pagination/collection-pagination.element.ts +++ b/src/packages/core/collection/components/pagination/collection-pagination.element.ts @@ -63,6 +63,10 @@ export class UmbCollectionPaginationElement extends UmbLitElement { UmbTextStyles, css` :host { + display: contents; + } + + uui-pagination { display: block; margin-top: var(--uui-size-layout-1); } diff --git a/src/packages/core/collection/default/collection-default.element.ts b/src/packages/core/collection/default/collection-default.element.ts index c1d0f54116..4350fdf0a7 100644 --- a/src/packages/core/collection/default/collection-default.element.ts +++ b/src/packages/core/collection/default/collection-default.element.ts @@ -113,11 +113,11 @@ export class UmbCollectionDefaultElement extends UmbLitElement { } #router { - display: none; + visibility: hidden; } .has-items #router { - display: block; + visibility: visible; } #empty-state { From 5baddfa18e484529d8ec6808a9979c434d01db27 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 10 Oct 2024 11:05:42 +0200 Subject: [PATCH 021/170] register modal routes for editing --- .../views/table.element.ts | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts index 7a55c757d2..505fed3b78 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts @@ -1,3 +1,4 @@ +import { UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN } from '../../../paths.js'; import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; @@ -5,6 +6,8 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbTreeItemModel } from '@umbraco-cms/backoffice/tree'; +import { UmbModalRouteRegistrationController, type UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router'; +import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; const elementName = 'umb-tree-item-children-table-collection-view'; @customElement(elementName) @@ -26,14 +29,16 @@ export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement private _tableItems: Array = []; #collectionContext?: UmbDefaultCollectionContext; + #routeBuilder?: UmbModalRouteBuilder; constructor() { super(); this.consumeContext(UMB_COLLECTION_CONTEXT, (instance) => { this.#collectionContext = instance; - this.#observeCollectionItems(); }); + + this.#registerModalRoute(); } #observeCollectionItems() { @@ -41,15 +46,35 @@ export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver'); } - #createTableItems(item: Array) { - this._tableItems = item.map((item) => { + #registerModalRoute() { + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(':entityType') + .onSetup((params) => { + return { data: { entityType: params.entityType, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this.#routeBuilder = routeBuilder; + + // NOTE: Configuring the observations AFTER the route builder is ready, + // otherwise there is a race condition and `#collectionContext.items` tends to win. [LK] + this.#observeCollectionItems(); + }); + } + + #createTableItems(items: Array) { + this._tableItems = items.map((item) => { + const editPath = this.#routeBuilder + ? this.#routeBuilder({ entityType: item.entityType }) + + UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }) + : ''; + return { id: item.unique, icon: item.isFolder && !item.icon ? 'icon-folder' : item.icon, data: [ { columnAlias: 'name', - value: item.name, + value: html``, }, ], }; From 2447864b856d0de97d6e3f83f2693a7da3d33584 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 10 Oct 2024 12:18:19 +0200 Subject: [PATCH 022/170] reorganize entity location --- .../entity-actions/create/manifests.ts | 3 +- .../documents/document-types/entity.ts | 4 +-- .../document-type.tree.server.data-source.ts | 7 ++--- .../document-types/tree/folder/entity.ts | 2 ++ .../document-types/tree/folder/index.ts | 1 + .../document-types/tree/folder/manifests.ts | 2 +- ...document-type-folder.server.data-source.ts | 2 +- .../document-type-folder-workspace.context.ts | 2 +- ...ent-type-folder.workspace.context-token.ts | 2 +- .../tree/folder/workspace/index.ts | 1 + .../tree/folder/workspace/manifests.ts | 2 +- .../tree/folder/workspace/paths.ts | 14 ++++++++++ .../document-types/tree/manifests.ts | 8 ++---- .../reload-tree-item-children/manifests.ts | 7 ++--- .../views/table.element.ts | 28 ++++++++++++------- 15 files changed, 51 insertions(+), 34 deletions(-) create mode 100644 src/packages/documents/document-types/tree/folder/entity.ts create mode 100644 src/packages/documents/document-types/tree/folder/workspace/paths.ts diff --git a/src/packages/documents/document-types/entity-actions/create/manifests.ts b/src/packages/documents/document-types/entity-actions/create/manifests.ts index 2879df41cf..59786bc3e6 100644 --- a/src/packages/documents/document-types/entity-actions/create/manifests.ts +++ b/src/packages/documents/document-types/entity-actions/create/manifests.ts @@ -1,4 +1,5 @@ -import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from '../../entity.js'; +import { UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from '../../entity.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../tree/index.js'; export const manifests: Array = [ { diff --git a/src/packages/documents/document-types/entity.ts b/src/packages/documents/document-types/entity.ts index 7279881dac..3e502f8058 100644 --- a/src/packages/documents/document-types/entity.ts +++ b/src/packages/documents/document-types/entity.ts @@ -1,10 +1,10 @@ +import type { UmbDocumentTypeFolderEntityType } from './tree/index.js'; + export const UMB_DOCUMENT_TYPE_ENTITY_TYPE = 'document-type'; export const UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE = 'document-type-root'; -export const UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE = 'document-type-folder'; export type UmbDocumentTypeEntityType = typeof UMB_DOCUMENT_TYPE_ENTITY_TYPE; export type UmbDocumentTypeRootEntityType = typeof UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE; -export type UmbDocumentTypeFolderEntityType = typeof UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE; export type UmbDocumentTypeEntityTypeUnion = | UmbDocumentTypeEntityType diff --git a/src/packages/documents/document-types/tree/document-type.tree.server.data-source.ts b/src/packages/documents/document-types/tree/document-type.tree.server.data-source.ts index afd9e20e58..7f8dbfa1b7 100644 --- a/src/packages/documents/document-types/tree/document-type.tree.server.data-source.ts +++ b/src/packages/documents/document-types/tree/document-type.tree.server.data-source.ts @@ -1,9 +1,6 @@ -import { - UMB_DOCUMENT_TYPE_ENTITY_TYPE, - UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, - UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, -} from '../entity.js'; +import { UMB_DOCUMENT_TYPE_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from '../entity.js'; import type { UmbDocumentTypeTreeItemModel } from './types.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from './folder/index.js'; import type { UmbTreeAncestorsOfRequestArgs, UmbTreeChildrenOfRequestArgs, diff --git a/src/packages/documents/document-types/tree/folder/entity.ts b/src/packages/documents/document-types/tree/folder/entity.ts new file mode 100644 index 0000000000..7b75b94cde --- /dev/null +++ b/src/packages/documents/document-types/tree/folder/entity.ts @@ -0,0 +1,2 @@ +export const UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE = 'document-type-folder'; +export type UmbDocumentTypeFolderEntityType = typeof UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE; diff --git a/src/packages/documents/document-types/tree/folder/index.ts b/src/packages/documents/document-types/tree/folder/index.ts index 388ec6aca4..8bf4a043c8 100644 --- a/src/packages/documents/document-types/tree/folder/index.ts +++ b/src/packages/documents/document-types/tree/folder/index.ts @@ -1,2 +1,3 @@ export * from './repository/index.js'; export * from './workspace/index.js'; +export * from './entity.js'; diff --git a/src/packages/documents/document-types/tree/folder/manifests.ts b/src/packages/documents/document-types/tree/folder/manifests.ts index e22ac7c538..6ae803323f 100644 --- a/src/packages/documents/document-types/tree/folder/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/manifests.ts @@ -1,8 +1,8 @@ -import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../entity.js'; import { manifests as collectionManifests } from '../tree-item-children-collection/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; import { UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS } from './repository/constants.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from './entity.js'; export const manifests: Array = [ { diff --git a/src/packages/documents/document-types/tree/folder/repository/document-type-folder.server.data-source.ts b/src/packages/documents/document-types/tree/folder/repository/document-type-folder.server.data-source.ts index 4c088664be..0c30b4d911 100644 --- a/src/packages/documents/document-types/tree/folder/repository/document-type-folder.server.data-source.ts +++ b/src/packages/documents/document-types/tree/folder/repository/document-type-folder.server.data-source.ts @@ -1,4 +1,4 @@ -import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../entity.js'; import type { UmbFolderModel } from '@umbraco-cms/backoffice/tree'; import { DocumentTypeService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/packages/documents/document-types/tree/folder/workspace/document-type-folder-workspace.context.ts b/src/packages/documents/document-types/tree/folder/workspace/document-type-folder-workspace.context.ts index 81ee4598ca..670f2a1ddf 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/document-type-folder-workspace.context.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/document-type-folder-workspace.context.ts @@ -1,8 +1,8 @@ -import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; import { UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS, type UmbDocumentTypeFolderRepository, } from '../repository/index.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../entity.js'; import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; import { UmbDocumentTypeFolderWorkspaceEditorElement } from './document-type-folder-editor.element.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/packages/documents/document-types/tree/folder/workspace/document-type-folder.workspace.context-token.ts b/src/packages/documents/document-types/tree/folder/workspace/document-type-folder.workspace.context-token.ts index f81ff2e17c..8f59d8fd8f 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/document-type-folder.workspace.context-token.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/document-type-folder.workspace.context-token.ts @@ -1,4 +1,4 @@ -import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../entity.js'; import type { UmbDocumentTypeFolderWorkspaceContext } from './document-type-folder-workspace.context.js'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/documents/document-types/tree/folder/workspace/index.ts b/src/packages/documents/document-types/tree/folder/workspace/index.ts index 4f07201dcf..14b140114e 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/index.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/index.ts @@ -1 +1,2 @@ export * from './constants.js'; +export * from './paths.js'; diff --git a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts index 52c211ec2f..0983b14e56 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts @@ -1,4 +1,4 @@ -import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../entity.js'; import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/documents/document-types/tree/folder/workspace/paths.ts b/src/packages/documents/document-types/tree/folder/workspace/paths.ts new file mode 100644 index 0000000000..5a9b113494 --- /dev/null +++ b/src/packages/documents/document-types/tree/folder/workspace/paths.ts @@ -0,0 +1,14 @@ +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../entity.js'; +import { UmbPathPattern } from '@umbraco-cms/backoffice/router'; +import { UMB_SETTINGS_SECTION_PATHNAME } from '@umbraco-cms/backoffice/settings'; +import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace'; + +export const UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generateAbsolute({ + sectionName: UMB_SETTINGS_SECTION_PATHNAME, + entityType: UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, +}); + +export const UMB_EDIT_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH_PATTERN = new UmbPathPattern<{ unique: string }>( + 'edit/:unique', + UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH, +); diff --git a/src/packages/documents/document-types/tree/manifests.ts b/src/packages/documents/document-types/tree/manifests.ts index 497519bcd3..50402bcba1 100644 --- a/src/packages/documents/document-types/tree/manifests.ts +++ b/src/packages/documents/document-types/tree/manifests.ts @@ -1,15 +1,11 @@ -import { - UMB_DOCUMENT_TYPE_ENTITY_TYPE, - UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, - UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, -} from '../entity.js'; +import { UMB_DOCUMENT_TYPE_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from '../entity.js'; import { UMB_DOCUMENT_TYPE_ROOT_WORKSPACE_ALIAS } from '../workspace/document-type-root/index.js'; import { UMB_DOCUMENT_TYPE_TREE_ALIAS, UMB_DOCUMENT_TYPE_TREE_REPOSITORY_ALIAS, UMB_DOCUMENT_TYPE_TREE_STORE_ALIAS, } from './constants.js'; -import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './folder/index.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './folder/index.js'; import { manifests as folderManifests } from './folder/manifests.js'; import { manifests as reloadManifests } from './reload-tree-item-children/manifests.js'; import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './tree-item-children-collection/index.js'; diff --git a/src/packages/documents/document-types/tree/reload-tree-item-children/manifests.ts b/src/packages/documents/document-types/tree/reload-tree-item-children/manifests.ts index 550364e51b..6f2ec7ed71 100644 --- a/src/packages/documents/document-types/tree/reload-tree-item-children/manifests.ts +++ b/src/packages/documents/document-types/tree/reload-tree-item-children/manifests.ts @@ -1,8 +1,5 @@ -import { - UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, - UMB_DOCUMENT_TYPE_ENTITY_TYPE, - UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, -} from '../../entity.js'; +import { UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../entity.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../folder/index.js'; export const manifests: Array = [ { diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts index 505fed3b78..de1c6d76fb 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts @@ -1,4 +1,5 @@ import { UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN } from '../../../paths.js'; +import { UMB_EDIT_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH_PATTERN } from '../../folder/index.js'; import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; @@ -41,11 +42,6 @@ export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement this.#registerModalRoute(); } - #observeCollectionItems() { - if (!this.#collectionContext) return; - this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver'); - } - #registerModalRoute() { new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .addAdditionalPath(':entityType') @@ -61,12 +57,22 @@ export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement }); } + #observeCollectionItems() { + if (!this.#collectionContext) return; + this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver'); + } + #createTableItems(items: Array) { + const routeBuilder = this.#routeBuilder; + if (!routeBuilder) throw new Error('Route builder not ready'); + this._tableItems = items.map((item) => { - const editPath = this.#routeBuilder - ? this.#routeBuilder({ entityType: item.entityType }) + - UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }) - : ''; + const modalEditPath = + routeBuilder({ entityType: item.entityType }) + + UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }); + const inlineEditPath = UMB_EDIT_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH_PATTERN.generateAbsolute({ + unique: item.unique, + }); return { id: item.unique, @@ -74,7 +80,9 @@ export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement data: [ { columnAlias: 'name', - value: html``, + value: html``, }, ], }; From 89c9f54b6c7d41495ac00b60e984150e3f93ff02 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 12:27:28 +0200 Subject: [PATCH 023/170] clean up --- .../tree-item-children-collection/constants.ts | 2 -- .../tree/tree-item-children-collection/index.ts | 1 + .../tree-item-children-collection/manifests.ts | 14 ++++---------- .../repository/constants.ts | 2 ++ ...ype-tree-item-children-collection.repository.ts | 2 +- .../repository/index.ts | 1 + .../repository/manifests.ts | 10 ++++++++++ ...ype-tree-item-table-collection-view.element.ts} | 8 ++++---- .../views/manifests.ts | 6 +++--- 9 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/repository/constants.ts rename src/packages/documents/document-types/tree/tree-item-children-collection/{ => repository}/document-type-tree-item-children-collection.repository.ts (94%) create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/repository/index.ts create mode 100644 src/packages/documents/document-types/tree/tree-item-children-collection/repository/manifests.ts rename src/packages/documents/document-types/tree/tree-item-children-collection/views/{table.element.ts => document-type-tree-item-table-collection-view.element.ts} (91%) diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts index 800c987d78..906ddd8683 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts @@ -1,3 +1 @@ export const UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS = 'Umb.Collection.DocumentType.TreeItemChildren'; -export const UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS = - 'Umb.Repository.DocumentType.TreeItemChildrenCollection'; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts index 4f07201dcf..6c11f6abbb 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts @@ -1 +1,2 @@ export * from './constants.js'; +export * from './repository/index.js'; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts index 2c7e7991ed..8f03eaf7df 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts @@ -1,8 +1,7 @@ -import { - UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS, - UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS, -} from './constants.js'; import { manifests as viewManifests } from './views/manifests.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; +import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './constants.js'; +import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS } from './repository/index.js'; export const manifests: Array = [ { @@ -14,11 +13,6 @@ export const manifests: Array = [ repositoryAlias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS, }, }, - { - type: 'repository', - alias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS, - name: 'Document Type Tree Item Children Collection Repository', - api: () => import('./document-type-tree-item-children-collection.repository.js'), - }, ...viewManifests, + ...repositoryManifests, ]; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/constants.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/constants.ts new file mode 100644 index 0000000000..2f9a0ac272 --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/constants.ts @@ -0,0 +1,2 @@ +export const UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS = + 'Umb.Repository.DocumentType.TreeItemChildrenCollection'; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/document-type-tree-item-children-collection.repository.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/document-type-tree-item-children-collection.repository.ts similarity index 94% rename from src/packages/documents/document-types/tree/tree-item-children-collection/document-type-tree-item-children-collection.repository.ts rename to src/packages/documents/document-types/tree/tree-item-children-collection/repository/document-type-tree-item-children-collection.repository.ts index a23282f427..ea0c71b3b7 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/document-type-tree-item-children-collection.repository.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/document-type-tree-item-children-collection.repository.ts @@ -1,4 +1,4 @@ -import { UmbDocumentTypeTreeRepository } from '../document-type-tree.repository.js'; +import { UmbDocumentTypeTreeRepository } from '../../document-type-tree.repository.js'; import type { UmbCollectionFilterModel, UmbCollectionRepository } from '@umbraco-cms/backoffice/collection'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/index.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/index.ts new file mode 100644 index 0000000000..4f07201dcf --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/index.ts @@ -0,0 +1 @@ +export * from './constants.js'; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/manifests.ts new file mode 100644 index 0000000000..5b37fad314 --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/repository/manifests.ts @@ -0,0 +1,10 @@ +import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS } from './constants.js'; + +export const manifests: Array = [ + { + type: 'repository', + alias: UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS, + name: 'Document Type Tree Item Children Collection Repository', + api: () => import('./document-type-tree-item-children-collection.repository.js'), + }, +]; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/views/document-type-tree-item-table-collection-view.element.ts similarity index 91% rename from src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts rename to src/packages/documents/document-types/tree/tree-item-children-collection/views/document-type-tree-item-table-collection-view.element.ts index de1c6d76fb..333370e1cc 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/views/table.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/views/document-type-tree-item-table-collection-view.element.ts @@ -10,9 +10,9 @@ import type { UmbTreeItemModel } from '@umbraco-cms/backoffice/tree'; import { UmbModalRouteRegistrationController, type UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -const elementName = 'umb-tree-item-children-table-collection-view'; +const elementName = 'umb-document-type-tree-item-table-collection-view'; @customElement(elementName) -export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement { +export class UmbDocumentTypeTreeItemTableCollectionViewElement extends UmbLitElement { @state() private _tableConfig: UmbTableConfig = { allowSelection: false, @@ -106,10 +106,10 @@ export class UmbTreeItemChildrenTableCollectionViewElement extends UmbLitElement ]; } -export default UmbTreeItemChildrenTableCollectionViewElement; +export { UmbDocumentTypeTreeItemTableCollectionViewElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbTreeItemChildrenTableCollectionViewElement; + [elementName]: UmbDocumentTypeTreeItemTableCollectionViewElement; } } diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts index 8b8cc044f7..489068637d 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts +++ b/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts @@ -4,9 +4,9 @@ import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collecti export const manifests: Array = [ { type: 'collectionView', - alias: 'Umb.CollectionView.DocumentType.Folder.Table', - name: 'Document Type Folder Children Table Collection View', - element: () => import('./table.element.js'), + alias: 'Umb.CollectionView.DocumentType.TreeItem.Table', + name: 'Document Type Tree Item Table Collection View', + element: () => import('./document-type-tree-item-table-collection-view.element.js'), weight: 300, meta: { label: 'Table', From cd928e214c526d613b66e1c7e1e95fd00ab0aa48 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 12:55:49 +0200 Subject: [PATCH 024/170] clean up --- .../documents/document-types/tree/folder/manifests.ts | 2 +- src/packages/documents/document-types/tree/index.ts | 2 +- src/packages/documents/document-types/tree/manifests.ts | 4 ++-- .../collection}/constants.ts | 0 .../collection}/index.ts | 0 .../collection}/manifests.ts | 0 .../collection}/repository/constants.ts | 0 .../document-type-tree-item-children-collection.repository.ts | 2 +- .../collection}/repository/index.ts | 0 .../collection}/repository/manifests.ts | 0 .../collection}/types.ts | 0 .../document-type-tree-item-table-collection-view.element.ts | 4 ++-- .../collection}/views/manifests.ts | 0 .../document-types/tree/tree-item-children/manifests.ts | 4 ++++ .../reload-entity-action}/manifests.ts | 4 ++-- 15 files changed, 13 insertions(+), 9 deletions(-) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/constants.ts (100%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/index.ts (100%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/manifests.ts (100%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/repository/constants.ts (100%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/repository/document-type-tree-item-children-collection.repository.ts (94%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/repository/index.ts (100%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/repository/manifests.ts (100%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/types.ts (100%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/views/document-type-tree-item-table-collection-view.element.ts (98%) rename src/packages/documents/document-types/tree/{tree-item-children-collection => tree-item-children/collection}/views/manifests.ts (100%) create mode 100644 src/packages/documents/document-types/tree/tree-item-children/manifests.ts rename src/packages/documents/document-types/tree/{reload-tree-item-children => tree-item-children/reload-entity-action}/manifests.ts (79%) diff --git a/src/packages/documents/document-types/tree/folder/manifests.ts b/src/packages/documents/document-types/tree/folder/manifests.ts index 6ae803323f..0ed7c51703 100644 --- a/src/packages/documents/document-types/tree/folder/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/manifests.ts @@ -1,4 +1,4 @@ -import { manifests as collectionManifests } from '../tree-item-children-collection/manifests.js'; +import { manifests as collectionManifests } from '../tree-item-children/collection/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; import { UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS } from './repository/constants.js'; diff --git a/src/packages/documents/document-types/tree/index.ts b/src/packages/documents/document-types/tree/index.ts index 4c002c1c02..7012f414b5 100644 --- a/src/packages/documents/document-types/tree/index.ts +++ b/src/packages/documents/document-types/tree/index.ts @@ -1,4 +1,4 @@ export { UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT } from './document-type.tree.store.context-token.js'; export * from './constants.js'; export * from './folder/index.js'; -export * from './tree-item-children-collection/index.js'; +export * from './tree-item-children/collection/index.js'; diff --git a/src/packages/documents/document-types/tree/manifests.ts b/src/packages/documents/document-types/tree/manifests.ts index 50402bcba1..30ef8c1313 100644 --- a/src/packages/documents/document-types/tree/manifests.ts +++ b/src/packages/documents/document-types/tree/manifests.ts @@ -7,8 +7,8 @@ import { } from './constants.js'; import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './folder/index.js'; import { manifests as folderManifests } from './folder/manifests.js'; -import { manifests as reloadManifests } from './reload-tree-item-children/manifests.js'; -import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './tree-item-children-collection/index.js'; +import { manifests as reloadManifests } from './tree-item-children/reload-entity-action/manifests.js'; +import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './tree-item-children/collection/index.js'; export const manifests: Array = [ { diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/constants.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/constants.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/constants.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/index.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/index.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/index.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/index.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/manifests.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/manifests.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/manifests.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/constants.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/constants.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/repository/constants.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/repository/constants.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/document-type-tree-item-children-collection.repository.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts similarity index 94% rename from src/packages/documents/document-types/tree/tree-item-children-collection/repository/document-type-tree-item-children-collection.repository.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts index ea0c71b3b7..f9fcde7d27 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/document-type-tree-item-children-collection.repository.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts @@ -1,4 +1,4 @@ -import { UmbDocumentTypeTreeRepository } from '../../document-type-tree.repository.js'; +import { UmbDocumentTypeTreeRepository } from '../../../document-type-tree.repository.js'; import type { UmbCollectionFilterModel, UmbCollectionRepository } from '@umbraco-cms/backoffice/collection'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/index.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/index.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/repository/index.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/repository/index.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/repository/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/manifests.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/repository/manifests.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/repository/manifests.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/types.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/types.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/types.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/types.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/document-type-tree-item-table-collection-view.element.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts similarity index 98% rename from src/packages/documents/document-types/tree/tree-item-children-collection/views/document-type-tree-item-table-collection-view.element.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts index 333370e1cc..8273ad9979 100644 --- a/src/packages/documents/document-types/tree/tree-item-children-collection/views/document-type-tree-item-table-collection-view.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts @@ -1,5 +1,5 @@ -import { UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN } from '../../../paths.js'; -import { UMB_EDIT_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH_PATTERN } from '../../folder/index.js'; +import { UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN } from '../../../../paths.js'; +import { UMB_EDIT_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH_PATTERN } from '../../../folder/index.js'; import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; diff --git a/src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/views/manifests.ts similarity index 100% rename from src/packages/documents/document-types/tree/tree-item-children-collection/views/manifests.ts rename to src/packages/documents/document-types/tree/tree-item-children/collection/views/manifests.ts diff --git a/src/packages/documents/document-types/tree/tree-item-children/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children/manifests.ts new file mode 100644 index 0000000000..b6ea5ab54e --- /dev/null +++ b/src/packages/documents/document-types/tree/tree-item-children/manifests.ts @@ -0,0 +1,4 @@ +import { manifests as collectionManifests } from './collection/manifests.js'; +import { manifests as reloadEntityActionManifests } from './reload-entity-action/manifests.js'; + +export const manifests: Array = [...collectionManifests, ...reloadEntityActionManifests]; diff --git a/src/packages/documents/document-types/tree/reload-tree-item-children/manifests.ts b/src/packages/documents/document-types/tree/tree-item-children/reload-entity-action/manifests.ts similarity index 79% rename from src/packages/documents/document-types/tree/reload-tree-item-children/manifests.ts rename to src/packages/documents/document-types/tree/tree-item-children/reload-entity-action/manifests.ts index 6f2ec7ed71..8f0ada4ebc 100644 --- a/src/packages/documents/document-types/tree/reload-tree-item-children/manifests.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/reload-entity-action/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../entity.js'; -import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../folder/index.js'; +import { UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../folder/index.js'; export const manifests: Array = [ { From 2641f642f36782b295d567a35b079d432b78f943 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 14:10:40 +0200 Subject: [PATCH 025/170] Update manifests.ts --- src/packages/documents/document-types/tree/manifests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/documents/document-types/tree/manifests.ts b/src/packages/documents/document-types/tree/manifests.ts index 30ef8c1313..47e012f97a 100644 --- a/src/packages/documents/document-types/tree/manifests.ts +++ b/src/packages/documents/document-types/tree/manifests.ts @@ -7,7 +7,7 @@ import { } from './constants.js'; import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE, UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './folder/index.js'; import { manifests as folderManifests } from './folder/manifests.js'; -import { manifests as reloadManifests } from './tree-item-children/reload-entity-action/manifests.js'; +import { manifests as treeItemChildrenManifests } from './tree-item-children/manifests.js'; import { UMB_DOCUMENT_TYPE_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './tree-item-children/collection/index.js'; export const manifests: Array = [ @@ -62,5 +62,5 @@ export const manifests: Array = [ ], }, ...folderManifests, - ...reloadManifests, + ...treeItemChildrenManifests, ]; From cf025685f88f5b00c781e269370e002b24869669 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 14:25:53 +0200 Subject: [PATCH 026/170] clean up --- ...ment-type-tree-item-children-collection.repository.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts index f9fcde7d27..fb8d23aeee 100644 --- a/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts @@ -1,7 +1,6 @@ import { UmbDocumentTypeTreeRepository } from '../../../document-type-tree.repository.js'; import type { UmbCollectionFilterModel, UmbCollectionRepository } from '@umbraco-cms/backoffice/collection'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_ENTITY_CONTEXT, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; export class UmbDocumentTypeTreeItemChildrenCollectionRepository @@ -10,14 +9,6 @@ export class UmbDocumentTypeTreeItemChildrenCollectionRepository { #treeRepository = new UmbDocumentTypeTreeRepository(this); - constructor(host: UmbControllerHost) { - super(host); - - this.consumeContext(UMB_ENTITY_CONTEXT, (entityContext) => { - console.log(entityContext); - }); - } - async requestCollection(filter: UmbCollectionFilterModel) { const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); if (!entityContext) throw new Error('Entity context not found'); From 7e5e2c546c569bd24b519464749517e63fa15f52 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 14:25:59 +0200 Subject: [PATCH 027/170] remove double export --- src/packages/documents/document-types/tree/folder/manifests.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/packages/documents/document-types/tree/folder/manifests.ts b/src/packages/documents/document-types/tree/folder/manifests.ts index 0ed7c51703..c8a24ff157 100644 --- a/src/packages/documents/document-types/tree/folder/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/manifests.ts @@ -1,4 +1,3 @@ -import { manifests as collectionManifests } from '../tree-item-children/collection/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; import { UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS } from './repository/constants.js'; @@ -25,7 +24,6 @@ export const manifests: Array = [ folderRepositoryAlias: UMB_DOCUMENT_TYPE_FOLDER_REPOSITORY_ALIAS, }, }, - ...collectionManifests, ...repositoryManifests, ...workspaceManifests, ]; From 7894a80b27dad34c6fa14d543d1c71f0fbb68cc5 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 14:29:13 +0200 Subject: [PATCH 028/170] fix types --- .../core/localization/stories/localize.element.stories.ts | 2 +- src/packages/documents/document-types/tree/folder/types.ts | 2 +- src/packages/documents/document-types/tree/types.ts | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/packages/core/localization/stories/localize.element.stories.ts b/src/packages/core/localization/stories/localize.element.stories.ts index 36991cac5e..95b0777c20 100644 --- a/src/packages/core/localization/stories/localize.element.stories.ts +++ b/src/packages/core/localization/stories/localize.element.stories.ts @@ -12,7 +12,7 @@ const meta: Meta = { argTypes: { args: { control: { - type: 'array', + type: 'array' as any, }, }, }, diff --git a/src/packages/documents/document-types/tree/folder/types.ts b/src/packages/documents/document-types/tree/folder/types.ts index 20929ae03b..4c5a953a9d 100644 --- a/src/packages/documents/document-types/tree/folder/types.ts +++ b/src/packages/documents/document-types/tree/folder/types.ts @@ -1,5 +1,5 @@ -import type { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../entity.js'; import type { UmbDocumentTypeTreeItemModel } from '../types.js'; +import type { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from './entity.js'; export interface UmbDocumentTypeFolderTreeItemModel extends UmbDocumentTypeTreeItemModel { entityType: typeof UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE; diff --git a/src/packages/documents/document-types/tree/types.ts b/src/packages/documents/document-types/tree/types.ts index 24d72d14ff..c8eeff4228 100644 --- a/src/packages/documents/document-types/tree/types.ts +++ b/src/packages/documents/document-types/tree/types.ts @@ -1,8 +1,5 @@ -import type { - UmbDocumentTypeEntityType, - UmbDocumentTypeFolderEntityType, - UmbDocumentTypeRootEntityType, -} from '../entity.js'; +import type { UmbDocumentTypeEntityType, UmbDocumentTypeRootEntityType } from '../entity.js'; +import type { UmbDocumentTypeFolderEntityType } from './folder/index.js'; import type { UmbTreeItemModel, UmbTreeRootModel } from '@umbraco-cms/backoffice/tree'; export interface UmbDocumentTypeTreeItemModel extends UmbTreeItemModel { From faa60e81389e6f619df087f06583ff6436b94a98 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 15:10:42 +0200 Subject: [PATCH 029/170] add element type column --- ...type-tree-item-table-collection-view.element.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts index 8273ad9979..fdfcdff7d9 100644 --- a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts @@ -1,12 +1,12 @@ import { UMB_EDIT_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN } from '../../../../paths.js'; import { UMB_EDIT_DOCUMENT_TYPE_FOLDER_WORKSPACE_PATH_PATTERN } from '../../../folder/index.js'; +import type { UmbDocumentTypeTreeItemModel } from '../../../types.js'; import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { UmbTreeItemModel } from '@umbraco-cms/backoffice/tree'; import { UmbModalRouteRegistrationController, type UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @@ -24,6 +24,10 @@ export class UmbDocumentTypeTreeItemTableCollectionViewElement extends UmbLitEle name: 'Name', alias: 'name', }, + { + name: 'Element Type', + alias: 'isElementType', + }, ]; @state() @@ -62,7 +66,7 @@ export class UmbDocumentTypeTreeItemTableCollectionViewElement extends UmbLitEle this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver'); } - #createTableItems(items: Array) { + #createTableItems(items: Array) { const routeBuilder = this.#routeBuilder; if (!routeBuilder) throw new Error('Route builder not ready'); @@ -84,6 +88,10 @@ export class UmbDocumentTypeTreeItemTableCollectionViewElement extends UmbLitEle href=${item.isFolder ? inlineEditPath : modalEditPath} label=${item.name}>`, }, + { + columnAlias: 'isElementType', + value: item.isElement ? html`` : nothing, + }, ], }; }); From 14fe353a4e02768d02f58bd81bde2842b20ce2f8 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 15:48:36 +0200 Subject: [PATCH 030/170] add boolean + entity actions global table column layouts --- .../boolean-table-column-layout.element.ts | 19 ++++++++++ ...ity-actions-table-column-layout.element.ts | 37 +++++++++++++++++++ .../core/collection/components/index.ts | 2 + 3 files changed, 58 insertions(+) create mode 100644 src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts create mode 100644 src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts diff --git a/src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts b/src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts new file mode 100644 index 0000000000..282498668d --- /dev/null +++ b/src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts @@ -0,0 +1,19 @@ +import { html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +const elementName = 'umb-boolean-table-column-layout'; +@customElement(elementName) +export class UmbBooleanTableColumnLayoutElement extends UmbLitElement { + @property({ attribute: false }) + value = false; + + override render() { + return this.value ? html`` : nothing; + } +} + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbBooleanTableColumnLayoutElement; + } +} diff --git a/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts b/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts new file mode 100644 index 0000000000..f7ebdd1209 --- /dev/null +++ b/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts @@ -0,0 +1,37 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import { html, nothing, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +const elementName = 'umb-entity-actions-table-column-layout'; +@customElement(elementName) +export class UmbEntityActionsTableColumnLayoutElement extends UmbLitElement { + @property({ attribute: false }) + value?: UmbEntityModel; + + @state() + _isOpen = false; + + #onActionExecuted() { + this._isOpen = false; + } + + override render() { + if (!this.value) return nothing; + + return html` + + + + + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbEntityActionsTableColumnLayoutElement; + } +} diff --git a/src/packages/core/collection/components/index.ts b/src/packages/core/collection/components/index.ts index 4b753400bf..521476d057 100644 --- a/src/packages/core/collection/components/index.ts +++ b/src/packages/core/collection/components/index.ts @@ -3,6 +3,8 @@ import './collection-selection-actions.element.js'; import './collection-toolbar.element.js'; import './collection-view-bundle.element.js'; import './collection-action-bundle.element.js'; +import './boolean-table-column-layout/boolean-table-column-layout.element.js'; +import './entity-actions-table-column-layout/entity-actions-table-column-layout.element.js'; export * from './pagination/collection-pagination.element.js'; export * from './collection-selection-actions.element.js'; From 37d8af70e18db7c62930e06b5e939977a926b437 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 15:49:00 +0200 Subject: [PATCH 031/170] use entity actions in extension insights --- ...extension-table-collection-view.element.ts | 9 ++--- ...le-entity-actions-column-layout.element.ts | 35 ------------------- 2 files changed, 5 insertions(+), 39 deletions(-) delete mode 100644 src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts diff --git a/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts b/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts index 4300dd8062..24a57c1ce9 100644 --- a/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts +++ b/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts @@ -6,8 +6,6 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import './extension-table-entity-actions-column-layout.element.js'; - @customElement('umb-extension-table-collection-view') export class UmbExtensionTableCollectionViewElement extends UmbLitElement { @state() @@ -36,7 +34,6 @@ export class UmbExtensionTableCollectionViewElement extends UmbLitElement { { name: '', alias: 'extensionAction', - elementName: 'umb-extension-table-entity-actions-column-layout', }, ]; @@ -82,7 +79,11 @@ export class UmbExtensionTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'extensionAction', - value: extension, + value: html``, }, ], }; diff --git a/src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts b/src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts deleted file mode 100644 index fed6e96a43..0000000000 --- a/src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { UmbExtensionDetailModel } from '../../types.js'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -const elementName = 'umb-extension-table-entity-actions-column-layout'; -@customElement(elementName) -export class UmbExtensionTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: UmbExtensionDetailModel; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - [elementName]: UmbExtensionTableEntityActionsColumnLayoutElement; - } -} From daa7379d18896e8b4d5cb67c2c11a9a4dd35c85b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 16:43:24 +0200 Subject: [PATCH 032/170] Update user-table-collection-view.element.ts --- .../table/user-table-collection-view.element.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts b/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts index 6efabcb53a..219f488421 100644 --- a/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts +++ b/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts @@ -48,6 +48,10 @@ export class UmbUserTableCollectionViewElement extends UmbLitElement { alias: 'userStatus', elementName: 'umb-user-table-status-column-layout', }, + { + name: '', + alias: 'entityActions', + }, ]; @state() @@ -140,6 +144,14 @@ export class UmbUserTableCollectionViewElement extends UmbLitElement { status: user.state, }, }, + { + columnAlias: 'entityActions', + value: html``, + }, ], }; }); From 5cb8cea280a9b9502cb3a4dd515f1918901205cb Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 16:43:31 +0200 Subject: [PATCH 033/170] Update user-group-table-collection-view.element.ts --- .../user-group-table-collection-view.element.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts b/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts index f94107c739..5892e13716 100644 --- a/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts +++ b/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts @@ -47,6 +47,10 @@ export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { name: this.localize.term('user_mediastartnode'), alias: 'userGroupMediaStartNode', }, + { + name: '', + alias: 'entityActions', + }, ]; @state() @@ -122,6 +126,14 @@ export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { ? this.#mediaStartNodeMap.get(userGroup.mediaStartNode.unique) : this.localize.term('media_mediaRoot'), }, + { + columnAlias: 'entityActions', + value: html``, + }, ], }; }); From 1616fdc5caec9aae2999da5129f3e5231d533f83 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 16:43:36 +0200 Subject: [PATCH 034/170] Update member-table-collection-view.element.ts --- .../table/member-table-collection-view.element.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts b/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts index 8fca9ecca1..c5315c3918 100644 --- a/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts +++ b/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts @@ -8,8 +8,6 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbMemberTypeItemRepository } from '@umbraco-cms/backoffice/member-type'; -import './member-table-entity-actions-column-layout.element.js'; - @customElement('umb-member-table-collection-view') export class UmbMemberTableCollectionViewElement extends UmbLitElement { @state() @@ -42,7 +40,6 @@ export class UmbMemberTableCollectionViewElement extends UmbLitElement { { name: '', alias: 'entityActions', - elementName: 'umb-member-table-entity-actions-column-layout', }, ]; @@ -106,10 +103,11 @@ export class UmbMemberTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'entityActions', - value: { - entityType: member.entityType, - unique: member.unique, - }, + value: html``, }, ], }; From 1763a4081021f710970764ba94afdc9fb1a7f624 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 16:43:45 +0200 Subject: [PATCH 035/170] Update language-table-collection-view.element.ts --- .../language-table-collection-view.element.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/packages/language/collection/views/table/language-table-collection-view.element.ts b/src/packages/language/collection/views/table/language-table-collection-view.element.ts index ed2e9b86de..9e7a189648 100644 --- a/src/packages/language/collection/views/table/language-table-collection-view.element.ts +++ b/src/packages/language/collection/views/table/language-table-collection-view.element.ts @@ -6,9 +6,7 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import './column-layouts/boolean/language-table-boolean-column-layout.element.js'; import './column-layouts/name/language-table-name-column-layout.element.js'; -import './column-layouts/entity-actions/language-table-entity-actions-column-layout.element.js'; @customElement('umb-language-table-collection-view') export class UmbLanguageTableCollectionViewElement extends UmbLitElement { @@ -31,12 +29,10 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { { name: 'Default', alias: 'defaultLanguage', - elementName: 'umb-language-table-boolean-column-layout', }, { name: 'Mandatory', alias: 'mandatoryLanguage', - elementName: 'umb-language-table-boolean-column-layout', }, { name: 'Fallback', @@ -45,7 +41,6 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { { name: '', alias: 'entityActions', - elementName: 'umb-language-table-entity-actions-column-layout', }, ]; @@ -88,11 +83,13 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'defaultLanguage', - value: language.isDefault, + value: html``, }, { columnAlias: 'mandatoryLanguage', - value: language.isMandatory, + value: html``, }, { columnAlias: 'fallbackLanguage', @@ -100,7 +97,11 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'entityActions', - value: language, + value: html``, }, ], }; From 051a79a5f75b2840357c064bc578a95a3fcfa353 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 16:43:51 +0200 Subject: [PATCH 036/170] Update member-group-table-collection-view.element.ts --- .../member-group-table-collection-view.element.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts b/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts index 2084d91556..264d5a4435 100644 --- a/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts +++ b/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts @@ -19,6 +19,10 @@ export class UmbMemberGroupTableCollectionViewElement extends UmbLitElement { name: this.localize.term('general_name'), alias: 'memberGroupName', }, + { + name: '', + alias: 'entityActions', + }, ]; @state() @@ -52,6 +56,14 @@ export class UmbMemberGroupTableCollectionViewElement extends UmbLitElement { >${memberGroup.name}`, }, + { + columnAlias: 'entityActions', + value: html``, + }, ], }; }); From 0863622b063e9eed8b9577b6e830fc175995592a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 16:44:06 +0200 Subject: [PATCH 037/170] align alias --- .../views/table/extension-table-collection-view.element.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts b/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts index 24a57c1ce9..53f30bfde4 100644 --- a/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts +++ b/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts @@ -33,7 +33,7 @@ export class UmbExtensionTableCollectionViewElement extends UmbLitElement { }, { name: '', - alias: 'extensionAction', + alias: 'entityActions', }, ]; @@ -78,7 +78,7 @@ export class UmbExtensionTableCollectionViewElement extends UmbLitElement { value: extension.weight, }, { - columnAlias: 'extensionAction', + columnAlias: 'entityActions', value: html` Date: Fri, 11 Oct 2024 16:44:18 +0200 Subject: [PATCH 038/170] stop click event --- .../entity-actions-table-column-layout.element.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts b/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts index f7ebdd1209..00c9f12842 100644 --- a/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts +++ b/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts @@ -15,11 +15,15 @@ export class UmbEntityActionsTableColumnLayoutElement extends UmbLitElement { this._isOpen = false; } + #onClick(event) { + event.stopPropagation(); + } + override render() { if (!this.value) return nothing; return html` - + Date: Fri, 11 Oct 2024 16:44:36 +0200 Subject: [PATCH 039/170] delete unused code --- ...age-table-boolean-column-layout.element.ts | 18 --------- ...le-entity-actions-column-layout.element.ts | 38 ------------------- ...le-entity-actions-column-layout.element.ts | 38 ------------------- 3 files changed, 94 deletions(-) delete mode 100644 src/packages/language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts delete mode 100644 src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts delete mode 100644 src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts diff --git a/src/packages/language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts b/src/packages/language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts deleted file mode 100644 index 479bc70b2e..0000000000 --- a/src/packages/language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -@customElement('umb-language-table-boolean-column-layout') -export class UmbLanguageTableBooleanColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value = false; - - override render() { - return this.value ? html`` : nothing; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-language-table-boolean-column-layout': UmbLanguageTableBooleanColumnLayoutElement; - } -} diff --git a/src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts b/src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts deleted file mode 100644 index d4479a0402..0000000000 --- a/src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { UmbLanguageDetailModel } from '../../../../../types.js'; -import { html, nothing, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -@customElement('umb-language-table-entity-actions-column-layout') -export class UmbLanguageTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: UmbLanguageDetailModel; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - // TODO: we need to use conditionals on each action here. But until we have that in place - // we'll just remove all actions on the default language. - if (this.value.isDefault) return nothing; - - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-language-table-entity-actions-column-layout': UmbLanguageTableEntityActionsColumnLayoutElement; - } -} diff --git a/src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts b/src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts deleted file mode 100644 index 61eab8c400..0000000000 --- a/src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { UmbMemberEntityType } from '../../../entity.js'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -const elementName = 'umb-member-table-entity-actions-column-layout'; -@customElement(elementName) -export class UmbMemberTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: { - unique: string; - entityType: UmbMemberEntityType; - }; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - [elementName]: UmbMemberTableEntityActionsColumnLayoutElement; - } -} From 9c3b69af83116718564e57e80550bc2f7e993f83 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 16:49:43 +0200 Subject: [PATCH 040/170] use global components --- ...ook-table-boolean-column-layout.element.ts | 18 ---------- ...le-entity-actions-column-layout.element.ts | 34 ------------------- .../webhook-table-collection-view.element.ts | 12 +++---- 3 files changed, 6 insertions(+), 58 deletions(-) delete mode 100644 src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts delete mode 100644 src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts diff --git a/src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts b/src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts deleted file mode 100644 index e16d4f4bb7..0000000000 --- a/src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -@customElement('umb-webhook-table-boolean-column-layout') -export class UmbWebhookTableBooleanColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value = false; - - override render() { - return html``; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-webhook-table-boolean-column-layout': UmbWebhookTableBooleanColumnLayoutElement; - } -} diff --git a/src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts b/src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts deleted file mode 100644 index 16cd56b978..0000000000 --- a/src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { UmbWebhookDetailModel } from '../../../../../types.js'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -@customElement('umb-webhook-table-entity-actions-column-layout') -export class UmbWebhookTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: UmbWebhookDetailModel; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-webhook-table-entity-actions-column-layout': UmbWebhookTableEntityActionsColumnLayoutElement; - } -} diff --git a/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts b/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts index 4128f4e9d2..acff032ed2 100644 --- a/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts +++ b/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts @@ -5,9 +5,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; -import './column-layouts/boolean/webhook-table-boolean-column-layout.element.js'; import './column-layouts/name/webhook-table-name-column-layout.element.js'; -import './column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.js'; import './column-layouts/content-type/webhook-table-name-column-layout.element.js'; @customElement('umb-webhook-table-collection-view') @@ -27,7 +25,6 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { { name: this.localize.term('webhooks_enabled'), alias: 'enabled', - elementName: 'umb-webhook-table-boolean-column-layout', }, { name: this.localize.term('webhooks_url'), @@ -45,7 +42,6 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { { name: '', alias: 'entityActions', - elementName: 'umb-webhook-table-entity-actions-column-layout', }, ]; @@ -85,7 +81,7 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'enabled', - value: webhook.enabled, + value: html``, }, { columnAlias: 'events', @@ -97,7 +93,11 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'entityActions', - value: webhook, + value: html``, }, ], }; From f58275182653d8d2461e41f3a13337c9db343446 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 17:55:14 +0200 Subject: [PATCH 041/170] add entity actions to document and media --- .../document-table-collection-view.element.ts | 13 ++++++++++++- .../table/media-table-collection-view.element.ts | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts index a4e4d89e2f..7587ee0f4a 100644 --- a/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -136,7 +136,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { }; }); - this._tableColumns = [...this.#systemColumns, ...userColumns]; + this._tableColumns = [...this.#systemColumns, ...userColumns, { name: '', alias: 'entityActions' }]; } } @@ -146,6 +146,17 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { const data = this._tableColumns?.map((column) => { + if (column.alias === 'entityActions') { + return { + columnAlias: 'entityActions', + value: html``, + }; + } + const editPath = this.#routeBuilder ? this.#routeBuilder({ entityType: item.entityType }) + UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }) diff --git a/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts b/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts index 0d28d08609..7f0c3101b5 100644 --- a/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts +++ b/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts @@ -125,9 +125,9 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { }; }); - this._tableColumns = [...this.#systemColumns, ...userColumns]; + this._tableColumns = [...this.#systemColumns, ...userColumns, { name: '', alias: 'entityActions' }]; } else { - this._tableColumns = [...this.#systemColumns]; + this._tableColumns = [...this.#systemColumns, { name: '', alias: 'entityActions' }]; } } @@ -141,6 +141,17 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { const data = this._tableColumns?.map((column) => { + if (column.alias === 'entityActions') { + return { + columnAlias: 'entityActions', + value: html``, + }; + } + const editPath = this.#routeBuilder ? this.#routeBuilder({ entityType: item.entityType }) + UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }) From 2bca898f9e9ccfc7542c77895f94afefc07abaac Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 17:59:03 +0200 Subject: [PATCH 042/170] add entity actions --- ...type-tree-item-table-collection-view.element.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts index fdfcdff7d9..6ad5f637a7 100644 --- a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts @@ -28,6 +28,10 @@ export class UmbDocumentTypeTreeItemTableCollectionViewElement extends UmbLitEle name: 'Element Type', alias: 'isElementType', }, + { + name: '', + alias: 'entityActions', + }, ]; @state() @@ -90,7 +94,15 @@ export class UmbDocumentTypeTreeItemTableCollectionViewElement extends UmbLitEle }, { columnAlias: 'isElementType', - value: item.isElement ? html`` : nothing, + value: html``, + }, + { + columnAlias: 'entityActions', + value: html``, }, ], }; From b316e778409847962049ec0908ef3ee8d6bc617e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 20:50:31 +0200 Subject: [PATCH 043/170] move to entity action module --- src/packages/core/collection/components/index.ts | 1 - .../entity-actions-table-column-layout.element.ts | 2 +- src/packages/core/entity-action/global-components/index.ts | 1 + src/packages/core/entity-action/index.ts | 2 ++ 4 files changed, 4 insertions(+), 2 deletions(-) rename src/packages/core/{collection/components => entity-action/global-components}/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts (97%) create mode 100644 src/packages/core/entity-action/global-components/index.ts diff --git a/src/packages/core/collection/components/index.ts b/src/packages/core/collection/components/index.ts index 521476d057..1e760844e9 100644 --- a/src/packages/core/collection/components/index.ts +++ b/src/packages/core/collection/components/index.ts @@ -4,7 +4,6 @@ import './collection-toolbar.element.js'; import './collection-view-bundle.element.js'; import './collection-action-bundle.element.js'; import './boolean-table-column-layout/boolean-table-column-layout.element.js'; -import './entity-actions-table-column-layout/entity-actions-table-column-layout.element.js'; export * from './pagination/collection-pagination.element.js'; export * from './collection-selection-actions.element.js'; diff --git a/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts b/src/packages/core/entity-action/global-components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts similarity index 97% rename from src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts rename to src/packages/core/entity-action/global-components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts index 00c9f12842..ef715a08dd 100644 --- a/src/packages/core/collection/components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts +++ b/src/packages/core/entity-action/global-components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts @@ -15,7 +15,7 @@ export class UmbEntityActionsTableColumnLayoutElement extends UmbLitElement { this._isOpen = false; } - #onClick(event) { + #onClick(event: Event) { event.stopPropagation(); } diff --git a/src/packages/core/entity-action/global-components/index.ts b/src/packages/core/entity-action/global-components/index.ts new file mode 100644 index 0000000000..b36e4f4c44 --- /dev/null +++ b/src/packages/core/entity-action/global-components/index.ts @@ -0,0 +1 @@ +import './entity-actions-table-column-layout/entity-actions-table-column-layout.element.js'; diff --git a/src/packages/core/entity-action/index.ts b/src/packages/core/entity-action/index.ts index 0fd5ba6de0..3166134fea 100644 --- a/src/packages/core/entity-action/index.ts +++ b/src/packages/core/entity-action/index.ts @@ -1,3 +1,5 @@ +import './global-components/index.js'; + export * from './common/index.js'; export * from './default/index.js'; export * from './entity-action-base.js'; From 503df51fdc783362f9d7f3ec2d057b75233cefc1 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 11 Oct 2024 21:02:37 +0200 Subject: [PATCH 044/170] Update localize.element.stories.ts --- .../core/localization/stories/localize.element.stories.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/localization/stories/localize.element.stories.ts b/src/packages/core/localization/stories/localize.element.stories.ts index 36991cac5e..95b0777c20 100644 --- a/src/packages/core/localization/stories/localize.element.stories.ts +++ b/src/packages/core/localization/stories/localize.element.stories.ts @@ -12,7 +12,7 @@ const meta: Meta = { argTypes: { args: { control: { - type: 'array', + type: 'array' as any, }, }, }, From 4bf1e368024c4a2c48b8c3a59f8b676e126cdf40 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 22 Oct 2024 09:28:39 +0200 Subject: [PATCH 045/170] add methods to get current user data --- .../user/current-user/current-user.context.ts | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/packages/user/current-user/current-user.context.ts b/src/packages/user/current-user/current-user.context.ts index b6836e70b7..4a18f94086 100644 --- a/src/packages/user/current-user/current-user.context.ts +++ b/src/packages/user/current-user/current-user.context.ts @@ -83,6 +83,74 @@ export class UmbCurrentUserContext extends UmbContextBase return currentUser?.isAdmin ?? false; } + getAllowedSection() { + return this.#currentUser.getValue()?.allowedSections; + } + + getAvatarUrls() { + return this.#currentUser.getValue()?.avatarUrls; + } + + getDocumentStartNodeUniques() { + return this.#currentUser.getValue()?.documentStartNodeUniques; + } + + getEmail() { + return this.#currentUser.getValue()?.email; + } + + getFallbackPermissions() { + return this.#currentUser.getValue()?.fallbackPermissions; + } + + getHasAccessToAllLanguages() { + return this.#currentUser.getValue()?.hasAccessToAllLanguages; + } + + getHasAccessToSensitiveData() { + return this.#currentUser.getValue()?.hasAccessToSensitiveData; + } + + getHasDocumentRootAccess() { + return this.#currentUser.getValue()?.hasDocumentRootAccess; + } + + getHasMediaRootAccess() { + return this.#currentUser.getValue()?.hasMediaRootAccess; + } + + getIsAdmin() { + return this.#currentUser.getValue()?.isAdmin; + } + + getLanguageIsoCode() { + return this.#currentUser.getValue()?.languageIsoCode; + } + + getLanguages() { + return this.#currentUser.getValue()?.languages; + } + + getMediaStartNodeUniques() { + return this.#currentUser.getValue()?.mediaStartNodeUniques; + } + + getName() { + return this.#currentUser.getValue()?.name; + } + + getPermissions() { + return this.#currentUser.getValue()?.permissions; + } + + getUnique() { + return this.#currentUser.getValue()?.unique; + } + + getUserName() { + return this.#currentUser.getValue()?.userName; + } + #observeIsAuthorized() { if (!this.#authContext) return; this.observe(this.#authContext.isAuthorized, (isAuthorized) => { From e8ae4c931ce6478e50b11d84105a9f03c4f3d74a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 22 Oct 2024 09:35:26 +0200 Subject: [PATCH 046/170] add jsdocs --- .../user/current-user/current-user.context.ts | 101 +++++++++++++++--- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/src/packages/user/current-user/current-user.context.ts b/src/packages/user/current-user/current-user.context.ts index 4a18f94086..d31467cce3 100644 --- a/src/packages/user/current-user/current-user.context.ts +++ b/src/packages/user/current-user/current-user.context.ts @@ -11,6 +11,7 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr import { UMB_SECTION_PATH_PATTERN } from '@umbraco-cms/backoffice/section'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; import { ensurePathEndsWithSlash } from '@umbraco-cms/backoffice/utils'; +import type { UmbReferenceByUnique } from '@umbraco-cms/backoffice/models'; export class UmbCurrentUserContext extends UmbContextBase { #currentUser = new UmbObjectState(undefined); @@ -83,71 +84,139 @@ export class UmbCurrentUserContext extends UmbContextBase return currentUser?.isAdmin ?? false; } - getAllowedSection() { + /** + * Get the allowed sections for the current user + * @returns {Array | undefined} The allowed sections for the current user + */ + getAllowedSection(): Array | undefined { return this.#currentUser.getValue()?.allowedSections; } - getAvatarUrls() { + /** + * Get the avatar urls for the current user + * @returns {Array | undefined} The avatar urls for the current user + */ + getAvatarUrls(): Array | undefined { return this.#currentUser.getValue()?.avatarUrls; } - getDocumentStartNodeUniques() { + /** + * Get the document start node uniques for the current user + * @returns {Array | undefined} The document start node uniques for the current user + */ + getDocumentStartNodeUniques(): Array | undefined { return this.#currentUser.getValue()?.documentStartNodeUniques; } - getEmail() { + /** + * Get the email for the current user + * @returns {string | undefined} The email for the current user + */ + getEmail(): string | undefined { return this.#currentUser.getValue()?.email; } - getFallbackPermissions() { + /** + * Get the fallback permissions for the current user + * @returns {Array | undefined} The fallback permissions for the current user + */ + getFallbackPermissions(): Array | undefined { return this.#currentUser.getValue()?.fallbackPermissions; } - getHasAccessToAllLanguages() { + /** + * Get if the current user has access to all languages + * @returns {boolean | undefined} True if the current user has access to all languages, otherwise false + */ + getHasAccessToAllLanguages(): boolean | undefined { return this.#currentUser.getValue()?.hasAccessToAllLanguages; } - getHasAccessToSensitiveData() { + /** + * Get if the current user has access to sensitive data + * @returns {boolean | undefined} True if the current user has access to sensitive data, otherwise false + */ + getHasAccessToSensitiveData(): boolean | undefined { return this.#currentUser.getValue()?.hasAccessToSensitiveData; } - getHasDocumentRootAccess() { + /** + * Get if the current user has document root access + * @returns {boolean | undefined} True if the current user has document root access, otherwise false + */ + getHasDocumentRootAccess(): boolean | undefined { return this.#currentUser.getValue()?.hasDocumentRootAccess; } - getHasMediaRootAccess() { + /** + * Get if the current user has media root access + * @returns {boolean | undefined} True if the current user has media root access, otherwise false + */ + getHasMediaRootAccess(): boolean | undefined { return this.#currentUser.getValue()?.hasMediaRootAccess; } - getIsAdmin() { + /** + * Get if the current user is an admin + * @returns {boolean | undefined} True if the current user is an admin, otherwise false + */ + getIsAdmin(): boolean | undefined { return this.#currentUser.getValue()?.isAdmin; } - getLanguageIsoCode() { + /** + * Get the language iso code for the current user + * @returns {string | undefined} The language iso code for the current user + */ + getLanguageIsoCode(): string | undefined { return this.#currentUser.getValue()?.languageIsoCode; } - getLanguages() { + /** + * Get the languages for the current user + * @returns {Array | undefined} The languages for the current user + */ + getLanguages(): Array | undefined { return this.#currentUser.getValue()?.languages; } - getMediaStartNodeUniques() { + /** + * Get the media start node uniques for the current user + * @returns {Array | undefined} The media start node uniques for the current user + */ + getMediaStartNodeUniques(): Array | undefined { return this.#currentUser.getValue()?.mediaStartNodeUniques; } - getName() { + /** + * Get the name for the current user + * @returns {string | undefined} The name for the current user + */ + getName(): string | undefined { return this.#currentUser.getValue()?.name; } + /** + * Get the permissions for the current user + * @returns {Array | undefined} The permissions for the current user + */ getPermissions() { return this.#currentUser.getValue()?.permissions; } - getUnique() { + /** + * Get the unique for the current user + * @returns {string | undefined} The unique for the current user + */ + getUnique(): string | undefined { return this.#currentUser.getValue()?.unique; } - getUserName() { + /** + * Get the user name for the current user + * @returns {string | undefined} The user name for the current user + */ + getUserName(): string | undefined { return this.#currentUser.getValue()?.userName; } From e881d08645d9c74ddb86b2ab3479df6947c4a197 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 22 Oct 2024 10:07:28 +0200 Subject: [PATCH 047/170] disable readonly languages when unpublishing --- .../entity-actions/unpublish.action.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/packages/documents/documents/entity-actions/unpublish.action.ts b/src/packages/documents/documents/entity-actions/unpublish.action.ts index ff9d645a17..d0f47c9878 100644 --- a/src/packages/documents/documents/entity-actions/unpublish.action.ts +++ b/src/packages/documents/documents/entity-actions/unpublish.action.ts @@ -11,6 +11,7 @@ import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase { constructor(host: UmbControllerHost, args: UmbEntityActionArgs) { @@ -28,8 +29,16 @@ export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase if (!documentData) throw new Error('The document was not found'); - const context = await this.getContext(UMB_APP_LANGUAGE_CONTEXT); - const appCulture = context.getAppCulture(); + const appLanguageContext = await this.getContext(UMB_APP_LANGUAGE_CONTEXT); + const appCulture = appLanguageContext.getAppCulture(); + + const currentUserContext = await this.getContext(UMB_CURRENT_USER_CONTEXT); + const currentUserAllowedLanguages = currentUserContext.getLanguages(); + const currentUserHasAccessToAllLanguages = currentUserContext.getHasAccessToAllLanguages(); + + if (currentUserAllowedLanguages === undefined) throw new Error('The current user languages are missing'); + if (currentUserHasAccessToAllLanguages === undefined) + throw new Error('The current user access to all languages is missing'); const options: Array = documentData.variants.map( (variant) => ({ @@ -65,6 +74,11 @@ export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase data: { documentUnique: this.args.unique, options, + pickableFilter: (option) => { + if (!option.culture) return false; + if (currentUserHasAccessToAllLanguages) return true; + return currentUserAllowedLanguages.includes(option.culture); + }, }, value: { selection }, }) @@ -89,4 +103,5 @@ export class UmbUnpublishDocumentEntityAction extends UmbEntityActionBase } } } + export default UmbUnpublishDocumentEntityAction; From 22935de139699442873aeb8d210446ae360c4269 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 22 Oct 2024 10:10:21 +0200 Subject: [PATCH 048/170] disable readonly languages when publishing --- .../documents/entity-actions/publish.action.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/packages/documents/documents/entity-actions/publish.action.ts b/src/packages/documents/documents/entity-actions/publish.action.ts index 1175fd3361..845f47e73d 100644 --- a/src/packages/documents/documents/entity-actions/publish.action.ts +++ b/src/packages/documents/documents/entity-actions/publish.action.ts @@ -8,6 +8,7 @@ import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; export class UmbPublishDocumentEntityAction extends UmbEntityActionBase { constructor(host: UmbControllerHost, args: UmbEntityActionArgs) { @@ -25,8 +26,16 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase { if (!documentData) throw new Error('The document was not found'); - const context = await this.getContext(UMB_APP_LANGUAGE_CONTEXT); - const appCulture = context.getAppCulture(); + const appLanguageContext = await this.getContext(UMB_APP_LANGUAGE_CONTEXT); + const appCulture = appLanguageContext.getAppCulture(); + + const currentUserContext = await this.getContext(UMB_CURRENT_USER_CONTEXT); + const currentUserAllowedLanguages = currentUserContext.getLanguages(); + const currentUserHasAccessToAllLanguages = currentUserContext.getHasAccessToAllLanguages(); + + if (currentUserAllowedLanguages === undefined) throw new Error('The current user languages are missing'); + if (currentUserHasAccessToAllLanguages === undefined) + throw new Error('The current user access to all languages is missing'); const options: Array = documentData.variants.map( (variant) => ({ @@ -76,6 +85,11 @@ export class UmbPublishDocumentEntityAction extends UmbEntityActionBase { .open(this, UMB_DOCUMENT_PUBLISH_MODAL, { data: { options, + pickableFilter: (option) => { + if (!option.culture) return false; + if (currentUserHasAccessToAllLanguages) return true; + return currentUserAllowedLanguages.includes(option.culture); + }, }, value: { selection }, }) From 5f4b3cabba18ff88da95f1c95644d013187b9b5a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 13:10:33 +0200 Subject: [PATCH 049/170] rename and deprecate the old name --- .../entity-detail/entity-detail-workspace-base.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index b6825550db..f172be2c3b 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -13,12 +13,17 @@ import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-ap import { umbExtensionsRegistry, type ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; -export interface UmbEntityWorkspaceContextArgs { +export interface UmbEntityDetailWorkspaceContextArgs { entityType: string; workspaceAlias: string; detailRepositoryAlias: string; } +/** + * @deprecated Use UmbEntityDetailWorkspaceContextArgs instead + */ +export type UmbEntityWorkspaceContextArgs = UmbEntityDetailWorkspaceContextArgs; + export interface UmbEntityDetailWorkspaceContextCreateArgs { parent: UmbEntityModel; preset?: Partial; From c3edc5bdcd77b3514fb6e7756083db9707256ab2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 13:22:41 +0200 Subject: [PATCH 050/170] add content detail context class scaffold --- .../content-detail-workspace-base.ts | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/packages/core/content/workspace/content-detail-workspace-base.ts diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts new file mode 100644 index 0000000000..a882005873 --- /dev/null +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -0,0 +1,27 @@ +import type { UmbContentDetailModel } from '../types.js'; +import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; +import { + UmbEntityDetailWorkspaceContextBase, + type UmbEntityDetailWorkspaceContextArgs, + type UmbEntityDetailWorkspaceContextCreateArgs, +} from '@umbraco-cms/backoffice/workspace'; +import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; +import type { UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; + +export abstract class UmbContentDetailWorkspaceBase< + DetailModelType extends UmbContentDetailModel, + DetailRepositoryType extends UmbDetailRepository = UmbDetailRepository, + ContentTypeDetailModel extends UmbContentTypeModel = UmbContentTypeModel, + VariantModelType extends UmbEntityVariantModel = UmbEntityVariantModel, + CreateArgsType extends + UmbEntityDetailWorkspaceContextCreateArgs = UmbEntityDetailWorkspaceContextCreateArgs, + > + extends UmbEntityDetailWorkspaceContextBase + implements UmbContentWorkspaceContext +{ + constructor(host: UmbControllerHost, args: UmbEntityDetailWorkspaceContextArgs) { + super(host, args); + } +} From fa8c1b91c4e38e6bf4ef8cb135955595d1ede792 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 14:19:43 +0200 Subject: [PATCH 051/170] wip move common logic to content workspace context base --- .../content-detail-workspace-base.ts | 309 ++++++++++++++- src/packages/core/content/workspace/index.ts | 3 +- .../workspace/document-workspace.context.ts | 355 ++---------------- 3 files changed, 330 insertions(+), 337 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index a882005873..b8dd760b82 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -1,14 +1,31 @@ import type { UmbContentDetailModel } from '../types.js'; +import { UmbContentWorkspaceDataManager } from '../manager/index.js'; import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; import { UmbEntityDetailWorkspaceContextBase, + UmbWorkspaceSplitViewManager, type UmbEntityDetailWorkspaceContextArgs, type UmbEntityDetailWorkspaceContextCreateArgs, } from '@umbraco-cms/backoffice/workspace'; -import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; -import type { UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; +import { UmbContentTypeStructureManager, type UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; +import { UMB_INVARIANT_CULTURE, UmbVariantId, type UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; +import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; +import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; +import { appendToFrozenArray, mergeObservables, UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbLanguageCollectionRepository, type UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; +import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; +import { firstValueFrom, map } from '@umbraco-cms/backoffice/external/rxjs'; +import { + UmbValidationContext, + UmbVariantsValidationPathTranslator, + UmbVariantValuesValidationPathTranslator, +} from '@umbraco-cms/backoffice/validation'; + +export interface UmbContentDetailWorkspaceContextArgs extends UmbEntityDetailWorkspaceContextArgs { + contentTypeDetailRepository: UmbDetailRepository; +} export abstract class UmbContentDetailWorkspaceBase< DetailModelType extends UmbContentDetailModel, @@ -21,7 +38,293 @@ export abstract class UmbContentDetailWorkspaceBase< extends UmbEntityDetailWorkspaceContextBase implements UmbContentWorkspaceContext { - constructor(host: UmbControllerHost, args: UmbEntityDetailWorkspaceContextArgs) { + public readonly IS_CONTENT_WORKSPACE_CONTEXT = true as const; + + protected override readonly _data = new UmbContentWorkspaceDataManager( + this, + UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, + ); + + public readonly readOnlyState = new UmbReadOnlyVariantStateManager(this); + + /* Content Data */ + public readonly values = this._data.createObservablePartOfCurrent((data) => data?.values); + public readonly variants = this._data.createObservablePartOfCurrent((data) => data?.variants ?? []); + + /* Content Type (Structure) Data */ + public readonly structure: UmbContentTypeStructureManager; + + public readonly variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); + public readonly variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); + public readonly varies = this.structure.ownerContentTypeObservablePart((x) => + x ? x.variesByCulture || x.variesBySegment : undefined, + ); + + /* Data Type */ + readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); + #dataTypeSchemaAliasMap = new Map(); + + #varies?: boolean; + #variesByCulture?: boolean; + #variesBySegment?: boolean; + + /* Split View */ + readonly splitView = new UmbWorkspaceSplitViewManager(); + + /* Variant Options */ + // TODO: Optimize this so it uses either a App Language Context? [NL] + #languageRepository = new UmbLanguageCollectionRepository(this); + #languages = new UmbArrayState([], (x) => x.unique); + /** + * @private + * @description - Should not be used by external code. + */ + public readonly languages = this.#languages.asObservable(); + + readonly variantOptions = mergeObservables( + [this.varies, this.variants, this.languages], + ([varies, variants, languages]) => { + // TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL] + if (varies === true) { + return languages.map((language) => { + return { + variant: variants.find((x) => x.culture === language.unique), + language, + // TODO: When including segments, this object should be updated to include a object for the segment. [NL] + // TODO: When including segments, the unique should be updated to include the segment as well. [NL] + unique: language.unique, // This must be a variantId string! + culture: language.unique, + segment: null, + } as UmbDocumentVariantOptionModel; + }); + } else if (varies === false) { + return [ + { + variant: variants.find((x) => x.culture === null), + language: languages.find((x) => x.isDefault), + culture: null, + segment: null, + unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! + } as UmbDocumentVariantOptionModel, + ]; + } + return [] as Array; + }, + ).pipe(map((results) => results.sort(sortVariants))); + + constructor(host: UmbControllerHost, args: UmbContentDetailWorkspaceContextArgs) { super(host, args); + + const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); + this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); + + this.addValidationContext(new UmbValidationContext(this)); + new UmbVariantValuesValidationPathTranslator(this); + new UmbVariantsValidationPathTranslator(this); + + this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); + + this.observe( + this.varies, + (varies) => { + this._data.setVaries(varies); + this.#varies = varies; + }, + null, + ); + this.observe( + this.variesByCulture, + (varies) => { + this._data.setVariesByCulture(varies); + this.#variesByCulture = varies; + }, + null, + ); + this.observe( + this.variesBySegment, + (varies) => { + this._data.setVariesBySegment(varies); + this.#variesBySegment = varies; + }, + null, + ); + this.observe( + this.structure.contentTypeDataTypeUniques, + (dataTypeUniques: Array) => { + this.#dataTypeItemManager.setUniques(dataTypeUniques); + }, + null, + ); + this.observe( + this.#dataTypeItemManager.items, + (dataTypes) => { + // Make a map of the data type unique and editorAlias: + this.#dataTypeSchemaAliasMap = new Map( + dataTypes.map((dataType) => { + return [dataType.unique, dataType.propertyEditorSchemaAlias]; + }), + ); + }, + null, + ); + + this.loadLanguages(); + } + + async loadLanguages() { + // TODO: If we don't end up having a Global Context for languages, then we should at least change this into using a asObservable which should be returned from the repository. [Nl] + const { data } = await this.#languageRepository.requestCollection({}); + this.#languages.setValue(data?.items ?? []); + } + + getName(variantId?: UmbVariantId) { + const variants = this._data.getCurrent()?.variants; + if (!variants) return; + if (variantId) { + return variants.find((x) => variantId.compare(x))?.name; + } else { + return variants[0]?.name; + } + } + + setName(name: string, variantId?: UmbVariantId) { + this._data.updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name }); + } + + name(variantId?: UmbVariantId) { + return this._data.createObservablePartOfCurrent( + (data) => data?.variants?.find((x) => variantId?.compare(x))?.name ?? '', + ); + } + + /* Variants */ + + getVariesByCulture() { + return this.#variesByCulture; + } + + getVariesBySegment() { + return this.#variesBySegment; + } + + getVaries() { + return this.#varies; + } + + variantById(variantId: UmbVariantId) { + return this._data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); + } + + getVariant(variantId: UmbVariantId) { + return this._data.getCurrent()?.variants?.find((x) => variantId.compare(x)); + } + + async propertyStructureById(propertyId: string) { + return this.structure.propertyStructureById(propertyId); + } + + /* Values */ + + getValues() { + return this._data.getCurrent()?.values; + } + + /** + * @function propertyValueByAlias + * @param {string} propertyAlias - The alias of the property + * @param {UmbVariantId} variantId - The variant + * @returns {Promise | undefined>} - An observable for the value of the property + * @description Get an Observable for the value of this property. + */ + async propertyValueByAlias( + propertyAlias: string, + variantId?: UmbVariantId, + ): Promise | undefined> { + return this._data.createObservablePartOfCurrent( + (data) => + data?.values?.find((x) => x?.alias === propertyAlias && (variantId ? variantId.compare(x) : true)) + ?.value as PropertyValueType, + ); + } + + /** + * Get the current value of the property with the given alias and variantId. + * @param {string} alias - The alias of the property + * @param {UmbVariantId | undefined} variantId - The variant id of the property + * @returns {ReturnType | undefined} The value or undefined if not set or found. + */ + getPropertyValue(alias: string, variantId?: UmbVariantId) { + const currentData = this._data.getCurrent(); + if (currentData) { + const newDataSet = currentData.values?.find( + (x) => x.alias === alias && (variantId ? variantId.compare(x) : true), + ); + return newDataSet?.value as ReturnType; + } + return undefined; + } + + async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { + this.initiatePropertyValueChange(); + variantId ??= UmbVariantId.CreateInvariant(); + const property = await this.structure.getPropertyStructureByAlias(alias); + + if (!property) { + throw new Error(`Property alias "${alias}" not found.`); + } + + const editorAlias = this.#dataTypeSchemaAliasMap.get(property.dataType.unique); + if (!editorAlias) { + throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`); + } + + const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbDocumentValueModel; + + const currentData = this.getData(); + if (currentData) { + const values = appendToFrozenArray( + currentData.values ?? [], + entry, + (x) => x.alias === alias && variantId!.compare(x), + ); + this._data.updateCurrent({ values }); + + // TODO: We should move this type of logic to the act of saving [NL] + this._data.ensureVariantData(variantId); + } + this.finishPropertyValueChange(); + } + + initiatePropertyValueChange() { + this._data.initiatePropertyValueChange(); + } + + finishPropertyValueChange = () => { + this._data.finishPropertyValueChange(); + }; + + protected async _determineVariantOptions() { + const options = await firstValueFrom(this.variantOptions); + + const activeVariants = this.splitView.getActiveVariants(); + const activeVariantIds = activeVariants.map((activeVariant) => UmbVariantId.Create(activeVariant)); + const changedVariantIds = this._data.getChangedVariants(); + const selectedVariantIds = activeVariantIds.concat(changedVariantIds); + + // Selected can contain entries that are not part of the options, therefor the modal filters selection based on options. + const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture); + let selected = selectedVariantIds.map((x) => x.toString()).filter((v, i, a) => a.indexOf(v) === i); + selected = selected.filter((x) => readOnlyCultures.includes(x) === false); + + return { + options, + selected, + }; + } + + public override destroy(): void { + this.structure.destroy(); + this.#languageRepository.destroy(); + super.destroy(); } } diff --git a/src/packages/core/content/workspace/index.ts b/src/packages/core/content/workspace/index.ts index 4c72bcced7..2d6e425ec3 100644 --- a/src/packages/core/content/workspace/index.ts +++ b/src/packages/core/content/workspace/index.ts @@ -1,3 +1,4 @@ -export type * from './content-workspace-context.interface.js'; +export * from './content-detail-workspace-base.js'; export * from './content-workspace.context-token.js'; export * from './views/edit/index.js'; +export type * from './content-workspace-context.interface.js'; diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index ab6dfeb43b..945583c931 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -1,7 +1,7 @@ import { UmbDocumentTypeDetailRepository } from '../../document-types/repository/detail/document-type-detail.repository.js'; import { UmbDocumentPropertyDatasetContext } from '../property-dataset-context/document-property-dataset-context.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; -import { UmbDocumentDetailRepository } from '../repository/index.js'; +import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, UmbDocumentDetailRepository } from '../repository/index.js'; import type { UmbDocumentVariantPublishModel, UmbDocumentDetailModel, @@ -65,6 +65,7 @@ import { import { UmbDocumentBlueprintDetailRepository } from '@umbraco-cms/backoffice/document-blueprint'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import { + UmbContentDetailWorkspaceBase, UmbContentWorkspaceDataManager, UmbMergeContentVariantDataController, type UmbContentCollectionWorkspaceContext, @@ -81,166 +82,34 @@ type EntityModel = UmbDocumentDetailModel; type EntityTypeModel = UmbDocumentTypeDetailModel; export class UmbDocumentWorkspaceContext - extends UmbSubmittableWorkspaceContextBase + extends UmbContentDetailWorkspaceBase implements UmbContentWorkspaceContext, UmbPublishableWorkspaceContext, UmbContentCollectionWorkspaceContext { - public readonly IS_CONTENT_WORKSPACE_CONTEXT = true as const; - - public readonly repository = new UmbDocumentDetailRepository(this); public readonly publishingRepository = new UmbDocumentPublishingRepository(this); - #parent = new UmbObjectState(undefined); - readonly parentUnique = this.#parent.asObservablePart((parent) => (parent ? parent.unique : undefined)); - readonly parentEntityType = this.#parent.asObservablePart((parent) => (parent ? parent.entityType : undefined)); - - readonly #data = new UmbContentWorkspaceDataManager(this, UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD); - #getDataPromise?: Promise>; - - // TODo: Optimize this so it uses either a App Language Context? [NL] - #languageRepository = new UmbLanguageCollectionRepository(this); - #languages = new UmbArrayState([], (x) => x.unique); - /** - * @private - * @description - Should not be used by external code. - */ - public readonly languages = this.#languages.asObservable(); - #serverValidation = new UmbServerModelValidatorContext(this); #validationRepository?: UmbDocumentValidationRepository; - public readonly readOnlyState = new UmbReadOnlyVariantStateManager(this); - - public isLoaded() { - return this.#getDataPromise; - } - - readonly data = this.#data.current; - readonly unique = this.#data.createObservablePartOfCurrent((data) => data?.unique); - readonly entityType = this.#data.createObservablePartOfCurrent((data) => data?.entityType); - readonly isTrashed = this.#data.createObservablePartOfCurrent((data) => data?.isTrashed); - readonly values = this.#data.createObservablePartOfCurrent((data) => data?.values); - getValues() { - return this.#data.getCurrent()?.values; - } - - readonly contentTypeUnique = this.#data.createObservablePartOfCurrent((data) => data?.documentType.unique); - readonly contentTypeHasCollection = this.#data.createObservablePartOfCurrent( + readonly isTrashed = this._data.createObservablePartOfCurrent((data) => data?.isTrashed); + readonly contentTypeUnique = this._data.createObservablePartOfCurrent((data) => data?.documentType.unique); + readonly contentTypeHasCollection = this._data.createObservablePartOfCurrent( (data) => !!data?.documentType.collection, ); + readonly urls = this._data.createObservablePartOfCurrent((data) => data?.urls || []); + readonly templateId = this._data.createObservablePartOfCurrent((data) => data?.template?.unique || null); - readonly variants = this.#data.createObservablePartOfCurrent((data) => data?.variants ?? []); - - readonly structure = new UmbContentTypeStructureManager(this, new UmbDocumentTypeDetailRepository(this)); - readonly variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); - readonly variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); - readonly varies = this.structure.ownerContentTypeObservablePart((x) => - x ? x.variesByCulture || x.variesBySegment : undefined, - ); - #varies?: boolean; - #variesByCulture?: boolean; - #variesBySegment?: boolean; - - readonly urls = this.#data.createObservablePartOfCurrent((data) => data?.urls || []); - readonly templateId = this.#data.createObservablePartOfCurrent((data) => data?.template?.unique || null); - - readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); - #dataTypeSchemaAliasMap = new Map(); - - readonly splitView = new UmbWorkspaceSplitViewManager(); - - readonly variantOptions = mergeObservables( - [this.varies, this.variants, this.languages], - ([varies, variants, languages]) => { - // TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL] - if (varies === true) { - return languages.map((language) => { - return { - variant: variants.find((x) => x.culture === language.unique), - language, - // TODO: When including segments, this object should be updated to include a object for the segment. [NL] - // TODO: When including segments, the unique should be updated to include the segment as well. [NL] - unique: language.unique, // This must be a variantId string! - culture: language.unique, - segment: null, - } as UmbDocumentVariantOptionModel; - }); - } else if (varies === false) { - return [ - { - variant: variants.find((x) => x.culture === null), - language: languages.find((x) => x.isDefault), - culture: null, - segment: null, - unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! - } as UmbDocumentVariantOptionModel, - ]; - } - return [] as Array; - }, - ).pipe(map((results) => results.sort(sortVariants))); - - // TODO: this should be set up for all entity workspace contexts in a base class - #entityContext = new UmbEntityContext(this); - // TODO: this might not be the correct place to spin this up #isTrashedContext = new UmbIsTrashedEntityContext(this); constructor(host: UmbControllerHost) { - super(host, UMB_DOCUMENT_WORKSPACE_ALIAS); - - this.addValidationContext(new UmbValidationContext(this)); - - new UmbVariantValuesValidationPathTranslator(this); - new UmbVariantsValidationPathTranslator(this); - - this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); - this.observe( - this.varies, - (varies) => { - this.#data.setVaries(varies); - this.#varies = varies; - }, - null, - ); - this.observe( - this.variesByCulture, - (varies) => { - this.#data.setVariesByCulture(varies); - this.#variesByCulture = varies; - }, - null, - ); - this.observe( - this.variesBySegment, - (varies) => { - this.#data.setVariesBySegment(varies); - this.#variesBySegment = varies; - }, - null, - ); - this.observe( - this.structure.contentTypeDataTypeUniques, - (dataTypeUniques: Array) => { - this.#dataTypeItemManager.setUniques(dataTypeUniques); - }, - null, - ); - this.observe( - this.#dataTypeItemManager.items, - (dataTypes) => { - // Make a map of the data type unique and editorAlias: - this.#dataTypeSchemaAliasMap = new Map( - dataTypes.map((dataType) => { - return [dataType.unique, dataType.propertyEditorSchemaAlias]; - }), - ); - }, - null, - ); - - this.loadLanguages(); + super(host, { + entityType: UMB_DOCUMENT_ENTITY_TYPE, + workspaceAlias: UMB_DOCUMENT_WORKSPACE_ALIAS, + detailRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, + contentTypeDetailRepository: UmbDocumentTypeDetailRepository, + }); this.routes.setRoutes([ { @@ -291,40 +160,17 @@ export class UmbDocumentWorkspaceContext override resetState() { super.resetState(); - this.#data.clear(); this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); } - async loadLanguages() { - // TODO: If we don't end up having a Global Context for languages, then we should at least change this into using a asObservable which should be returned from the repository. [Nl] - const { data } = await this.#languageRepository.requestCollection({}); - this.#languages.setValue(data?.items ?? []); - } - - async load(unique: string) { - this.resetState(); - this.#getDataPromise = this.repository.requestByUnique(unique); - - type GetDataType = Awaited>; - const { data, asObservable } = (await this.#getDataPromise) as GetDataType; + override async load(unique: string) { + const response = await super.load(unique); - if (data) { - this.#entityContext.setEntityType(UMB_DOCUMENT_ENTITY_TYPE); - this.#entityContext.setUnique(unique); - this.#isTrashedContext.setIsTrashed(data.isTrashed); - this.setIsNew(false); - this.#data.setPersisted(data); - this.#data.setCurrent(data); + if (response.data) { + this.#isTrashedContext.setIsTrashed(response.data.isTrashed); } - this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbDocumentStoreObserver'); - } - - #onStoreChange(entity: EntityModel | undefined) { - if (!entity) { - //TODO: This solution is alright for now. But reconsider when we introduce signal-r - history.pushState(null, '', UMB_DOCUMENTS_SECTION_PATH); - } + return response; } async create(parent: UmbEntityModel, documentTypeUnique: string, blueprintUnique?: string) { @@ -365,159 +211,14 @@ export class UmbDocumentWorkspaceContext return UMB_DOCUMENT_COLLECTION_ALIAS; } - getData() { - return this.#data.getCurrent(); - } - - getUnique() { - return this.getData()?.unique; - } - - getEntityType() { - return UMB_DOCUMENT_ENTITY_TYPE; - } - getContentTypeId() { return this.getData()?.documentType.unique; } - getVaries() { - return this.#varies; - } - getVariesByCulture() { - return this.#variesByCulture; - } - getVariesBySegment() { - return this.#variesBySegment; - } - - variantById(variantId: UmbVariantId) { - return this.#data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); - } - - getVariant(variantId: UmbVariantId) { - return this.#data.getCurrent()?.variants?.find((x) => variantId.compare(x)); - } - - getName(variantId?: UmbVariantId) { - const variants = this.#data.getCurrent()?.variants; - if (!variants) return; - if (variantId) { - return variants.find((x) => variantId.compare(x))?.name; - } else { - return variants[0]?.name; - } - } - - setName(name: string, variantId?: UmbVariantId) { - this.#data.updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name }); - } - - name(variantId?: UmbVariantId) { - return this.#data.createObservablePartOfCurrent( - (data) => data?.variants?.find((x) => variantId?.compare(x))?.name ?? '', - ); - } - setTemplate(templateUnique: string) { this.#data.updateCurrent({ template: { unique: templateUnique } }); } - async propertyStructureById(propertyId: string) { - return this.structure.propertyStructureById(propertyId); - } - - /** - * @function propertyValueByAlias - * @param {string} propertyAlias - The alias of the property - * @param {UmbVariantId} variantId - The variant - * @returns {Promise | undefined>} - An observable for the value of the property - * @description Get an Observable for the value of this property. - */ - async propertyValueByAlias( - propertyAlias: string, - variantId?: UmbVariantId, - ): Promise | undefined> { - return this.#data.createObservablePartOfCurrent( - (data) => - data?.values?.find((x) => x?.alias === propertyAlias && (variantId ? variantId.compare(x) : true)) - ?.value as PropertyValueType, - ); - } - - /** - * Get the current value of the property with the given alias and variantId. - * @param {string} alias - The alias of the property - * @param {UmbVariantId | undefined} variantId - The variant id of the property - * @returns {ReturnType | undefined} The value or undefined if not set or found. - */ - getPropertyValue(alias: string, variantId?: UmbVariantId) { - const currentData = this.#data.getCurrent(); - if (currentData) { - const newDataSet = currentData.values?.find( - (x) => x.alias === alias && (variantId ? variantId.compare(x) : true), - ); - return newDataSet?.value as ReturnType; - } - return undefined; - } - async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { - this.initiatePropertyValueChange(); - variantId ??= UmbVariantId.CreateInvariant(); - const property = await this.structure.getPropertyStructureByAlias(alias); - - if (!property) { - throw new Error(`Property alias "${alias}" not found.`); - } - - const editorAlias = this.#dataTypeSchemaAliasMap.get(property.dataType.unique); - if (!editorAlias) { - throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`); - } - - const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbDocumentValueModel; - - const currentData = this.getData(); - if (currentData) { - const values = appendToFrozenArray( - currentData.values ?? [], - entry, - (x) => x.alias === alias && variantId!.compare(x), - ); - this.#data.updateCurrent({ values }); - - // TODO: We should move this type of logic to the act of saving [NL] - this.#data.ensureVariantData(variantId); - } - this.finishPropertyValueChange(); - } - - initiatePropertyValueChange() { - this.#data.initiatePropertyValueChange(); - } - finishPropertyValueChange = () => { - this.#data.finishPropertyValueChange(); - }; - - async #determineVariantOptions() { - const options = await firstValueFrom(this.variantOptions); - - const activeVariants = this.splitView.getActiveVariants(); - const activeVariantIds = activeVariants.map((activeVariant) => UmbVariantId.Create(activeVariant)); - const changedVariantIds = this.#data.getChangedVariants(); - const selectedVariantIds = activeVariantIds.concat(changedVariantIds); - - // Selected can contain entries that are not part of the options, therefor the modal filters selection based on options. - const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture); - let selected = selectedVariantIds.map((x) => x.toString()).filter((v, i, a) => a.indexOf(v) === i); - selected = selected.filter((x) => readOnlyCultures.includes(x) === false); - - return { - options, - selected, - }; - } - async #performSaveOrCreate(variantIds: Array, saveData: UmbDocumentDetailModel): Promise { if (this.getIsNew()) { // Create: @@ -772,6 +473,7 @@ export class UmbDocumentWorkspaceContext public submit() { return this.#handleSave(); } + public override invalidSubmit() { return this.#handleSave(); } @@ -789,7 +491,7 @@ export class UmbDocumentWorkspaceContext } public async schedule() { - const { options, selected } = await this.#determineVariantOptions(); + const { options, selected } = await this._determineVariantOptions(); const modalManagerContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); const result = await modalManagerContext @@ -832,7 +534,7 @@ export class UmbDocumentWorkspaceContext } public async publishWithDescendants() { - const { options, selected } = await this.#determineVariantOptions(); + const { options, selected } = await this._determineVariantOptions(); const modalManagerContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); const result = await modalManagerContext @@ -864,25 +566,12 @@ export class UmbDocumentWorkspaceContext ); } - async delete() { - const id = this.getUnique(); - if (id) { - await this.repository.delete(id); - } - } - public createPropertyDatasetContext( host: UmbControllerHost, variantId: UmbVariantId, ): UmbDocumentPropertyDatasetContext { return new UmbDocumentPropertyDatasetContext(host, this, variantId); } - - public override destroy(): void { - this.structure.destroy(); - this.#languageRepository.destroy(); - super.destroy(); - } } export default UmbDocumentWorkspaceContext; From 1fb22a0df6ce444902227c6809661e7e7d50df3c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 14:54:30 +0200 Subject: [PATCH 052/170] add methods to get parent data --- .../entity-detail/entity-detail-workspace-base.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index f172be2c3b..174400fe50 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -86,6 +86,18 @@ export abstract class UmbEntityDetailWorkspaceContextBase< return this._data.getCurrent()?.unique; } + getParent() { + return this.#parent.getValue(); + } + + getParentUnique() { + return this.#parent.getValue()?.unique; + } + + getParentEntityType() { + return this.#parent.getValue()?.entityType; + } + async load(unique: string) { await this.#init; this.resetState(); From 6b00ea87e4030b7102860fbc54b01dcc8d6ca62e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 15:12:51 +0200 Subject: [PATCH 053/170] move more logic to content detail workspace base --- .../content-detail-workspace-base.ts | 153 +++++++++++++ .../workspace/document-workspace.context.ts | 208 ++---------------- 2 files changed, 173 insertions(+), 188 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index b8dd760b82..0f801301d0 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -1,5 +1,6 @@ import type { UmbContentDetailModel } from '../types.js'; import { UmbContentWorkspaceDataManager } from '../manager/index.js'; +import { UmbMergeContentVariantDataController } from '../controller/merge-content-variant-data.controller.js'; import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; @@ -18,10 +19,19 @@ import { UmbLanguageCollectionRepository, type UmbLanguageDetailModel } from '@u import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; import { firstValueFrom, map } from '@umbraco-cms/backoffice/external/rxjs'; import { + UMB_VALIDATION_CONTEXT, + UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, + UmbDataPathVariantQuery, UmbValidationContext, UmbVariantsValidationPathTranslator, UmbVariantValuesValidationPathTranslator, } from '@umbraco-cms/backoffice/validation'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { + UmbRequestReloadChildrenOfEntityEvent, + UmbRequestReloadStructureForEntityEvent, +} from '@umbraco-cms/backoffice/entity-action'; export interface UmbContentDetailWorkspaceContextArgs extends UmbEntityDetailWorkspaceContextArgs { contentTypeDetailRepository: UmbDetailRepository; @@ -322,6 +332,149 @@ export abstract class UmbContentDetailWorkspaceBase< }; } + protected _readOnlyLanguageVariantsFilter = (option: UmbDocumentVariantOptionModel) => { + const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture); + return readOnlyCultures.includes(option.culture) === false; + }; + + /* validation */ + protected async _runMandatoryValidationForSaveData(saveData: DetailModelType) { + // Check that the data is valid before we save it. + // Check variants have a name: + const variantsWithoutAName = saveData.variants.filter((x) => !x.name); + if (variantsWithoutAName.length > 0) { + const validationContext = await this.getContext(UMB_VALIDATION_CONTEXT); + variantsWithoutAName.forEach((variant) => { + validationContext.messages.addMessage( + 'client', + `$.variants[${UmbDataPathVariantQuery(variant)}].name`, + UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, + ); + }); + throw new Error('All variants must have a name'); + } + } + + public override requestSubmit() { + return this.#handleSubmit(); + } + + public override submit() { + return this.#handleSubmit(); + } + + public override invalidSubmit() { + return this.#handleSubmit(); + } + + async #handleSubmit() { + const { options, selected } = await this._determineVariantOptions(); + + let variantIds: Array = []; + + // If there is only one variant, we don't need to open the modal. + if (options.length === 0) { + throw new Error('No variants are available'); + } else if (options.length === 1) { + // If only one option we will skip ahead and save the document with the only variant available: + variantIds.push(UmbVariantId.Create(options[0])); + } else { + // If there are multiple variants, we will open the modal to let the user pick which variants to save. + const modalManagerContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + const result = await modalManagerContext + .open(this, UMB_DOCUMENT_SAVE_MODAL, { + data: { + options, + pickableFilter: this._readOnlyLanguageVariantsFilter, + }, + value: { selection: selected }, + }) + .onSubmit() + .catch(() => undefined); + + if (!result?.selection.length) return; + + variantIds = result?.selection.map((x) => UmbVariantId.FromString(x)) ?? []; + } + + const saveData = await this._data.constructData(variantIds); + await this._runMandatoryValidationForSaveData(saveData); + await this._performCreateOrUpdate(variantIds, saveData); + } + + protected async _performCreateOrUpdate(variantIds: Array, saveData: DetailModelType) { + if (this.getIsNew()) { + await this.#create(variantIds, saveData); + } else { + await this.#update(variantIds, saveData); + } + } + + async #create(variantIds: Array, saveData: DetailModelType) { + if (!this._detailRepository) throw new Error('Detail repository is not set'); + + const parent = this.getParent(); + if (!parent) throw new Error('Parent is not set'); + + const { data, error } = await this._detailRepository.create(saveData, parent.unique); + if (!data || error) { + throw new Error('Error creating document'); + } + + this.setIsNew(false); + this._data.setPersisted(data); + // TODO: Only update the variants that was chosen to be saved: + const currentData = this._data.getCurrent(); + + const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; + + const newCurrentData = await new UmbMergeContentVariantDataController(this).process( + currentData, + data, + variantIds, + variantIdsIncludingInvariant, + ); + this._data.setCurrent(newCurrentData); + + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + const event = new UmbRequestReloadChildrenOfEntityEvent({ + entityType: parent.entityType, + unique: parent.unique, + }); + eventContext.dispatchEvent(event); + } + + async #update(variantIds: Array, saveData: DetailModelType) { + if (!this._detailRepository) throw new Error('Detail repository is not set'); + + const { data, error } = await this._detailRepository.save(saveData); + if (!data || error) { + throw new Error('Error saving document'); + } + + this._data.setPersisted(data); + // TODO: Only update the variants that was chosen to be saved: + const currentData = this._data.getCurrent(); + + const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; + + const newCurrentData = await new UmbMergeContentVariantDataController(this).process( + currentData, + data, + variantIds, + variantIdsIncludingInvariant, + ); + this._data.setCurrent(newCurrentData); + + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + const event = new UmbRequestReloadStructureForEntityEvent({ + entityType: this.getEntityType(), + unique: this.getUnique()!, + }); + + eventContext.dispatchEvent(event); + } + public override destroy(): void { this.structure.destroy(); this.#languageRepository.destroy(); diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 945583c931..40395ed504 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -1,19 +1,12 @@ import { UmbDocumentTypeDetailRepository } from '../../document-types/repository/detail/document-type-detail.repository.js'; import { UmbDocumentPropertyDatasetContext } from '../property-dataset-context/document-property-dataset-context.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; -import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, UmbDocumentDetailRepository } from '../repository/index.js'; -import type { - UmbDocumentVariantPublishModel, - UmbDocumentDetailModel, - UmbDocumentValueModel, - UmbDocumentVariantModel, - UmbDocumentVariantOptionModel, -} from '../types.js'; +import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; +import type { UmbDocumentVariantPublishModel, UmbDocumentDetailModel, UmbDocumentVariantModel } from '../types.js'; import { UMB_DOCUMENT_PUBLISH_MODAL, UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL, UMB_DOCUMENT_SCHEDULE_MODAL, - UMB_DOCUMENT_SAVE_MODAL, } from '../modals/index.js'; import { UmbDocumentPublishingRepository } from '../repository/publishing/index.js'; import { UmbUnpublishDocumentEntityAction } from '../entity-actions/unpublish.action.js'; @@ -23,59 +16,30 @@ import { UMB_CREATE_FROM_BLUEPRINT_DOCUMENT_WORKSPACE_PATH_PATTERN, UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN, } from '../paths.js'; -import { UMB_DOCUMENTS_SECTION_PATH } from '../../section/paths.js'; import { UmbDocumentPreviewRepository } from '../repository/preview/index.js'; -import { sortVariants } from '../utils.js'; import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../collection/index.js'; -import { UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, UMB_DOCUMENT_WORKSPACE_ALIAS } from './constants.js'; -import { UmbEntityContext, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import { UMB_DOCUMENT_WORKSPACE_ALIAS } from './constants.js'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import { UMB_INVARIANT_CULTURE, UmbVariantId } from '@umbraco-cms/backoffice/variant'; -import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type'; import { type UmbPublishableWorkspaceContext, - UmbSubmittableWorkspaceContextBase, UmbWorkspaceIsNewRedirectController, - UmbWorkspaceSplitViewManager, UmbWorkspaceIsNewRedirectControllerAlias, } from '@umbraco-cms/backoffice/workspace'; -import { - appendToFrozenArray, - mergeObservables, - UmbArrayState, - UmbObjectState, -} from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbLanguageCollectionRepository, type UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; -import { type Observable, firstValueFrom, map } from '@umbraco-cms/backoffice/external/rxjs'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { - UmbRequestReloadChildrenOfEntityEvent, - UmbRequestReloadStructureForEntityEvent, -} from '@umbraco-cms/backoffice/entity-action'; +import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; -import { - UMB_VALIDATION_CONTEXT, - UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, - UmbDataPathVariantQuery, - UmbServerModelValidatorContext, - UmbValidationContext, - UmbVariantValuesValidationPathTranslator, - UmbVariantsValidationPathTranslator, -} from '@umbraco-cms/backoffice/validation'; +import { UmbServerModelValidatorContext } from '@umbraco-cms/backoffice/validation'; import { UmbDocumentBlueprintDetailRepository } from '@umbraco-cms/backoffice/document-blueprint'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import { UmbContentDetailWorkspaceBase, - UmbContentWorkspaceDataManager, - UmbMergeContentVariantDataController, type UmbContentCollectionWorkspaceContext, type UmbContentWorkspaceContext, } from '@umbraco-cms/backoffice/content'; import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/document-type'; import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin'; -import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; -import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; -import type { UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; type EntityModel = UmbDocumentDetailModel; @@ -216,77 +180,9 @@ export class UmbDocumentWorkspaceContext } setTemplate(templateUnique: string) { - this.#data.updateCurrent({ template: { unique: templateUnique } }); + this._data.updateCurrent({ template: { unique: templateUnique } }); } - async #performSaveOrCreate(variantIds: Array, saveData: UmbDocumentDetailModel): Promise { - if (this.getIsNew()) { - // Create: - const parent = this.#parent.getValue(); - if (!parent) throw new Error('Parent is not set'); - - const { data, error } = await this.repository.create(saveData, parent.unique); - if (!data || error) { - throw new Error('Error creating document'); - } - - this.setIsNew(false); - this.#data.setPersisted(data); - // TODO: Only update the variants that was chosen to be saved: - const currentData = this.#data.getCurrent(); - - const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; - - const newCurrentData = await new UmbMergeContentVariantDataController(this).process( - currentData, - data, - variantIds, - variantIdsIncludingInvariant, - ); - this.#data.setCurrent(newCurrentData); - - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadChildrenOfEntityEvent({ - entityType: parent.entityType, - unique: parent.unique, - }); - eventContext.dispatchEvent(event); - } else { - // Save: - const { data, error } = await this.repository.save(saveData); - if (!data || error) { - throw new Error('Error saving document'); - } - - this.#data.setPersisted(data); - // TODO: Only update the variants that was chosen to be saved: - const currentData = this.#data.getCurrent(); - - const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; - - const newCurrentData = await new UmbMergeContentVariantDataController(this).process( - currentData, - data, - variantIds, - variantIdsIncludingInvariant, - ); - this.#data.setCurrent(newCurrentData); - - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadStructureForEntityEvent({ - entityType: this.getEntityType(), - unique: this.getUnique()!, - }); - - eventContext.dispatchEvent(event); - } - } - - #readOnlyLanguageVariantsFilter = (option: UmbDocumentVariantOptionModel) => { - const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture); - return readOnlyCultures.includes(option.culture) === false; - }; - async #handleSaveAndPreview() { const unique = this.getUnique(); if (!unique) throw new Error('Unique is missing'); @@ -294,13 +190,13 @@ export class UmbDocumentWorkspaceContext let culture = UMB_INVARIANT_CULTURE; // Save document (the active variant) before previewing. - const { selected } = await this.#determineVariantOptions(); + const { selected } = await this._determineVariantOptions(); if (selected.length > 0) { culture = selected[0]; const variantIds = [UmbVariantId.FromString(culture)]; - const saveData = await this.#data.constructData(variantIds); - await this.#runMandatoryValidationForSaveData(saveData); - await this.#performSaveOrCreate(variantIds, saveData); + const saveData = await this._data.constructData(variantIds); + await this._runMandatoryValidationForSaveData(saveData); + await this._performCreateOrUpdate(variantIds, saveData); } // Tell the server that we're entering preview mode. @@ -325,7 +221,7 @@ export class UmbDocumentWorkspaceContext let variantIds: Array = []; - const { options, selected } = await this.#determineVariantOptions(); + const { options, selected } = await this._determineVariantOptions(); // If there is only one variant, we don't need to open the modal. if (options.length === 0) { @@ -340,7 +236,7 @@ export class UmbDocumentWorkspaceContext .open(this, UMB_DOCUMENT_PUBLISH_MODAL, { data: { options, - pickableFilter: this.#readOnlyLanguageVariantsFilter, + pickableFilter: this._readOnlyLanguageVariantsFilter, }, value: { selection: selected }, }) @@ -352,15 +248,15 @@ export class UmbDocumentWorkspaceContext variantIds = result?.selection.map((x) => UmbVariantId.FromString(x)) ?? []; } - const saveData = await this.#data.constructData(variantIds); - await this.#runMandatoryValidationForSaveData(saveData); + const saveData = await this._data.constructData(variantIds); + await this._runMandatoryValidationForSaveData(saveData); // Create the validation repository if it does not exist. (we first create this here when we need it) [NL] this.#validationRepository ??= new UmbDocumentValidationRepository(this); // We ask the server first to get a concatenated set of validation messages. So we see both front-end and back-end validation messages [NL] if (this.getIsNew()) { - const parent = this.#parent.getValue(); + const parent = this.getParent(); if (!parent) throw new Error('Parent is not set'); this.#serverValidation.askServerForValidation( saveData, @@ -380,7 +276,7 @@ export class UmbDocumentWorkspaceContext }, async () => { // If data of the selection is not valid Then just save: - await this.#performSaveOrCreate(variantIds, saveData); + await this._performCreateOrUpdate(variantIds, saveData); // Notifying that the save was successful, but we did not publish, which is what we want to symbolize here. [NL] const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT); // TODO: Get rid of the save notification. @@ -394,28 +290,11 @@ export class UmbDocumentWorkspaceContext ); } - async #runMandatoryValidationForSaveData(saveData: UmbDocumentDetailModel) { - // Check that the data is valid before we save it. - // Check variants have a name: - const variantsWithoutAName = saveData.variants.filter((x) => !x.name); - if (variantsWithoutAName.length > 0) { - const validationContext = await this.getContext(UMB_VALIDATION_CONTEXT); - variantsWithoutAName.forEach((variant) => { - validationContext.messages.addMessage( - 'client', - `$.variants[${UmbDataPathVariantQuery(variant)}].name`, - UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, - ); - }); - throw new Error('All variants must have a name'); - } - } - async #performSaveAndPublish(variantIds: Array, saveData: UmbDocumentDetailModel): Promise { const unique = this.getUnique(); if (!unique) throw new Error('Unique is missing'); - await this.#performSaveOrCreate(variantIds, saveData); + await this._performCreateOrUpdate(variantIds, saveData); await this.publishingRepository.publish( unique, @@ -431,53 +310,6 @@ export class UmbDocumentWorkspaceContext eventContext.dispatchEvent(event); } - async #handleSave() { - const { options, selected } = await this.#determineVariantOptions(); - - let variantIds: Array = []; - - // If there is only one variant, we don't need to open the modal. - if (options.length === 0) { - throw new Error('No variants are available'); - } else if (options.length === 1) { - // If only one option we will skip ahead and save the document with the only variant available: - variantIds.push(UmbVariantId.Create(options[0])); - } else { - // If there are multiple variants, we will open the modal to let the user pick which variants to save. - const modalManagerContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); - const result = await modalManagerContext - .open(this, UMB_DOCUMENT_SAVE_MODAL, { - data: { - options, - pickableFilter: this.#readOnlyLanguageVariantsFilter, - }, - value: { selection: selected }, - }) - .onSubmit() - .catch(() => undefined); - - if (!result?.selection.length) return; - - variantIds = result?.selection.map((x) => UmbVariantId.FromString(x)) ?? []; - } - - const saveData = await this.#data.constructData(variantIds); - await this.#runMandatoryValidationForSaveData(saveData); - return await this.#performSaveOrCreate(variantIds, saveData); - } - - public override requestSubmit() { - return this.#handleSave(); - } - - public submit() { - return this.#handleSave(); - } - - public override invalidSubmit() { - return this.#handleSave(); - } - public async publish() { throw new Error('Method not implemented.'); } @@ -498,7 +330,7 @@ export class UmbDocumentWorkspaceContext .open(this, UMB_DOCUMENT_SCHEDULE_MODAL, { data: { options, - pickableFilter: this.#readOnlyLanguageVariantsFilter, + pickableFilter: this._readOnlyLanguageVariantsFilter, }, value: { selection: selected.map((unique) => ({ unique, schedule: {} })) }, }) @@ -541,7 +373,7 @@ export class UmbDocumentWorkspaceContext .open(this, UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL, { data: { options, - pickableFilter: this.#readOnlyLanguageVariantsFilter, + pickableFilter: this._readOnlyLanguageVariantsFilter, }, value: { selection: selected }, }) From bd20747bc8a65f1411173105cb399045eccca301 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 15:31:19 +0200 Subject: [PATCH 054/170] temp move back --- .../documents/documents/workspace/document-workspace.context.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 40395ed504..3cef649bc2 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -75,6 +75,8 @@ export class UmbDocumentWorkspaceContext contentTypeDetailRepository: UmbDocumentTypeDetailRepository, }); + this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); + this.routes.setRoutes([ { path: UMB_CREATE_FROM_BLUEPRINT_DOCUMENT_WORKSPACE_PATH_PATTERN.toString(), From 846479ed87113dd245462a07e70be7306d3d0e6a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 15:31:32 +0200 Subject: [PATCH 055/170] add check for data --- .../content/workspace/content-detail-workspace-base.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 0f801301d0..487d37dab6 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -132,8 +132,6 @@ export abstract class UmbContentDetailWorkspaceBase< new UmbVariantValuesValidationPathTranslator(this); new UmbVariantsValidationPathTranslator(this); - this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); - this.observe( this.varies, (varies) => { @@ -368,6 +366,11 @@ export abstract class UmbContentDetailWorkspaceBase< } async #handleSubmit() { + const data = this.getData(); + if (!data) { + throw new Error('Data is missing'); + } + const { options, selected } = await this._determineVariantOptions(); let variantIds: Array = []; From 2d2b32c380d9225629036506af9b82f316fe7587 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 15:31:49 +0200 Subject: [PATCH 056/170] wip implement UmbContentDetailWorkspaceBase for media workspace context --- .../workspace/media-workspace.context.ts | 302 ++---------------- 1 file changed, 19 insertions(+), 283 deletions(-) diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index e22db20690..07830ba90a 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -1,33 +1,20 @@ import { UmbMediaTypeDetailRepository } from '../../media-types/repository/detail/media-type-detail.repository.js'; import { UmbMediaPropertyDatasetContext } from '../property-dataset-context/media-property-dataset-context.js'; import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; -import { UmbMediaDetailRepository } from '../repository/index.js'; -import type { - UmbMediaDetailModel, - UmbMediaValueModel, - UmbMediaVariantModel, - UmbMediaVariantOptionModel, -} from '../types.js'; +import { UMB_MEDIA_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; +import type { UmbMediaDetailModel, UmbMediaVariantModel, UmbMediaVariantOptionModel } from '../types.js'; import { UMB_CREATE_MEDIA_WORKSPACE_PATH_PATTERN, UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../paths.js'; -import { UMB_MEDIA_SECTION_PATH } from '../../media-section/paths.js'; import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js'; import { UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD } from './constants.js'; -import { UMB_INVARIANT_CULTURE, UmbVariantId } from '@umbraco-cms/backoffice/variant'; -import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type'; +import { UMB_MEDIA_WORKSPACE_ALIAS } from './manifests.js'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import { UMB_INVARIANT_CULTURE } from '@umbraco-cms/backoffice/variant'; import { - UmbSubmittableWorkspaceContextBase, UmbWorkspaceIsNewRedirectController, UmbWorkspaceIsNewRedirectControllerAlias, - UmbWorkspaceSplitViewManager, } from '@umbraco-cms/backoffice/workspace'; -import { - appendToFrozenArray, - mergeObservables, - UmbArrayState, - UmbObjectState, -} from '@umbraco-cms/backoffice/observable-api'; +import { mergeObservables } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbLanguageCollectionRepository, type UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbRequestReloadChildrenOfEntityEvent, @@ -35,74 +22,29 @@ import { } from '@umbraco-cms/backoffice/entity-action'; import type { UmbMediaTypeDetailModel } from '@umbraco-cms/backoffice/media-type'; import { + UmbContentDetailWorkspaceBase, UmbContentWorkspaceDataManager, type UmbContentCollectionWorkspaceContext, type UmbContentWorkspaceContext, } from '@umbraco-cms/backoffice/content'; -import { UmbEntityContext } from '@umbraco-cms/backoffice/entity'; import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin'; -import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; type ContentModel = UmbMediaDetailModel; type ContentTypeModel = UmbMediaTypeDetailModel; export class UmbMediaWorkspaceContext - extends UmbSubmittableWorkspaceContextBase + extends UmbContentDetailWorkspaceBase implements UmbContentWorkspaceContext, UmbContentCollectionWorkspaceContext { - public readonly IS_CONTENT_WORKSPACE_CONTEXT = true as const; - - public readonly repository = new UmbMediaDetailRepository(this); - - #parent = new UmbObjectState<{ entityType: string; unique: string | null } | undefined>(undefined); - readonly parentUnique = this.#parent.asObservablePart((parent) => (parent ? parent.unique : undefined)); - readonly parentEntityType = this.#parent.asObservablePart((parent) => (parent ? parent.entityType : undefined)); - readonly #data = new UmbContentWorkspaceDataManager(this, UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD); - #getDataPromise?: Promise; - // TODo: Optimize this so it uses either a App Language Context? [NL] - #languageRepository = new UmbLanguageCollectionRepository(this); - #languages = new UmbArrayState([], (x) => x.unique); - public readonly languages = this.#languages.asObservable(); - - readOnlyState = new UmbReadOnlyVariantStateManager(this); - - public isLoaded() { - return this.#getDataPromise; - } - - readonly unique = this.#data.createObservablePartOfCurrent((data) => data?.unique); - readonly entityType = this.#data.createObservablePartOfCurrent((data) => data?.entityType); readonly contentTypeUnique = this.#data.createObservablePartOfCurrent((data) => data?.mediaType.unique); readonly contentTypeHasCollection = this.#data.createObservablePartOfCurrent((data) => !!data?.mediaType.collection); - readonly variants = this.#data.createObservablePartOfCurrent((data) => data?.variants || []); - - readonly values = this.#data.createObservablePartOfCurrent((data) => data?.values); - getValues() { - return this.#data.getCurrent()?.values; - } - readonly urls = this.#data.createObservablePartOfCurrent((data) => data?.urls || []); - readonly structure = new UmbContentTypeStructureManager(this, new UmbMediaTypeDetailRepository(this)); - readonly variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); - readonly variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); - readonly varies = this.structure.ownerContentTypeObservablePart((x) => - x ? x.variesByCulture || x.variesBySegment : undefined, - ); - #varies?: boolean; - #variesByCulture?: boolean; - #variesBySegment?: boolean; - - readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); - #dataTypeSchemaAliasMap = new Map(); - - readonly splitView = new UmbWorkspaceSplitViewManager(); - readonly variantOptions = mergeObservables( [this.varies, this.variants, this.languages], ([varies, variants, languages]) => { @@ -134,59 +76,18 @@ export class UmbMediaWorkspaceContext }, ); - // TODO: this should be set up for all entity workspace contexts in a base class - #entityContext = new UmbEntityContext(this); // TODO: this might not be the correct place to spin this up #isTrashedContext = new UmbIsTrashedEntityContext(this); constructor(host: UmbControllerHost) { - super(host, 'Umb.Workspace.Media'); + super(host, { + entityType: UMB_MEDIA_ENTITY_TYPE, + workspaceAlias: UMB_MEDIA_WORKSPACE_ALIAS, + detailRepositoryAlias: UMB_MEDIA_DETAIL_REPOSITORY_ALIAS, + contentTypeDetailRepository: UmbMediaTypeDetailRepository, + }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); - this.observe( - this.varies, - (varies) => { - this.#data.setVaries(varies); - this.#varies = varies; - }, - null, - ); - this.observe( - this.variesByCulture, - (varies) => { - this.#data.setVariesByCulture(varies); - this.#variesByCulture = varies; - }, - null, - ); - this.observe( - this.variesBySegment, - (varies) => { - this.#data.setVariesBySegment(varies); - this.#variesBySegment = varies; - }, - null, - ); - this.observe( - this.structure.contentTypeDataTypeUniques, - (dataTypeUniques: Array) => { - this.#dataTypeItemManager.setUniques(dataTypeUniques); - }, - null, - ); - this.observe( - this.#dataTypeItemManager.items, - (dataTypes) => { - // Make a map of the data type unique and editorAlias: - this.#dataTypeSchemaAliasMap = new Map( - dataTypes.map((dataType) => { - return [dataType.unique, dataType.propertyEditorSchemaAlias]; - }), - ); - }, - null, - ); - this.loadLanguages(); this.routes.setRoutes([ { @@ -222,35 +123,14 @@ export class UmbMediaWorkspaceContext this.#data.clear(); } - async loadLanguages() { - // TODO: If we don't end up having a Global Context for languages, then we should at least change this into using a asObservable which should be returned from the repository. [Nl] - const { data } = await this.#languageRepository.requestCollection({}); - this.#languages.setValue(data?.items ?? []); - } - - async load(unique: string) { - this.resetState(); - this.#getDataPromise = this.repository.requestByUnique(unique); - type GetDataType = Awaited>; - const { data, asObservable } = (await this.#getDataPromise) as GetDataType; + override async load(unique: string) { + const response = await super.load(unique); - if (data) { - this.#entityContext.setEntityType(UMB_MEDIA_ENTITY_TYPE); - this.#entityContext.setUnique(unique); - this.#isTrashedContext.setIsTrashed(data.isTrashed); - this.setIsNew(false); - this.#data.setPersisted(data); - this.#data.setCurrent(data); + if (response.data) { + this.#isTrashedContext.setIsTrashed(response.data.isTrashed); } - this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'umbMediaStoreObserver'); - } - - #onStoreChange(entity: ContentModel | undefined) { - if (!entity) { - //TODO: This solution is alright for now. But reconsider when we introduce signal-r - history.pushState(null, '', UMB_MEDIA_SECTION_PATH); - } + return response; } async create(parent: { entityType: string; unique: string | null }, mediaTypeUnique: string) { @@ -272,133 +152,10 @@ export class UmbMediaWorkspaceContext return UMB_MEDIA_COLLECTION_ALIAS; } - getData() { - return this.#data.getCurrent(); - } - - getUnique() { - return this.getData()?.unique; - } - - getEntityType() { - return UMB_MEDIA_ENTITY_TYPE; - } - getContentTypeId() { return this.getData()?.mediaType.unique; } - getVaries() { - return this.#varies; - } - getVariesByCulture() { - return this.#variesByCulture; - } - getVariesBySegment() { - return this.#variesBySegment; - } - - variantById(variantId: UmbVariantId) { - return this.#data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); - } - - getVariant(variantId: UmbVariantId) { - return this.#data.getCurrent()?.variants?.find((x) => variantId.compare(x)); - } - - getName(variantId?: UmbVariantId) { - const variants = this.#data.getCurrent()?.variants; - if (!variants) return; - if (variantId) { - return variants.find((x) => variantId.compare(x))?.name; - } else { - return variants[0]?.name; - } - } - - setName(name: string, variantId?: UmbVariantId) { - this.#data.updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name }); - } - - name(variantId?: UmbVariantId) { - return this.#data.createObservablePartOfCurrent( - (data) => data?.variants?.find((x) => variantId?.compare(x))?.name ?? '', - ); - } - - async propertyStructureById(propertyId: string) { - return this.structure.propertyStructureById(propertyId); - } - /** - * @function propertyValueByAlias - * @param {string} propertyAlias - * @param {UmbVariantId} variantId - * @returns {Promise | undefined>} - * @description Get an Observable for the value of this property. - */ - async propertyValueByAlias(propertyAlias: string, variantId?: UmbVariantId) { - return this.#data.createObservablePartOfCurrent( - (data) => - data?.values?.find((x) => x?.alias === propertyAlias && (variantId ? variantId.compare(x) : true)) - ?.value as PropertyValueType, - ); - } - - /** - * Get the current value of the property with the given alias and variantId. - * @param {string} alias - * @param {UmbVariantId} variantId - * @returns The value or undefined if not set or found. - */ - getPropertyValue(alias: string, variantId?: UmbVariantId) { - const currentData = this.#data.getCurrent(); - if (currentData) { - const newDataSet = currentData.values?.find( - (x) => x.alias === alias && (variantId ? variantId.compare(x) : true), - ); - return newDataSet?.value as ReturnType; - } - return undefined; - } - - async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { - this.initiatePropertyValueChange(); - variantId ??= UmbVariantId.CreateInvariant(); - const property = await this.structure.getPropertyStructureByAlias(alias); - - if (!property) { - throw new Error(`Property alias "${alias}" not found.`); - } - - const editorAlias = this.#dataTypeSchemaAliasMap.get(property.dataType.unique); - if (!editorAlias) { - throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`); - } - - const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbMediaValueModel; - - const currentData = this.getData(); - if (currentData) { - const values = appendToFrozenArray( - currentData.values ?? [], - entry, - (x) => x.alias === alias && variantId!.compare(x), - ); - this.#data.updateCurrent({ values }); - - // TODO: We should move this type of logic to the act of saving [NL] - this.#data.ensureVariantData(variantId); - } - this.finishPropertyValueChange(); - } - - initiatePropertyValueChange() { - this.#data.initiatePropertyValueChange(); - } - finishPropertyValueChange = () => { - this.#data.finishPropertyValueChange(); - }; - async #handleSave() { const saveData = this.#data.getCurrent(); if (!saveData?.unique) throw new Error('Unique is missing'); @@ -443,33 +200,12 @@ export class UmbMediaWorkspaceContext } } - async submit() { - const data = this.getData(); - if (!data) { - throw new Error('Data is missing'); - } - await this.#handleSave(); - } - - async delete() { - const id = this.getUnique(); - if (id) { - await this.repository.delete(id); - } - } - public createPropertyDatasetContext( host: UmbControllerHost, variantId: UmbVariantId, ): UmbMediaPropertyDatasetContext { return new UmbMediaPropertyDatasetContext(host, this, variantId); } - - public override destroy(): void { - this.structure.destroy(); - this.#languageRepository.destroy(); - super.destroy(); - } } export { UmbMediaWorkspaceContext as api }; From 487908a10482dd4ae8391e850e8a1087e7a4a42b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 17:14:41 +0200 Subject: [PATCH 057/170] provide entity context --- .../entity-detail/entity-detail-workspace-base.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 174400fe50..06b276baac 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -2,7 +2,7 @@ import { UmbSubmittableWorkspaceContextBase } from '../submittable/index.js'; import { UmbEntityWorkspaceDataManager } from '../entity/entity-workspace-data-manager.js'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbEntityModel, UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; +import { UmbEntityContext, type UmbEntityModel, type UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; import { UMB_DISCARD_CHANGES_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import { @@ -50,6 +50,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< protected _detailRepository?: DetailRepositoryType; + #entityContext = new UmbEntityContext(this); #entityType: string; #parent = new UmbObjectState<{ entityType: string; unique: UmbEntityUnique } | undefined>(undefined); @@ -107,9 +108,11 @@ export abstract class UmbEntityDetailWorkspaceContextBase< const data = response.data; if (data) { - this.setIsNew(false); + this.#entityContext.setEntityType(this.#entityType); + this.#entityContext.setUnique(unique); this._data.setPersisted(data); this._data.setCurrent(data); + this.setIsNew(false); } return response; @@ -128,12 +131,16 @@ export abstract class UmbEntityDetailWorkspaceContextBase< let { data } = await request; if (!data) return undefined; + this.#entityContext.setEntityType(this.#entityType); + this.#entityContext.setUnique(data.unique); + if (this.modalContext) { data = { ...data, ...this.modalContext.data.preset }; } this.setIsNew(true); this._data.setPersisted(data); this._data.setCurrent(data); + return data; } @@ -263,6 +270,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< public override destroy(): void { window.removeEventListener('willchangestate', this.#onWillNavigate); this._detailRepository?.destroy(); + this.#entityContext.destroy(); super.destroy(); } } From c4b42b933aa7abe3e39fdc086db06b88952861b7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 17:14:52 +0200 Subject: [PATCH 058/170] remove duplicated code --- .../workspace/media-workspace.context.ts | 126 +++--------------- 1 file changed, 21 insertions(+), 105 deletions(-) diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index 07830ba90a..97521e840c 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -2,24 +2,17 @@ import { UmbMediaTypeDetailRepository } from '../../media-types/repository/detai import { UmbMediaPropertyDatasetContext } from '../property-dataset-context/media-property-dataset-context.js'; import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; import { UMB_MEDIA_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; -import type { UmbMediaDetailModel, UmbMediaVariantModel, UmbMediaVariantOptionModel } from '../types.js'; +import type { UmbMediaDetailModel, UmbMediaVariantModel } from '../types.js'; import { UMB_CREATE_MEDIA_WORKSPACE_PATH_PATTERN, UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../paths.js'; import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js'; import { UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD } from './constants.js'; import { UMB_MEDIA_WORKSPACE_ALIAS } from './manifests.js'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; -import { UMB_INVARIANT_CULTURE } from '@umbraco-cms/backoffice/variant'; import { UmbWorkspaceIsNewRedirectController, UmbWorkspaceIsNewRedirectControllerAlias, } from '@umbraco-cms/backoffice/workspace'; -import { mergeObservables } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { - UmbRequestReloadChildrenOfEntityEvent, - UmbRequestReloadStructureForEntityEvent, -} from '@umbraco-cms/backoffice/entity-action'; import type { UmbMediaTypeDetailModel } from '@umbraco-cms/backoffice/media-type'; import { UmbContentDetailWorkspaceBase, @@ -28,10 +21,10 @@ import { type UmbContentWorkspaceContext, } from '@umbraco-cms/backoffice/content'; import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin'; -import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; type ContentModel = UmbMediaDetailModel; type ContentTypeModel = UmbMediaTypeDetailModel; + export class UmbMediaWorkspaceContext extends UmbContentDetailWorkspaceBase implements @@ -45,38 +38,6 @@ export class UmbMediaWorkspaceContext readonly urls = this.#data.createObservablePartOfCurrent((data) => data?.urls || []); - readonly variantOptions = mergeObservables( - [this.varies, this.variants, this.languages], - ([varies, variants, languages]) => { - // TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL] - if (varies === true) { - return languages.map((language) => { - return { - variant: variants.find((x) => x.culture === language.unique), - language, - // TODO: When including segments, this object should be updated to include a object for the segment. [NL] - // TODO: When including segments, the unique should be updated to include the segment as well. [NL] - unique: language.unique, // This must be a variantId string! - culture: language.unique, - segment: null, - } as UmbMediaVariantOptionModel; - }); - } else if (varies === false) { - return [ - { - variant: variants.find((x) => x.culture === null), - language: languages.find((x) => x.isDefault), - culture: null, - segment: null, - unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! - } as UmbMediaVariantOptionModel, - ]; - } - return [] as Array; - }, - ); - - // TODO: this might not be the correct place to spin this up #isTrashedContext = new UmbIsTrashedEntityContext(this); constructor(host: UmbControllerHost) { @@ -97,7 +58,10 @@ export class UmbMediaWorkspaceContext const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; const mediaTypeUnique = info.match.params.mediaTypeUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, mediaTypeUnique); + this.createScaffold({ + parent: { entityType: parentEntityType, unique: parentUnique }, + preset: { mediaType: { unique: mediaTypeUnique, collection: null } }, + }); new UmbWorkspaceIsNewRedirectController( this, @@ -118,12 +82,7 @@ export class UmbMediaWorkspaceContext ]); } - override resetState() { - super.resetState(); - this.#data.clear(); - } - - override async load(unique: string) { + public override async load(unique: string) { const response = await super.load(unique); if (response.data) { @@ -133,71 +92,28 @@ export class UmbMediaWorkspaceContext return response; } - async create(parent: { entityType: string; unique: string | null }, mediaTypeUnique: string) { - this.resetState(); - this.#parent.setValue(parent); - this.#getDataPromise = this.repository.createScaffold({ mediaType: { unique: mediaTypeUnique, collection: null } }); - const { data } = await this.#getDataPromise; - if (!data) return undefined; - - this.#entityContext.setEntityType(UMB_MEDIA_ENTITY_TYPE); - this.#entityContext.setUnique(data.unique); - this.setIsNew(true); - this.#data.setPersisted(undefined); - this.#data.setCurrent(data); - return data; + /* + * @deprecated Use `createScaffold` instead. + */ + public async create(parent: { entityType: string; unique: string | null }, mediaTypeUnique: string) { + const args = { + parent, + preset: { mediaType: { unique: mediaTypeUnique, collection: null } }, + }; + return this.createScaffold(args); } - getCollectionAlias() { + public getCollectionAlias() { return UMB_MEDIA_COLLECTION_ALIAS; } - getContentTypeId() { + public getContentTypeId() { return this.getData()?.mediaType.unique; } - async #handleSave() { - const saveData = this.#data.getCurrent(); - if (!saveData?.unique) throw new Error('Unique is missing'); - - if (this.getIsNew()) { - const parent = this.#parent.getValue(); - if (!parent) throw new Error('Parent is not set'); - - const { data, error } = await this.repository.create(saveData, parent.unique); - if (!data || error) { - throw new Error('Error creating document'); - } - - this.setIsNew(false); - this.#data.setPersisted(data); - this.#data.setCurrent(data); - - // TODO: this might not be the right place to alert the tree, but it works for now - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadChildrenOfEntityEvent({ - entityType: parent.entityType, - unique: parent.unique, - }); - eventContext.dispatchEvent(event); - } else { - // Save: - const { data, error } = await this.repository.save(saveData); - if (!data || error) { - throw new Error('Error saving document'); - } - - this.#data.setPersisted(data); - this.#data.setCurrent(data); - - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadStructureForEntityEvent({ - unique: this.getUnique()!, - entityType: this.getEntityType(), - }); - - eventContext.dispatchEvent(event); - } + public override resetState() { + super.resetState(); + this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); } public createPropertyDatasetContext( From 20638d5b767b4603ede2004cd1d357366a2db358 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 18:52:04 +0200 Subject: [PATCH 059/170] move more logic to base class --- src/packages/core/content-type/types.ts | 1 + .../content-detail-workspace-base.ts | 108 ++++++++++-------- .../detail/detail-repository.interface.ts | 5 + src/packages/core/repository/detail/index.ts | 2 + .../entity-detail-workspace-base.ts | 2 +- .../workspace/document-workspace.context.ts | 12 +- .../workspace/media-workspace.context.ts | 10 +- 7 files changed, 80 insertions(+), 60 deletions(-) diff --git a/src/packages/core/content-type/types.ts b/src/packages/core/content-type/types.ts index 132af25ee5..092835bac4 100644 --- a/src/packages/core/content-type/types.ts +++ b/src/packages/core/content-type/types.ts @@ -13,6 +13,7 @@ export interface UmbPropertyTypeContainerModel { export interface UmbContentTypeModel { unique: string; + entityType: string; name: string; alias: string; description: string; diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 487d37dab6..6d45afd405 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -1,9 +1,9 @@ -import type { UmbContentDetailModel } from '../types.js'; +import type { UmbContentDetailModel, UmbElementValueModel } from '../types.js'; import { UmbContentWorkspaceDataManager } from '../manager/index.js'; import { UmbMergeContentVariantDataController } from '../controller/merge-content-variant-data.controller.js'; import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; +import type { UmbDetailRepository, UmbDetailRepositoryConstructor } from '@umbraco-cms/backoffice/repository'; import { UmbEntityDetailWorkspaceContextBase, UmbWorkspaceSplitViewManager, @@ -11,7 +11,12 @@ import { type UmbEntityDetailWorkspaceContextCreateArgs, } from '@umbraco-cms/backoffice/workspace'; import { UmbContentTypeStructureManager, type UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; -import { UMB_INVARIANT_CULTURE, UmbVariantId, type UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; +import { + UMB_INVARIANT_CULTURE, + UmbVariantId, + type UmbEntityVariantModel, + type UmbEntityVariantOptionModel, +} from '@umbraco-cms/backoffice/variant'; import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; import { appendToFrozenArray, mergeObservables, UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; @@ -33,8 +38,9 @@ import { UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; -export interface UmbContentDetailWorkspaceContextArgs extends UmbEntityDetailWorkspaceContextArgs { - contentTypeDetailRepository: UmbDetailRepository; +export interface UmbContentDetailWorkspaceContextArgs extends UmbEntityDetailWorkspaceContextArgs { + contentTypeDetailRepository: UmbDetailRepositoryConstructor; + contentVariantScaffold: UmbEntityVariantModel; } export abstract class UmbContentDetailWorkspaceBase< @@ -50,25 +56,18 @@ export abstract class UmbContentDetailWorkspaceBase< { public readonly IS_CONTENT_WORKSPACE_CONTEXT = true as const; - protected override readonly _data = new UmbContentWorkspaceDataManager( - this, - UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, - ); - public readonly readOnlyState = new UmbReadOnlyVariantStateManager(this); /* Content Data */ + protected override _data: UmbContentWorkspaceDataManager; public readonly values = this._data.createObservablePartOfCurrent((data) => data?.values); public readonly variants = this._data.createObservablePartOfCurrent((data) => data?.variants ?? []); /* Content Type (Structure) Data */ - public readonly structure: UmbContentTypeStructureManager; - - public readonly variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); - public readonly variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); - public readonly varies = this.structure.ownerContentTypeObservablePart((x) => - x ? x.variesByCulture || x.variesBySegment : undefined, - ); + public readonly structure; + public readonly variesByCulture; + public readonly variesBySegment; + public readonly varies; /* Data Type */ readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); @@ -91,42 +90,51 @@ export abstract class UmbContentDetailWorkspaceBase< */ public readonly languages = this.#languages.asObservable(); - readonly variantOptions = mergeObservables( - [this.varies, this.variants, this.languages], - ([varies, variants, languages]) => { - // TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL] - if (varies === true) { - return languages.map((language) => { - return { - variant: variants.find((x) => x.culture === language.unique), - language, - // TODO: When including segments, this object should be updated to include a object for the segment. [NL] - // TODO: When including segments, the unique should be updated to include the segment as well. [NL] - unique: language.unique, // This must be a variantId string! - culture: language.unique, - segment: null, - } as UmbDocumentVariantOptionModel; - }); - } else if (varies === false) { - return [ - { - variant: variants.find((x) => x.culture === null), - language: languages.find((x) => x.isDefault), - culture: null, - segment: null, - unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! - } as UmbDocumentVariantOptionModel, - ]; - } - return [] as Array; - }, - ).pipe(map((results) => results.sort(sortVariants))); - - constructor(host: UmbControllerHost, args: UmbContentDetailWorkspaceContextArgs) { + readonly variantOptions; + + constructor(host: UmbControllerHost, args: UmbContentDetailWorkspaceContextArgs) { super(host, args); + this._data = new UmbContentWorkspaceDataManager(this, args.contentVariantScaffold); + const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); + this.variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); + this.variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); + this.varies = this.structure.ownerContentTypeObservablePart((x) => + x ? x.variesByCulture || x.variesBySegment : undefined, + ); + + this.variantOptions = mergeObservables( + [this.varies, this.variants, this.languages], + ([varies, variants, languages]) => { + // TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL] + if (varies === true) { + return languages.map((language) => { + return { + variant: variants.find((x) => x.culture === language.unique), + language, + // TODO: When including segments, this object should be updated to include a object for the segment. [NL] + // TODO: When including segments, the unique should be updated to include the segment as well. [NL] + unique: language.unique, // This must be a variantId string! + culture: language.unique, + segment: null, + } as UmbEntityVariantOptionModel; + }); + } else if (varies === false) { + return [ + { + variant: variants.find((x) => x.culture === null), + language: languages.find((x) => x.isDefault), + culture: null, + segment: null, + unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! + } as UmbEntityVariantOptionModel, + ]; + } + return [] as Array; + }, + ); this.addValidationContext(new UmbValidationContext(this)); new UmbVariantValuesValidationPathTranslator(this); @@ -286,7 +294,7 @@ export abstract class UmbContentDetailWorkspaceBase< throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`); } - const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbDocumentValueModel; + const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbElementValueModel; const currentData = this.getData(); if (currentData) { diff --git a/src/packages/core/repository/detail/detail-repository.interface.ts b/src/packages/core/repository/detail/detail-repository.interface.ts index d2d4832fa0..6fe7f3a281 100644 --- a/src/packages/core/repository/detail/detail-repository.interface.ts +++ b/src/packages/core/repository/detail/detail-repository.interface.ts @@ -1,7 +1,12 @@ import type { UmbRepositoryErrorResponse, UmbRepositoryResponse } from '../types.js'; import type { UmbReadDetailRepository } from './read/index.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; +export interface UmbDetailRepositoryConstructor { + new (host: UmbControllerHost): UmbDetailRepository; +} + export interface UmbDetailRepository extends UmbReadDetailRepository, UmbApi { createScaffold(preset?: Partial): Promise>; create(data: DetailModelType, parentUnique: string | null): Promise>; diff --git a/src/packages/core/repository/detail/index.ts b/src/packages/core/repository/detail/index.ts index f190db5763..3e13f2e154 100644 --- a/src/packages/core/repository/detail/index.ts +++ b/src/packages/core/repository/detail/index.ts @@ -9,3 +9,5 @@ export type { UmbReadDetailRepository } from './read/read-detail-repository.inte export type { UmbDetailDataSource, UmbDetailDataSourceConstructor } from './detail-data-source.interface.js'; export { UmbDetailRepositoryBase } from './detail-repository-base.js'; export type { UmbDetailRepository } from './detail-repository.interface.js'; + +export * from './detail-repository.interface.js'; diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 06b276baac..2149898a52 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -40,7 +40,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< * @protected * @memberof UmbEntityWorkspaceContextBase */ - protected readonly _data = new UmbEntityWorkspaceDataManager(this); + protected _data = new UmbEntityWorkspaceDataManager(this); public readonly data = this._data.current; public readonly entityType = this._data.createObservablePartOfCurrent((data) => data?.entityType); diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 3cef649bc2..ebb850c1fe 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -1,6 +1,7 @@ import { UmbDocumentTypeDetailRepository } from '../../document-types/repository/detail/document-type-detail.repository.js'; import { UmbDocumentPropertyDatasetContext } from '../property-dataset-context/document-property-dataset-context.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; +import type { UmbDocumentDetailRepository } from '../repository/index.js'; import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; import type { UmbDocumentVariantPublishModel, UmbDocumentDetailModel, UmbDocumentVariantModel } from '../types.js'; import { @@ -18,7 +19,7 @@ import { } from '../paths.js'; import { UmbDocumentPreviewRepository } from '../repository/preview/index.js'; import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../collection/index.js'; -import { UMB_DOCUMENT_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, UMB_DOCUMENT_WORKSPACE_ALIAS } from './constants.js'; import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import { UMB_INVARIANT_CULTURE, UmbVariantId } from '@umbraco-cms/backoffice/variant'; import { @@ -46,7 +47,12 @@ type EntityModel = UmbDocumentDetailModel; type EntityTypeModel = UmbDocumentTypeDetailModel; export class UmbDocumentWorkspaceContext - extends UmbContentDetailWorkspaceBase + extends UmbContentDetailWorkspaceBase< + EntityModel, + UmbDocumentDetailRepository, + EntityTypeModel, + UmbDocumentVariantModel + > implements UmbContentWorkspaceContext, UmbPublishableWorkspaceContext, @@ -73,6 +79,7 @@ export class UmbDocumentWorkspaceContext workspaceAlias: UMB_DOCUMENT_WORKSPACE_ALIAS, detailRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbDocumentTypeDetailRepository, + contentVariantScaffold: UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); @@ -140,7 +147,6 @@ export class UmbDocumentWorkspaceContext } async create(parent: UmbEntityModel, documentTypeUnique: string, blueprintUnique?: string) { - this.resetState(); this.#parent.setValue(parent); if (blueprintUnique) { diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index 97521e840c..c103472b09 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -16,7 +16,6 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbMediaTypeDetailModel } from '@umbraco-cms/backoffice/media-type'; import { UmbContentDetailWorkspaceBase, - UmbContentWorkspaceDataManager, type UmbContentCollectionWorkspaceContext, type UmbContentWorkspaceContext, } from '@umbraco-cms/backoffice/content'; @@ -31,12 +30,10 @@ export class UmbMediaWorkspaceContext UmbContentWorkspaceContext, UmbContentCollectionWorkspaceContext { - readonly #data = new UmbContentWorkspaceDataManager(this, UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD); + readonly contentTypeUnique = this._data.createObservablePartOfCurrent((data) => data?.mediaType.unique); + readonly contentTypeHasCollection = this._data.createObservablePartOfCurrent((data) => !!data?.mediaType.collection); - readonly contentTypeUnique = this.#data.createObservablePartOfCurrent((data) => data?.mediaType.unique); - readonly contentTypeHasCollection = this.#data.createObservablePartOfCurrent((data) => !!data?.mediaType.collection); - - readonly urls = this.#data.createObservablePartOfCurrent((data) => data?.urls || []); + readonly urls = this._data.createObservablePartOfCurrent((data) => data?.urls || []); #isTrashedContext = new UmbIsTrashedEntityContext(this); @@ -46,6 +43,7 @@ export class UmbMediaWorkspaceContext workspaceAlias: UMB_MEDIA_WORKSPACE_ALIAS, detailRepositoryAlias: UMB_MEDIA_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbMediaTypeDetailRepository, + contentVariantScaffold: UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); From b808d95e2dab9d190992c0236b3fd7d84e682f22 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 18:52:45 +0200 Subject: [PATCH 060/170] remove unused --- .../core/content/workspace/content-detail-workspace-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 6d45afd405..c04b2705bc 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -22,7 +22,7 @@ import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-t import { appendToFrozenArray, mergeObservables, UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; import { UmbLanguageCollectionRepository, type UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; -import { firstValueFrom, map } from '@umbraco-cms/backoffice/external/rxjs'; +import { firstValueFrom } from '@umbraco-cms/backoffice/external/rxjs'; import { UMB_VALIDATION_CONTEXT, UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, From c5e1fa44153b6377ca006dcb0c15500e2772a573 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 19:07:49 +0200 Subject: [PATCH 061/170] wip implement base class on member workspace --- .../member/member-workspace.context.ts | 403 +----------------- 1 file changed, 20 insertions(+), 383 deletions(-) diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index 0c54e85606..653651bd04 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -1,186 +1,37 @@ -import { UmbMemberDetailRepository } from '../../repository/index.js'; -import type { - UmbMemberDetailModel, - UmbMemberValueModel, - UmbMemberVariantModel, - UmbMemberVariantOptionModel, -} from '../../types.js'; +import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS } from '../../repository/index.js'; +import type { UmbMemberDetailModel, UmbMemberVariantModel } from '../../types.js'; import { UmbMemberPropertyDatasetContext } from '../../property-dataset-context/member-property-dataset-context.js'; -import { UMB_MEMBER_ENTITY_TYPE, UMB_MEMBER_ROOT_ENTITY_TYPE } from '../../entity.js'; -import { sortVariants } from '../../utils.js'; -import { UMB_MEMBER_MANAGEMENT_SECTION_PATH } from '../../../section/index.js'; +import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js'; import { UMB_MEMBER_WORKSPACE_ALIAS } from './manifests.js'; import { UmbMemberWorkspaceEditorElement } from './member-workspace-editor.element.js'; import { UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD } from './constants.js'; import { UmbMemberTypeDetailRepository, type UmbMemberTypeDetailModel } from '@umbraco-cms/backoffice/member-type'; import { - UmbSubmittableWorkspaceContextBase, UmbWorkspaceIsNewRedirectController, UmbWorkspaceIsNewRedirectControllerAlias, - UmbWorkspaceSplitViewManager, } from '@umbraco-cms/backoffice/workspace'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { - UmbArrayState, - UmbObjectState, - appendToFrozenArray, - mergeObservables, -} from '@umbraco-cms/backoffice/observable-api'; -import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type'; -import { UMB_INVARIANT_CULTURE, UmbVariantId } from '@umbraco-cms/backoffice/variant'; -import type { UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; -import { UmbLanguageCollectionRepository } from '@umbraco-cms/backoffice/language'; -import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository'; -import { UmbContentWorkspaceDataManager, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; -import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; -import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; -import { map } from '@umbraco-cms/backoffice/external/rxjs'; -import { UmbEntityContext, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -import { - UmbRequestReloadChildrenOfEntityEvent, - UmbRequestReloadStructureForEntityEvent, -} from '@umbraco-cms/backoffice/entity-action'; -import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import { UmbContentDetailWorkspaceBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; type EntityModel = UmbMemberDetailModel; export class UmbMemberWorkspaceContext - extends UmbSubmittableWorkspaceContextBase + extends UmbContentDetailWorkspaceBase implements UmbContentWorkspaceContext { - public readonly IS_CONTENT_WORKSPACE_CONTEXT = true as const; - - public readonly repository = new UmbMemberDetailRepository(this); - - #parent = new UmbObjectState({ entityType: UMB_MEMBER_ROOT_ENTITY_TYPE, unique: null }); - readonly parentUnique = this.#parent.asObservablePart((parent) => (parent ? parent.unique : undefined)); - readonly parentEntityType = this.#parent.asObservablePart((parent) => (parent ? parent.entityType : undefined)); - - readonly #data = new UmbContentWorkspaceDataManager(this, UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD); - #getDataPromise?: Promise>; - - // TODO: Optimize this so it uses either a App Language Context or another somehow cached solution? [NL] - #languageRepository = new UmbLanguageCollectionRepository(this); - #languages = new UmbArrayState([], (x) => x.unique); - public readonly languages = this.#languages.asObservable(); - - public readonly readOnlyState = new UmbReadOnlyVariantStateManager(this); - - public isLoaded() { - return this.#getDataPromise; - } - - readonly data = this.#data.current; - readonly unique = this.#data.createObservablePartOfCurrent((data) => data?.unique); - readonly createDate = this.#data.createObservablePartOfCurrent((data) => data?.variants[0].createDate); - readonly updateDate = this.#data.createObservablePartOfCurrent((data) => data?.variants[0].updateDate); - readonly contentTypeUnique = this.#data.createObservablePartOfCurrent((data) => data?.memberType.unique); - - readonly variants = this.#data.createObservablePartOfCurrent((data) => data?.variants ?? []); - - readonly values = this.#data.createObservablePartOfCurrent((data) => data?.values); - getValues() { - return this.#data.getCurrent()?.values; - } - - readonly structure = new UmbContentTypeStructureManager(this, new UmbMemberTypeDetailRepository(this)); - readonly variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); - readonly variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); - readonly varies = this.structure.ownerContentTypeObservablePart((x) => - x ? x.variesByCulture || x.variesBySegment : undefined, - ); - #varies?: boolean; - #variesByCulture?: boolean; - #variesBySegment?: boolean; - - readonly kind = this.#data.createObservablePartOfCurrent((data) => data?.kind); - - readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); - #dataTypeSchemaAliasMap = new Map(); - - readonly splitView = new UmbWorkspaceSplitViewManager(); - - readonly variantOptions = mergeObservables( - [this.varies, this.variants, this.languages], - ([varies, variants, languages]) => { - // TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL] - if (varies === true) { - return languages.map((language) => { - return { - variant: variants.find((x) => x.culture === language.unique), - language, - // TODO: When including segments, this object should be updated to include a object for the segment. [NL] - // TODO: When including segments, the unique should be updated to include the segment as well. [NL] - unique: language.unique, // This must be a variantId string! - culture: language.unique, - segment: null, - } as UmbMemberVariantOptionModel; - }); - } else if (varies === false) { - return [ - { - variant: variants.find((x) => x.culture === null), - language: languages.find((x) => x.isDefault), - culture: null, - segment: null, - unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! - } as UmbMemberVariantOptionModel, - ]; - } - return [] as Array; - }, - ).pipe(map((results) => results.sort(sortVariants))); - - // TODO: this should be set up for all entity workspace contexts in a base class - #entityContext = new UmbEntityContext(this); + readonly contentTypeUnique = this._data.createObservablePartOfCurrent((data) => data?.memberType.unique); + readonly kind = this._data.createObservablePartOfCurrent((data) => data?.kind); constructor(host: UmbControllerHost) { - super(host, UMB_MEMBER_WORKSPACE_ALIAS); + super(host, { + entityType: UMB_MEMBER_ENTITY_TYPE, + workspaceAlias: UMB_MEMBER_WORKSPACE_ALIAS, + detailRepositoryAlias: UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, + contentTypeDetailRepository: UmbMemberTypeDetailRepository, + contentVariantScaffold: UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, + }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); - this.observe( - this.varies, - (varies) => { - this.#data.setVaries(varies); - this.#varies = varies; - }, - null, - ); - this.observe( - this.variesByCulture, - (varies) => { - this.#data.setVariesByCulture(varies); - this.#variesByCulture = varies; - }, - null, - ); - this.observe( - this.variesBySegment, - (varies) => { - this.#data.setVariesBySegment(varies); - this.#variesBySegment = varies; - }, - null, - ); - this.observe( - this.structure.contentTypeDataTypeUniques, - (dataTypeUniques: Array) => { - this.#dataTypeItemManager.setUniques(dataTypeUniques); - }, - null, - ); - this.observe( - this.#dataTypeItemManager.items, - (dataTypes) => { - // Make a map of the data type unique and editorAlias: - this.#dataTypeSchemaAliasMap = new Map( - dataTypes.map((dataType) => { - return [dataType.unique, dataType.propertyEditorSchemaAlias]; - }), - ); - }, - null, - ); - this.loadLanguages(); this.routes.setRoutes([ { @@ -211,37 +62,7 @@ export class UmbMemberWorkspaceContext override resetState() { super.resetState(); - this.#data.clear(); - } - - async loadLanguages() { - // TODO: If we don't end up having a Global Context for languages, then we should at least change this into using a asObservable which should be returned from the repository. [Nl] - const { data } = await this.#languageRepository.requestCollection({}); - this.#languages.setValue(data?.items ?? []); - } - - async load(unique: string) { - this.resetState(); - this.#getDataPromise = this.repository.requestByUnique(unique); - type GetDataType = Awaited>; - const { data, asObservable } = (await this.#getDataPromise) as GetDataType; - - if (data) { - this.#entityContext.setEntityType(UMB_MEMBER_ENTITY_TYPE); - this.#entityContext.setUnique(unique); - this.setIsNew(false); - this.#data.setPersisted(data); - this.#data.setCurrent(data); - } - - this.observe(asObservable(), (member) => this.#onMemberStoreChange(member), 'umbMemberStoreObserver'); - } - - #onMemberStoreChange(member: EntityModel | undefined) { - if (!member) { - //TODO: This solution is alright for now. But reconsider when we introduce signal-r - history.pushState(null, '', UMB_MEMBER_MANAGEMENT_SECTION_PATH); - } + this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); } async create(memberTypeUnique: string) { @@ -262,190 +83,10 @@ export class UmbMemberWorkspaceContext return data; } - getData() { - return this.#data.getCurrent(); - } - - getUnique() { - return this.getData()?.unique; - } - - getEntityType() { - return UMB_MEMBER_ENTITY_TYPE; - } - getContentTypeId() { return this.getData()?.memberType.unique; } - getVaries() { - return this.#varies; - } - getVariesByCulture() { - return this.#variesByCulture; - } - getVariesBySegment() { - return this.#variesBySegment; - } - - variantById(variantId: UmbVariantId) { - return this.#data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); - } - - getVariant(variantId: UmbVariantId) { - return this.#data.getCurrent()?.variants?.find((x) => variantId.compare(x)); - } - - getName(variantId?: UmbVariantId) { - const variants = this.#data.getCurrent()?.variants; - if (!variants) return; - if (variantId) { - return variants.find((x) => variantId.compare(x))?.name; - } else { - return variants[0]?.name; - } - } - - setName(name: string, variantId?: UmbVariantId) { - this.#data.updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name }); - } - - name(variantId?: UmbVariantId) { - return this.#data.createObservablePartOfCurrent( - (data) => data?.variants?.find((x) => variantId?.compare(x))?.name ?? '', - ); - } - - async propertyStructureById(propertyId: string) { - return this.structure.propertyStructureById(propertyId); - } - - /** - * @function propertyValueByAlias - * @param {string} propertyAlias - property alias to observe - * @param {UmbVariantId} variantId - variant identifier for the value to observe - * @returns {Promise | undefined>} - * @description Get an Observable for the value of this property. - */ - async propertyValueByAlias(propertyAlias: string, variantId?: UmbVariantId) { - return this.#data.createObservablePartOfCurrent( - (data) => - data?.values?.find((x) => x?.alias === propertyAlias && (variantId ? variantId.compare(x) : true)) - ?.value as PropertyValueType, - ); - } - - /** - * Get the current value of the property with the given alias and variantId. - * @param {string} alias - property alias to set. - * @param {UmbVariantId} variantId - variant identifier for this value to be defined for. - * @returns {ReturnType | undefined}The value or undefined if not set or found. - */ - getPropertyValue(alias: string, variantId?: UmbVariantId) { - const currentData = this.getData(); - if (currentData) { - const newDataSet = currentData.values?.find( - (x) => x.alias === alias && (variantId ? variantId.compare(x) : true), - ); - return newDataSet?.value as ReturnType; - } - return undefined; - } - async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { - this.initiatePropertyValueChange(); - variantId ??= UmbVariantId.CreateInvariant(); - const property = await this.structure.getPropertyStructureByAlias(alias); - - if (!property) { - throw new Error(`Property alias "${alias}" not found.`); - } - - const editorAlias = this.#dataTypeSchemaAliasMap.get(property.dataType.unique); - if (!editorAlias) { - throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`); - } - - const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbMemberValueModel; - - const currentData = this.getData(); - if (currentData) { - const values = appendToFrozenArray( - currentData.values ?? [], - entry, - (x) => x.alias === alias && variantId!.compare(x), - ); - this.#data.updateCurrent({ values }); - - // TODO: We should move this type of logic to the act of saving [NL] - this.#data.ensureVariantData(variantId); - } - this.finishPropertyValueChange(); - } - - initiatePropertyValueChange() { - this.#data.initiatePropertyValueChange(); - } - finishPropertyValueChange = () => { - this.#data.finishPropertyValueChange(); - }; - - async #handleSave() { - const current = this.#data.getCurrent(); - if (!current) throw new Error('Data is missing'); - if (!current.unique) throw new Error('Unique is missing'); - - if (this.getIsNew()) { - // Create: - const parent = this.#parent.getValue(); - if (!parent) throw new Error('Parent is not set'); - - const { data, error } = await this.repository.create(current); - if (!data || error) { - throw new Error('Could not create member.'); - } - - this.setIsNew(false); - this.#data.setPersisted(data); - // TODO: Missing variant data filtering. - this.#data.setCurrent(data); - - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadChildrenOfEntityEvent({ - entityType: parent.entityType, - unique: parent.unique, - }); - eventContext.dispatchEvent(event); - } else { - // Save: - const { data, error } = await this.repository.save(current); - if (!data || error) { - throw new Error('Could not update member.'); - } - this.#data.setPersisted(data); - // TODO: Missing variant data filtering. - this.#data.setCurrent(data); - - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadStructureForEntityEvent({ - entityType: this.getEntityType(), - unique: this.getUnique()!, - }); - - eventContext.dispatchEvent(event); - } - } - - async submit() { - return this.#handleSave(); - } - - async delete() { - const id = this.getUnique(); - if (id) { - await this.repository.delete(id); - } - } - public createPropertyDatasetContext( host: UmbControllerHost, variantId: UmbVariantId, @@ -453,22 +94,18 @@ export class UmbMemberWorkspaceContext return new UmbMemberPropertyDatasetContext(host, this, variantId); } - public override destroy(): void { - super.destroy(); - } - set( propertyName: PropertyName, value: UmbMemberDetailModel[PropertyName], ) { - this.#data.updateCurrent({ [propertyName]: value }); + this._data.updateCurrent({ [propertyName]: value }); } // Only for CRUD demonstration purposes updateData(data: Partial) { - const currentData = this.#data.getCurrent(); + const currentData = this._data.getCurrent(); if (!currentData) throw new Error('No data to update'); - this.#data.setCurrent({ ...currentData, ...data }); + this._data.setCurrent({ ...currentData, ...data }); } get email(): string { @@ -512,7 +149,7 @@ export class UmbMemberWorkspaceContext } #get(propertyName: PropertyName) { - return this.#data.getCurrent()?.[propertyName]; + return this._data.getCurrent()?.[propertyName]; } } From 3d91fcca11b16443f21a94f6f2e8efc3a115baa4 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:08:06 +0200 Subject: [PATCH 062/170] make UmbContentDetailModel generic and pass variant model type --- src/packages/core/content/types.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/packages/core/content/types.ts b/src/packages/core/content/types.ts index a1e7c8cd01..169c1d43b0 100644 --- a/src/packages/core/content/types.ts +++ b/src/packages/core/content/types.ts @@ -19,10 +19,11 @@ export interface UmbPotentialContentValueModel extends UmbP segment?: string | null; } -export interface UmbContentDetailModel extends UmbElementDetailModel { +export interface UmbContentDetailModel + extends UmbElementDetailModel { unique: string; entityType: string; - variants: Array; + variants: Array; } export interface UmbContentLikeDetailModel From 5fe335c91a7fa23d2e1c029ec8aeba1b6e42c418 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:08:38 +0200 Subject: [PATCH 063/170] use create scaffold method --- .../workspace/document-workspace.context.ts | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index ebb850c1fe..7cf8f8d818 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -147,36 +147,29 @@ export class UmbDocumentWorkspaceContext } async create(parent: UmbEntityModel, documentTypeUnique: string, blueprintUnique?: string) { - this.#parent.setValue(parent); - if (blueprintUnique) { const blueprintRepository = new UmbDocumentBlueprintDetailRepository(this); const { data } = await blueprintRepository.requestByUnique(blueprintUnique); - this.#getDataPromise = this.repository.createScaffold({ - documentType: data?.documentType, - values: data?.values, - variants: data?.variants as Array, + return this.createScaffold({ + parent, + preset: { + documentType: data?.documentType, + values: data?.values, + variants: data?.variants as Array, + }, }); - } else { - this.#getDataPromise = this.repository.createScaffold({ + } + + return this.createScaffold({ + parent, + preset: { documentType: { unique: documentTypeUnique, collection: null, }, - }); - } - - const { data } = await this.#getDataPromise; - if (!data) return undefined; - - this.#entityContext.setEntityType(UMB_DOCUMENT_ENTITY_TYPE); - this.#entityContext.setUnique(data.unique); - this.#isTrashedContext.setIsTrashed(data.isTrashed); - this.setIsNew(true); - this.#data.setPersisted(undefined); - this.#data.setCurrent(data); - return data; + }, + }); } getCollectionAlias() { From c0ecd94209015270d35294b8a4f9f56e76166850 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:08:46 +0200 Subject: [PATCH 064/170] type casting --- .../workspace/content-detail-workspace-base.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index c04b2705bc..946d6e6e0d 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -11,12 +11,7 @@ import { type UmbEntityDetailWorkspaceContextCreateArgs, } from '@umbraco-cms/backoffice/workspace'; import { UmbContentTypeStructureManager, type UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; -import { - UMB_INVARIANT_CULTURE, - UmbVariantId, - type UmbEntityVariantModel, - type UmbEntityVariantOptionModel, -} from '@umbraco-cms/backoffice/variant'; +import { UMB_INVARIANT_CULTURE, UmbVariantId, type UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; import { appendToFrozenArray, mergeObservables, UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; @@ -44,7 +39,7 @@ export interface UmbContentDetailWorkspaceContextArgs extends U } export abstract class UmbContentDetailWorkspaceBase< - DetailModelType extends UmbContentDetailModel, + DetailModelType extends UmbContentDetailModel, DetailRepositoryType extends UmbDetailRepository = UmbDetailRepository, ContentTypeDetailModel extends UmbContentTypeModel = UmbContentTypeModel, VariantModelType extends UmbEntityVariantModel = UmbEntityVariantModel, @@ -119,7 +114,7 @@ export abstract class UmbContentDetailWorkspaceBase< unique: language.unique, // This must be a variantId string! culture: language.unique, segment: null, - } as UmbEntityVariantOptionModel; + } as unknown as VariantModelType; }); } else if (varies === false) { return [ @@ -129,10 +124,10 @@ export abstract class UmbContentDetailWorkspaceBase< culture: null, segment: null, unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! - } as UmbEntityVariantOptionModel, + } as unknown as VariantModelType, ]; } - return [] as Array; + return [] as Array; }, ); From b25b348105ad052f686d5c0255c91f212c256105 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:12:26 +0200 Subject: [PATCH 065/170] call create scaffold in member workspace context --- .../member/member-workspace.context.ts | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index 653651bd04..88ee9b37b2 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -1,7 +1,7 @@ import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS } from '../../repository/index.js'; import type { UmbMemberDetailModel, UmbMemberVariantModel } from '../../types.js'; import { UmbMemberPropertyDatasetContext } from '../../property-dataset-context/member-property-dataset-context.js'; -import { UMB_MEMBER_ENTITY_TYPE } from '../../entity.js'; +import { UMB_MEMBER_ENTITY_TYPE, UMB_MEMBER_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_MEMBER_WORKSPACE_ALIAS } from './manifests.js'; import { UmbMemberWorkspaceEditorElement } from './member-workspace-editor.element.js'; import { UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD } from './constants.js'; @@ -66,21 +66,14 @@ export class UmbMemberWorkspaceContext } async create(memberTypeUnique: string) { - this.resetState(); - this.#getDataPromise = this.repository.createScaffold({ - memberType: { - unique: memberTypeUnique, + return this.createScaffold({ + parent: { entityType: UMB_MEMBER_ROOT_ENTITY_TYPE, unique: null }, + preset: { + memberType: { + unique: memberTypeUnique, + }, }, }); - const { data } = await this.#getDataPromise; - if (!data) return undefined; - - this.#entityContext.setEntityType(UMB_MEMBER_ENTITY_TYPE); - this.#entityContext.setUnique(data.unique); - this.setIsNew(true); - this.#data.setPersisted(undefined); - this.#data.setCurrent(data); - return data; } getContentTypeId() { From f0b612e86631f72e58d1a340af23677b3bd09dee Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:16:11 +0200 Subject: [PATCH 066/170] add back observables for create and update date --- .../members/member/workspace/member/member-workspace.context.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index 88ee9b37b2..d234c4ea70 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -21,6 +21,8 @@ export class UmbMemberWorkspaceContext { readonly contentTypeUnique = this._data.createObservablePartOfCurrent((data) => data?.memberType.unique); readonly kind = this._data.createObservablePartOfCurrent((data) => data?.kind); + readonly createDate = this._data.createObservablePartOfCurrent((data) => data?.variants[0].createDate); + readonly updateDate = this._data.createObservablePartOfCurrent((data) => data?.variants[0].updateDate); constructor(host: UmbControllerHost) { super(host, { From f204d4d6ac5a0531307920bad720f9e96b6dfe7e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:19:23 +0200 Subject: [PATCH 067/170] use correct unique type --- .../action/create-media-collection-action.element.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/packages/media/media/collection/action/create-media-collection-action.element.ts b/src/packages/media/media/collection/action/create-media-collection-action.element.ts index 0b3faf83a1..1a14b5ec76 100644 --- a/src/packages/media/media/collection/action/create-media-collection-action.element.ts +++ b/src/packages/media/media/collection/action/create-media-collection-action.element.ts @@ -9,6 +9,7 @@ import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import type { ManifestCollectionAction } from '@umbraco-cms/backoffice/collection'; import type { UmbAllowedMediaTypeModel } from '@umbraco-cms/backoffice/media-type'; +import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; @customElement('umb-create-media-collection-action') export class UmbCreateMediaCollectionActionElement extends UmbLitElement { @@ -22,7 +23,7 @@ export class UmbCreateMediaCollectionActionElement extends UmbLitElement { private _currentView?: string; @state() - private _mediaUnique?: string; + private _mediaUnique?: UmbEntityUnique; @state() private _mediaTypeUnique?: string; @@ -54,6 +55,7 @@ export class UmbCreateMediaCollectionActionElement extends UmbLitElement { this.observe(workspaceContext.unique, (unique) => { this._mediaUnique = unique; }); + this.observe(workspaceContext.contentTypeUnique, (mediaTypeUnique) => { this._mediaTypeUnique = mediaTypeUnique; }); From 466623c4a78de6507d32ff78c275df0099ef0def Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:19:35 +0200 Subject: [PATCH 068/170] pass content type model --- .../core/content/workspace/content-detail-workspace-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 946d6e6e0d..630eda9b9a 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -93,7 +93,7 @@ export abstract class UmbContentDetailWorkspaceBase< this._data = new UmbContentWorkspaceDataManager(this, args.contentVariantScaffold); const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); - this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); + this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); this.variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); this.variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); this.varies = this.structure.ownerContentTypeObservablePart((x) => From ed6535e9daab01b887e38337514cf63cc8a0f391 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:27:05 +0200 Subject: [PATCH 069/170] pass variant option model --- .../workspace/content-detail-workspace-base.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 630eda9b9a..6025088ca4 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -11,7 +11,12 @@ import { type UmbEntityDetailWorkspaceContextCreateArgs, } from '@umbraco-cms/backoffice/workspace'; import { UmbContentTypeStructureManager, type UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; -import { UMB_INVARIANT_CULTURE, UmbVariantId, type UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; +import { + UMB_INVARIANT_CULTURE, + UmbVariantId, + type UmbEntityVariantModel, + type UmbEntityVariantOptionModel, +} from '@umbraco-cms/backoffice/variant'; import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; import { appendToFrozenArray, mergeObservables, UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; @@ -32,6 +37,7 @@ import { UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; +import type { UmbDocumentVariantOptionModel } from '@umbraco-cms/backoffice/document'; export interface UmbContentDetailWorkspaceContextArgs extends UmbEntityDetailWorkspaceContextArgs { contentTypeDetailRepository: UmbDetailRepositoryConstructor; @@ -43,6 +49,7 @@ export abstract class UmbContentDetailWorkspaceBase< DetailRepositoryType extends UmbDetailRepository = UmbDetailRepository, ContentTypeDetailModel extends UmbContentTypeModel = UmbContentTypeModel, VariantModelType extends UmbEntityVariantModel = UmbEntityVariantModel, + VariantOptionModelType extends UmbEntityVariantOptionModel = UmbEntityVariantOptionModel, CreateArgsType extends UmbEntityDetailWorkspaceContextCreateArgs = UmbEntityDetailWorkspaceContextCreateArgs, > @@ -85,7 +92,7 @@ export abstract class UmbContentDetailWorkspaceBase< */ public readonly languages = this.#languages.asObservable(); - readonly variantOptions; + public readonly variantOptions: Observable>; constructor(host: UmbControllerHost, args: UmbContentDetailWorkspaceContextArgs) { super(host, args); @@ -114,7 +121,7 @@ export abstract class UmbContentDetailWorkspaceBase< unique: language.unique, // This must be a variantId string! culture: language.unique, segment: null, - } as unknown as VariantModelType; + } as VariantOptionModelType; }); } else if (varies === false) { return [ @@ -124,10 +131,10 @@ export abstract class UmbContentDetailWorkspaceBase< culture: null, segment: null, unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! - } as unknown as VariantModelType, + } as VariantOptionModelType, ]; } - return [] as Array; + return [] as Array; }, ); From d2d4a0c5b67c196cfb25d13c87df4071bd6b8a37 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:29:54 +0200 Subject: [PATCH 070/170] pass types --- src/packages/media/media/workspace/media-workspace.context.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index c103472b09..2c01c33b5b 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -1,6 +1,7 @@ import { UmbMediaTypeDetailRepository } from '../../media-types/repository/detail/media-type-detail.repository.js'; import { UmbMediaPropertyDatasetContext } from '../property-dataset-context/media-property-dataset-context.js'; import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; +import type { UmbMediaDetailRepository } from '../repository/index.js'; import { UMB_MEDIA_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; import type { UmbMediaDetailModel, UmbMediaVariantModel } from '../types.js'; import { UMB_CREATE_MEDIA_WORKSPACE_PATH_PATTERN, UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../paths.js'; @@ -25,7 +26,7 @@ type ContentModel = UmbMediaDetailModel; type ContentTypeModel = UmbMediaTypeDetailModel; export class UmbMediaWorkspaceContext - extends UmbContentDetailWorkspaceBase + extends UmbContentDetailWorkspaceBase implements UmbContentWorkspaceContext, UmbContentCollectionWorkspaceContext From 6a143506cef219a7c1b2ccd503b0d86102ef2dd1 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:30:31 +0200 Subject: [PATCH 071/170] align local type names --- .../documents/workspace/document-workspace.context.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 7cf8f8d818..2fdc797439 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -43,18 +43,18 @@ import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/documen import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; -type EntityModel = UmbDocumentDetailModel; -type EntityTypeModel = UmbDocumentTypeDetailModel; +type ContentModel = UmbDocumentDetailModel; +type ContentTypeModel = UmbDocumentTypeDetailModel; export class UmbDocumentWorkspaceContext extends UmbContentDetailWorkspaceBase< - EntityModel, + ContentModel, UmbDocumentDetailRepository, - EntityTypeModel, + ContentTypeModel, UmbDocumentVariantModel > implements - UmbContentWorkspaceContext, + UmbContentWorkspaceContext, UmbPublishableWorkspaceContext, UmbContentCollectionWorkspaceContext { From 967b7148c1246c792873cc7c885b015dbfa3eeb9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 20:31:46 +0200 Subject: [PATCH 072/170] use correct local type --- .../action/create-document-collection-action.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts b/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts index 29e72c693b..4b0fafd6f8 100644 --- a/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts +++ b/src/packages/documents/documents/collection/action/create-document-collection-action.element.ts @@ -12,6 +12,7 @@ import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import type { ManifestCollectionAction } from '@umbraco-cms/backoffice/collection'; import type { UmbAllowedDocumentTypeModel } from '@umbraco-cms/backoffice/document-type'; +import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; @customElement('umb-create-document-collection-action') export class UmbCreateDocumentCollectionActionElement extends UmbLitElement { @@ -25,7 +26,7 @@ export class UmbCreateDocumentCollectionActionElement extends UmbLitElement { private _currentView?: string; @state() - private _documentUnique?: string; + private _documentUnique?: UmbEntityUnique; @state() private _documentTypeUnique?: string; From 2918e002073ce13547b85f9a7357fa96e3d0c395 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 21:39:18 +0200 Subject: [PATCH 073/170] add variant picker interface --- src/packages/core/content/index.ts | 1 + src/packages/core/content/variant-picker/index.ts | 1 + src/packages/core/content/variant-picker/types.ts | 8 ++++++++ 3 files changed, 10 insertions(+) create mode 100644 src/packages/core/content/variant-picker/index.ts create mode 100644 src/packages/core/content/variant-picker/types.ts diff --git a/src/packages/core/content/index.ts b/src/packages/core/content/index.ts index 1fe642380a..f1bd92d5c0 100644 --- a/src/packages/core/content/index.ts +++ b/src/packages/core/content/index.ts @@ -5,5 +5,6 @@ export * from './constants.js'; export * from './controller/merge-content-variant-data.controller.js'; export * from './manager/index.js'; export * from './property-dataset-context/index.js'; +export * from './variant-picker/index.js'; export * from './workspace/index.js'; export type * from './types.js'; diff --git a/src/packages/core/content/variant-picker/index.ts b/src/packages/core/content/variant-picker/index.ts new file mode 100644 index 0000000000..d4702960d5 --- /dev/null +++ b/src/packages/core/content/variant-picker/index.ts @@ -0,0 +1 @@ +export * from './types.js'; diff --git a/src/packages/core/content/variant-picker/types.ts b/src/packages/core/content/variant-picker/types.ts new file mode 100644 index 0000000000..42a4467c92 --- /dev/null +++ b/src/packages/core/content/variant-picker/types.ts @@ -0,0 +1,8 @@ +export interface UmbContentVariantPickerData { + options: Array; + pickableFilter?: (variantOption: VariantOptionModelType) => boolean; +} + +export interface UmbContentVariantPickerValue { + selection: Array; +} From 44c569cadfcfe4f54c17d8ed1bacb207783082f0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 21:39:38 +0200 Subject: [PATCH 074/170] pass in modal token --- .../content-detail-workspace-base.ts | 25 +++++++++++++------ .../documents/documents/modals/types.ts | 11 +++----- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 6025088ca4..1d3c981c87 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -1,6 +1,7 @@ import type { UmbContentDetailModel, UmbElementValueModel } from '../types.js'; import { UmbContentWorkspaceDataManager } from '../manager/index.js'; import { UmbMergeContentVariantDataController } from '../controller/merge-content-variant-data.controller.js'; +import type { UmbContentVariantPickerData, UmbContentVariantPickerValue } from '../variant-picker/index.js'; import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbDetailRepository, UmbDetailRepositoryConstructor } from '@umbraco-cms/backoffice/repository'; @@ -31,17 +32,19 @@ import { UmbVariantsValidationPathTranslator, UmbVariantValuesValidationPathTranslator, } from '@umbraco-cms/backoffice/validation'; +import type { UmbModalToken } from '@umbraco-cms/backoffice/modal'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; -import type { UmbDocumentVariantOptionModel } from '@umbraco-cms/backoffice/document'; -export interface UmbContentDetailWorkspaceContextArgs extends UmbEntityDetailWorkspaceContextArgs { +export interface UmbContentDetailWorkspaceContextArgs + extends UmbEntityDetailWorkspaceContextArgs { contentTypeDetailRepository: UmbDetailRepositoryConstructor; contentVariantScaffold: UmbEntityVariantModel; + saveModalToken: UmbModalToken, UmbContentVariantPickerValue>; } export abstract class UmbContentDetailWorkspaceBase< @@ -94,10 +97,16 @@ export abstract class UmbContentDetailWorkspaceBase< public readonly variantOptions: Observable>; - constructor(host: UmbControllerHost, args: UmbContentDetailWorkspaceContextArgs) { + #saveModalToken: UmbModalToken, UmbContentVariantPickerValue>; + + constructor( + host: UmbControllerHost, + args: UmbContentDetailWorkspaceContextArgs, + ) { super(host, args); this._data = new UmbContentWorkspaceDataManager(this, args.contentVariantScaffold); + this.#saveModalToken = args.saveModalToken; const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); @@ -340,7 +349,7 @@ export abstract class UmbContentDetailWorkspaceBase< }; } - protected _readOnlyLanguageVariantsFilter = (option: UmbDocumentVariantOptionModel) => { + protected _readOnlyLanguageVariantsFilter = (option: VariantOptionModelType) => { const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture); return readOnlyCultures.includes(option.culture) === false; }; @@ -389,13 +398,13 @@ export abstract class UmbContentDetailWorkspaceBase< if (options.length === 0) { throw new Error('No variants are available'); } else if (options.length === 1) { - // If only one option we will skip ahead and save the document with the only variant available: + // If only one option we will skip ahead and save the content with the only variant available: variantIds.push(UmbVariantId.Create(options[0])); } else { // If there are multiple variants, we will open the modal to let the user pick which variants to save. const modalManagerContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); const result = await modalManagerContext - .open(this, UMB_DOCUMENT_SAVE_MODAL, { + .open(this, this.#saveModalToken, { data: { options, pickableFilter: this._readOnlyLanguageVariantsFilter, @@ -431,7 +440,7 @@ export abstract class UmbContentDetailWorkspaceBase< const { data, error } = await this._detailRepository.create(saveData, parent.unique); if (!data || error) { - throw new Error('Error creating document'); + throw new Error('Error creating content'); } this.setIsNew(false); @@ -462,7 +471,7 @@ export abstract class UmbContentDetailWorkspaceBase< const { data, error } = await this._detailRepository.save(saveData); if (!data || error) { - throw new Error('Error saving document'); + throw new Error('Error saving content'); } this._data.setPersisted(data); diff --git a/src/packages/documents/documents/modals/types.ts b/src/packages/documents/documents/modals/types.ts index d3e91cdf89..56eeb92f50 100644 --- a/src/packages/documents/documents/modals/types.ts +++ b/src/packages/documents/documents/modals/types.ts @@ -1,10 +1,5 @@ import type { UmbDocumentVariantOptionModel } from '../types.js'; +import type { UmbContentVariantPickerData, UmbContentVariantPickerValue } from '@umbraco-cms/backoffice/content'; -export interface UmbDocumentVariantPickerData { - options: Array; - pickableFilter?: (variantOption: UmbDocumentVariantOptionModel) => boolean; -} - -export interface UmbDocumentVariantPickerValue { - selection: Array; -} +export type UmbDocumentVariantPickerData = UmbContentVariantPickerData; +export type UmbDocumentVariantPickerValue = UmbContentVariantPickerValue; From 6f39dbb33f8fdb40253ef6df0296fb51a2b2c167 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 22:04:20 +0200 Subject: [PATCH 075/170] pass save modal --- .../documents/documents/workspace/document-workspace.context.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 2fdc797439..df587ce823 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -7,6 +7,7 @@ import type { UmbDocumentVariantPublishModel, UmbDocumentDetailModel, UmbDocumen import { UMB_DOCUMENT_PUBLISH_MODAL, UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL, + UMB_DOCUMENT_SAVE_MODAL, UMB_DOCUMENT_SCHEDULE_MODAL, } from '../modals/index.js'; import { UmbDocumentPublishingRepository } from '../repository/publishing/index.js'; @@ -80,6 +81,7 @@ export class UmbDocumentWorkspaceContext detailRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbDocumentTypeDetailRepository, contentVariantScaffold: UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, + saveModalToken: UMB_DOCUMENT_SAVE_MODAL, }); this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); From 4fad10881935c4f26fd8fd6b8555abddda54bc46 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 23 Oct 2024 22:04:28 +0200 Subject: [PATCH 076/170] update types --- .../content-detail-workspace-base.ts | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 1d3c981c87..35b8b44eb5 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -40,24 +40,32 @@ import { UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; -export interface UmbContentDetailWorkspaceContextArgs - extends UmbEntityDetailWorkspaceContextArgs { - contentTypeDetailRepository: UmbDetailRepositoryConstructor; - contentVariantScaffold: UmbEntityVariantModel; - saveModalToken: UmbModalToken, UmbContentVariantPickerValue>; +export interface UmbContentDetailWorkspaceContextArgs< + DetailModelType extends UmbContentDetailModel, + ContentTypeDetailModelType extends UmbContentTypeModel = UmbContentTypeModel, + VariantModelType extends UmbEntityVariantModel = DetailModelType extends { variants: UmbEntityVariantModel[] } + ? DetailModelType['variants'][0] + : never, + VariantOptionModelType extends UmbEntityVariantOptionModel = UmbEntityVariantOptionModel, +> extends UmbEntityDetailWorkspaceContextArgs { + contentTypeDetailRepository: UmbDetailRepositoryConstructor; + contentVariantScaffold: VariantModelType; + saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; } export abstract class UmbContentDetailWorkspaceBase< DetailModelType extends UmbContentDetailModel, DetailRepositoryType extends UmbDetailRepository = UmbDetailRepository, - ContentTypeDetailModel extends UmbContentTypeModel = UmbContentTypeModel, - VariantModelType extends UmbEntityVariantModel = UmbEntityVariantModel, + ContentTypeDetailModelType extends UmbContentTypeModel = UmbContentTypeModel, + VariantModelType extends UmbEntityVariantModel = DetailModelType extends { variants: UmbEntityVariantModel[] } + ? DetailModelType['variants'][0] + : never, VariantOptionModelType extends UmbEntityVariantOptionModel = UmbEntityVariantOptionModel, CreateArgsType extends UmbEntityDetailWorkspaceContextCreateArgs = UmbEntityDetailWorkspaceContextCreateArgs, > extends UmbEntityDetailWorkspaceContextBase - implements UmbContentWorkspaceContext + implements UmbContentWorkspaceContext { public readonly IS_CONTENT_WORKSPACE_CONTEXT = true as const; @@ -97,19 +105,27 @@ export abstract class UmbContentDetailWorkspaceBase< public readonly variantOptions: Observable>; - #saveModalToken: UmbModalToken, UmbContentVariantPickerValue>; + #saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; constructor( host: UmbControllerHost, - args: UmbContentDetailWorkspaceContextArgs, + args: UmbContentDetailWorkspaceContextArgs< + DetailModelType, + ContentTypeDetailModelType, + VariantModelType, + VariantOptionModelType + >, ) { super(host, args); - this._data = new UmbContentWorkspaceDataManager(this, args.contentVariantScaffold); + this._data = new UmbContentWorkspaceDataManager( + this, + args.contentVariantScaffold, + ); this.#saveModalToken = args.saveModalToken; const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); - this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); + this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); this.variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); this.variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); this.varies = this.structure.ownerContentTypeObservablePart((x) => @@ -400,7 +416,7 @@ export abstract class UmbContentDetailWorkspaceBase< } else if (options.length === 1) { // If only one option we will skip ahead and save the content with the only variant available: variantIds.push(UmbVariantId.Create(options[0])); - } else { + } else if (this.#saveModalToken) { // If there are multiple variants, we will open the modal to let the user pick which variants to save. const modalManagerContext = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); const result = await modalManagerContext @@ -417,6 +433,8 @@ export abstract class UmbContentDetailWorkspaceBase< if (!result?.selection.length) return; variantIds = result?.selection.map((x) => UmbVariantId.FromString(x)) ?? []; + } else { + throw new Error('No variant picker modal token is set. There are multiple variants to save. Cannot proceed.'); } const saveData = await this._data.constructData(variantIds); From 563b42a5e81428677d54a6d14ecb01ec23e68b02 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 09:18:55 +0200 Subject: [PATCH 077/170] add setVariantScaffold method --- .../core/content/manager/content-data-manager.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/packages/core/content/manager/content-data-manager.ts b/src/packages/core/content/manager/content-data-manager.ts index 3c6601037f..1a14bcee89 100644 --- a/src/packages/core/content/manager/content-data-manager.ts +++ b/src/packages/core/content/manager/content-data-manager.ts @@ -14,11 +14,20 @@ export class UmbContentWorkspaceDataManager< //#repository; #variantScaffold?: ModelVariantType; - constructor(host: UmbControllerHost, variantScaffold: ModelVariantType) { + constructor(host: UmbControllerHost, variantScaffold?: ModelVariantType) { super(host); this.#variantScaffold = variantScaffold; } + /** + * Sets the variant scaffold data + * @param {ModelVariantType} variantScaffold The variant scaffold data + * @memberof UmbContentWorkspaceDataManager + */ + setVariantScaffold(variantScaffold: ModelVariantType) { + this.#variantScaffold = variantScaffold; + } + ensureVariantData(variantId: UmbVariantId) { this.updateVariantData(variantId); } From ffd1f73f55afbc167257b79d7f78bfe140e57cbf Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 09:19:23 +0200 Subject: [PATCH 078/170] set variant scaffold --- .../workspace/content-detail-workspace-base.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 35b8b44eb5..f22ca6cc2e 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -11,7 +11,11 @@ import { type UmbEntityDetailWorkspaceContextArgs, type UmbEntityDetailWorkspaceContextCreateArgs, } from '@umbraco-cms/backoffice/workspace'; -import { UmbContentTypeStructureManager, type UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; +import { + UmbContentTypeStructureManager, + type UmbContentTypeModel, + type UmbPropertyTypeModel, +} from '@umbraco-cms/backoffice/content-type'; import { UMB_INVARIANT_CULTURE, UmbVariantId, @@ -72,7 +76,9 @@ export abstract class UmbContentDetailWorkspaceBase< public readonly readOnlyState = new UmbReadOnlyVariantStateManager(this); /* Content Data */ - protected override _data: UmbContentWorkspaceDataManager; + protected override readonly _data = new UmbContentWorkspaceDataManager(this); + public override readonly entityType = this._data.createObservablePartOfCurrent((data) => data?.entityType); + public override readonly unique = this._data.createObservablePartOfCurrent((data) => data?.unique); public readonly values = this._data.createObservablePartOfCurrent((data) => data?.values); public readonly variants = this._data.createObservablePartOfCurrent((data) => data?.variants ?? []); @@ -103,7 +109,7 @@ export abstract class UmbContentDetailWorkspaceBase< */ public readonly languages = this.#languages.asObservable(); - public readonly variantOptions: Observable>; + public readonly variantOptions; #saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; @@ -118,10 +124,7 @@ export abstract class UmbContentDetailWorkspaceBase< ) { super(host, args); - this._data = new UmbContentWorkspaceDataManager( - this, - args.contentVariantScaffold, - ); + this._data.setVariantScaffold(args.contentVariantScaffold); this.#saveModalToken = args.saveModalToken; const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); From 0e8b45804e07d81b5bb1d747b3e53ebd49aefff5 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 09:19:30 +0200 Subject: [PATCH 079/170] add js docs --- .../content-detail-workspace-base.ts | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index f22ca6cc2e..547b2cccd4 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -245,33 +245,71 @@ export abstract class UmbContentDetailWorkspaceBase< /* Variants */ - getVariesByCulture() { + /** + * Get whether the content varies by culture + * @returns { boolean | undefined } - If the content varies by culture + * @memberof UmbContentDetailWorkspaceBase + */ + getVariesByCulture(): boolean | undefined { return this.#variesByCulture; } - getVariesBySegment() { + /** + * Get whether the content varies by segment + * @returns {boolean | undefined} - If the content varies by segment + * @memberof UmbContentDetailWorkspaceBase + */ + getVariesBySegment(): boolean | undefined { return this.#variesBySegment; } - getVaries() { + /** + * Get whether the content varies + * @returns { boolean | undefined } - If the content varies + * @memberof UmbContentDetailWorkspaceBase + */ + getVaries(): boolean | undefined { return this.#varies; } - variantById(variantId: UmbVariantId) { + /** + * Get the variant by the given variantId + * @param {UmbVariantId} variantId - The variant id + * @returns { Observable } - The variant or undefined if not found + * @memberof UmbContentDetailWorkspaceBase + */ + variantById(variantId: UmbVariantId): Observable { return this._data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); } - getVariant(variantId: UmbVariantId) { + /** + * Get the variant by the given variantId + * @param {UmbVariantId} variantId - The variant id + * @returns { VariantModelType | undefined } - The variant or undefined if not found + * @memberof UmbContentDetailWorkspaceBase + */ + getVariant(variantId: UmbVariantId): VariantModelType | undefined { return this._data.getCurrent()?.variants?.find((x) => variantId.compare(x)); } - async propertyStructureById(propertyId: string) { + /** + * Observe the property type + * @param {string} propertyId - The id of the property + * @returns {Promise>} - An observable for the property type + * @memberof UmbContentDetailWorkspaceBase + */ + async propertyStructureById(propertyId: string): Promise> { return this.structure.propertyStructureById(propertyId); } /* Values */ - getValues() { + /** + * Get the values of the content + * @returns {Array | undefined} - The values of the content + * @memberof UmbContentDetailWorkspaceBase + */ + getValues(): Array | undefined { return this._data.getCurrent()?.values; } From 875012110632c8f388ca4a94095c442f0650fbaa Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 09:26:14 +0200 Subject: [PATCH 080/170] pass types --- .../member/member-workspace.context.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index d234c4ea70..f650fa6e5c 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -1,4 +1,4 @@ -import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS } from '../../repository/index.js'; +import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, UmbMemberDetailRepository } from '../../repository/index.js'; import type { UmbMemberDetailModel, UmbMemberVariantModel } from '../../types.js'; import { UmbMemberPropertyDatasetContext } from '../../property-dataset-context/member-property-dataset-context.js'; import { UMB_MEMBER_ENTITY_TYPE, UMB_MEMBER_ROOT_ENTITY_TYPE } from '../../entity.js'; @@ -14,10 +14,17 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import { UmbContentDetailWorkspaceBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; -type EntityModel = UmbMemberDetailModel; +type ContentModel = UmbMemberDetailModel; +type ContentTypeModel = UmbMemberTypeDetailModel; + export class UmbMemberWorkspaceContext - extends UmbContentDetailWorkspaceBase - implements UmbContentWorkspaceContext + extends UmbContentDetailWorkspaceBase< + ContentModel, + UmbMemberDetailRepository, + ContentTypeModel, + UmbMemberVariantModel + > + implements UmbContentWorkspaceContext { readonly contentTypeUnique = this._data.createObservablePartOfCurrent((data) => data?.memberType.unique); readonly kind = this._data.createObservablePartOfCurrent((data) => data?.kind); @@ -97,7 +104,7 @@ export class UmbMemberWorkspaceContext } // Only for CRUD demonstration purposes - updateData(data: Partial) { + updateData(data: Partial) { const currentData = this._data.getCurrent(); if (!currentData) throw new Error('No data to update'); this._data.setCurrent({ ...currentData, ...data }); From 31e739ddd49776a56ef62e989ec4f49585a47c50 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 09:35:37 +0200 Subject: [PATCH 081/170] deprecate getContentTypeId and implement getContentTypeUnique --- .../content-detail-workspace-base.ts | 4 ++++ .../workspace/document-workspace.context.ts | 17 +++++++++++++++- .../workspace/media-workspace.context.ts | 17 +++++++++++++++- .../member/member-workspace.context.ts | 20 +++++++++++++++++-- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 547b2cccd4..2d65528bf2 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -88,6 +88,8 @@ export abstract class UmbContentDetailWorkspaceBase< public readonly variesBySegment; public readonly varies; + abstract readonly contentTypeUnique: Observable; + /* Data Type */ readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); #dataTypeSchemaAliasMap = new Map(); @@ -556,6 +558,8 @@ export abstract class UmbContentDetailWorkspaceBase< eventContext.dispatchEvent(event); } + abstract getContentTypeUnique(): string | undefined; + public override destroy(): void { this.structure.destroy(); this.#languageRepository.destroy(); diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index df587ce823..2229a9c834 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -178,7 +178,22 @@ export class UmbDocumentWorkspaceContext return UMB_DOCUMENT_COLLECTION_ALIAS; } - getContentTypeId() { + /** + * Gets the unique identifier of the content type. + * @deprecated Use `getContentTypeUnique` instead. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbDocumentWorkspaceContext + */ + getContentTypeId(): string | undefined { + return this.getContentTypeUnique(); + } + + /** + * Gets the unique identifier of the content type. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbDocumentWorkspaceContext + */ + getContentTypeUnique(): string | undefined { return this.getData()?.documentType.unique; } diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index 2c01c33b5b..3ddd508301 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -106,7 +106,22 @@ export class UmbMediaWorkspaceContext return UMB_MEDIA_COLLECTION_ALIAS; } - public getContentTypeId() { + /** + * Gets the unique identifier of the content type. + * @deprecated Use `getContentTypeUnique` instead. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbMediaWorkspaceContext + */ + getContentTypeId(): string | undefined { + return this.getContentTypeUnique(); + } + + /** + * Gets the unique identifier of the content type. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbMediaWorkspaceContext + */ + getContentTypeUnique(): string | undefined { return this.getData()?.mediaType.unique; } diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index f650fa6e5c..2c83fa7ca4 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -1,4 +1,5 @@ -import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, UmbMemberDetailRepository } from '../../repository/index.js'; +import type { UmbMemberDetailRepository } from '../../repository/index.js'; +import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS } from '../../repository/index.js'; import type { UmbMemberDetailModel, UmbMemberVariantModel } from '../../types.js'; import { UmbMemberPropertyDatasetContext } from '../../property-dataset-context/member-property-dataset-context.js'; import { UMB_MEMBER_ENTITY_TYPE, UMB_MEMBER_ROOT_ENTITY_TYPE } from '../../entity.js'; @@ -85,7 +86,22 @@ export class UmbMemberWorkspaceContext }); } - getContentTypeId() { + /** + * Gets the unique identifier of the content type. + * @deprecated Use `getContentTypeUnique` instead. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbMemberWorkspaceContext + */ + getContentTypeId(): string | undefined { + return this.getContentTypeUnique(); + } + + /** + * Gets the unique identifier of the content type. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbMemberWorkspaceContext + */ + getContentTypeUnique(): string | undefined { return this.getData()?.memberType.unique; } From b00629215fb28e12c21ab1ed39ed4b5fe9cd713d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 10:09:59 +0200 Subject: [PATCH 082/170] add js docs --- .../content-detail-workspace-base.ts | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 2d65528bf2..d2701689a0 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -111,6 +111,9 @@ export abstract class UmbContentDetailWorkspaceBase< */ public readonly languages = this.#languages.asObservable(); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + // TODO: fix type error public readonly variantOptions; #saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; @@ -225,7 +228,13 @@ export abstract class UmbContentDetailWorkspaceBase< this.#languages.setValue(data?.items ?? []); } - getName(variantId?: UmbVariantId) { + /** + * Get the name of a variant + * @param {UmbVariantId } [variantId] - The variant id + * @returns { string | undefined} - The name of the variant + * @memberof UmbContentDetailWorkspaceBase + */ + getName(variantId?: UmbVariantId): string | undefined { const variants = this._data.getCurrent()?.variants; if (!variants) return; if (variantId) { @@ -235,7 +244,16 @@ export abstract class UmbContentDetailWorkspaceBase< } } - setName(name: string, variantId?: UmbVariantId) { + /** + * Set the name of a variant + * @param {string} name - The name of the variant + * @param {UmbVariantId} [variantId] - The variant id + * @memberof UmbContentDetailWorkspaceBase + */ + setName(name: string, variantId?: UmbVariantId): void { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + // TODO: fix type error this._data.updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name }); } @@ -373,6 +391,10 @@ export abstract class UmbContentDetailWorkspaceBase< entry, (x) => x.alias === alias && variantId!.compare(x), ); + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + // TODO: fix type error this._data.updateCurrent({ values }); // TODO: We should move this type of logic to the act of saving [NL] From b4ebee2c3b944838206c2e051f6c6d6ead57b57d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 10:41:58 +0200 Subject: [PATCH 083/170] add docs --- .../documents/workspace/document-workspace.context.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 2229a9c834..46b76cdfe6 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -197,6 +197,11 @@ export class UmbDocumentWorkspaceContext return this.getData()?.documentType.unique; } + /** + * Set the template + * @param {string} templateUnique The unique identifier of the template. + * @memberof UmbDocumentWorkspaceContext + */ setTemplate(templateUnique: string) { this._data.updateCurrent({ template: { unique: templateUnique } }); } From 49acdb8970dffcd735bbfa2abe3b74feb4dc160a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 10:45:29 +0200 Subject: [PATCH 084/170] add more docs --- .../workspace/content-detail-workspace-base.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index d2701689a0..014f61b2e4 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -257,7 +257,13 @@ export abstract class UmbContentDetailWorkspaceBase< this._data.updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name }); } - name(variantId?: UmbVariantId) { + /** + * Get an observable for the name of a variant + * @param {UmbVariantId} [variantId] - The variant id + * @returns {Observable} - The name of the variant + * @memberof UmbContentDetailWorkspaceBase + */ + name(variantId?: UmbVariantId): Observable { return this._data.createObservablePartOfCurrent( (data) => data?.variants?.find((x) => variantId?.compare(x))?.name ?? '', ); @@ -368,6 +374,14 @@ export abstract class UmbContentDetailWorkspaceBase< return undefined; } + /** + * Set the value of the property with the given alias and variantId. + * @template ValueType + * @param {string} alias - The alias of the property + * @param {ValueType} value - The value to set + * @param {UmbVariantId} [variantId] - The variant id of the property + * @memberof UmbContentDetailWorkspaceBase + */ async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { this.initiatePropertyValueChange(); variantId ??= UmbVariantId.CreateInvariant(); From ca60dc894508806bbe2a33bc2bcd7ae35fecec8f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 10:48:00 +0200 Subject: [PATCH 085/170] add public to public methods --- .../content-detail-workspace-base.ts | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 014f61b2e4..efc3f44467 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -222,7 +222,7 @@ export abstract class UmbContentDetailWorkspaceBase< this.loadLanguages(); } - async loadLanguages() { + public async loadLanguages() { // TODO: If we don't end up having a Global Context for languages, then we should at least change this into using a asObservable which should be returned from the repository. [Nl] const { data } = await this.#languageRepository.requestCollection({}); this.#languages.setValue(data?.items ?? []); @@ -234,7 +234,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns { string | undefined} - The name of the variant * @memberof UmbContentDetailWorkspaceBase */ - getName(variantId?: UmbVariantId): string | undefined { + public getName(variantId?: UmbVariantId): string | undefined { const variants = this._data.getCurrent()?.variants; if (!variants) return; if (variantId) { @@ -250,7 +250,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @param {UmbVariantId} [variantId] - The variant id * @memberof UmbContentDetailWorkspaceBase */ - setName(name: string, variantId?: UmbVariantId): void { + public setName(name: string, variantId?: UmbVariantId): void { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore // TODO: fix type error @@ -263,7 +263,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns {Observable} - The name of the variant * @memberof UmbContentDetailWorkspaceBase */ - name(variantId?: UmbVariantId): Observable { + public name(variantId?: UmbVariantId): Observable { return this._data.createObservablePartOfCurrent( (data) => data?.variants?.find((x) => variantId?.compare(x))?.name ?? '', ); @@ -276,7 +276,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns { boolean | undefined } - If the content varies by culture * @memberof UmbContentDetailWorkspaceBase */ - getVariesByCulture(): boolean | undefined { + public getVariesByCulture(): boolean | undefined { return this.#variesByCulture; } @@ -285,7 +285,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns {boolean | undefined} - If the content varies by segment * @memberof UmbContentDetailWorkspaceBase */ - getVariesBySegment(): boolean | undefined { + public getVariesBySegment(): boolean | undefined { return this.#variesBySegment; } @@ -294,7 +294,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns { boolean | undefined } - If the content varies * @memberof UmbContentDetailWorkspaceBase */ - getVaries(): boolean | undefined { + public getVaries(): boolean | undefined { return this.#varies; } @@ -304,7 +304,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns { Observable } - The variant or undefined if not found * @memberof UmbContentDetailWorkspaceBase */ - variantById(variantId: UmbVariantId): Observable { + public variantById(variantId: UmbVariantId): Observable { return this._data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); } @@ -314,7 +314,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns { VariantModelType | undefined } - The variant or undefined if not found * @memberof UmbContentDetailWorkspaceBase */ - getVariant(variantId: UmbVariantId): VariantModelType | undefined { + public getVariant(variantId: UmbVariantId): VariantModelType | undefined { return this._data.getCurrent()?.variants?.find((x) => variantId.compare(x)); } @@ -324,7 +324,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns {Promise>} - An observable for the property type * @memberof UmbContentDetailWorkspaceBase */ - async propertyStructureById(propertyId: string): Promise> { + public async propertyStructureById(propertyId: string): Promise> { return this.structure.propertyStructureById(propertyId); } @@ -335,7 +335,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns {Array | undefined} - The values of the content * @memberof UmbContentDetailWorkspaceBase */ - getValues(): Array | undefined { + public getValues(): Array | undefined { return this._data.getCurrent()?.values; } @@ -346,7 +346,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @returns {Promise | undefined>} - An observable for the value of the property * @description Get an Observable for the value of this property. */ - async propertyValueByAlias( + public async propertyValueByAlias( propertyAlias: string, variantId?: UmbVariantId, ): Promise | undefined> { @@ -363,7 +363,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @param {UmbVariantId | undefined} variantId - The variant id of the property * @returns {ReturnType | undefined} The value or undefined if not set or found. */ - getPropertyValue(alias: string, variantId?: UmbVariantId) { + public getPropertyValue(alias: string, variantId?: UmbVariantId) { const currentData = this._data.getCurrent(); if (currentData) { const newDataSet = currentData.values?.find( @@ -382,7 +382,7 @@ export abstract class UmbContentDetailWorkspaceBase< * @param {UmbVariantId} [variantId] - The variant id of the property * @memberof UmbContentDetailWorkspaceBase */ - async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { + public async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { this.initiatePropertyValueChange(); variantId ??= UmbVariantId.CreateInvariant(); const property = await this.structure.getPropertyStructureByAlias(alias); @@ -417,11 +417,11 @@ export abstract class UmbContentDetailWorkspaceBase< this.finishPropertyValueChange(); } - initiatePropertyValueChange() { + public initiatePropertyValueChange() { this._data.initiatePropertyValueChange(); } - finishPropertyValueChange = () => { + public finishPropertyValueChange = () => { this._data.finishPropertyValueChange(); }; From 581dc091e4cd98e014b842330dd3b8f5a7ddb6e8 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 11:23:34 +0200 Subject: [PATCH 086/170] add abstract method createPropertyDatasetContext --- .../core/content/workspace/content-detail-workspace-base.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index efc3f44467..02b203f5d5 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -43,6 +43,7 @@ import { UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; +import type { UmbContentPropertyDatasetContext } from '../property-dataset-context/index.js'; export interface UmbContentDetailWorkspaceContextArgs< DetailModelType extends UmbContentDetailModel, @@ -596,6 +597,11 @@ export abstract class UmbContentDetailWorkspaceBase< abstract getContentTypeUnique(): string | undefined; + abstract createPropertyDatasetContext( + host: UmbControllerHost, + variantId: UmbVariantId, + ): UmbContentPropertyDatasetContext; + public override destroy(): void { this.structure.destroy(); this.#languageRepository.destroy(); From cec32971b2f6497fa4f432e2c105f64798c6942e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 12:27:46 +0200 Subject: [PATCH 087/170] add readonly back --- .../workspace/entity-detail/entity-detail-workspace-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index dc5bd5875c..83638414a6 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -40,7 +40,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< * @protected * @memberof UmbEntityWorkspaceContextBase */ - protected _data = new UmbEntityWorkspaceDataManager(this); + protected readonly _data = new UmbEntityWorkspaceDataManager(this); public readonly data = this._data.current; public readonly entityType = this._data.createObservablePartOfCurrent((data) => data?.entityType); From 442d16f5acf4f2c73dd7806d4a9cb753977c6374 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 12:44:41 +0200 Subject: [PATCH 088/170] add js docs --- .../entity-detail-workspace-base.ts | 59 +++++++++++++++---- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 83638414a6..efc0f003e0 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -75,23 +75,44 @@ export abstract class UmbEntityDetailWorkspaceContextBase< this.#observeRepository(args.detailRepositoryAlias); } - getEntityType() { + /** + * Get the entity type + * @returns { string } The entity type + */ + getEntityType(): string { return this.#entityType; } - getData() { + /** + * Get the current data + * @returns { DetailModelType | undefined } The entity context + */ + getData(): DetailModelType | undefined { return this._data.getCurrent(); } - getUnique() { + /** + * Get the unique + * @returns { string | undefined } The unique identifier + * + */ + getUnique(): UmbEntityUnique | undefined { return this._data.getCurrent()?.unique; } - getParent() { + /** + * Get the parent + * @returns { UmbEntityModel | undefined } The parent entity + */ + getParent(): UmbEntityModel | undefined { return this.#parent.getValue(); } - getParentUnique() { + /** + * Get the parent unique + * @returns { string | undefined } The parent unique identifier + */ + getParentUnique(): UmbEntityUnique | undefined { return this.#parent.getValue()?.unique; } @@ -118,10 +139,24 @@ export abstract class UmbEntityDetailWorkspaceContextBase< return response; } - public isLoaded() { + /** + * Method to check if the workspace data is loaded. + * @returns { Promise | undefined } true if the workspace data is loaded. + * @memberof UmbEntityWorkspaceContextBase + */ + public isLoaded(): Promise | undefined { return this._getDataPromise; } + /** + * Create a data scaffold + * @param {CreateArgsType} args The arguments to create the scaffold. + * @param {UmbEntityModel} args.parent The parent entity. + * @param {UmbEntityUnique} args.parent.unique The unique identifier of the parent entity. + * @param {string} args.parent.entityType The entity type of the parent entity. + * @param {Partial} args.preset The preset data. + * @returns { Promise | undefined } The data of the scaffold. + */ async createScaffold(args: CreateArgsType) { await this.#init; this.resetState(); @@ -163,19 +198,23 @@ export abstract class UmbEntityDetailWorkspaceContextBase< } } + /** + * Deletes the entity. + * @param unique The unique identifier of the entity to delete. + */ async delete(unique: string) { await this.#init; await this._detailRepository!.delete(unique); } /** - * @description method to check if the workspace is about to navigate away. + * Check if the workspace is about to navigate away. * @protected - * @param {string} newUrl - * @returns {*} + * @param {string} newUrl The new url that the workspace is navigating to. + * @returns { boolean} true if the workspace is navigating away. * @memberof UmbEntityWorkspaceContextBase */ - protected _checkWillNavigateAway(newUrl: string) { + protected _checkWillNavigateAway(newUrl: string): boolean { return !newUrl.includes(this.routes.getActiveLocalPath()); } From 7fedd71631d7be2148ee2a309e2edc146bc73161 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 13:14:06 +0200 Subject: [PATCH 089/170] add js docs --- .../entity-detail/entity-detail-workspace-base.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index efc0f003e0..4507bfe441 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -11,7 +11,7 @@ import { } from '@umbraco-cms/backoffice/entity-action'; import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry, type ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; -import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; +import type { UmbDetailRepository, UmbRepositoryResponseWithAsObservable } from '@umbraco-cms/backoffice/repository'; export interface UmbEntityDetailWorkspaceContextArgs { entityType: string; @@ -120,7 +120,12 @@ export abstract class UmbEntityDetailWorkspaceContextBase< return this.#parent.getValue()?.entityType; } - async load(unique: string) { + /** + * Load the workspace data + * @param {string} unique The unique identifier of the entity to load. + * @returns { Promise> } The data of the entity. + */ + async load(unique: string): Promise> { await this.#init; this.resetState(); this._getDataPromise = this._detailRepository!.requestByUnique(unique); From 5135b7376de3fbfb4dbc198ccfd47d4de4f00dcb Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 13:23:24 +0200 Subject: [PATCH 090/170] Update types.ts --- src/packages/core/content-type/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/packages/core/content-type/types.ts b/src/packages/core/content-type/types.ts index 092835bac4..132af25ee5 100644 --- a/src/packages/core/content-type/types.ts +++ b/src/packages/core/content-type/types.ts @@ -13,7 +13,6 @@ export interface UmbPropertyTypeContainerModel { export interface UmbContentTypeModel { unique: string; - entityType: string; name: string; alias: string; description: string; From f00f0f7d87bb404fe7d7fa336a3d9daf30f9aa49 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 14:26:53 +0200 Subject: [PATCH 091/170] implement on document blueprint --- .../content-detail-workspace-base.ts | 2 +- .../document-blueprint-workspace.context.ts | 440 ++---------------- 2 files changed, 43 insertions(+), 399 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 02b203f5d5..200a6ccec0 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -2,6 +2,7 @@ import type { UmbContentDetailModel, UmbElementValueModel } from '../types.js'; import { UmbContentWorkspaceDataManager } from '../manager/index.js'; import { UmbMergeContentVariantDataController } from '../controller/merge-content-variant-data.controller.js'; import type { UmbContentVariantPickerData, UmbContentVariantPickerValue } from '../variant-picker/index.js'; +import type { UmbContentPropertyDatasetContext } from '../property-dataset-context/index.js'; import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbDetailRepository, UmbDetailRepositoryConstructor } from '@umbraco-cms/backoffice/repository'; @@ -43,7 +44,6 @@ import { UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; -import type { UmbContentPropertyDatasetContext } from '../property-dataset-context/index.js'; export interface UmbContentDetailWorkspaceContextArgs< DetailModelType extends UmbContentDetailModel, diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index c3b5b3264f..7d21c5a073 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -1,190 +1,52 @@ import { UmbDocumentBlueprintPropertyDatasetContext } from '../property-dataset-context/document-blueprint-property-dataset-context.js'; import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../entity.js'; -import { UmbDocumentBlueprintDetailRepository } from '../repository/index.js'; -import type { - UmbDocumentBlueprintDetailModel, - UmbDocumentBlueprintValueModel, - UmbDocumentBlueprintVariantModel, - UmbDocumentBlueprintVariantOptionModel, -} from '../types.js'; -import { sortVariants } from '../utils.js'; +import type { UmbDocumentBlueprintDetailRepository } from '../repository/index.js'; +import { UMB_DOCUMENT_BLUEPRINT_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; +import type { UmbDocumentBlueprintDetailModel, UmbDocumentBlueprintVariantModel } from '../types.js'; import { UMB_CREATE_DOCUMENT_BLUEPRINT_WORKSPACE_PATH_PATTERN } from '../paths.js'; import { UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS } from './manifests.js'; import { - appendToFrozenArray, - mergeObservables, - UmbArrayState, - UmbObjectState, -} from '@umbraco-cms/backoffice/observable-api'; -import { - UmbSubmittableWorkspaceContextBase, UmbWorkspaceIsNewRedirectController, UmbWorkspaceIsNewRedirectControllerAlias, - UmbWorkspaceSplitViewManager, } from '@umbraco-cms/backoffice/workspace'; -import { UmbContentTypeStructureManager } from '@umbraco-cms/backoffice/content-type'; import { type UmbDocumentTypeDetailModel, UmbDocumentTypeDetailRepository, } from '@umbraco-cms/backoffice/document-type'; -import { UmbLanguageCollectionRepository } from '@umbraco-cms/backoffice/language'; -import { - UmbRequestReloadChildrenOfEntityEvent, - UmbRequestReloadStructureForEntityEvent, -} from '@umbraco-cms/backoffice/entity-action'; -import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { UMB_INVARIANT_CULTURE, UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbLanguageDetailModel } from '@umbraco-cms/backoffice/language'; -import { UmbContentWorkspaceDataManager, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; -import { UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; +import { UmbContentDetailWorkspaceBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; import { UMB_DOCUMENT_COLLECTION_ALIAS, UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN, } from '@umbraco-cms/backoffice/document'; -import { UmbDataTypeItemRepositoryManager } from '@umbraco-cms/backoffice/data-type'; -import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; -import { map } from '@umbraco-cms/backoffice/external/rxjs'; -import { UmbEntityContext, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -import { UMB_SETTINGS_SECTION_PATH } from '@umbraco-cms/backoffice/settings'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -type EntityModel = UmbDocumentBlueprintDetailModel; +type ContentModel = UmbDocumentBlueprintDetailModel; +type ContentTypeModel = UmbDocumentTypeDetailModel; export class UmbDocumentBlueprintWorkspaceContext - extends UmbSubmittableWorkspaceContextBase - implements UmbContentWorkspaceContext + extends UmbContentDetailWorkspaceBase< + ContentModel, + UmbDocumentBlueprintDetailRepository, + ContentTypeModel, + UmbDocumentBlueprintVariantModel + > + implements UmbContentWorkspaceContext { - readonly IS_CONTENT_WORKSPACE_CONTEXT = true as const; - // - readonly repository = new UmbDocumentBlueprintDetailRepository(this); - - #parent = new UmbObjectState<{ entityType: string; unique: string | null } | undefined>(undefined); - readonly parentUnique = this.#parent.asObservablePart((parent) => (parent ? parent.unique : undefined)); - readonly parentEntityType = this.#parent.asObservablePart((parent) => (parent ? parent.entityType : undefined)); - - readonly #data = new UmbContentWorkspaceDataManager(this, UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD); - - #getDataPromise?: Promise; - // TODO: Optimize this so it uses either a App Language Context? [NL] - #languageRepository = new UmbLanguageCollectionRepository(this); - #languages = new UmbArrayState([], (x) => x.unique); - public readonly languages = this.#languages.asObservable(); - - public readonly readOnlyState = new UmbReadOnlyVariantStateManager(this); - - public isLoaded() { - return this.#getDataPromise; - } - - readonly unique = this.#data.createObservablePartOfCurrent((data) => data?.unique); - readonly entityType = this.#data.createObservablePartOfCurrent((data) => data?.entityType); - - readonly contentTypeUnique = this.#data.createObservablePartOfCurrent((data) => data?.documentType.unique); - - readonly variants = this.#data.createObservablePartOfCurrent((data) => data?.variants || []); - - readonly values = this.#data.createObservablePartOfCurrent((data) => data?.values); - getValues() { - return this.#data.getCurrent()?.values; - } - - //readonly urls = this.#data.current.asObservablePart((data) => data?.urls || []); - - readonly structure = new UmbContentTypeStructureManager(this, new UmbDocumentTypeDetailRepository(this)); - readonly variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); - readonly variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); - readonly varies = this.structure.ownerContentTypeObservablePart((x) => - x ? x.variesByCulture || x.variesBySegment : undefined, - ); - #varies?: boolean; - #variesByCulture?: boolean; - #variesBySegment?: boolean; - - readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); - #dataTypeSchemaAliasMap = new Map(); - - readonly splitView = new UmbWorkspaceSplitViewManager(); - - readonly variantOptions = mergeObservables( - [this.varies, this.variants, this.languages], - ([varies, variants, languages]) => { - // TODO: When including segments, when be aware about the case of segment varying when not culture varying. [NL] - if (varies === true) { - return languages.map((language) => { - return { - variant: variants.find((x) => x.culture === language.unique), - language, - // TODO: When including segments, this object should be updated to include a object for the segment. [NL] - // TODO: When including segments, the unique should be updated to include the segment as well. [NL] - unique: language.unique, // This must be a variantId string! - culture: language.unique, - segment: null, - } as UmbDocumentBlueprintVariantOptionModel; - }); - } else if (varies === false) { - return [ - { - variant: variants.find((x) => x.culture === null), - language: languages.find((x) => x.isDefault), - culture: null, - segment: null, - unique: UMB_INVARIANT_CULTURE, // This must be a variantId string! - } as UmbDocumentBlueprintVariantOptionModel, - ]; - } - return []; - }, - ).pipe(map((results) => results.sort(sortVariants))); - - // TODO: this should be set up for all entity workspace contexts in a base class - #entityContext = new UmbEntityContext(this); + readonly contentTypeUnique = this._data.createObservablePartOfCurrent((data) => data?.documentType.unique); constructor(host: UmbControllerHost) { - super(host, UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS); - - this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); - this.observe( - this.varies, - (varies) => { - this.#data.setVaries(varies); - this.#varies = varies; - }, - null, - ); - this.observe( - this.variesByCulture, - (varies) => { - this.#data.setVariesByCulture(varies); - this.#variesByCulture = varies; - }, - null, - ); - this.observe( - this.variesBySegment, - (varies) => { - this.#data.setVariesBySegment(varies); - this.#variesBySegment = varies; - }, - null, - ); - this.observe( - this.structure.contentTypeDataTypeUniques, - (dataTypeUniques: Array) => { - this.#dataTypeItemManager.setUniques(dataTypeUniques); - }, - null, - ); - this.observe(this.#dataTypeItemManager.items, (dataTypes) => { - // Make a map of the data type unique and editorAlias: - this.#dataTypeSchemaAliasMap = new Map( - dataTypes.map((dataType) => { - return [dataType.unique, dataType.propertyEditorSchemaAlias]; - }), - ); + super(host, { + entityType: UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE, + workspaceAlias: UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS, + detailRepositoryAlias: UMB_DOCUMENT_BLUEPRINT_DETAIL_REPOSITORY_ALIAS, + contentTypeDetailRepository: UmbDocumentTypeDetailRepository, + contentVariantScaffold: UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, }); - this.loadLanguages(); + this.observe(this.contentTypeUnique, (unique) => this.structure.loadType(unique), null); this.routes.setRoutes([ { @@ -215,251 +77,39 @@ export class UmbDocumentBlueprintWorkspaceContext ]); } - override resetState() { - super.resetState(); - this.#data.clear(); - } - - async loadLanguages() { - // TODO: If we don't end up having a Global Context for languages, then we should at least change this into using a asObservable which should be returned from the repository. [Nl] - const { data } = await this.#languageRepository.requestCollection({}); - this.#languages.setValue(data?.items ?? []); - } - - async load(unique: string) { - this.resetState(); - this.#getDataPromise = this.repository.requestByUnique(unique); - type GetDataType = Awaited>; - const { data, asObservable } = (await this.#getDataPromise) as GetDataType; - - if (data) { - this.#entityContext.setEntityType(UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE); - this.#entityContext.setUnique(unique); - this.setIsNew(false); - this.#data.setPersisted(data); - this.#data.setCurrent(data); - } - - this.observe(asObservable(), (entity) => this.#onStoreChange(entity), 'UmbDocumentBlueprintStoreObserver'); - } - - #onStoreChange(entity: EntityModel | undefined) { - if (!entity) { - //TODO: This solution is alright for now. But reconsider when we introduce signal-r - history.pushState(null, '', UMB_SETTINGS_SECTION_PATH); - } - } - async create(parent: UmbEntityModel, documentTypeUnique: string) { - this.resetState(); - this.#parent.setValue(parent); - - this.#getDataPromise = this.repository.createScaffold({ - documentType: { unique: documentTypeUnique, collection: null }, + return this.createScaffold({ + parent, + preset: { + documentType: { + unique: documentTypeUnique, + collection: null, + }, + }, }); - - const { data } = await this.#getDataPromise; - if (!data) return undefined; - - this.#entityContext.setEntityType(UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE); - this.#entityContext.setUnique(data.unique); - this.setIsNew(true); - this.#data.setPersisted(undefined); - this.#data.setCurrent(data); - return data; } getCollectionAlias() { return UMB_DOCUMENT_COLLECTION_ALIAS; } - getData() { - return this.#data.getCurrent(); - } - - getUnique() { - return this.getData()?.unique; - } - - getEntityType() { - return UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE; - } - - getContentTypeId() { - return this.getData()?.documentType.unique; - } - - getVaries() { - return this.#varies; - } - getVariesByCulture() { - return this.#variesByCulture; - } - getVariesBySegment() { - return this.#variesBySegment; - } - - variantById(variantId: UmbVariantId) { - return this.#data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); - } - - getVariant(variantId: UmbVariantId) { - return this.#data.getCurrent()?.variants?.find((x) => variantId.compare(x)); - } - - getName(variantId?: UmbVariantId) { - const variants = this.#data.getCurrent()?.variants; - if (!variants) return; - if (variantId) { - return variants.find((x) => variantId.compare(x))?.name; - } else { - return variants[0]?.name; - } - } - - setName(name: string, variantId?: UmbVariantId) { - this.#data.updateVariantData(variantId ?? UmbVariantId.CreateInvariant(), { name }); - } - - name(variantId?: UmbVariantId) { - return this.#data.createObservablePartOfCurrent( - (data) => data?.variants?.find((x) => variantId?.compare(x))?.name ?? '', - ); - } - - async propertyStructureById(propertyId: string) { - return this.structure.propertyStructureById(propertyId); - } /** - * @function propertyValueByAlias - * @param variantId - * @param {string} propertyAlias - * @returns {Promise | undefined>} - * @description Get an Observable for the value of this property. + * Gets the unique identifier of the content type. + * @deprecated Use `getContentTypeUnique` instead. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbDocumentWorkspaceContext */ - async propertyValueByAlias( - propertyAlias: string, - variantId?: UmbVariantId, - ): Promise | undefined> { - return this.#data.createObservablePartOfCurrent( - (data) => - data?.values?.find((x) => x?.alias === propertyAlias && (variantId ? variantId.compare(x as any) : true)) - ?.value as PropertyValueType, - ); + getContentTypeId(): string | undefined { + return this.getContentTypeUnique(); } /** - * Get the current value of the property with the given alias and variantId. - * @param alias - * @param variantId - * @returns The value or undefined if not set or found. + * Gets the unique identifier of the content type. + * @returns { string | undefined} The unique identifier of the content type. + * @memberof UmbDocumentWorkspaceContext */ - getPropertyValue(alias: string, variantId?: UmbVariantId) { - const currentData = this.#data.getCurrent(); - if (currentData) { - const newDataSet = currentData.values?.find( - (x) => x.alias === alias && (variantId ? variantId.compare(x as any) : true), - ); - return newDataSet?.value as ReturnType; - } - return undefined; - } - async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { - this.initiatePropertyValueChange(); - variantId ??= UmbVariantId.CreateInvariant(); - const property = await this.structure.getPropertyStructureByAlias(alias); - - if (!property) { - throw new Error(`Property alias "${alias}" not found.`); - } - - const editorAlias = this.#dataTypeSchemaAliasMap.get(property.dataType.unique); - if (!editorAlias) { - throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`); - } - - const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbDocumentBlueprintValueModel; - - const currentData = this.getData(); - if (currentData) { - const values = appendToFrozenArray( - currentData.values ?? [], - entry, - (x) => x.alias === alias && variantId!.compare(x), - ); - this.#data.updateCurrent({ values }); - - // TODO: We should move this type of logic to the act of saving [NL] - this.#data.ensureVariantData(variantId); - } - this.finishPropertyValueChange(); - } - - initiatePropertyValueChange() { - this.#data.initiatePropertyValueChange(); - } - finishPropertyValueChange = () => { - this.#data.finishPropertyValueChange(); - }; - - async #handleSave() { - const current = this.#data.getCurrent(); - if (!current?.unique) throw new Error('Unique is missing'); - - if (this.getIsNew()) { - const parent = this.#parent.getValue(); - if (!parent) throw new Error('Parent is not set'); - - const { data, error } = await this.repository.create(current, parent.unique); - if (!data || error) { - console.error('Error creating document', error); - throw new Error('Error creating document'); - } - - this.setIsNew(false); - this.#data.setPersisted(data); - // We do not know about the variant IDs, so lets update everything. - this.#data.setCurrent(data); - - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadChildrenOfEntityEvent({ - entityType: parent.entityType, - unique: parent.unique, - }); - eventContext.dispatchEvent(event); - } else { - // Save: - const { data, error } = await this.repository.save(current); - if (!data || error) { - console.error('Error saving document', error); - throw new Error('Error saving document'); - } - - this.#data.setPersisted(data); - // We do not know about the variant IDs, so lets update everything. - this.#data.setCurrent(data); - - const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadStructureForEntityEvent({ - unique: this.getUnique()!, - entityType: this.getEntityType(), - }); - - eventContext.dispatchEvent(event); - } - } - - async submit() { - const data = this.getData(); - if (!data) throw new Error('Data is missing'); - await this.#handleSave(); - } - - async delete() { - const id = this.getUnique(); - if (id) { - await this.repository.delete(id); - } + getContentTypeUnique(): string | undefined { + return this.getData()?.documentType.unique; } public createPropertyDatasetContext( @@ -468,12 +118,6 @@ export class UmbDocumentBlueprintWorkspaceContext ): UmbDocumentBlueprintPropertyDatasetContext { return new UmbDocumentBlueprintPropertyDatasetContext(host, this, variantId); } - - public override destroy(): void { - this.structure.destroy(); - this.#languageRepository.destroy(); - super.destroy(); - } } export { UmbDocumentBlueprintWorkspaceContext as api }; From 76b7e29ad320ff110691413d6b552618c542ee51 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 14:34:09 +0200 Subject: [PATCH 092/170] align resetState --- .../workspace/document-blueprint-workspace.context.ts | 5 +++++ .../media/media/workspace/media-workspace.context.ts | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index 7d21c5a073..2840311cbe 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -77,6 +77,11 @@ export class UmbDocumentBlueprintWorkspaceContext ]); } + override resetState() { + super.resetState(); + this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); + } + async create(parent: UmbEntityModel, documentTypeUnique: string) { return this.createScaffold({ parent, diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index 3ddd508301..32b00552bd 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -81,6 +81,11 @@ export class UmbMediaWorkspaceContext ]); } + public override resetState() { + super.resetState(); + this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); + } + public override async load(unique: string) { const response = await super.load(unique); @@ -125,11 +130,6 @@ export class UmbMediaWorkspaceContext return this.getData()?.mediaType.unique; } - public override resetState() { - super.resetState(); - this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); - } - public createPropertyDatasetContext( host: UmbControllerHost, variantId: UmbVariantId, From 71cca74ff9ce5c4d9f1f152e2f26111b5318c807 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 14:46:33 +0200 Subject: [PATCH 093/170] add check for repository --- .../workspace/entity-detail/entity-detail-workspace-base.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 4507bfe441..cce84e90f1 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -224,9 +224,12 @@ export abstract class UmbEntityDetailWorkspaceContextBase< } async #create(currentData: DetailModelType) { + if (!this._detailRepository) throw new Error('Detail repository is not set'); + const parent = this.#parent.getValue(); if (!parent) throw new Error('Parent is not set'); - const { error, data } = await this._detailRepository!.create(currentData, parent.unique); + + const { error, data } = await this._detailRepository.create(currentData, parent.unique); if (error || !data) { throw error?.message ?? 'Repository did not return data after create.'; } From d926a24e68727dac9c3039614eb7f9261a5f3efd Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 14:46:41 +0200 Subject: [PATCH 094/170] align order --- .../core/content/workspace/content-detail-workspace-base.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 200a6ccec0..73a4523408 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -541,8 +541,8 @@ export abstract class UmbContentDetailWorkspaceBase< throw new Error('Error creating content'); } - this.setIsNew(false); this._data.setPersisted(data); + // TODO: Only update the variants that was chosen to be saved: const currentData = this._data.getCurrent(); @@ -554,6 +554,7 @@ export abstract class UmbContentDetailWorkspaceBase< variantIds, variantIdsIncludingInvariant, ); + this._data.setCurrent(newCurrentData); const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); @@ -562,6 +563,7 @@ export abstract class UmbContentDetailWorkspaceBase< unique: parent.unique, }); eventContext.dispatchEvent(event); + this.setIsNew(false); } async #update(variantIds: Array, saveData: DetailModelType) { From 330151e812d375ece7e78696968037a3629b8b48 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 15:07:29 +0200 Subject: [PATCH 095/170] remove --- .../workspace/document-blueprint-workspace.context.ts | 5 ----- .../documents/workspace/document-workspace.context.ts | 5 ----- .../member/workspace/member/member-workspace.context.ts | 5 ----- 3 files changed, 15 deletions(-) diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index 2840311cbe..7d21c5a073 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -77,11 +77,6 @@ export class UmbDocumentBlueprintWorkspaceContext ]); } - override resetState() { - super.resetState(); - this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); - } - async create(parent: UmbEntityModel, documentTypeUnique: string) { return this.createScaffold({ parent, diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 46b76cdfe6..c918b6ec2c 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -133,11 +133,6 @@ export class UmbDocumentWorkspaceContext ]); } - override resetState() { - super.resetState(); - this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); - } - override async load(unique: string) { const response = await super.load(unique); diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index 2c83fa7ca4..daa64f2680 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -70,11 +70,6 @@ export class UmbMemberWorkspaceContext ]); } - override resetState() { - super.resetState(); - this.removeUmbControllerByAlias(UmbWorkspaceIsNewRedirectControllerAlias); - } - async create(memberTypeUnique: string) { return this.createScaffold({ parent: { entityType: UMB_MEMBER_ROOT_ENTITY_TYPE, unique: null }, From fe2c26610b02c0c5540b785e6a5dbacd6138d791 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 22:58:07 +0200 Subject: [PATCH 096/170] export element --- .../core/workspace/components/workspace-split-view/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/core/workspace/components/workspace-split-view/index.ts b/src/packages/core/workspace/components/workspace-split-view/index.ts index 1312849754..509b219054 100644 --- a/src/packages/core/workspace/components/workspace-split-view/index.ts +++ b/src/packages/core/workspace/components/workspace-split-view/index.ts @@ -1,2 +1,3 @@ export * from './workspace-split-view.context.js'; export * from './workspace-split-view.element.js'; +export * from './workspace-split-view-variant-selector.element.js'; From 2d2033a130648fb53d4b96f6cb3625c9808d7dd2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 22:58:45 +0200 Subject: [PATCH 097/170] allow to slot in custom variant selectors --- .../workspace-split-view.element.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts index 0c3209b02b..57ee63c769 100644 --- a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts +++ b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts @@ -1,5 +1,5 @@ import { UmbWorkspaceSplitViewContext } from './workspace-split-view.context.js'; -import { css, html, customElement, property, ifDefined } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, property, ifDefined, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -31,6 +31,12 @@ export class UmbWorkspaceSplitViewElement extends UmbLitElement { return this.splitViewContext.getSplitViewIndex()!; } + @state() + private _variantSelectorSlotHasContent = false; + private _variantSelectorSlotChanged = (e: Event) => { + this._variantSelectorSlotHasContent = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0; + }; + splitViewContext = new UmbWorkspaceSplitViewContext(this); override render() { @@ -40,9 +46,12 @@ export class UmbWorkspaceSplitViewElement extends UmbLitElement { back-path=${ifDefined(this.backPath)} .hideNavigation=${!this.displayNavigation} .enforceNoFooter=${true}> - + + ${this._variantSelectorSlotHasContent + ? nothing + : html``} + + ${this.displayNavigation ? html`` : ''} @@ -67,6 +76,7 @@ export class UmbWorkspaceSplitViewElement extends UmbLitElement { #header { flex: 1 1 auto; + display: block; } `, ]; From 92fd8f2f1eab43149c65073ff00122ab205fdf2b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 22:59:13 +0200 Subject: [PATCH 098/170] make current variant selector more generic --- ...ace-split-view-variant-selector.element.ts | 86 ++++++++++--------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts index d7be226d99..1d0912e225 100644 --- a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts +++ b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts @@ -5,29 +5,43 @@ import { UUIInputEvent, type UUIPopoverContainerElement, } from '@umbraco-cms/backoffice/external/uui'; -import { css, html, nothing, customElement, state, query, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; -import type { UmbDocumentVariantOptionModel, UmbDocumentWorkspaceContext } from '@umbraco-cms/backoffice/document'; -import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import { + css, + html, + nothing, + customElement, + state, + query, + ifDefined, + type TemplateResult, +} from '@umbraco-cms/backoffice/external/lit'; +import { + UmbVariantId, + type UmbEntityVariantModel, + type UmbEntityVariantOptionModel, +} from '@umbraco-cms/backoffice/variant'; import { UMB_PROPERTY_DATASET_CONTEXT, isNameablePropertyDatasetContext } from '@umbraco-cms/backoffice/property'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { UmbVariantState } from '@umbraco-cms/backoffice/utils'; import { UmbDataPathVariantQuery, umbBindToValidation } from '@umbraco-cms/backoffice/validation'; +import type { UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; const elementName = 'umb-workspace-split-view-variant-selector'; @customElement(elementName) -export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { +export class UmbWorkspaceSplitViewVariantSelectorElement< + VariantOptionModelType extends + UmbEntityVariantOptionModel = UmbEntityVariantOptionModel, +> extends UmbLitElement { @query('#variant-selector-popover') private _popoverElement?: UUIPopoverContainerElement; @state() - private _variantOptions: Array = []; + private _variantOptions: Array = []; @state() private _readOnlyStates: Array = []; - // TODO: Stop using document context specific ActiveVariant type. @state() _activeVariants: Array = []; @@ -41,7 +55,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { private _name?: string; @state() - private _activeVariant?: UmbDocumentVariantOptionModel; + private _activeVariant?: VariantOptionModelType; @state() private _variantId?: UmbVariantId; @@ -52,22 +66,13 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { @state() private _readOnlyCultures: string[] = []; - #publishStateLocalizationMap = { - [DocumentVariantStateModel.DRAFT]: 'content_unpublished', - [DocumentVariantStateModel.PUBLISHED]: 'content_published', - [DocumentVariantStateModel.PUBLISHED_PENDING_CHANGES]: 'content_publishedPendingChanges', - [DocumentVariantStateModel.NOT_CREATED]: 'content_notCreated', - }; - constructor() { super(); this.consumeContext(UMB_WORKSPACE_SPLIT_VIEW_CONTEXT, (instance) => { this.#splitViewContext = instance; - // NOTICE: This is hacky (the TypeScript casting), we can only accept doing this so far because we currently only use the Variant Selector on Document Workspace. [NL] - // This would need a refactor to enable the code below to work with different ContentTypes. Main problem here is the state, which is not generic for them all. [NL] - const workspaceContext = this.#splitViewContext.getWorkspaceContext() as unknown as UmbDocumentWorkspaceContext; + const workspaceContext = this.#splitViewContext.getWorkspaceContext() as unknown as UmbContentWorkspaceContext; if (!workspaceContext) throw new Error('Split View Workspace context not found'); this.#observeVariants(workspaceContext); @@ -83,18 +88,18 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { }); } - async #observeVariants(workspaceContext: UmbDocumentWorkspaceContext) { + async #observeVariants(workspaceContext: UmbContentWorkspaceContext) { this.observe( workspaceContext.variantOptions, (variantOptions) => { - this._variantOptions = variantOptions; + this._variantOptions = variantOptions as Array; this.#setReadOnlyCultures(); }, '_observeVariantOptions', ); } - async #observeReadOnlyStates(workspaceContext: UmbDocumentWorkspaceContext) { + async #observeReadOnlyStates(workspaceContext: UmbContentWorkspaceContext) { this.observe( workspaceContext.readOnlyState.states, (states) => { @@ -105,7 +110,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { ); } - async #observeActiveVariants(workspaceContext: UmbDocumentWorkspaceContext) { + async #observeActiveVariants(workspaceContext: UmbContentWorkspaceContext) { this.observe( workspaceContext.splitView.activeVariantsInfo, (activeVariants) => { @@ -131,7 +136,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { async #observeCurrentVariant() { if (!this.#datasetContext || !this.#splitViewContext) return; - const workspaceContext = this.#splitViewContext.getWorkspaceContext() as unknown as UmbDocumentWorkspaceContext; + const workspaceContext = this.#splitViewContext.getWorkspaceContext() as unknown as UmbContentWorkspaceContext; if (!workspaceContext) return; this._variantId = this.#datasetContext.getVariantId(); @@ -140,7 +145,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { workspaceContext.variantOptions, (options) => { const option = options.find((option) => option.language.unique === this._variantId?.culture); - this._activeVariant = option; + this._activeVariant = option as VariantOptionModelType; }, '_currentLanguage', ); @@ -160,11 +165,11 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { } } - #switchVariant(variant: UmbDocumentVariantOptionModel) { + #switchVariant(variant: VariantOptionModelType) { this.#splitViewContext?.switchVariant(UmbVariantId.Create(variant)); } - #openSplitView(variant: UmbDocumentVariantOptionModel) { + #openSplitView(variant: VariantOptionModelType) { this.#splitViewContext?.openSplitView(UmbVariantId.Create(variant)); } @@ -176,7 +181,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { return culture !== null ? this._activeVariantsCultures.includes(culture) : true; } - #isCreateMode(variantOption: UmbDocumentVariantOptionModel) { + #isCreateMode(variantOption: VariantOptionModelType) { return !variantOption.variant && !this.#isVariantActive(variantOption.culture); } @@ -270,7 +275,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { : nothing; } - #renderListItem(variantOption: UmbDocumentVariantOptionModel) { + #renderListItem(variantOption: VariantOptionModelType) { return html`
  • @@ -300,6 +303,11 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { `; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + protected _renderVariantDetails(variantOption: VariantOptionModelType): TemplateResult { + return html``; + } + #isReadOnly(culture: string | null) { if (!culture) return false; return this._readOnlyCultures.includes(culture); @@ -310,7 +318,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { return this.#isReadOnly(culture) ? html`Read-only` : nothing; } - #renderSplitViewButton(variant: UmbDocumentVariantOptionModel) { + #renderSplitViewButton(variant: VariantOptionModelType) { return html` ${this.#isVariantActive(variant.culture) ? nothing @@ -451,7 +459,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement extends UmbLitElement { display: none; } - .variant-publish-state { + .variant-details { color: var(--uui-palette-malibu-dimmed); font-size: 12px; font-weight: normal; From f669bcf6d4beec1aa2397c6ad523ac647ab83392 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 22:59:29 +0200 Subject: [PATCH 099/170] add specific variant selector for documents --- ...ace-split-view-variant-selector.element.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts diff --git a/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts b/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts new file mode 100644 index 0000000000..fb4c54b3d5 --- /dev/null +++ b/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts @@ -0,0 +1,30 @@ +import type { UmbDocumentVariantOptionModel } from '../types.js'; +import { customElement, html } from '@umbraco-cms/backoffice/external/lit'; +import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbWorkspaceSplitViewVariantSelectorElement } from '@umbraco-cms/backoffice/workspace'; + +const elementName = 'umb-document-workspace-split-view-variant-selector'; +@customElement(elementName) +export class UmbDocumentWorkspaceSplitViewVariantSelectorElement extends UmbWorkspaceSplitViewVariantSelectorElement { + #publishStateLocalizationMap = { + [DocumentVariantStateModel.DRAFT]: 'content_unpublished', + [DocumentVariantStateModel.PUBLISHED]: 'content_published', + [DocumentVariantStateModel.PUBLISHED_PENDING_CHANGES]: 'content_publishedPendingChanges', + [DocumentVariantStateModel.NOT_CREATED]: 'content_notCreated', + }; + + override _renderVariantDetails(variantOption: UmbDocumentVariantOptionModel) { + return html` ${this.localize.term( + this.#publishStateLocalizationMap[variantOption.variant?.state || DocumentVariantStateModel.NOT_CREATED], + )}`; + } + + static override styles = [...UmbWorkspaceSplitViewVariantSelectorElement.styles, UmbTextStyles]; +} + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbDocumentWorkspaceSplitViewVariantSelectorElement; + } +} From 68649d579f467e5bed036ac1c0cb6aee1e1d14c0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 22:59:49 +0200 Subject: [PATCH 100/170] render new variant selector for in document workspace --- .../workspace/document-workspace-split-view.element.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts b/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts index 97f56208fa..270dd446a6 100644 --- a/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts +++ b/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts @@ -4,6 +4,8 @@ import { css, html, nothing, customElement, state, repeat } from '@umbraco-cms/b import type { ActiveVariant } from '@umbraco-cms/backoffice/workspace'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import './document-workspace-split-view-variant-selector.element.js'; + @customElement('umb-document-workspace-split-view') export class UmbDocumentWorkspaceSplitViewElement extends UmbLitElement { // TODO: Refactor: use the split view context token: @@ -44,7 +46,10 @@ export class UmbDocumentWorkspaceSplitViewElement extends UmbLitElement { + .displayNavigation=${view.index === this._variants!.length - 1}> + + `, )} From 4df21645c639d7fbe6007eca3d2812d7d36ace08 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 23:04:09 +0200 Subject: [PATCH 101/170] add null check --- .../element-property-dataset.context.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts b/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts index 0490888eb7..80eca0c95c 100644 --- a/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts +++ b/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts @@ -214,8 +214,8 @@ export abstract class UmbElementPropertyDatasetContext< } override destroy() { - super.destroy(); - this.#propertyVariantIdMap.destroy(); + this.#propertyVariantIdMap?.destroy(); (this.#propertyVariantIdMap as unknown) = undefined; + super.destroy(); } } From 879bd12b092603979b52588d1222d119893ae6d6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 24 Oct 2024 23:10:36 +0200 Subject: [PATCH 102/170] add label --- .../workspace-split-view-variant-selector.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts index 1d0912e225..773a4f9fbc 100644 --- a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts +++ b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts @@ -236,7 +236,8 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< compact slot="append" popovertarget="variant-selector-popover" - title=${ifDefined(this._activeVariant?.language.name)}> + title=${ifDefined(this._activeVariant?.language.name)} + label="Select a variant"> ${this._activeVariant?.language.name} ${this.#renderReadOnlyTag(this._activeVariant?.culture)} From 3fa1bd3775ca836535fcec7014449c5749443d6d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 25 Oct 2024 14:19:36 +0200 Subject: [PATCH 103/170] include context in the class name --- .../content/workspace/content-detail-workspace-base.ts | 2 +- .../workspace/document-blueprint-workspace.context.ts | 4 ++-- .../documents/workspace/document-workspace.context.ts | 4 ++-- .../media/media/workspace/media-workspace.context.ts | 9 +++++++-- .../member/workspace/member/member-workspace.context.ts | 4 ++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 73a4523408..dd905fd88a 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -58,7 +58,7 @@ export interface UmbContentDetailWorkspaceContextArgs< saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; } -export abstract class UmbContentDetailWorkspaceBase< +export abstract class UmbContentDetailWorkspaceContextBase< DetailModelType extends UmbContentDetailModel, DetailRepositoryType extends UmbDetailRepository = UmbDetailRepository, ContentTypeDetailModelType extends UmbContentTypeModel = UmbContentTypeModel, diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index 7d21c5a073..f794e75f94 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -15,7 +15,7 @@ import { } from '@umbraco-cms/backoffice/document-type'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbContentDetailWorkspaceBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; +import { UmbContentDetailWorkspaceContextBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; import { UMB_DOCUMENT_COLLECTION_ALIAS, UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, @@ -27,7 +27,7 @@ type ContentModel = UmbDocumentBlueprintDetailModel; type ContentTypeModel = UmbDocumentTypeDetailModel; export class UmbDocumentBlueprintWorkspaceContext - extends UmbContentDetailWorkspaceBase< + extends UmbContentDetailWorkspaceContextBase< ContentModel, UmbDocumentBlueprintDetailRepository, ContentTypeModel, diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index c918b6ec2c..02c7a4c548 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -36,7 +36,7 @@ import { UmbServerModelValidatorContext } from '@umbraco-cms/backoffice/validati import { UmbDocumentBlueprintDetailRepository } from '@umbraco-cms/backoffice/document-blueprint'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import { - UmbContentDetailWorkspaceBase, + UmbContentDetailWorkspaceContextBase, type UmbContentCollectionWorkspaceContext, type UmbContentWorkspaceContext, } from '@umbraco-cms/backoffice/content'; @@ -48,7 +48,7 @@ type ContentModel = UmbDocumentDetailModel; type ContentTypeModel = UmbDocumentTypeDetailModel; export class UmbDocumentWorkspaceContext - extends UmbContentDetailWorkspaceBase< + extends UmbContentDetailWorkspaceContextBase< ContentModel, UmbDocumentDetailRepository, ContentTypeModel, diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index 32b00552bd..cfcb2ee384 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -16,7 +16,7 @@ import { import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbMediaTypeDetailModel } from '@umbraco-cms/backoffice/media-type'; import { - UmbContentDetailWorkspaceBase, + UmbContentDetailWorkspaceContextBase, type UmbContentCollectionWorkspaceContext, type UmbContentWorkspaceContext, } from '@umbraco-cms/backoffice/content'; @@ -26,7 +26,12 @@ type ContentModel = UmbMediaDetailModel; type ContentTypeModel = UmbMediaTypeDetailModel; export class UmbMediaWorkspaceContext - extends UmbContentDetailWorkspaceBase + extends UmbContentDetailWorkspaceContextBase< + ContentModel, + UmbMediaDetailRepository, + ContentTypeModel, + UmbMediaVariantModel + > implements UmbContentWorkspaceContext, UmbContentCollectionWorkspaceContext diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index daa64f2680..b943cc6036 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -13,13 +13,13 @@ import { } from '@umbraco-cms/backoffice/workspace'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; -import { UmbContentDetailWorkspaceBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; +import { UmbContentDetailWorkspaceContextBase, type UmbContentWorkspaceContext } from '@umbraco-cms/backoffice/content'; type ContentModel = UmbMemberDetailModel; type ContentTypeModel = UmbMemberTypeDetailModel; export class UmbMemberWorkspaceContext - extends UmbContentDetailWorkspaceBase< + extends UmbContentDetailWorkspaceContextBase< ContentModel, UmbMemberDetailRepository, ContentTypeModel, From 2db8b47934a5e451a257cacd76eb634e0b64b6f0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 25 Oct 2024 14:53:30 +0200 Subject: [PATCH 104/170] sort variants --- .../workspace-split-view-variant-selector.element.ts | 7 ++++++- ...cument-workspace-split-view-variant-selector.element.ts | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts index 773a4f9fbc..1c0a09f6a2 100644 --- a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts +++ b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts @@ -66,6 +66,11 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< @state() private _readOnlyCultures: string[] = []; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + protected _variantSorter = (a: VariantOptionModelType, b: VariantOptionModelType) => { + return 0; + }; + constructor() { super(); @@ -92,7 +97,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< this.observe( workspaceContext.variantOptions, (variantOptions) => { - this._variantOptions = variantOptions as Array; + this._variantOptions = (variantOptions as Array).sort(this._variantSorter); this.#setReadOnlyCultures(); }, '_observeVariantOptions', diff --git a/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts b/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts index fb4c54b3d5..46a4bac112 100644 --- a/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts +++ b/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts @@ -1,4 +1,5 @@ import type { UmbDocumentVariantOptionModel } from '../types.js'; +import { sortVariants } from '../utils.js'; import { customElement, html } from '@umbraco-cms/backoffice/external/lit'; import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @@ -7,6 +8,8 @@ import { UmbWorkspaceSplitViewVariantSelectorElement } from '@umbraco-cms/backof const elementName = 'umb-document-workspace-split-view-variant-selector'; @customElement(elementName) export class UmbDocumentWorkspaceSplitViewVariantSelectorElement extends UmbWorkspaceSplitViewVariantSelectorElement { + protected override _variantSorter = sortVariants; + #publishStateLocalizationMap = { [DocumentVariantStateModel.DRAFT]: 'content_unpublished', [DocumentVariantStateModel.PUBLISHED]: 'content_published', From a07923c2a6c6965403f8c168e4061fd6eb26e3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 10:08:08 +0100 Subject: [PATCH 105/170] Feat: condition config types as a generic for extension registry (#2473) get condition config types as a generic for extension registry --- src/libs/extension-api/registry/extension.registry.ts | 5 +++-- src/packages/core/extension-registry/registry.ts | 7 +++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libs/extension-api/registry/extension.registry.ts b/src/libs/extension-api/registry/extension.registry.ts index 580da1cb1f..0d53be4b26 100644 --- a/src/libs/extension-api/registry/extension.registry.ts +++ b/src/libs/extension-api/registry/extension.registry.ts @@ -100,6 +100,7 @@ const sortExtensions = (a: ManifestBase, b: ManifestBase): number => (b.weight | export class UmbExtensionRegistry< IncomingManifestTypes extends ManifestBase, + IncomingConditionConfigTypes extends UmbConditionConfigBase = UmbConditionConfigBase, ManifestTypes extends ManifestBase = IncomingManifestTypes | ManifestBase, > { readonly MANIFEST_TYPES: ManifestTypes = undefined as never; @@ -490,7 +491,7 @@ export class UmbExtensionRegistry< * @param {string} alias - The alias of the extension to append the condition to. * @param {UmbConditionConfigBase} newCondition - The condition to append to the extension. */ - appendCondition(alias: string, newCondition: UmbConditionConfigBase) { + appendCondition(alias: string, newCondition: IncomingConditionConfigTypes) { this.appendConditions(alias, [newCondition]); } @@ -499,7 +500,7 @@ export class UmbExtensionRegistry< * @param {string} alias - The alias of the extension to append the condition to * @param {Array} newConditions - An array of conditions to be appended to an extension manifest. */ - appendConditions(alias: string, newConditions: Array) { + appendConditions(alias: string, newConditions: Array) { const existingConditionsToBeAdded = this.#additionalConditions.get(alias); this.#additionalConditions.set( alias, diff --git a/src/packages/core/extension-registry/registry.ts b/src/packages/core/extension-registry/registry.ts index 0985b3226e..22849345b6 100644 --- a/src/packages/core/extension-registry/registry.ts +++ b/src/packages/core/extension-registry/registry.ts @@ -2,9 +2,12 @@ import type { ManifestKind } from '@umbraco-cms/backoffice/extension-api'; import { UmbExtensionRegistry } from '@umbraco-cms/backoffice/extension-api'; export type UmbExtensionManifestKind = ManifestKind; -export type UmbBackofficeExtensionRegistry = UmbExtensionRegistry; +export type UmbBackofficeExtensionRegistry = UmbExtensionRegistry; -export const umbExtensionsRegistry = new UmbExtensionRegistry() as UmbBackofficeExtensionRegistry; +export const umbExtensionsRegistry = new UmbExtensionRegistry< + UmbExtensionManifest, + UmbExtensionConditionConfig +>() as UmbBackofficeExtensionRegistry; /** * @deprecated Use `UmbExtensionManifestKind` instead. From 21926435d6deac0c8e1bf2537577e9a7002a7ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 10:33:55 +0100 Subject: [PATCH 106/170] fix example --- examples/ufm-custom-component/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/ufm-custom-component/index.ts b/examples/ufm-custom-component/index.ts index af49cdc0f3..c7ee1eeba6 100644 --- a/examples/ufm-custom-component/index.ts +++ b/examples/ufm-custom-component/index.ts @@ -7,6 +7,7 @@ export const manifests: Array = [ name: 'Custom UFM Component', api: () => import('./custom-ufm-component.js'), meta: { + alias: 'myCustomComponent', marker: '%', }, }, From 15d068a53ae3b1e404acdfc517b76bb436b54034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 10:41:52 +0100 Subject: [PATCH 107/170] use slotchange callback + clean up --- .../workspace-split-view/workspace-split-view.element.ts | 9 +++++---- ...ment-workspace-split-view-variant-selector.element.ts | 3 --- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts index 57ee63c769..d205654112 100644 --- a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts +++ b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view.element.ts @@ -33,12 +33,13 @@ export class UmbWorkspaceSplitViewElement extends UmbLitElement { @state() private _variantSelectorSlotHasContent = false; - private _variantSelectorSlotChanged = (e: Event) => { - this._variantSelectorSlotHasContent = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0; - }; splitViewContext = new UmbWorkspaceSplitViewContext(this); + #onVariantSelectorSlotChanged(e: Event) { + this._variantSelectorSlotHasContent = (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0; + } + override render() { return html` - + ${this._variantSelectorSlotHasContent ? nothing : html``} diff --git a/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts b/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts index 46a4bac112..f08abb5f61 100644 --- a/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts +++ b/src/packages/documents/documents/workspace/document-workspace-split-view-variant-selector.element.ts @@ -2,7 +2,6 @@ import type { UmbDocumentVariantOptionModel } from '../types.js'; import { sortVariants } from '../utils.js'; import { customElement, html } from '@umbraco-cms/backoffice/external/lit'; import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbWorkspaceSplitViewVariantSelectorElement } from '@umbraco-cms/backoffice/workspace'; const elementName = 'umb-document-workspace-split-view-variant-selector'; @@ -22,8 +21,6 @@ export class UmbDocumentWorkspaceSplitViewVariantSelectorElement extends UmbWork this.#publishStateLocalizationMap[variantOption.variant?.state || DocumentVariantStateModel.NOT_CREATED], )}`; } - - static override styles = [...UmbWorkspaceSplitViewVariantSelectorElement.styles, UmbTextStyles]; } declare global { From c6c512e8fea40ddaa45fe678406a5f1a0ae31251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 10:44:38 +0100 Subject: [PATCH 108/170] author on comment --- .../workspace/document-workspace-split-view.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts b/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts index 270dd446a6..09c5ab3bbc 100644 --- a/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts +++ b/src/packages/documents/documents/workspace/document-workspace-split-view.element.ts @@ -17,7 +17,7 @@ export class UmbDocumentWorkspaceSplitViewElement extends UmbLitElement { constructor() { super(); - // TODO: Refactor: use a split view workspace context token: + // TODO: Refactor: use a split view workspace context token: [NL] this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (context) => { this._workspaceContext = context; this._observeActiveVariantInfo(); From 8f50c20a19daf2d8ab09b9306ea90097debe92f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 10:47:11 +0100 Subject: [PATCH 109/170] jsdocs updates --- .../content-detail-workspace-base.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index dd905fd88a..f097a97ddf 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -93,6 +93,9 @@ export abstract class UmbContentDetailWorkspaceContextBase< /* Data Type */ readonly #dataTypeItemManager = new UmbDataTypeItemRepositoryManager(this); + /** + * Data Type Schema Map is used for lookup, this should make coder simpler and give better performance. [NL] + */ #dataTypeSchemaAliasMap = new Map(); #varies?: boolean; @@ -210,7 +213,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< this.observe( this.#dataTypeItemManager.items, (dataTypes) => { - // Make a map of the data type unique and editorAlias: + // Make a map of the data type unique and editorAlias this.#dataTypeSchemaAliasMap = new Map( dataTypes.map((dataType) => { return [dataType.unique, dataType.propertyEditorSchemaAlias]; @@ -233,7 +236,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< * Get the name of a variant * @param {UmbVariantId } [variantId] - The variant id * @returns { string | undefined} - The name of the variant - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public getName(variantId?: UmbVariantId): string | undefined { const variants = this._data.getCurrent()?.variants; @@ -249,7 +252,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< * Set the name of a variant * @param {string} name - The name of the variant * @param {UmbVariantId} [variantId] - The variant id - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public setName(name: string, variantId?: UmbVariantId): void { // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -262,7 +265,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< * Get an observable for the name of a variant * @param {UmbVariantId} [variantId] - The variant id * @returns {Observable} - The name of the variant - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public name(variantId?: UmbVariantId): Observable { return this._data.createObservablePartOfCurrent( @@ -275,7 +278,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< /** * Get whether the content varies by culture * @returns { boolean | undefined } - If the content varies by culture - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public getVariesByCulture(): boolean | undefined { return this.#variesByCulture; @@ -284,7 +287,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< /** * Get whether the content varies by segment * @returns {boolean | undefined} - If the content varies by segment - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public getVariesBySegment(): boolean | undefined { return this.#variesBySegment; @@ -293,7 +296,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< /** * Get whether the content varies * @returns { boolean | undefined } - If the content varies - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public getVaries(): boolean | undefined { return this.#varies; @@ -303,7 +306,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< * Get the variant by the given variantId * @param {UmbVariantId} variantId - The variant id * @returns { Observable } - The variant or undefined if not found - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public variantById(variantId: UmbVariantId): Observable { return this._data.createObservablePartOfCurrent((data) => data?.variants?.find((x) => variantId.compare(x))); @@ -313,7 +316,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< * Get the variant by the given variantId * @param {UmbVariantId} variantId - The variant id * @returns { VariantModelType | undefined } - The variant or undefined if not found - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public getVariant(variantId: UmbVariantId): VariantModelType | undefined { return this._data.getCurrent()?.variants?.find((x) => variantId.compare(x)); @@ -323,7 +326,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< * Observe the property type * @param {string} propertyId - The id of the property * @returns {Promise>} - An observable for the property type - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public async propertyStructureById(propertyId: string): Promise> { return this.structure.propertyStructureById(propertyId); @@ -334,7 +337,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< /** * Get the values of the content * @returns {Array | undefined} - The values of the content - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public getValues(): Array | undefined { return this._data.getCurrent()?.values; @@ -381,7 +384,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< * @param {string} alias - The alias of the property * @param {ValueType} value - The value to set * @param {UmbVariantId} [variantId] - The variant id of the property - * @memberof UmbContentDetailWorkspaceBase + * @memberof UmbContentDetailWorkspaceContextBase */ public async setPropertyValue(alias: string, value: ValueType, variantId?: UmbVariantId) { this.initiatePropertyValueChange(); From f3ac97bb49bd30f67157410a8b0853487d8550f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 10:47:39 +0100 Subject: [PATCH 110/170] correct comment --- .../core/content/workspace/content-detail-workspace-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index f097a97ddf..020064e55f 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -415,7 +415,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< // TODO: fix type error this._data.updateCurrent({ values }); - // TODO: We should move this type of logic to the act of saving [NL] + // TODO: Ideally we should move this type of logic to the act of saving [NL] this._data.ensureVariantData(variantId); } this.finishPropertyValueChange(); From 73641183f7fcb56326eaf9eec0a440fa13072035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 10:56:05 +0100 Subject: [PATCH 111/170] jsdocs --- .../content/workspace/content-detail-workspace-base.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 020064e55f..14d08ae9d6 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -471,6 +471,10 @@ export abstract class UmbContentDetailWorkspaceContextBase< } } + /** + * Request a submit of the workspace, in the case of Content Workspaces the validation does not need to be valid for this to be submitted. + * @returns {Promise} a promise which resolves once it has been completed. + */ public override requestSubmit() { return this.#handleSubmit(); } @@ -479,6 +483,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< return this.#handleSubmit(); } + // Because we do not make validation prevent submission this also submits the workspace. [NL] public override invalidSubmit() { return this.#handleSubmit(); } @@ -546,11 +551,11 @@ export abstract class UmbContentDetailWorkspaceContextBase< this._data.setPersisted(data); - // TODO: Only update the variants that was chosen to be saved: const currentData = this._data.getCurrent(); const variantIdsIncludingInvariant = [...variantIds, UmbVariantId.CreateInvariant()]; + // Retrieve a data set which only contains updates from the selected variants + invariant. [NL] const newCurrentData = await new UmbMergeContentVariantDataController(this).process( currentData, data, From 3df3187fd9ff248daa900f8a0709578a4dcd0ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 11:13:57 +0100 Subject: [PATCH 112/170] correct variant selector look --- ...ace-split-view-variant-selector.element.ts | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts index 947f26a67a..efbce1d52c 100644 --- a/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts +++ b/src/packages/core/workspace/components/workspace-split-view/workspace-split-view-variant-selector.element.ts @@ -290,9 +290,10 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< : ''} ${this.#isReadOnly(variantOption.culture) ? 'readonly-mode' : ''}" @click=${() => this.#switchVariant(variantOption)}> ${this.#isCreateMode(variantOption) ? html`` : nothing} -
    +
    - ${variantOption.language.name} ${this.#renderReadOnlyTag(variantOption.culture)} + ${variantOption.variant?.name ?? variantOption.language.name} + ${this.#renderReadOnlyTag(variantOption.culture)}
    ${this._renderVariantDetails(variantOption)} @@ -303,6 +304,7 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< >
    +
    ${variantOption.language.name}
    ${this.#renderSplitViewButton(variantOption)}
  • @@ -332,10 +334,11 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< ? nothing : html` this.#openSplitView(variant)}> - Split view + Open in Split view `} `; @@ -423,6 +426,32 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< background: var(--uui-palette-sand); color: var(--uui-palette-space-cadet-light); } + .variant-selector-switch-button .variant-info { + flex-grow: 1; + } + + .variant-selector-switch-button .variant-details { + color: var(--uui-color-text-alt); + font-size: 12px; + font-weight: normal; + } + .variant-selector-switch-button .variant-details { + color: var(--uui-color-text-alt); + font-size: 12px; + font-weight: normal; + } + .variant-selector-switch-button.add-mode .variant-details { + color: var(--uui-palette-dusty-grey-dark); + } + + .variant-selector-switch-button .specs-info { + color: var(--uui-color-text-alt); + font-size: 12px; + font-weight: normal; + } + .variant-selector-switch-button.add-mode .specs-info { + color: var(--uui-palette-dusty-grey-dark); + } .variant-selector-switch-button i { font-weight: normal; @@ -466,12 +495,6 @@ export class UmbWorkspaceSplitViewVariantSelectorElement< bottom: 1px; display: none; } - - .variant-details { - color: var(--uui-palette-malibu-dimmed); - font-size: 12px; - font-weight: normal; - } `, ]; } From 6b5959884234907573ab40e3555c70857366d3c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:23:03 +0000 Subject: [PATCH 113/170] Bump @playwright/test from 1.46.1 to 1.48.2 (#2506) Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.46.1 to 1.48.2. - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.46.1...v1.48.2) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ca5630445..521348e994 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@eslint/js": "^9.9.1", "@hey-api/openapi-ts": "^0.52.11", "@open-wc/testing": "^4.0.0", - "@playwright/test": "^1.45.3", + "@playwright/test": "^1.48.2", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", @@ -1332,12 +1332,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.1.tgz", - "integrity": "sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", "dev": true, "dependencies": { - "playwright": "1.46.1" + "playwright": "1.48.2" }, "bin": { "playwright": "cli.js" @@ -13332,12 +13332,12 @@ } }, "node_modules/playwright": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz", - "integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", "dev": true, "dependencies": { - "playwright-core": "1.46.1" + "playwright-core": "1.48.2" }, "bin": { "playwright": "cli.js" @@ -13350,9 +13350,9 @@ } }, "node_modules/playwright-core": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz", - "integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==", + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", "dev": true, "bin": { "playwright-core": "cli.js" diff --git a/package.json b/package.json index 168c6ae73d..7d824eedd5 100644 --- a/package.json +++ b/package.json @@ -235,7 +235,7 @@ "@eslint/js": "^9.9.1", "@hey-api/openapi-ts": "^0.52.11", "@open-wc/testing": "^4.0.0", - "@playwright/test": "^1.45.3", + "@playwright/test": "^1.48.2", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", From 9282f57198e4097f7c77d5b6b1b26a66aa529298 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 14:44:15 +0100 Subject: [PATCH 114/170] visual corrections --- .../block-grid-block-inline.element.ts | 1 + .../components/block-grid-entry/block-grid-entry.element.ts | 6 +++--- .../user/user/components/user-avatar/user-avatar.element.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts index 82e3f4333f..d532cd46a8 100644 --- a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts +++ b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts @@ -294,6 +294,7 @@ export class UmbBlockGridBlockInlineElement extends UmbLitElement { #inside { position: relative; display: block; + padding: calc(var(--uui-size-layout-1)); } `, ]; diff --git a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts index 4e39f774d5..b46881743f 100644 --- a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts +++ b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts @@ -598,15 +598,15 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper inset: 0; border: 1px solid transparent; border-radius: var(--uui-border-radius); - box-shadow: - 0 0 0 1px rgba(255, 255, 255, 0.7), - inset 0 0 0 1px rgba(255, 255, 255, 0.7); transition: border-color 240ms ease-in; } :host(:hover):not(:drop)::after { display: block; border-color: var(--uui-color-interactive-emphasis); + box-shadow: + 0 0 0 1px rgba(255, 255, 255, 0.7), + inset 0 0 0 1px rgba(255, 255, 255, 0.7); } :host([drag-placeholder])::after { diff --git a/src/packages/user/user/components/user-avatar/user-avatar.element.ts b/src/packages/user/user/components/user-avatar/user-avatar.element.ts index 44661991dc..84fe60e2da 100644 --- a/src/packages/user/user/components/user-avatar/user-avatar.element.ts +++ b/src/packages/user/user/components/user-avatar/user-avatar.element.ts @@ -117,8 +117,8 @@ export class UmbUserAvatarElement extends UmbLitElement { css` uui-avatar { background-color: transparent; - border: 1.5px solid var(--uui-color-border); color: inherit; + box-shadow: 0 0 0 1.5px var(--uui-color-border); } uui-avatar.has-image { From 9a347bd7dbfa2d57200027b5658df77666618f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 15:38:26 +0100 Subject: [PATCH 115/170] validation translators ctrl alias --- ...nt-values-validation-path-translator.controller.ts | 4 +++- .../abstract-array-path-translator.controller.ts | 11 ++++++++--- .../validation-path-translator-base.controller.ts | 6 +++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/packages/block/block/validation/block-element-values-validation-path-translator.controller.ts b/src/packages/block/block/validation/block-element-values-validation-path-translator.controller.ts index 2c2b9da88c..4eaa8b431c 100644 --- a/src/packages/block/block/validation/block-element-values-validation-path-translator.controller.ts +++ b/src/packages/block/block/validation/block-element-values-validation-path-translator.controller.ts @@ -4,9 +4,11 @@ import { UmbDataPathPropertyValueQuery, } from '@umbraco-cms/backoffice/validation'; +const ctrlAlias = Symbol(); + export class UmbBlockElementValuesDataValidationPathTranslator extends UmbAbstractArrayValidationPathTranslator { constructor(host: UmbControllerHost) { - super(host, '$.values[', UmbDataPathPropertyValueQuery); + super(host, '$.values[', UmbDataPathPropertyValueQuery, ctrlAlias); } getDataFromIndex(index: number) { diff --git a/src/packages/core/validation/translators/abstract-array-path-translator.controller.ts b/src/packages/core/validation/translators/abstract-array-path-translator.controller.ts index 121310af55..4e7200a340 100644 --- a/src/packages/core/validation/translators/abstract-array-path-translator.controller.ts +++ b/src/packages/core/validation/translators/abstract-array-path-translator.controller.ts @@ -1,12 +1,17 @@ import { UmbValidationPathTranslatorBase } from './validation-path-translator-base.controller.js'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbControllerAlias, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; export abstract class UmbAbstractArrayValidationPathTranslator extends UmbValidationPathTranslatorBase { #initialPathToMatch: string; #queryMethod: (data: unknown) => string; - constructor(host: UmbControllerHost, initialPathToMatch: string, queryMethod: (data: any) => string) { - super(host); + constructor( + host: UmbControllerHost, + initialPathToMatch: string, + queryMethod: (data: any) => string, + ctrlAlias?: UmbControllerAlias, + ) { + super(host, ctrlAlias); this.#initialPathToMatch = initialPathToMatch; this.#queryMethod = queryMethod; diff --git a/src/packages/core/validation/translators/validation-path-translator-base.controller.ts b/src/packages/core/validation/translators/validation-path-translator-base.controller.ts index 27dda12276..b9a9bacb8e 100644 --- a/src/packages/core/validation/translators/validation-path-translator-base.controller.ts +++ b/src/packages/core/validation/translators/validation-path-translator-base.controller.ts @@ -1,6 +1,6 @@ import { UMB_VALIDATION_CONTEXT } from '../index.js'; import type { UmbValidationMessageTranslator } from './validation-message-path-translator.interface.js'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { UmbControllerAlias, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; export abstract class UmbValidationPathTranslatorBase @@ -10,8 +10,8 @@ export abstract class UmbValidationPathTranslatorBase // protected _context?: typeof UMB_VALIDATION_CONTEXT.TYPE; - constructor(host: UmbControllerHost) { - super(host); + constructor(host: UmbControllerHost, ctrlAlias?: UmbControllerAlias) { + super(host, ctrlAlias); this.consumeContext(UMB_VALIDATION_CONTEXT, (context) => { this._context?.removeTranslator(this); From 06839466b43e8aea8ea87e5817473cf9683eff06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 16:23:55 +0100 Subject: [PATCH 116/170] remember provider host for validation context --- .../core/validation/controllers/validation.controller.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/packages/core/validation/controllers/validation.controller.ts b/src/packages/core/validation/controllers/validation.controller.ts index feaf76897a..e535dc933d 100644 --- a/src/packages/core/validation/controllers/validation.controller.ts +++ b/src/packages/core/validation/controllers/validation.controller.ts @@ -79,13 +79,16 @@ export class UmbValidationController extends UmbControllerBase implements UmbVal this.messages.removeTranslator(translator); } + #currentProvideHost?: UmbClassInterface; /** * Provide this validation context to a specific controller host. * This can be used to Host a validation context in a Workspace, but provide it on a certain scope, like a specific Workspace View. * @param controllerHost {UmbClassInterface} */ provideAt(controllerHost: UmbClassInterface): void { + if (this.#currentProvideHost === controllerHost) return; this.#providerCtrl?.destroy(); + this.#currentProvideHost = controllerHost; this.#providerCtrl = controllerHost.provideContext(UMB_VALIDATION_CONTEXT, this); } From 24fc8acfe32e2bb87d31b902f0b347b015a6b6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 16:25:42 +0100 Subject: [PATCH 117/170] remove event listener --- src/libs/context-api/provide/context-provider.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/context-api/provide/context-provider.ts b/src/libs/context-api/provide/context-provider.ts index 31f62cdc8e..61d8f461b4 100644 --- a/src/libs/context-api/provide/context-provider.ts +++ b/src/libs/context-api/provide/context-provider.ts @@ -103,6 +103,8 @@ export class UmbContextProvider Date: Tue, 5 Nov 2024 16:28:59 +0100 Subject: [PATCH 118/170] can be destroyed multiple times --- .../element-property-dataset.context.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts b/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts index 0490888eb7..35a1a81a5b 100644 --- a/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts +++ b/src/packages/core/content/property-dataset-context/element-property-dataset.context.ts @@ -215,7 +215,8 @@ export abstract class UmbElementPropertyDatasetContext< override destroy() { super.destroy(); - this.#propertyVariantIdMap.destroy(); + + this.#propertyVariantIdMap?.destroy(); (this.#propertyVariantIdMap as unknown) = undefined; } } From 778866151dd57025499bfb79f62480b95f717e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 16:29:51 +0100 Subject: [PATCH 119/170] error to help general error discovery --- src/libs/context-api/consume/context-consumer.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/context-api/consume/context-consumer.ts b/src/libs/context-api/consume/context-consumer.ts index f4eab04f67..2805353c35 100644 --- a/src/libs/context-api/consume/context-consumer.ts +++ b/src/libs/context-api/consume/context-consumer.ts @@ -72,6 +72,10 @@ export class UmbContextConsumer Date: Tue, 5 Nov 2024 20:11:53 +0100 Subject: [PATCH 120/170] update to life cycle of extension initializers --- ...e-extension-initializer.controller.test.ts | 49 +++++------ .../base-extension-initializer.controller.ts | 83 +++++++++++-------- ...-extensions-initializer.controller.test.ts | 52 +++++++----- 3 files changed, 103 insertions(+), 81 deletions(-) diff --git a/src/libs/extension-api/controller/base-extension-initializer.controller.test.ts b/src/libs/extension-api/controller/base-extension-initializer.controller.test.ts index 29624ff01c..49853d3b33 100644 --- a/src/libs/extension-api/controller/base-extension-initializer.controller.test.ts +++ b/src/libs/extension-api/controller/base-extension-initializer.controller.test.ts @@ -59,12 +59,12 @@ class UmbTestConditionAlwaysInvalid extends UmbControllerBase implements UmbExte describe('UmbBaseExtensionController', () => { describe('Manifest without conditions', () => { - //let hostElement: UmbControllerHostElement; + let hostElement: UmbControllerHostElement; let extensionRegistry: UmbExtensionRegistry; let manifest: ManifestWithDynamicConditions; beforeEach(async () => { - //hostElement = await fixture(html``); + hostElement = await fixture(html``); extensionRegistry = new UmbExtensionRegistry(); manifest = { type: 'section', @@ -74,7 +74,7 @@ describe('UmbBaseExtensionController', () => { extensionRegistry.register(manifest); }); - /* + it('permits when there is no conditions', (done) => { const extensionController = new UmbTestExtensionController( hostElement, @@ -92,16 +92,15 @@ describe('UmbBaseExtensionController', () => { }, ); }); - */ }); describe('Manifest with empty conditions', () => { - //let hostElement: UmbControllerHostElement; + let hostElement: UmbControllerHostElement; let extensionRegistry: UmbExtensionRegistry; let manifest: ManifestWithDynamicConditions; beforeEach(async () => { - //hostElement = await fixture(html``); + hostElement = await fixture(html``); extensionRegistry = new UmbExtensionRegistry(); manifest = { type: 'section', @@ -113,7 +112,6 @@ describe('UmbBaseExtensionController', () => { extensionRegistry.register(manifest); }); - /* it('permits when there is empty conditions', (done) => { const extensionController = new UmbTestExtensionController( hostElement, @@ -124,7 +122,7 @@ describe('UmbBaseExtensionController', () => { if (extensionController.permitted) { expect(extensionController?.manifest?.alias).to.eq('Umb.Test.Section.1'); - // Also verifying that the promise gets resolved. + // Also verifying that the promise gets resolved. [NL] extensionController.asPromise().then(() => { done(); }); @@ -132,7 +130,6 @@ describe('UmbBaseExtensionController', () => { }, ); }); - */ }); describe('Manifest with valid conditions', () => { @@ -225,14 +222,14 @@ describe('UmbBaseExtensionController', () => { if (isPermitted) { count++; if (count === 1) { - // First time render, there is no conditions. + // First time render, there is no conditions. [NL] expect(extensionController.manifest?.weight).to.be.equal(2); expect(extensionController.manifest?.conditions?.length).to.be.equal(1); } else if (count === 2) { - // Second time render, there is conditions and weight is 22. + // Second time render, there is conditions and weight is 22. [NL] expect(extensionController.manifest?.weight).to.be.equal(22); expect(extensionController.manifest?.conditions?.length).to.be.equal(1); - // Check that the promise has been resolved for the first render to ensure timing is right. + // Check that the promise has been resolved for the first render to ensure timing is right. [NL] expect(initialPromiseResolved).to.be.true; done(); extensionController.destroy(); @@ -270,14 +267,14 @@ describe('UmbBaseExtensionController', () => { if (isPermitted) { count++; if (count === 1) { - // First time render, there is no conditions. + // First time render, there is no conditions. [NL] expect(extensionController.manifest?.weight).to.be.equal(3); expect(extensionController.manifest?.conditions?.length).to.be.equal(0); } else if (count === 2) { - // Second time render, there is conditions and weight is 33. + // Second time render, there is conditions and weight is 33. [NL] expect(extensionController.manifest?.weight).to.be.equal(33); expect(extensionController.manifest?.conditions?.length).to.be.equal(0); - // Check that the promise has been resolved for the first render to ensure timing is right. + // Check that the promise has been resolved for the first render to ensure timing is right. [NL] expect(initialPromiseResolved).to.be.true; done(); extensionController.destroy(); @@ -315,14 +312,14 @@ describe('UmbBaseExtensionController', () => { if (isPermitted) { count++; if (count === 1) { - // First time render, there is no conditions. + // First time render, there is no conditions. [NL] expect(extensionController.manifest?.weight).to.be.equal(4); expect(extensionController.manifest?.conditions?.length).to.be.equal(0); } else if (count === 2) { - // Second time render, there is conditions and weight is 33. + // Second time render, there is conditions and weight is updated. [NL] expect(extensionController.manifest?.weight).to.be.equal(44); expect(extensionController.manifest?.conditions?.length).to.be.equal(1); - // Check that the promise has been resolved for the first render to ensure timing is right. + // Check that the promise has been resolved for the first render to ensure timing is right. [NL] expect(initialPromiseResolved).to.be.true; done(); extensionController.destroy(); @@ -370,14 +367,14 @@ describe('UmbBaseExtensionController', () => { if (isPermitted) { count++; if (count === 1) { - // First time render, there is no conditions. + // First time render, there is no conditions. [NL] expect(extensionController.manifest?.weight).to.be.undefined; expect(extensionController.manifest?.conditions?.length).to.be.equal(0); } else if (count === 2) { - // Second time render, there is a matching kind and then weight is 123. + // Second time render, there is a matching kind and then weight is 123. [NL] expect(extensionController.manifest?.weight).to.be.equal(123); expect(extensionController.manifest?.conditions?.length).to.be.equal(0); - // Check that the promise has been resolved for the first render to ensure timing is right. + // Check that the promise has been resolved for the first render to ensure timing is right. [NL] expect(initialPromiseResolved).to.be.true; done(); extensionController.destroy(); @@ -531,7 +528,7 @@ describe('UmbBaseExtensionController', () => { 'Umb.Test.Section.1', async () => { count++; - // We want the controller callback to first fire when conditions are initialized. + // We want the controller callback to first fire when conditions are initialized. [NL] expect(extensionController.manifest?.conditions?.length).to.be.equal(1); expect(extensionController?.manifest?.alias).to.eq('Umb.Test.Section.1'); if (count === 1) { @@ -596,27 +593,27 @@ describe('UmbBaseExtensionController', () => { 'Umb.Test.Section.1', async (isPermitted) => { count++; - // We want the controller callback to first fire when conditions are initialized. + // We want the controller callback to first fire when conditions are initialized. [NL] expect(extensionController.manifest?.conditions?.length).to.be.equal(2); expect(extensionController?.manifest?.alias).to.eq('Umb.Test.Section.1'); if (count === 1) { expect(isPermitted).to.be.true; expect(extensionController?.permitted).to.be.true; - // Hack to double check that its two conditions that make up the state: + // Hack to double check that its two conditions that make up the state: [NL] expect( extensionController.getUmbControllers((controller) => (controller as any).permitted).length, ).to.equal(2); } else if (count === 2) { expect(isPermitted).to.be.false; expect(extensionController?.permitted).to.be.false; - // Hack to double check that its two conditions that make up the state, in this case its one, cause we already got the callback when one of the conditions changed. meaning in this split second one is still good: + // Hack to double check that its two conditions that make up the state, in this case its one, cause we already got the callback when one of the conditions changed. meaning in this split second one is still good: [NL] expect( extensionController.getUmbControllers((controller) => (controller as any).permitted).length, ).to.equal(1); // Then we are done: extensionController.destroy(); // End this test. - setTimeout(() => done(), 60); // Lets wait another round of the conditions approve/disapprove, just to see if the destroy stopped the conditions. (60ms, as that should be enough to test that another round does not happen.) + setTimeout(() => done(), 60); // Lets wait another round of the conditions approve/disapprove, just to see if the destroy stopped the conditions. (60ms, as that should be enough to test that another round does not happen.) [NL] } else if (count === 5) { expect(false).to.be.true; // This should not be called. } diff --git a/src/libs/extension-api/controller/base-extension-initializer.controller.ts b/src/libs/extension-api/controller/base-extension-initializer.controller.ts index cf5fcf63b7..d425586bd2 100644 --- a/src/libs/extension-api/controller/base-extension-initializer.controller.ts +++ b/src/libs/extension-api/controller/base-extension-initializer.controller.ts @@ -8,7 +8,10 @@ import type { ManifestWithDynamicConditions, UmbExtensionRegistry, } from '@umbraco-cms/backoffice/extension-api'; -import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { jsonStringComparison, type UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; + +const observeConditionsCtrlAlias = Symbol(); +const observeExtensionsCtrlAlias = Symbol(); /** * This abstract Controller holds the core to manage a single Extension. @@ -73,8 +76,6 @@ export abstract class UmbBaseExtensionInitializer< this.#manifestObserver = this.observe( this.#extensionRegistry.byAlias(this.#alias), (extensionManifest) => { - this.#clearPermittedState(); - this.#manifest = extensionManifest; if (extensionManifest) { if (extensionManifest.overwrites) { if (typeof extensionManifest.overwrites === 'string') { @@ -83,13 +84,15 @@ export abstract class UmbBaseExtensionInitializer< this.#overwrites = extensionManifest.overwrites; } } - this.#gotManifest(); + this.#gotManifest(extensionManifest); } else { + this.#manifest = undefined; + this.#clearPermittedState(); this.#overwrites = []; this.#cleanConditions(); } }, - '_observeExtensionManifest', + observeExtensionsCtrlAlias, ); } @@ -107,19 +110,22 @@ export abstract class UmbBaseExtensionInitializer< if (this.#conditionControllers === undefined || this.#conditionControllers.length === 0) return; this.#conditionControllers.forEach((controller) => controller.destroy()); this.#conditionControllers = []; - this.removeUmbControllerByAlias('_observeConditions'); + this.removeUmbControllerByAlias(observeConditionsCtrlAlias); } - #gotManifest() { - if (!this.#manifest) return; - const conditionConfigs = this.#manifest.conditions ?? []; + #gotManifest(manifest: ManifestType) { + const conditionConfigs = manifest.conditions ?? []; + const oldManifest = this.#manifest; + this.#manifest = manifest; - // As conditionConfigs might have been configured as something else than an array, then we ignorer them. + /* + // As conditionConfigs might have been configured as something else than an array, then we ignorer them. [NL] if (conditionConfigs.length === 0) { this.#cleanConditions(); this.#onConditionsChangedCallback(); return; } + */ const conditionAliases = conditionConfigs .map((condition) => condition.alias) @@ -130,32 +136,39 @@ export abstract class UmbBaseExtensionInitializer< this.#conditionControllers = this.#conditionControllers.filter((current) => { const continueExistence = conditionConfigs.find((config) => config === current.config); if (!continueExistence) { - // Destroy condition that is no longer needed. + // Destroy condition that is no longer needed. [NL] current.destroy(); } return continueExistence; }); - // Check if there was no change in conditions: - // First check if any got removed(old amount equal controllers after clean-up) - // && check if any new is about to be added(old equal new amount): - const noChangeInConditions = - oldAmountOfControllers === this.#conditionControllers.length && - oldAmountOfControllers === conditionConfigs.length; - if (conditionConfigs.length > 0) { - // Observes the conditions and initialize as they come in. + // Observes the conditions and initialize as they come in. [NL] this.observe( this.#extensionRegistry.byTypeAndAliases('condition', conditionAliases), this.#gotConditions, - '_observeConditions', + observeConditionsCtrlAlias, ); } else { - this.removeUmbControllerByAlias('_observeConditions'); + this.removeUmbControllerByAlias(observeConditionsCtrlAlias); } - if (noChangeInConditions) { - // There was not change in the amount of conditions, but the manifest was changed, this means this.#isPermitted is set to undefined and this will always fire the callback: + // If permitted we want to fire an update because we got a new manifest. [NL] + if (this.#isPermitted) { + // Check if there was no change in conditions: + // First check if any got removed(old amount equal controllers after clean-up) + // && check if any new is about to be added(old equal new amount): [NL] + // The reason for this is because we will get an update via the code above if there is a change in conditions. But if not we will trigger it here [NL] + const noChangeInConditions = + oldAmountOfControllers === this.#conditionControllers.length && + oldAmountOfControllers === conditionConfigs.length; + if (noChangeInConditions) { + if (jsonStringComparison(oldManifest, manifest) === false) { + // There was not change in the amount of conditions, but the manifest was changed, this means this.#isPermitted is set to undefined and this will always fire the callback: [NL] + this.#onPermissionChanged?.(this.#isPermitted, this as any); + } + } + } else { this.#onConditionsChangedCallback(); } } @@ -189,9 +202,9 @@ export abstract class UmbBaseExtensionInitializer< newConditionControllers .filter((x) => x !== undefined) .forEach((emerging) => { - // TODO: All of this could use a refactor at one point, when someone is fresh in their mind. - // Niels Notes: Current problem being that we are not aware about what is in the making, so we don't know if we end up creating the same condition multiple times. - // Because it took some time to create the conditions, it maybe have already gotten created by another cycle, so lets test again. + // TODO: All of this could use a refactor at one point, when someone is fresh in their mind. [NL] + // Niels Notes: Current problem being that we are not aware about what is in the making, so we don't know if we end up creating the same condition multiple times. [NL] + // Because it took some time to create the conditions, it maybe have already gotten created by another cycle, so lets test again. [NL] const existing = this.#conditionControllers.find((existing) => existing.config === emerging?.config); if (!existing) { this.#conditionControllers.push(emerging!); @@ -200,7 +213,7 @@ export abstract class UmbBaseExtensionInitializer< } }); - // If a change to amount of condition controllers, this will make sure that when new conditions are added, the callback is fired, so the extensions can be re-evaluated, starting out as bad. + // If a change to amount of condition controllers, this will make sure that when new conditions are added, the callback is fired, so the extensions can be re-evaluated, starting out as bad. [NL] if (oldLength !== this.#conditionControllers.length) { this.#onConditionsChangedCallback(); } @@ -230,14 +243,14 @@ export abstract class UmbBaseExtensionInitializer< #conditionsAreInitialized() { // Not good if we don't have a manifest. - // Only good if conditions of manifest is equal to the amount of condition controllers (one for each condition). + // Only good if conditions of manifest is equal to the amount of condition controllers (one for each condition). [NL] return ( this.#manifest !== undefined && this.#conditionControllers.length === (this.#manifest.conditions ?? []).length ); } #onConditionsChangedCallback = async () => { - // We will collect old value here, but we need to re-collect it after a async method have been called, as it could have changed in the mean time. + // We will collect old value here, but we need to re-collect it after a async method have been called, as it could have changed in the mean time. [NL] let oldValue = this.#isPermitted ?? false; // Find a condition that is not permitted (Notice how no conditions, means that this extension is permitted) @@ -250,13 +263,13 @@ export abstract class UmbBaseExtensionInitializer< if (isPositive === true) { if (this.#isPermitted !== true) { const newPermission = await this._conditionsAreGood(); - // Only set new permission if we are still positive, otherwise it means that we have been destroyed in the mean time. + // Only set new permission if we are still positive, otherwise it means that we have been destroyed in the mean time. [NL] if (newPermission === false || this._isConditionsPositive === false) { // Then we need to revert the above work: this._conditionsAreBad(); return; } - // We update the oldValue as this point, cause in this way we are sure its the value at this point, when doing async code someone else might have changed the state in the mean time. + // We update the oldValue as this point, cause in this way we are sure its the value at this point, when doing async code someone else might have changed the state in the mean time. [NL] oldValue = this.#isPermitted ?? false; this.#isPermitted = newPermission; } @@ -264,11 +277,11 @@ export abstract class UmbBaseExtensionInitializer< // Clean up: await this._conditionsAreBad(); - // Only continue if we are still negative, otherwise it means that something changed in the mean time. + // Only continue if we are still negative, otherwise it means that something changed in the mean time. [NL] if (this._isConditionsPositive === true) { return; } - // We update the oldValue as this point, cause in this way we are sure its the value at this point, when doing async code someone else might have changed the state in the mean time. + // We update the oldValue as this point, cause in this way we are sure its the value at this point, when doing async code someone else might have changed the state in the mean time. [NL] oldValue = this.#isPermitted ?? false; this.#isPermitted = false; } @@ -296,6 +309,7 @@ export abstract class UmbBaseExtensionInitializer< } */ + /* public override hostDisconnected(): void { super.hostDisconnected(); this._isConditionsPositive = false; @@ -305,6 +319,7 @@ export abstract class UmbBaseExtensionInitializer< this.#onPermissionChanged?.(false, this as unknown as SubClassType); } } + */ #clearPermittedState() { if (this.#isPermitted === true) { @@ -318,7 +333,7 @@ export abstract class UmbBaseExtensionInitializer< if (!this.#extensionRegistry) return; this.#manifest = undefined; this.#promiseResolvers = []; - this.#clearPermittedState(); // This fires the callback as not permitted, if it was permitted before. + this.#clearPermittedState(); // This fires the callback as not permitted, if it was permitted before. [NL] this.#isPermitted = undefined; this._isConditionsPositive = false; this.#overwrites = []; diff --git a/src/libs/extension-api/controller/base-extensions-initializer.controller.test.ts b/src/libs/extension-api/controller/base-extensions-initializer.controller.test.ts index abcf3326db..2b12443731 100644 --- a/src/libs/extension-api/controller/base-extensions-initializer.controller.test.ts +++ b/src/libs/extension-api/controller/base-extensions-initializer.controller.test.ts @@ -13,6 +13,8 @@ import { customElement, html } from '@umbraco-cms/backoffice/external/lit'; class UmbTestControllerHostElement extends UmbControllerHostElementMixin(HTMLElement) {} class UmbTestExtensionController extends UmbBaseExtensionInitializer { + testInsidesIsDestroyed?: boolean; + constructor( host: UmbControllerHost, extensionRegistry: UmbExtensionRegistry, @@ -28,7 +30,8 @@ class UmbTestExtensionController extends UmbBaseExtensionInitializer { } protected async _conditionsAreBad() { - // Destroy the element/class. + // Destroy the element/class. (or in the case of this test, then we just set a flag) [NL] + this.testInsidesIsDestroyed = true; } } @@ -111,7 +114,7 @@ describe('UmbBaseExtensionsController', () => { it('exposes both manifests', (done) => { let count = 0; - const extensionController = new UmbTestExtensionsController( + const extensionsInitController = new UmbTestExtensionsController( hostElement, testExtensionRegistry, 'extension-type', @@ -120,7 +123,7 @@ describe('UmbBaseExtensionsController', () => { count++; if (count === 1) { expect(permitted.length).to.eq(2); - extensionController.destroy(); + extensionsInitController.destroy(); } else if (count === 2) { done(); } @@ -138,7 +141,7 @@ describe('UmbBaseExtensionsController', () => { testExtensionRegistry.register(manifestExtra); let count = 0; - const extensionController = new UmbTestExtensionsController( + const extensionsInitController = new UmbTestExtensionsController( hostElement, testExtensionRegistry, ['extension-type', 'extension-type-extra'], @@ -151,9 +154,9 @@ describe('UmbBaseExtensionsController', () => { expect(permitted[1].alias).to.eq('Umb.Test.Extension.B'); expect(permitted[2].alias).to.eq('Umb.Test.Extension.Extra'); - extensionController.destroy(); + extensionsInitController.destroy(); } else if (count === 2) { - // Cause we destroyed there will be a last call to reset permitted controllers: + // Cause we destroyed there will be a last call to reset permitted controllers: [NL] expect(permitted.length).to.eq(0); done(); } @@ -189,7 +192,7 @@ describe('UmbBaseExtensionsController', () => { it('exposes just one manifests', (done) => { let count = 0; - const extensionController = new UmbTestExtensionsController( + const extensionsInitController = new UmbTestExtensionsController( hostElement, testExtensionRegistry, 'extension-type', @@ -197,17 +200,17 @@ describe('UmbBaseExtensionsController', () => { (permitted) => { count++; if (count === 1) { - // Still just equal one, as the second one overwrites the first one. + // Still just equal one, as the second one overwrites the first one. [NL] expect(permitted.length).to.eq(1); expect(permitted[0].alias).to.eq('Umb.Test.Extension.B'); - // lets remove the overwriting extension to see the original coming back. + // lets remove the overwriting extension to see the original coming back. [NL] testExtensionRegistry.unregister('Umb.Test.Extension.B'); } else if (count === 2) { expect(permitted.length).to.eq(1); expect(permitted[0].alias).to.eq('Umb.Test.Extension.A'); done(); - extensionController.destroy(); + extensionsInitController.destroy(); } }, ); @@ -255,7 +258,8 @@ describe('UmbBaseExtensionsController', () => { it('exposes only the overwriting manifest', (done) => { let count = 0; - const extensionController = new UmbTestExtensionsController( + let lastPermitted: PermittedControllerType[] = []; + const extensionsInitController = new UmbTestExtensionsController( hostElement, testExtensionRegistry, 'extension-type', @@ -263,24 +267,30 @@ describe('UmbBaseExtensionsController', () => { (permitted) => { count++; if (count === 1) { - // Still just equal one, as the second one overwrites the first one. + // Still just equal one, as the second one overwrites the first one. [NL] expect(permitted.length).to.eq(1); expect(permitted[0].alias).to.eq('Umb.Test.Extension.B'); - // lets remove the overwriting extension to see the original coming back. + // lets remove the overwriting extension to see the original coming back. [NL] testExtensionRegistry.unregister('Umb.Test.Extension.B'); } else if (count === 2) { expect(permitted.length).to.eq(1); expect(permitted[0].alias).to.eq('Umb.Test.Extension.A'); - extensionController.destroy(); + // CHecks that the controller that got overwritten is destroyed. [NL] + expect(lastPermitted[0].testInsidesIsDestroyed).to.be.true; + // Then continue the test and destroy the initializer. [NL] + extensionsInitController.destroy(); + // And then checks that the controller is destroyed. [NL] + expect(permitted[0].testInsidesIsDestroyed).to.be.true; } else if (count === 3) { - // Expect that destroy will only result in one last callback with no permitted controllers. + // Expect that destroy will only result in one last callback with no permitted controllers. [NL] expect(permitted.length).to.eq(0); - Promise.resolve().then(() => done()); // This wrap is to enable the test to detect if more callbacks are fired. + Promise.resolve().then(() => done()); // This wrap is to enable the test to detect if more callbacks are fired. [NL] } else if (count === 4) { - // This should not happen, we do only want one last callback when destroyed. + // This should not happen, we do only want one last callback when destroyed. [NL] expect(false).to.eq(true); } + lastPermitted = permitted; }, ); }); @@ -308,7 +318,7 @@ describe('UmbBaseExtensionsController', () => { ], }; - // Register opposite order, to ensure B is there when A comes around. A fix to be able to test this. Cause a late registration of B would not cause a change that is test able. + // Register opposite order, to ensure B is there when A comes around. A fix to be able to test this. Cause a late registration of B would not cause a change that is test able. [NL] testExtensionRegistry.register(manifestB); testExtensionRegistry.register(manifestA); testExtensionRegistry.register({ @@ -329,7 +339,7 @@ describe('UmbBaseExtensionsController', () => { it('exposes only the original manifest', (done) => { let count = 0; - const extensionController = new UmbTestExtensionsController( + const extensionsInitController = new UmbTestExtensionsController( hostElement, testExtensionRegistry, 'extension-type', @@ -338,11 +348,11 @@ describe('UmbBaseExtensionsController', () => { count++; if (count === 1) { - // First callback gives just one. We need to make a feature to gather changes to only reply after a computation cycle if we like to avoid this. + // First callback gives just one. We need to make a feature to gather changes to only reply after a computation cycle if we like to avoid this. [NL] expect(permitted.length).to.eq(1); expect(permitted[0].alias).to.eq('Umb.Test.Extension.A'); done(); - extensionController.destroy(); + extensionsInitController.destroy(); } }, ); From 099483d09d8c299780391be20c1285b25dc3cb51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 20:40:10 +0100 Subject: [PATCH 121/170] update style --- .../block-grid-block-inline.element.ts | 13 +++++++++++++ .../inline-list-block/inline-list-block.element.ts | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts index d532cd46a8..0145768cc8 100644 --- a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts +++ b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts @@ -277,6 +277,19 @@ export class UmbBlockGridBlockInlineElement extends UmbLitElement { margin-right: var(--uui-size-1); } + #info { + display: flex; + flex-direction: column; + align-items: start; + justify-content: center; + height: 100%; + padding-left: var(--uui-size-2, 6px); + } + + #name { + font-weight: 700; + } + :host(:not([disabled])) #open-part:hover #icon { color: var(--uui-color-interactive-emphasis); } diff --git a/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts b/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts index b0685a4828..f6749f63d3 100644 --- a/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts +++ b/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts @@ -271,6 +271,19 @@ export class UmbInlineListBlockElement extends UmbLitElement { margin-right: var(--uui-size-1); } + #info { + display: flex; + flex-direction: column; + align-items: start; + justify-content: center; + height: 100%; + padding-left: var(--uui-size-2, 6px); + } + + #name { + font-weight: 700; + } + :host(:not([disabled])) #open-part:hover #icon { color: var(--uui-color-interactive-emphasis); } From 54f6b1b75e99b5df73203ab7b21857ff17557778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 20:52:15 +0100 Subject: [PATCH 122/170] temp removal of umbDestroyOnDisconnect --- .../block-grid-entry/block-grid-entry.element.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts index b46881743f..70cad07654 100644 --- a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts +++ b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts @@ -414,8 +414,8 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper .unpublished=${!this._exposed} .config=${this._blockViewProps.config} .content=${this._blockViewProps.content} - .settings=${this._blockViewProps.settings} - ${umbDestroyOnDisconnect()}>`; + .settings=${this._blockViewProps.settings}>`; + //TODO: investigate if we should have ${umbDestroyOnDisconnect()} here. Note how it works for drag n' drop in grid between areas and areas-root } #renderRefBlock() { @@ -426,8 +426,8 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper .unpublished=${!this._exposed} .config=${this._blockViewProps.config} .content=${this._blockViewProps.content} - .settings=${this._blockViewProps.settings} - ${umbDestroyOnDisconnect()}>`; + .settings=${this._blockViewProps.settings}>`; + //TODO: investigate if we should have ${umbDestroyOnDisconnect()} here. Note how it works for drag n' drop in grid between areas and areas-root } #renderBlock() { From b42ab48d18d8db00157bfbb07ae0880374fa6ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 21:04:13 +0100 Subject: [PATCH 123/170] remove unused import --- .../components/block-grid-entry/block-grid-entry.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts index 70cad07654..c7f3811fa5 100644 --- a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts +++ b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts @@ -1,5 +1,5 @@ import { UmbBlockGridEntryContext } from '../../context/block-grid-entry.context.js'; -import { UmbLitElement, umbDestroyOnDisconnect } from '@umbraco-cms/backoffice/lit-element'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { html, css, customElement, property, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor'; From 74119ea36e2b85c43d7598d5b0aa9ec6e7be53fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 5 Nov 2024 22:17:33 +0100 Subject: [PATCH 124/170] fix infinite layout update --- .../controller/base-extension-initializer.controller.ts | 7 ++++++- .../block/block/workspace/block-workspace.context.ts | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libs/extension-api/controller/base-extension-initializer.controller.ts b/src/libs/extension-api/controller/base-extension-initializer.controller.ts index d425586bd2..52cff378b7 100644 --- a/src/libs/extension-api/controller/base-extension-initializer.controller.ts +++ b/src/libs/extension-api/controller/base-extension-initializer.controller.ts @@ -250,6 +250,11 @@ export abstract class UmbBaseExtensionInitializer< } #onConditionsChangedCallback = async () => { + if (this.#manifest === undefined) { + // This is cause by this controller begin destroyed in the mean time. [NL] + // When writing this the only plausible case is a call from the conditionController to the onChange callback. + return; + } // We will collect old value here, but we need to re-collect it after a async method have been called, as it could have changed in the mean time. [NL] let oldValue = this.#isPermitted ?? false; @@ -299,7 +304,7 @@ export abstract class UmbBaseExtensionInitializer< protected abstract _conditionsAreBad(): Promise; public equal(otherClass: UmbBaseExtensionInitializer | undefined): boolean { - return otherClass?.manifest === this.manifest; + return otherClass?.manifest === this.#manifest; } /* diff --git a/src/packages/block/block/workspace/block-workspace.context.ts b/src/packages/block/block/workspace/block-workspace.context.ts index 31cf151c32..1d1827445b 100644 --- a/src/packages/block/block/workspace/block-workspace.context.ts +++ b/src/packages/block/block/workspace/block-workspace.context.ts @@ -348,10 +348,15 @@ export class UmbBlockWorkspaceContext { if (layoutData) { + if (initialLayoutSet) { + initialLayoutSet = false; + return; + } this.#blockManager?.setOneLayout( layoutData, this.#modalContext?.data.originData as UmbBlockWorkspaceOriginData, From 7622a2adaae6bdb7fa87317d2ffeeb4bf5907ea8 Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Wed, 6 Nov 2024 09:21:22 +0000 Subject: [PATCH 125/170] Chore: Upgraded Tiptap dependencies to 2.9.1 (#2511) * Upgraded Tiptap dependencies to v2.9.1 * Uninstalled @tiptap/extension-text-style dependency as it's now part of @tiptap/starter-kit --- package-lock.json | 286 +++++++++++++++++++++++----------------------- package.json | 29 +++-- 2 files changed, 155 insertions(+), 160 deletions(-) diff --git a/package-lock.json b/package-lock.json index 521348e994..ffc2c48c1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,21 +12,20 @@ "./src/packages/*" ], "dependencies": { - "@tiptap/core": "^2.8.0", - "@tiptap/extension-image": "^2.8.0", - "@tiptap/extension-link": "^2.8.0", - "@tiptap/extension-placeholder": "^2.8.0", - "@tiptap/extension-subscript": "^2.8.0", - "@tiptap/extension-superscript": "^2.8.0", - "@tiptap/extension-table": "^2.8.0", - "@tiptap/extension-table-cell": "^2.8.0", - "@tiptap/extension-table-header": "^2.8.0", - "@tiptap/extension-table-row": "^2.8.0", - "@tiptap/extension-text-align": "^2.8.0", - "@tiptap/extension-text-style": "^2.8.0", - "@tiptap/extension-underline": "^2.8.0", - "@tiptap/pm": "^2.8.0", - "@tiptap/starter-kit": "^2.8.0", + "@tiptap/core": "^2.9.1", + "@tiptap/extension-image": "^2.9.1", + "@tiptap/extension-link": "^2.9.1", + "@tiptap/extension-placeholder": "^2.9.1", + "@tiptap/extension-subscript": "^2.9.1", + "@tiptap/extension-superscript": "^2.9.1", + "@tiptap/extension-table": "^2.9.1", + "@tiptap/extension-table-cell": "^2.9.1", + "@tiptap/extension-table-header": "^2.9.1", + "@tiptap/extension-table-row": "^2.9.1", + "@tiptap/extension-text-align": "^2.9.1", + "@tiptap/extension-underline": "^2.9.1", + "@tiptap/pm": "^2.9.1", + "@tiptap/starter-kit": "^2.9.1", "@types/diff": "^5.2.1", "@types/dompurify": "^3.0.5", "@types/uuid": "^10.0.0", @@ -2318,9 +2317,9 @@ } }, "node_modules/@tiptap/core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.8.0.tgz", - "integrity": "sha512-xsqDI4BNzYRWRtBq7+/38ThhqEr7uG9Njip1x+9/wgR3vWPBFnBkYJTz6jSxS35NRE6BSnERm4/B/vrLuY1Hdw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.9.1.tgz", + "integrity": "sha512-tifnLL/ARzQ6/FGEJjVwj9UT3v+pENdWHdk9x6F3X0mB1y0SeCjV21wpFLYESzwNdBPAj8NMp8Behv7dBnhIfw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2330,9 +2329,9 @@ } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.8.0.tgz", - "integrity": "sha512-m3CKrOIvV7fY1Ak2gYf5LkKiz6AHxHpg6wxfVaJvdBqXgLyVtHo552N+A4oSHOSRbB4AG9EBQ2NeBM8cdEQ4MA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.9.1.tgz", + "integrity": "sha512-Y0jZxc/pdkvcsftmEZFyG+73um8xrx6/DMfgUcNg3JAM63CISedNcr+OEI11L0oFk1KFT7/aQ9996GM6Kubdqg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2342,9 +2341,9 @@ } }, "node_modules/@tiptap/extension-bold": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.8.0.tgz", - "integrity": "sha512-U1YkZBxDkSLNvPNiqxB5g42IeJHr27C7zDb/yGQN2xL4UBeg4O9xVhCFfe32f6tLwivSL0dar4ScElpaCJuqow==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.9.1.tgz", + "integrity": "sha512-e2P1zGpnnt4+TyxTC5pX/lPxPasZcuHCYXY0iwQ3bf8qRQQEjDfj3X7EI+cXqILtnhOiviEOcYmeu5op2WhQDg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2354,23 +2353,21 @@ } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.8.0.tgz", - "integrity": "sha512-H4O2X0ozbc/ce9/XF1H98sqWVUdtt7jzy7hMBunwmY8ZxI4dHtcRkeg81CZbpKTqOqRrMCLWjE3M2tgiDXrDkA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.9.1.tgz", + "integrity": "sha512-0hizL/0j9PragJObjAWUVSuGhN1jKjCFnhLQVRxtx4HutcvS/lhoWMvFg6ZF8xqWgIa06n6A7MaknQkqhTdhKA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/extension-list-item": "^2.7.0", - "@tiptap/extension-text-style": "^2.7.0" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-code": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.8.0.tgz", - "integrity": "sha512-VSFn3sFF6qPpOGkXFhik8oYRH5iByVJpFEFd/duIEftmS0MdPzkbSItOpN3mc9xsJ5dCX80LYaResSj5hr5zkA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.9.1.tgz", + "integrity": "sha512-WQqcVGe7i/E+yO3wz5XQteU1ETNZ00euUEl4ylVVmH2NM4Dh0KDjEhbhHlCM0iCfLUo7jhjC7dmS+hMdPUb+Tg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2380,9 +2377,9 @@ } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.8.0.tgz", - "integrity": "sha512-POuA5Igx+Dto0DTazoBFAQTj/M/FCdkqRVD9Uhsxhv49swPyANTJRr05vgbgtHB+NDDsZfCawVh7pI0IAD/O0w==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.9.1.tgz", + "integrity": "sha512-A/50wPWDqEUUUPhrwRKILP5gXMO5UlQ0F6uBRGYB9CEVOREam9yIgvONOnZVJtszHqOayjIVMXbH/JMBeq11/g==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2393,9 +2390,9 @@ } }, "node_modules/@tiptap/extension-document": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.8.0.tgz", - "integrity": "sha512-mp7Isx1sVc/ifeW4uW/PexGQ9exN3NRUOebSpnLfqXeWYk4y1RS1PA/3+IHkOPVetbnapgPjFx/DswlCP3XLjA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.9.1.tgz", + "integrity": "sha512-1a+HCoDPnBttjqExfYLwfABq8MYdiowhy/wp8eCxVb6KGFEENO53KapstISvPzqH7eOi+qRjBB1KtVYb/ZXicg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2405,9 +2402,9 @@ } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.8.0.tgz", - "integrity": "sha512-rAFvx44YuT6dtS1c+ALw0ROAGI16l5L1HxquL4hR1gtxDcTieST5xhw5bkshXlmrlfotZXPrhokzqA7qjhZtJw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.9.1.tgz", + "integrity": "sha512-wJZspSmJRkDBtPkzFz1g7gvZOEOayk8s93UHsgbJxcV4VWHYleZ5XhT74sZunSjefNDm3qC6v2BSgLp3vNHVKQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2418,9 +2415,9 @@ } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.8.0.tgz", - "integrity": "sha512-Be1LWCmvteQInOnNVN+HTqc1XWsj1bCl+Q7et8qqNjtGtTaCbdCp8ppcH1SKJxNTM/RLUtPyJ8FDgOTj51ixCA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.9.1.tgz", + "integrity": "sha512-jsRBmX01vr+5H02GljiHMo0n5H1vzoMLmFarxe0Yq2d2l9G/WV2VWX2XnGliqZAYWd1bI0phs7uLQIN3mxGQTw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2431,9 +2428,9 @@ } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.8.0.tgz", - "integrity": "sha512-vqiIfviNiCmy/pJTHuDSCAGL2O4QDEdDmAvGJu8oRmElUrnlg8DbJUfKvn6DWQHNSQwRb+LDrwWlzAYj1K9u6A==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.9.1.tgz", + "integrity": "sha512-fCuaOD/b7nDjm47PZ58oanq7y4ccS2wjPh42Qm0B0yipu/1fmC8eS1SmaXmk28F89BLtuL6uOCtR1spe+lZtlQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2443,9 +2440,9 @@ } }, "node_modules/@tiptap/extension-heading": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.8.0.tgz", - "integrity": "sha512-4inWgrTPiqlivPmEHFOM5ck2UsmOsbKKPtqga6bALvWPmCv24S6/EBwFp8Jz4YABabXDnkviihmGu0LpP9D69w==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.9.1.tgz", + "integrity": "sha512-SjZowzLixOFaCrV2cMaWi1mp8REK0zK1b3OcVx7bCZfVSmsOETJyrAIUpCKA8o60NwF7pwhBg0MN8oXlNKMeFw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2455,9 +2452,9 @@ } }, "node_modules/@tiptap/extension-history": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.8.0.tgz", - "integrity": "sha512-u5YS0J5Egsxt8TUWMMAC3QhPZaak+IzQeyHch4gtqxftx96tprItY7AD/A3pGDF2uCSnN+SZrk6yVexm6EncDw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.9.1.tgz", + "integrity": "sha512-wp9qR1NM+LpvyLZFmdNaAkDq0d4jDJ7z7Fz7icFQPu31NVxfQYO3IXNmvJDCNu8hFAbImpA5aG8MBuwzRo0H9w==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2468,9 +2465,9 @@ } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.8.0.tgz", - "integrity": "sha512-Sn/MI8WVFBoIYSIHA9NJryJIyCEzZdRysau8pC5TFnfifre0QV1ksPz2bgF+DyCD69ozQiRdBBHDEwKe47ZbfQ==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.9.1.tgz", + "integrity": "sha512-ydUhABeaBI1CoJp+/BBqPhXINfesp1qMNL/jiDcMsB66fsD4nOyphpAJT7FaRFZFtQVF06+nttBtFZVkITQVqg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2481,9 +2478,9 @@ } }, "node_modules/@tiptap/extension-image": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.8.0.tgz", - "integrity": "sha512-5CReomgHGTUgxaX8P3i6qiC9VRWcWQgVoYtds4ZM52LVx/oGwMxQ4ECyzdVYKaRW+6PrNnAe6ew3Qpd5Wk0cIg==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.9.1.tgz", + "integrity": "sha512-aGqJnsuS8oagIhsx7wetm8jw4NEDsOV0OSx4FQ4VPlUqWlnzK0N+erFKKJmXTdAxL8PGzoPSlITFH63MV3eV3Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2493,9 +2490,9 @@ } }, "node_modules/@tiptap/extension-italic": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.8.0.tgz", - "integrity": "sha512-PwwSE2LTYiHI47NJnsfhBmPiLE8IXZYqaSoNPU6flPrk1KxEzqvRI1joKZBmD9wuqzmHJ93VFIeZcC+kfwi8ZA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.9.1.tgz", + "integrity": "sha512-VkNA6Vz96+/+7uBlsgM7bDXXx4b62T1fDam/3UKifA72aD/fZckeWrbT7KrtdUbzuIniJSbA0lpTs5FY29+86Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2505,9 +2502,9 @@ } }, "node_modules/@tiptap/extension-link": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.8.0.tgz", - "integrity": "sha512-p67hCG/pYCiOK/oCTPZnlkw9Ei7KJ7kCKFaluTcAmr5j8IBdYfDqSMDNCT4vGXBvKFh4X6xD7S7QvOqcH0Gn9A==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.9.1.tgz", + "integrity": "sha512-yG+e3e8cCCN9dZjX4ttEe3e2xhh58ryi3REJV4MdiEkOT9QF75Bl5pUbMIS4tQ8HkOr04QBFMHKM12kbSxg1BA==", "dependencies": { "linkifyjs": "^4.1.0" }, @@ -2521,9 +2518,9 @@ } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.8.0.tgz", - "integrity": "sha512-o7OGymGxB0B9x3x2prp3KBDYFuBYGc5sW69O672jk8G52DqhzzndgPnkk0qUn8nXAUKuDGbJmpmHVA2kagqnRg==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.9.1.tgz", + "integrity": "sha512-6O4NtYNR5N2Txi4AC0/4xMRJq9xd4+7ShxCZCDVL0WDVX37IhaqMO7LGQtA6MVlYyNaX4W1swfdJaqrJJ5HIUw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2533,23 +2530,21 @@ } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.8.0.tgz", - "integrity": "sha512-sCvNbcTS1+5QTTXwUPFa10vf5I1pr8sGcOTIh0G+a5ZkS5+6FxT12k7VLzPt39QyNbOi+77U2o4Xr4XyaEkfSg==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.9.1.tgz", + "integrity": "sha512-6J9jtv1XP8dW7/JNSH/K4yiOABc92tBJtgCsgP8Ep4+fjfjdj4HbjS1oSPWpgItucF2Fp/VF8qg55HXhjxHjTw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/extension-list-item": "^2.7.0", - "@tiptap/extension-text-style": "^2.7.0" + "@tiptap/core": "^2.7.0" } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.8.0.tgz", - "integrity": "sha512-XgxxNNbuBF48rAGwv7/s6as92/xjm/lTZIGTq9aG13ClUKFtgdel7C33SpUCcxg3cO2WkEyllXVyKUiauFZw/A==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.9.1.tgz", + "integrity": "sha512-JOmT0xd4gd3lIhLwrsjw8lV+ZFROKZdIxLi0Ia05XSu4RLrrvWj0zdKMSB+V87xOWfSB3Epo95zAvnPox5Q16A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2559,9 +2554,9 @@ } }, "node_modules/@tiptap/extension-placeholder": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.8.0.tgz", - "integrity": "sha512-BMqv/C9Tcjd7L1/OphUAJTZhWfpWs0rTQJ0bs3RRGsC8L+K20Fg+li45vw7M0teojpfrw57zwJogJd/m23Zr1Q==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.9.1.tgz", + "integrity": "sha512-Q/w3OOg/C6jGBf4QKEWKF9k+iaCQCgPoaIg2IDTPx8QmaxRfgoVE5Csd+oTOY/brdmSNXOxykZWEci6OJP+MbA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2572,9 +2567,9 @@ } }, "node_modules/@tiptap/extension-strike": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.8.0.tgz", - "integrity": "sha512-ezkDiXxQ3ME/dDMMM7tAMkKRi6UWw7tIu+Mx7Os0z8HCGpVBk1gFhLlhEd8I5rJaPZr4tK1wtSehMA9bscFGQw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.9.1.tgz", + "integrity": "sha512-V5aEXdML+YojlPhastcu7w4biDPwmzy/fWq0T2qjfu5Te/THcqDmGYVBKESBm5x6nBy5OLkanw2O+KHu2quDdg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2584,9 +2579,9 @@ } }, "node_modules/@tiptap/extension-subscript": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.8.0.tgz", - "integrity": "sha512-m14K5M7E+SqqrBul+B9t5sjN4zqTddV+Q+vd+RIm+OHG6AQhwewNoFyghZz5dGZ2Xj7HqiEyusBN+iHwfgJpmg==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.9.1.tgz", + "integrity": "sha512-jjfuHmF2dCUAtHmJH2K/7HhOCleM3aPVOI/UsBBYa8xM4mDU4xuW1O5sLAr2JWcB1xxyk9YKcBWwyRq+b1ENFA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2596,9 +2591,9 @@ } }, "node_modules/@tiptap/extension-superscript": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.8.0.tgz", - "integrity": "sha512-3rAVyRvzhoM51vaeIAEXmr2PkucIwv7ptgyxg6zx6STxcyzMchafGee0LJL7Kcn9uE/n7Yt7ek6bDqo8jU8CtA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.9.1.tgz", + "integrity": "sha512-7cgAPpUNgO/3QdvCN9/6dWP6JQC641o8dSgkyv0XzVv0nxISck4SU+2eADRYQLyP2s4M3xuSEFhCCiKZleK2yA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2608,9 +2603,9 @@ } }, "node_modules/@tiptap/extension-table": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.8.0.tgz", - "integrity": "sha512-dm9CitjacXyJuE5SZfV2lUc3uOiP2sxo6fygIzMz7iuxHqQueyONWG+TBkK7HjqzXOiMPsvOf/25NazzIG8HMg==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.9.1.tgz", + "integrity": "sha512-OmWZFZOSZwSSEvoVUkDsRFyCXTYei/pV396Xjv9pfFzXQkVbfq/CjTp61zvb/9mmEz3rcfvfG7G39eRlZTvBNg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2621,9 +2616,9 @@ } }, "node_modules/@tiptap/extension-table-cell": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.8.0.tgz", - "integrity": "sha512-IZpxONWyOd474L8+k4bHrFNRhbsl9eRwbNs5O877JkVFItc2WUz1DIhbJzjmBRsqExtWQJuOsiqWFab1kpiwGQ==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.9.1.tgz", + "integrity": "sha512-/wrcniLdhMhs5M2NDetFcfq510N5to7YKK+52KOXNotBI8K/GjMmGmtwWEKPITD0/RgYrXzpMcta/O+/0OCOPQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2633,9 +2628,9 @@ } }, "node_modules/@tiptap/extension-table-header": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.8.0.tgz", - "integrity": "sha512-B67A96yMQlG96IFzZBc7D5dnn7O29hcjuDLtjyZkKvU5D/RlFKPMmC9nVphCV3CnbkvEOZUdK9pNaOpen64naw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.9.1.tgz", + "integrity": "sha512-KtI01636Du1IB/I3pe9ZJWKkOc6INqAaIw+RFirRCnd8Xnik7tJfAwdhXzoPRcer6ViZmlzSrM2dkwaZCF7gcw==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2645,9 +2640,9 @@ } }, "node_modules/@tiptap/extension-table-row": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.8.0.tgz", - "integrity": "sha512-Iezej6l7X+WqKzGLmCgAwmpL+QsfjFv1g8yVH5d0/3Pkcj3G9nDn+GSm4bZnbfYFyqInHG94PZ5PMReiALrJtA==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.9.1.tgz", + "integrity": "sha512-Wq7QlI/S5iX4UCAdX+ok/szegVMbvrM3H8o6jwO+G4p8JJt6iv7ZmEnJ19xIINhmiKsrdanqH9FFK4tQ3yvQ0A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2657,9 +2652,9 @@ } }, "node_modules/@tiptap/extension-text": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.8.0.tgz", - "integrity": "sha512-EDAdFFzWOvQfVy7j3qkKhBpOeE5thkJaBemSWfXI93/gMVc0ZCdLi24mDvNNgUHlT+RjlIoQq908jZaaxLKN2A==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.9.1.tgz", + "integrity": "sha512-3wo9uCrkLVLQFgbw2eFU37QAa1jq1/7oExa+FF/DVxdtHRS9E2rnUZ8s2hat/IWzvPUHXMwo3Zg2XfhoamQpCA==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2669,9 +2664,9 @@ } }, "node_modules/@tiptap/extension-text-align": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.8.0.tgz", - "integrity": "sha512-Y6s/DF+P4lxpAnvSrnmt4xGwQT/AJJJm0aA1wu5GuPKpAQ+K4C7K6rE6uGNAXtR39GlewC7KdmcvA+CYhL8xlw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.9.1.tgz", + "integrity": "sha512-oUp0XnwJpAImcOVV68vsY2CpkHpRZ3gzWfIRTuy+aYitQim3xDKis/qfWQUWZsANp9/TZ0VyjtkZxNMwOfcu1g==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2681,9 +2676,9 @@ } }, "node_modules/@tiptap/extension-text-style": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.8.0.tgz", - "integrity": "sha512-jJp0vcZ2Ty7RvIL0VU6dm1y+fTfXq1lN2GwtYzYM0ueFuESa+Qo8ticYOImyWZ3wGJGVrjn7OV9r0ReW0/NYkQ==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.9.1.tgz", + "integrity": "sha512-LAxc0SeeiPiAVBwksczeA7BJSZb6WtVpYhy5Esvy9K0mK5kttB4KxtnXWeQzMIJZQbza65yftGKfQlexf/Y7yg==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2693,9 +2688,9 @@ } }, "node_modules/@tiptap/extension-underline": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.8.0.tgz", - "integrity": "sha512-1ouuHwZJphT8OosAmp6x8e+Wly3cUd1pNWBiOutJX+6QRGBXJnIKFCzn8YOTlWhg1YQigisG7dNF3YdlyuRNHw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.9.1.tgz", + "integrity": "sha512-IrUsIqKPgD7GcAjr4D+RC0WvLHUDBTMkD8uPNEoeD1uH9t9zFyDfMRPnx/z3/6Gf6fTh3HzLcHGibiW2HiMi2A==", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -2705,9 +2700,9 @@ } }, "node_modules/@tiptap/pm": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.8.0.tgz", - "integrity": "sha512-eMGpRooUMvKz/vOpnKKppApMSoNM325HxTdAJvTlVAmuHp5bOY5kyY1kfUlePRiVx1t1UlFcXs3kecFwkkBD3Q==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.9.1.tgz", + "integrity": "sha512-mvV86fr7kEuDYEApQ2uMPCKL2uagUE0BsXiyyz3KOkY1zifyVm1fzdkscb24Qy1GmLzWAIIihA+3UHNRgYdOlQ==", "dependencies": { "prosemirror-changeset": "^2.2.1", "prosemirror-collab": "^1.3.1", @@ -2726,7 +2721,7 @@ "prosemirror-tables": "^1.4.0", "prosemirror-trailing-node": "^3.0.0", "prosemirror-transform": "^1.10.0", - "prosemirror-view": "^1.33.10" + "prosemirror-view": "^1.34.3" }, "funding": { "type": "github", @@ -2734,30 +2729,31 @@ } }, "node_modules/@tiptap/starter-kit": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.8.0.tgz", - "integrity": "sha512-r7UwaTrECkQoheWVZKFDqtL5tBx07x7IFT+prfgnsVlYFutGWskVVqzCDvD3BDmrg5PzeCWYZrQGlPaLib7tjg==", - "dependencies": { - "@tiptap/core": "^2.8.0", - "@tiptap/extension-blockquote": "^2.8.0", - "@tiptap/extension-bold": "^2.8.0", - "@tiptap/extension-bullet-list": "^2.8.0", - "@tiptap/extension-code": "^2.8.0", - "@tiptap/extension-code-block": "^2.8.0", - "@tiptap/extension-document": "^2.8.0", - "@tiptap/extension-dropcursor": "^2.8.0", - "@tiptap/extension-gapcursor": "^2.8.0", - "@tiptap/extension-hard-break": "^2.8.0", - "@tiptap/extension-heading": "^2.8.0", - "@tiptap/extension-history": "^2.8.0", - "@tiptap/extension-horizontal-rule": "^2.8.0", - "@tiptap/extension-italic": "^2.8.0", - "@tiptap/extension-list-item": "^2.8.0", - "@tiptap/extension-ordered-list": "^2.8.0", - "@tiptap/extension-paragraph": "^2.8.0", - "@tiptap/extension-strike": "^2.8.0", - "@tiptap/extension-text": "^2.8.0", - "@tiptap/pm": "^2.8.0" + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.9.1.tgz", + "integrity": "sha512-nsw6UF/7wDpPfHRhtGOwkj1ipIEiWZS1VGw+c14K61vM1CNj0uQ4jogbHwHZqN1dlL5Hh+FCqUHDPxG6ECbijg==", + "dependencies": { + "@tiptap/core": "^2.9.1", + "@tiptap/extension-blockquote": "^2.9.1", + "@tiptap/extension-bold": "^2.9.1", + "@tiptap/extension-bullet-list": "^2.9.1", + "@tiptap/extension-code": "^2.9.1", + "@tiptap/extension-code-block": "^2.9.1", + "@tiptap/extension-document": "^2.9.1", + "@tiptap/extension-dropcursor": "^2.9.1", + "@tiptap/extension-gapcursor": "^2.9.1", + "@tiptap/extension-hard-break": "^2.9.1", + "@tiptap/extension-heading": "^2.9.1", + "@tiptap/extension-history": "^2.9.1", + "@tiptap/extension-horizontal-rule": "^2.9.1", + "@tiptap/extension-italic": "^2.9.1", + "@tiptap/extension-list-item": "^2.9.1", + "@tiptap/extension-ordered-list": "^2.9.1", + "@tiptap/extension-paragraph": "^2.9.1", + "@tiptap/extension-strike": "^2.9.1", + "@tiptap/extension-text": "^2.9.1", + "@tiptap/extension-text-style": "^2.9.1", + "@tiptap/pm": "^2.9.1" }, "funding": { "type": "github", @@ -13814,9 +13810,9 @@ } }, "node_modules/prosemirror-view": { - "version": "1.34.2", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.34.2.tgz", - "integrity": "sha512-tPX/V2Xd70vrAGQ/V9CppJtPKnQyQMypJGlLylvdI94k6JaG+4P6fVmXPR1zc1eVTW0gq3c6zsfqwJKCRLaG9Q==", + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.35.0.tgz", + "integrity": "sha512-Umtbh22fmUlpZpRTiOVXA0PpdRZeYEeXQsLp51VfnMhjkJrqJ0n8APinIZrRAD5Jr3UxH8FnOaUqRylSuMsqHA==", "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", diff --git a/package.json b/package.json index 7d824eedd5..1c7df1a50b 100644 --- a/package.json +++ b/package.json @@ -198,21 +198,20 @@ "npm": ">=10.1 < 11" }, "dependencies": { - "@tiptap/core": "^2.8.0", - "@tiptap/extension-image": "^2.8.0", - "@tiptap/extension-link": "^2.8.0", - "@tiptap/extension-placeholder": "^2.8.0", - "@tiptap/extension-subscript": "^2.8.0", - "@tiptap/extension-superscript": "^2.8.0", - "@tiptap/extension-table": "^2.8.0", - "@tiptap/extension-table-cell": "^2.8.0", - "@tiptap/extension-table-header": "^2.8.0", - "@tiptap/extension-table-row": "^2.8.0", - "@tiptap/extension-text-align": "^2.8.0", - "@tiptap/extension-text-style": "^2.8.0", - "@tiptap/extension-underline": "^2.8.0", - "@tiptap/pm": "^2.8.0", - "@tiptap/starter-kit": "^2.8.0", + "@tiptap/core": "^2.9.1", + "@tiptap/extension-image": "^2.9.1", + "@tiptap/extension-link": "^2.9.1", + "@tiptap/extension-placeholder": "^2.9.1", + "@tiptap/extension-subscript": "^2.9.1", + "@tiptap/extension-superscript": "^2.9.1", + "@tiptap/extension-table": "^2.9.1", + "@tiptap/extension-table-cell": "^2.9.1", + "@tiptap/extension-table-header": "^2.9.1", + "@tiptap/extension-table-row": "^2.9.1", + "@tiptap/extension-text-align": "^2.9.1", + "@tiptap/extension-underline": "^2.9.1", + "@tiptap/pm": "^2.9.1", + "@tiptap/starter-kit": "^2.9.1", "@types/diff": "^5.2.1", "@types/dompurify": "^3.0.5", "@types/uuid": "^10.0.0", From 3eef6b0be721115cc886852802614cbd866c81cf Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 6 Nov 2024 12:38:22 +0100 Subject: [PATCH 126/170] Feature: reusable table column view components (#2448) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add boolean + entity actions global table column layouts * use entity actions in extension insights * Update user-table-collection-view.element.ts * Update user-group-table-collection-view.element.ts * Update member-table-collection-view.element.ts * Update language-table-collection-view.element.ts * Update member-group-table-collection-view.element.ts * align alias * stop click event * delete unused code * use global components * add entity actions to document and media * move to entity action module * Update localize.element.stories.ts * change layout to view --------- Co-authored-by: Niels Lyngsø --- .../boolean-table-column-view.element.ts} | 7 ++-- .../core/collection/components/index.ts | 1 + ...ntity-actions-table-column-view.element.ts | 41 +++++++++++++++++++ .../entity-action/global-components/index.ts | 1 + src/packages/core/entity-action/index.ts | 2 + .../document-table-collection-view.element.ts | 13 +++++- ...extension-table-collection-view.element.ts | 13 +++--- ...le-entity-actions-column-layout.element.ts | 35 ---------------- ...le-entity-actions-column-layout.element.ts | 38 ----------------- .../language-table-collection-view.element.ts | 15 ++++--- .../media-table-collection-view.element.ts | 15 ++++++- ...ber-group-table-collection-view.element.ts | 12 ++++++ .../member-table-collection-view.element.ts | 12 +++--- ...le-entity-actions-column-layout.element.ts | 38 ----------------- ...ser-group-table-collection-view.element.ts | 12 ++++++ .../user-table-collection-view.element.ts | 12 ++++++ ...ook-table-boolean-column-layout.element.ts | 18 -------- ...le-entity-actions-column-layout.element.ts | 34 --------------- .../webhook-table-collection-view.element.ts | 12 +++--- 19 files changed, 135 insertions(+), 196 deletions(-) rename src/packages/{language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts => core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts} (62%) create mode 100644 src/packages/core/entity-action/global-components/entity-actions-table-column-view/entity-actions-table-column-view.element.ts create mode 100644 src/packages/core/entity-action/global-components/index.ts delete mode 100644 src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts delete mode 100644 src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts delete mode 100644 src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts delete mode 100644 src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts delete mode 100644 src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts diff --git a/src/packages/language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts b/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts similarity index 62% rename from src/packages/language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts rename to src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts index 479bc70b2e..cecfee1d0d 100644 --- a/src/packages/language/collection/views/table/column-layouts/boolean/language-table-boolean-column-layout.element.ts +++ b/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts @@ -1,8 +1,9 @@ import { html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -@customElement('umb-language-table-boolean-column-layout') -export class UmbLanguageTableBooleanColumnLayoutElement extends UmbLitElement { +const elementName = 'umb-boolean-table-column-view'; +@customElement(elementName) +export class UmbBooleanTableColumnViewElement extends UmbLitElement { @property({ attribute: false }) value = false; @@ -13,6 +14,6 @@ export class UmbLanguageTableBooleanColumnLayoutElement extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - 'umb-language-table-boolean-column-layout': UmbLanguageTableBooleanColumnLayoutElement; + [elementName]: UmbBooleanTableColumnViewElement; } } diff --git a/src/packages/core/collection/components/index.ts b/src/packages/core/collection/components/index.ts index 7abcffff90..a0bff0823a 100644 --- a/src/packages/core/collection/components/index.ts +++ b/src/packages/core/collection/components/index.ts @@ -3,6 +3,7 @@ import './collection-filter-field.element.js'; import './collection-selection-actions.element.js'; import './collection-toolbar.element.js'; import './collection-view-bundle.element.js'; +import './boolean-table-column-view/boolean-table-column-view.element.js'; import './pagination/collection-pagination.element.js'; export * from './collection-action-bundle.element.js'; diff --git a/src/packages/core/entity-action/global-components/entity-actions-table-column-view/entity-actions-table-column-view.element.ts b/src/packages/core/entity-action/global-components/entity-actions-table-column-view/entity-actions-table-column-view.element.ts new file mode 100644 index 0000000000..453664f142 --- /dev/null +++ b/src/packages/core/entity-action/global-components/entity-actions-table-column-view/entity-actions-table-column-view.element.ts @@ -0,0 +1,41 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import { html, nothing, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +const elementName = 'umb-entity-actions-table-column-view'; +@customElement(elementName) +export class UmbEntityActionsTableColumnViewElement extends UmbLitElement { + @property({ attribute: false }) + value?: UmbEntityModel; + + @state() + _isOpen = false; + + #onActionExecuted() { + this._isOpen = false; + } + + #onClick(event: Event) { + event.stopPropagation(); + } + + override render() { + if (!this.value) return nothing; + + return html` + + + + + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbEntityActionsTableColumnViewElement; + } +} diff --git a/src/packages/core/entity-action/global-components/index.ts b/src/packages/core/entity-action/global-components/index.ts new file mode 100644 index 0000000000..841ca85af1 --- /dev/null +++ b/src/packages/core/entity-action/global-components/index.ts @@ -0,0 +1 @@ +import './entity-actions-table-column-view/entity-actions-table-column-view.element.js'; diff --git a/src/packages/core/entity-action/index.ts b/src/packages/core/entity-action/index.ts index 60881da438..bf8c1a0d9b 100644 --- a/src/packages/core/entity-action/index.ts +++ b/src/packages/core/entity-action/index.ts @@ -1,3 +1,5 @@ +import './global-components/index.js'; + export * from './common/index.js'; export * from './default/index.js'; export * from './entity-action-base.js'; diff --git a/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts index a4e4d89e2f..c69efbe228 100644 --- a/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -136,7 +136,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { }; }); - this._tableColumns = [...this.#systemColumns, ...userColumns]; + this._tableColumns = [...this.#systemColumns, ...userColumns, { name: '', alias: 'entityActions' }]; } } @@ -146,6 +146,17 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { const data = this._tableColumns?.map((column) => { + if (column.alias === 'entityActions') { + return { + columnAlias: 'entityActions', + value: html``, + }; + } + const editPath = this.#routeBuilder ? this.#routeBuilder({ entityType: item.entityType }) + UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }) diff --git a/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts b/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts index 4300dd8062..64f6e4b90b 100644 --- a/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts +++ b/src/packages/extension-insights/collection/views/table/extension-table-collection-view.element.ts @@ -6,8 +6,6 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import './extension-table-entity-actions-column-layout.element.js'; - @customElement('umb-extension-table-collection-view') export class UmbExtensionTableCollectionViewElement extends UmbLitElement { @state() @@ -35,8 +33,7 @@ export class UmbExtensionTableCollectionViewElement extends UmbLitElement { }, { name: '', - alias: 'extensionAction', - elementName: 'umb-extension-table-entity-actions-column-layout', + alias: 'entityActions', }, ]; @@ -81,8 +78,12 @@ export class UmbExtensionTableCollectionViewElement extends UmbLitElement { value: extension.weight, }, { - columnAlias: 'extensionAction', - value: extension, + columnAlias: 'entityActions', + value: html``, }, ], }; diff --git a/src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts b/src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts deleted file mode 100644 index fed6e96a43..0000000000 --- a/src/packages/extension-insights/collection/views/table/extension-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { UmbExtensionDetailModel } from '../../types.js'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -const elementName = 'umb-extension-table-entity-actions-column-layout'; -@customElement(elementName) -export class UmbExtensionTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: UmbExtensionDetailModel; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - [elementName]: UmbExtensionTableEntityActionsColumnLayoutElement; - } -} diff --git a/src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts b/src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts deleted file mode 100644 index d4479a0402..0000000000 --- a/src/packages/language/collection/views/table/column-layouts/entity-actions/language-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { UmbLanguageDetailModel } from '../../../../../types.js'; -import { html, nothing, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -@customElement('umb-language-table-entity-actions-column-layout') -export class UmbLanguageTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: UmbLanguageDetailModel; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - // TODO: we need to use conditionals on each action here. But until we have that in place - // we'll just remove all actions on the default language. - if (this.value.isDefault) return nothing; - - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-language-table-entity-actions-column-layout': UmbLanguageTableEntityActionsColumnLayoutElement; - } -} diff --git a/src/packages/language/collection/views/table/language-table-collection-view.element.ts b/src/packages/language/collection/views/table/language-table-collection-view.element.ts index ed2e9b86de..1a37448b3f 100644 --- a/src/packages/language/collection/views/table/language-table-collection-view.element.ts +++ b/src/packages/language/collection/views/table/language-table-collection-view.element.ts @@ -6,9 +6,7 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import './column-layouts/boolean/language-table-boolean-column-layout.element.js'; import './column-layouts/name/language-table-name-column-layout.element.js'; -import './column-layouts/entity-actions/language-table-entity-actions-column-layout.element.js'; @customElement('umb-language-table-collection-view') export class UmbLanguageTableCollectionViewElement extends UmbLitElement { @@ -31,12 +29,10 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { { name: 'Default', alias: 'defaultLanguage', - elementName: 'umb-language-table-boolean-column-layout', }, { name: 'Mandatory', alias: 'mandatoryLanguage', - elementName: 'umb-language-table-boolean-column-layout', }, { name: 'Fallback', @@ -45,7 +41,6 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { { name: '', alias: 'entityActions', - elementName: 'umb-language-table-entity-actions-column-layout', }, ]; @@ -88,11 +83,11 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'defaultLanguage', - value: language.isDefault, + value: html``, }, { columnAlias: 'mandatoryLanguage', - value: language.isMandatory, + value: html``, }, { columnAlias: 'fallbackLanguage', @@ -100,7 +95,11 @@ export class UmbLanguageTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'entityActions', - value: language, + value: html``, }, ], }; diff --git a/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts b/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts index 0d28d08609..19f90522ed 100644 --- a/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts +++ b/src/packages/media/media/collection/views/table/media-table-collection-view.element.ts @@ -125,9 +125,9 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { }; }); - this._tableColumns = [...this.#systemColumns, ...userColumns]; + this._tableColumns = [...this.#systemColumns, ...userColumns, { name: '', alias: 'entityActions' }]; } else { - this._tableColumns = [...this.#systemColumns]; + this._tableColumns = [...this.#systemColumns, { name: '', alias: 'entityActions' }]; } } @@ -141,6 +141,17 @@ export class UmbMediaTableCollectionViewElement extends UmbLitElement { const data = this._tableColumns?.map((column) => { + if (column.alias === 'entityActions') { + return { + columnAlias: 'entityActions', + value: html``, + }; + } + const editPath = this.#routeBuilder ? this.#routeBuilder({ entityType: item.entityType }) + UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }) diff --git a/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts b/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts index 2084d91556..a3ca46c992 100644 --- a/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts +++ b/src/packages/members/member-group/collection/views/table/member-group-table-collection-view.element.ts @@ -19,6 +19,10 @@ export class UmbMemberGroupTableCollectionViewElement extends UmbLitElement { name: this.localize.term('general_name'), alias: 'memberGroupName', }, + { + name: '', + alias: 'entityActions', + }, ]; @state() @@ -52,6 +56,14 @@ export class UmbMemberGroupTableCollectionViewElement extends UmbLitElement { >${memberGroup.name}`, }, + { + columnAlias: 'entityActions', + value: html``, + }, ], }; }); diff --git a/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts b/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts index 8fca9ecca1..d7f0b3abcf 100644 --- a/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts +++ b/src/packages/members/member/collection/views/table/member-table-collection-view.element.ts @@ -8,8 +8,6 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbMemberTypeItemRepository } from '@umbraco-cms/backoffice/member-type'; -import './member-table-entity-actions-column-layout.element.js'; - @customElement('umb-member-table-collection-view') export class UmbMemberTableCollectionViewElement extends UmbLitElement { @state() @@ -42,7 +40,6 @@ export class UmbMemberTableCollectionViewElement extends UmbLitElement { { name: '', alias: 'entityActions', - elementName: 'umb-member-table-entity-actions-column-layout', }, ]; @@ -106,10 +103,11 @@ export class UmbMemberTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'entityActions', - value: { - entityType: member.entityType, - unique: member.unique, - }, + value: html``, }, ], }; diff --git a/src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts b/src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts deleted file mode 100644 index 61eab8c400..0000000000 --- a/src/packages/members/member/collection/views/table/member-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { UmbMemberEntityType } from '../../../entity.js'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -const elementName = 'umb-member-table-entity-actions-column-layout'; -@customElement(elementName) -export class UmbMemberTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: { - unique: string; - entityType: UmbMemberEntityType; - }; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - [elementName]: UmbMemberTableEntityActionsColumnLayoutElement; - } -} diff --git a/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts b/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts index f94107c739..fd9ea76a2b 100644 --- a/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts +++ b/src/packages/user/user-group/collection/views/user-group-table-collection-view.element.ts @@ -47,6 +47,10 @@ export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { name: this.localize.term('user_mediastartnode'), alias: 'userGroupMediaStartNode', }, + { + name: '', + alias: 'entityActions', + }, ]; @state() @@ -122,6 +126,14 @@ export class UmbUserGroupCollectionTableViewElement extends UmbLitElement { ? this.#mediaStartNodeMap.get(userGroup.mediaStartNode.unique) : this.localize.term('media_mediaRoot'), }, + { + columnAlias: 'entityActions', + value: html``, + }, ], }; }); diff --git a/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts b/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts index 6efabcb53a..8893980225 100644 --- a/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts +++ b/src/packages/user/user/collection/views/table/user-table-collection-view.element.ts @@ -48,6 +48,10 @@ export class UmbUserTableCollectionViewElement extends UmbLitElement { alias: 'userStatus', elementName: 'umb-user-table-status-column-layout', }, + { + name: '', + alias: 'entityActions', + }, ]; @state() @@ -140,6 +144,14 @@ export class UmbUserTableCollectionViewElement extends UmbLitElement { status: user.state, }, }, + { + columnAlias: 'entityActions', + value: html``, + }, ], }; }); diff --git a/src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts b/src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts deleted file mode 100644 index e16d4f4bb7..0000000000 --- a/src/packages/webhook/collection/views/table/column-layouts/boolean/webhook-table-boolean-column-layout.element.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -@customElement('umb-webhook-table-boolean-column-layout') -export class UmbWebhookTableBooleanColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value = false; - - override render() { - return html``; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-webhook-table-boolean-column-layout': UmbWebhookTableBooleanColumnLayoutElement; - } -} diff --git a/src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts b/src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts deleted file mode 100644 index 16cd56b978..0000000000 --- a/src/packages/webhook/collection/views/table/column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { UmbWebhookDetailModel } from '../../../../../types.js'; -import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -@customElement('umb-webhook-table-entity-actions-column-layout') -export class UmbWebhookTableEntityActionsColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value!: UmbWebhookDetailModel; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - override render() { - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - 'umb-webhook-table-entity-actions-column-layout': UmbWebhookTableEntityActionsColumnLayoutElement; - } -} diff --git a/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts b/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts index 4128f4e9d2..26e6566274 100644 --- a/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts +++ b/src/packages/webhook/collection/views/table/webhook-table-collection-view.element.ts @@ -5,9 +5,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; -import './column-layouts/boolean/webhook-table-boolean-column-layout.element.js'; import './column-layouts/name/webhook-table-name-column-layout.element.js'; -import './column-layouts/entity-actions/webhook-table-entity-actions-column-layout.element.js'; import './column-layouts/content-type/webhook-table-name-column-layout.element.js'; @customElement('umb-webhook-table-collection-view') @@ -27,7 +25,6 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { { name: this.localize.term('webhooks_enabled'), alias: 'enabled', - elementName: 'umb-webhook-table-boolean-column-layout', }, { name: this.localize.term('webhooks_url'), @@ -45,7 +42,6 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { { name: '', alias: 'entityActions', - elementName: 'umb-webhook-table-entity-actions-column-layout', }, ]; @@ -85,7 +81,7 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'enabled', - value: webhook.enabled, + value: html``, }, { columnAlias: 'events', @@ -97,7 +93,11 @@ export class UmbWebhookTableCollectionViewElement extends UmbLitElement { }, { columnAlias: 'entityActions', - value: webhook, + value: html``, }, ], }; From b74ad48097d684a4026ec175b6e220a234bfd576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Nov 2024 13:01:15 +0100 Subject: [PATCH 127/170] make host optionally be a method --- .../consume/context-consumer.controller.ts | 2 +- .../consume/context-consumer.test.ts | 45 ++++++++++++++++++- .../context-api/consume/context-consumer.ts | 16 ++++--- ...e-extension-initializer.controller.test.ts | 7 +-- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/libs/context-api/consume/context-consumer.controller.ts b/src/libs/context-api/consume/context-consumer.controller.ts index 892264047d..573cb5aadd 100644 --- a/src/libs/context-api/consume/context-consumer.controller.ts +++ b/src/libs/context-api/consume/context-consumer.controller.ts @@ -19,7 +19,7 @@ export class UmbContextConsumerController, callback?: UmbContextCallback, ) { - super(host.getHostElement(), contextAlias, callback); + super(() => host.getHostElement(), contextAlias, callback); this.#host = host; host.addUmbController(this); } diff --git a/src/libs/context-api/consume/context-consumer.test.ts b/src/libs/context-api/consume/context-consumer.test.ts index e45ea4170a..fdb78164b9 100644 --- a/src/libs/context-api/consume/context-consumer.test.ts +++ b/src/libs/context-api/consume/context-consumer.test.ts @@ -7,7 +7,7 @@ import { expect, oneEvent } from '@open-wc/testing'; const testContextAlias = 'my-test-context'; const testContextAliasAndApiAlias = 'my-test-context#testApi'; -const testContextAliasAndNotExstingApiAlias = 'my-test-context#notExistingTestApi'; +const testContextAliasAndNotExistingApiAlias = 'my-test-context#notExistingTestApi'; class UmbTestContextConsumerClass { public prop: string = 'value from provider'; @@ -74,6 +74,47 @@ describe('UmbContextConsumer', () => { localConsumer.hostConnected(); }); + it('works with host as a method', (done) => { + const provider = new UmbContextProvider(document.body, testContextAlias, new UmbTestContextConsumerClass()); + provider.hostConnected(); + + const element = document.createElement('div'); + document.body.appendChild(element); + + const localConsumer = new UmbContextConsumer( + () => element, + testContextAlias, + (_instance: UmbTestContextConsumerClass | undefined) => { + if (_instance) { + expect(_instance.prop).to.eq('value from provider'); + done(); + localConsumer.hostDisconnected(); + provider.hostDisconnected(); + } + }, + ); + localConsumer.hostConnected(); + }); + + it('works with host method returning undefined', async () => { + const element = undefined; + + const localConsumer = new UmbContextConsumer( + () => element, + testContextAlias, + (_instance: UmbTestContextConsumerClass | undefined) => { + if (_instance) { + expect.fail('Callback should not be called when never permitted'); + } + }, + ); + localConsumer.hostConnected(); + + await Promise.resolve(); + + localConsumer.hostDisconnected(); + }); + /* Unprovided feature is out commented currently. I'm not sure there is a use case. So lets leave the code around until we know for sure. it('acts to Context API disconnected', (done) => { @@ -139,7 +180,7 @@ describe('UmbContextConsumer', () => { const element = document.createElement('div'); document.body.appendChild(element); - const localConsumer = new UmbContextConsumer(element, testContextAliasAndNotExstingApiAlias, () => { + const localConsumer = new UmbContextConsumer(element, testContextAliasAndNotExistingApiAlias, () => { expect(false).to.be.true; }); localConsumer.hostConnected(); diff --git a/src/libs/context-api/consume/context-consumer.ts b/src/libs/context-api/consume/context-consumer.ts index 2805353c35..0230a3f1fd 100644 --- a/src/libs/context-api/consume/context-consumer.ts +++ b/src/libs/context-api/consume/context-consumer.ts @@ -3,11 +3,13 @@ import { isUmbContextProvideEventType, UMB_CONTEXT_PROVIDE_EVENT_TYPE } from '.. import type { UmbContextCallback } from './context-request.event.js'; import { UmbContextRequestEventImplementation } from './context-request.event.js'; +type HostElementMethod = () => Element | undefined; + /** * @class UmbContextConsumer */ export class UmbContextConsumer { - protected _host: Element; + protected _retrieveHost: HostElementMethod; #skipHost?: boolean; #stopAtContextMatch = true; @@ -33,11 +35,15 @@ export class UmbContextConsumer, callback?: UmbContextCallback, ) { - this._host = host; + if (typeof host === 'function') { + this._retrieveHost = host; + } else { + this._retrieveHost = () => host; + } const idSplit = contextIdentifier.toString().split('#'); this.#contextAlias = idSplit[0]; this.#apiAlias = idSplit[1] ?? 'default'; @@ -130,7 +136,7 @@ export class UmbContextConsumer { 'Umb.Test.Section.1', () => { // This should not be called. - expect(true).to.be.false; + expect.fail('Callback should not be called when never permitted'); }, ); Promise.resolve().then(() => { @@ -448,7 +448,7 @@ describe('UmbBaseExtensionController', () => { 'Umb.Test.Section.1', () => { // This should not be called. - expect(true).to.be.false; + expect.fail('Callback should not be called when never permitted'); }, ); @@ -615,7 +615,8 @@ describe('UmbBaseExtensionController', () => { extensionController.destroy(); // End this test. setTimeout(() => done(), 60); // Lets wait another round of the conditions approve/disapprove, just to see if the destroy stopped the conditions. (60ms, as that should be enough to test that another round does not happen.) [NL] } else if (count === 5) { - expect(false).to.be.true; // This should not be called. + // This should not be called. + expect.fail('Callback should not be called when never permitted'); } }, ); From 5d95867c577461b0e3fb7152b2d84264ad2a786c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 6 Nov 2024 13:03:45 +0100 Subject: [PATCH 128/170] ensure scaffolding is done before initializing the redirect controller --- .../block-type/workspace/block-type-workspace.context.ts | 2 +- .../block/block/workspace/block-workspace.context.ts | 2 +- .../workspace/property-type-workspace.context.ts | 2 +- .../data-type/workspace/data-type-workspace.context.ts | 4 ++-- .../dictionary/workspace/dictionary-workspace.context.ts | 2 +- .../workspace/document-blueprint-workspace.context.ts | 2 +- .../workspace/document-type-workspace.context.ts | 4 ++-- .../documents/workspace/document-workspace.context.ts | 8 ++++++-- .../workspace/language/language-workspace.context.ts | 2 +- .../media-types/workspace/media-type-workspace.context.ts | 4 ++-- .../media/media/workspace/media-workspace.context.ts | 2 +- .../member-group/member-group-workspace.context.ts | 4 ++-- .../workspace/member-type-workspace.context.ts | 4 ++-- .../member/workspace/member/member-workspace.context.ts | 2 +- .../scripts/workspace/script-workspace.context.ts | 2 +- .../stylesheets/workspace/stylesheet-workspace.context.ts | 2 +- .../templates/workspace/template-workspace.context.ts | 4 ++-- .../workspace/user-group/user-group-workspace.context.ts | 4 ++-- .../workspace/webhook/webhook-workspace.context.ts | 2 +- 19 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/packages/block/block-type/workspace/block-type-workspace.context.ts b/src/packages/block/block-type/workspace/block-type-workspace.context.ts index 8b9d425241..cdc2b71b29 100644 --- a/src/packages/block/block-type/workspace/block-type-workspace.context.ts +++ b/src/packages/block/block-type/workspace/block-type-workspace.context.ts @@ -46,7 +46,7 @@ export class UmbBlockTypeWorkspaceContext { + setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); + await this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/dictionary/workspace/dictionary-workspace.context.ts b/src/packages/dictionary/workspace/dictionary-workspace.context.ts index e85b75a67f..b329909230 100644 --- a/src/packages/dictionary/workspace/dictionary-workspace.context.ts +++ b/src/packages/dictionary/workspace/dictionary-workspace.context.ts @@ -32,7 +32,7 @@ export class UmbDictionaryWorkspaceContext setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); + await this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index a3959a1686..0083aa04fb 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -189,7 +189,7 @@ export class UmbDocumentBlueprintWorkspaceContext const parentEntityType = info.match.params.parentEntityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; const documentTypeUnique = info.match.params.documentTypeUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); + await this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/packages/documents/document-types/workspace/document-type-workspace.context.ts index e1791d7ec0..57e2766b1c 100644 --- a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts +++ b/src/packages/documents/document-types/workspace/document-type-workspace.context.ts @@ -110,7 +110,7 @@ export class UmbDocumentTypeWorkspaceContext { path: UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN.toString(), component: UmbDocumentTypeWorkspaceEditorElement, - setup: (_component, info) => { + setup: async (_component, info) => { const params = info.match.params as unknown as UmbPathPatternTypeAsEncodedParamsType< typeof UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN.PARAMS >; @@ -120,7 +120,7 @@ export class UmbDocumentTypeWorkspaceContext if (parentUnique === undefined) { throw new Error('ParentUnique url parameter is required to create a document type'); } - this.create({ entityType: parentEntityType, unique: parentUnique }, presetAlias); + await this.create({ entityType: parentEntityType, unique: parentUnique }, presetAlias); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 79ebeffdcd..f7dc75910f 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -249,7 +249,11 @@ export class UmbDocumentWorkspaceContext const documentTypeUnique = info.match.params.documentTypeUnique; const blueprintUnique = info.match.params.blueprintUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique, blueprintUnique); + await this.create( + { entityType: parentEntityType, unique: parentUnique }, + documentTypeUnique, + blueprintUnique, + ); new UmbWorkspaceIsNewRedirectController( this, this, @@ -264,7 +268,7 @@ export class UmbDocumentWorkspaceContext const parentEntityType = info.match.params.parentEntityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; const documentTypeUnique = info.match.params.documentTypeUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); + await this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/language/workspace/language/language-workspace.context.ts b/src/packages/language/workspace/language/language-workspace.context.ts index 97b2dc8507..00c28e9870 100644 --- a/src/packages/language/workspace/language/language-workspace.context.ts +++ b/src/packages/language/workspace/language/language-workspace.context.ts @@ -32,7 +32,7 @@ export class UmbLanguageWorkspaceContext path: 'create', component: UmbLanguageWorkspaceEditorElement, setup: async () => { - this.createScaffold({ parent: { entityType: UMB_LANGUAGE_ROOT_ENTITY_TYPE, unique: null } }); + await this.createScaffold({ parent: { entityType: UMB_LANGUAGE_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/media/media-types/workspace/media-type-workspace.context.ts b/src/packages/media/media-types/workspace/media-type-workspace.context.ts index e5c23009f2..ae9c12ae11 100644 --- a/src/packages/media/media-types/workspace/media-type-workspace.context.ts +++ b/src/packages/media/media-types/workspace/media-type-workspace.context.ts @@ -81,10 +81,10 @@ export class UmbMediaTypeWorkspaceContext { path: 'create/parent/:entityType/:parentUnique', component: UmbMediaTypeWorkspaceEditorElement, - setup: (_component, info) => { + setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index 173dad9b46..2e2562151d 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -191,7 +191,7 @@ export class UmbMediaWorkspaceContext const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; const mediaTypeUnique = info.match.params.mediaTypeUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, mediaTypeUnique); + await this.create({ entityType: parentEntityType, unique: parentUnique }, mediaTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts b/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts index fd2daebf9e..7b8c8f5687 100644 --- a/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts +++ b/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts @@ -29,8 +29,8 @@ export class UmbMemberGroupWorkspaceContext { path: 'create', component: UmbMemberGroupWorkspaceEditorElement, - setup: () => { - this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); + setup: async () => { + await this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/members/member-type/workspace/member-type-workspace.context.ts b/src/packages/members/member-type/workspace/member-type-workspace.context.ts index e791fc1e19..5cb6063562 100644 --- a/src/packages/members/member-type/workspace/member-type-workspace.context.ts +++ b/src/packages/members/member-type/workspace/member-type-workspace.context.ts @@ -77,10 +77,10 @@ export class UmbMemberTypeWorkspaceContext { path: 'create/parent/:entityType/:parentUnique', component: UmbMemberTypeWorkspaceEditorElement, - setup: (_component, info) => { + setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index 12ecd26c37..532ada9be0 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -183,7 +183,7 @@ export class UmbMemberWorkspaceContext component: () => new UmbMemberWorkspaceEditorElement(), setup: async (_component, info) => { const memberTypeUnique = info.match.params.memberTypeUnique; - this.create(memberTypeUnique); + await this.create(memberTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/templating/scripts/workspace/script-workspace.context.ts b/src/packages/templating/scripts/workspace/script-workspace.context.ts index fd116f0efe..4bdc50a90a 100644 --- a/src/packages/templating/scripts/workspace/script-workspace.context.ts +++ b/src/packages/templating/scripts/workspace/script-workspace.context.ts @@ -33,7 +33,7 @@ export class UmbScriptWorkspaceContext setup: async (component: PageComponent, info: IRoutingInfo) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); + await this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts b/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts index d68dc8824c..118981c9f1 100644 --- a/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts +++ b/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts @@ -45,7 +45,7 @@ export class UmbStylesheetWorkspaceContext setup: async (component: PageComponent, info: IRoutingInfo) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/templating/templates/workspace/template-workspace.context.ts b/src/packages/templating/templates/workspace/template-workspace.context.ts index 86a68407b4..6636e43d5f 100644 --- a/src/packages/templating/templates/workspace/template-workspace.context.ts +++ b/src/packages/templating/templates/workspace/template-workspace.context.ts @@ -41,10 +41,10 @@ export class UmbTemplateWorkspaceContext { path: 'create/parent/:entityType/:parentUnique', component: UmbTemplateWorkspaceEditorElement, - setup: (component: PageComponent, info: IRoutingInfo) => { + setup: async (component: PageComponent, info: IRoutingInfo) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts index 7650f9daa5..0e2d78241b 100644 --- a/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts +++ b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts @@ -42,8 +42,8 @@ export class UmbUserGroupWorkspaceContext { path: 'create', component: UmbUserGroupWorkspaceEditorElement, - setup: () => { - this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); + setup: async () => { + await this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts b/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts index d817275122..67da34f9a9 100644 --- a/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts +++ b/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts @@ -28,7 +28,7 @@ export class UmbWebhookWorkspaceContext path: 'create', component: UmbWebhookWorkspaceEditorElement, setup: async () => { - this.createScaffold({ parent: { entityType: UMB_WEBHOOK_ROOT_ENTITY_TYPE, unique: null } }); + await this.createScaffold({ parent: { entityType: UMB_WEBHOOK_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, From a828eb9f668f82ef789f7c8a0e7a4d9210e599cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Nov 2024 13:24:18 +0100 Subject: [PATCH 129/170] update JSDocs --- .../observable-api/utils/push-at-to-unique-array.function.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/observable-api/utils/push-at-to-unique-array.function.ts b/src/libs/observable-api/utils/push-at-to-unique-array.function.ts index a46b329639..f31ab8c332 100644 --- a/src/libs/observable-api/utils/push-at-to-unique-array.function.ts +++ b/src/libs/observable-api/utils/push-at-to-unique-array.function.ts @@ -5,6 +5,7 @@ * @param {T} entry - The object to insert or replace with. * @param {getUniqueMethod: (entry: T) => unknown} [getUniqueMethod] - Method to get the unique value of an entry. * @description - Append or replaces an item of an Array. + * @returns {T[]} - Returns a new array with the updated entry. * @example Example append new entry for a Array. Where the key is unique and the item will be updated if matched with existing. * const entry = {key: 'myKey', value: 'myValue'}; * const newDataSet = pushToUniqueArray([], entry, x => x.key === key, 1); From 24c9902db8f908429878ed4ef967fef8873089df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Nov 2024 13:42:45 +0100 Subject: [PATCH 130/170] give block workspace origin data to work from --- .../block-grid-block-inline.element.ts | 15 ++++++ .../context/block-grid-entries.context.ts | 21 +++++++- .../workspace/block-workspace.context.ts | 52 ++++++++----------- 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts index 0145768cc8..38a103f3a2 100644 --- a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts +++ b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts @@ -1,4 +1,6 @@ import { UMB_BLOCK_GRID_ENTRY_CONTEXT } from '../../context/block-grid-entry.context-token.js'; +import type { UmbBlockGridWorkspaceOriginData } from '../../workspace/block-grid-workspace.modal-token.js'; +import { UMB_BLOCK_GRID_ENTRIES_CONTEXT } from '../../context/block-grid-entries.context-token.js'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyTypeModel } from '@umbraco-cms/backoffice/content-type'; @@ -32,6 +34,8 @@ export class UmbBlockGridBlockInlineElement extends UmbLitElement { #blockContext?: typeof UMB_BLOCK_GRID_ENTRY_CONTEXT.TYPE; #workspaceContext?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE; #contentKey?: string; + #parentUnique?: string | null; + #areaKey?: string | null; @property({ attribute: false }) config?: UmbBlockEditorCustomViewConfiguration; @@ -71,6 +75,10 @@ export class UmbBlockGridBlockInlineElement extends UmbLitElement { 'observeContentKey', ); }); + this.consumeContext(UMB_BLOCK_GRID_ENTRIES_CONTEXT, (entriesContext) => { + this.#parentUnique = entriesContext.getParentUnique(); + this.#areaKey = entriesContext.getAreaKey(); + }); new UmbExtensionApiInitializer( this, umbExtensionsRegistry, @@ -79,7 +87,14 @@ export class UmbBlockGridBlockInlineElement extends UmbLitElement { (permitted, ctrl) => { const context = ctrl.api as typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE; if (permitted && context) { + if (this.#parentUnique === undefined || this.#areaKey === undefined) { + throw new Error('Parent unique and area key must be defined'); + } this.#workspaceContext = context; + context.setOriginData({ + areaKey: this.#areaKey, + parentUnique: this.#parentUnique, + } as UmbBlockGridWorkspaceOriginData); this.#workspaceContext.establishLiveSync(); this.#load(); diff --git a/src/packages/block/block-grid/context/block-grid-entries.context.ts b/src/packages/block/block-grid/context/block-grid-entries.context.ts index b69f1a2853..1850c2dd14 100644 --- a/src/packages/block/block-grid/context/block-grid-entries.context.ts +++ b/src/packages/block/block-grid/context/block-grid-entries.context.ts @@ -99,6 +99,10 @@ export class UmbBlockGridEntriesContext this.#catalogueModal.setUniquePathValue('parentUnique', pathFolderName(contentKey ?? 'null')); } + getParentUnique(): string | null | undefined { + return this.#parentUnique; + } + setAreaKey(areaKey: string | null) { this.#areaKey = areaKey; this.#workspaceModal.setUniquePathValue('areaKey', areaKey ?? 'null'); @@ -110,6 +114,10 @@ export class UmbBlockGridEntriesContext // If not, we want to set the layoutDataPath to a base one. } + getAreaKey(): string | null | undefined { + return this.#areaKey; + } + setLayoutColumns(columns: number | undefined) { this.#layoutColumns.setValue(columns); } @@ -157,7 +165,11 @@ export class UmbBlockGridEntriesContext blocks: this.#allowedBlockTypes.getValue(), blockGroups: this._manager.getBlockGroups() ?? [], openClipboard: routingInfo.view === 'clipboard', - originData: { index: index, areaKey: this.#areaKey, parentUnique: this.#parentUnique }, + originData: { + index: index, + areaKey: this.#areaKey, + parentUnique: this.#parentUnique, + } as UmbBlockGridWorkspaceOriginData, createBlockInWorkspace: this._manager.getInlineEditingMode() === false, }, }; @@ -195,7 +207,12 @@ export class UmbBlockGridEntriesContext data: { entityType: 'block', preset: {}, - originData: { areaKey: this.#areaKey, parentUnique: this.#parentUnique, baseDataPath: this._dataPath }, + originData: { + index: -1, + areaKey: this.#areaKey, + parentUnique: this.#parentUnique, + baseDataPath: this._dataPath, + } as UmbBlockGridWorkspaceOriginData, }, modal: { size: 'medium' }, }; diff --git a/src/packages/block/block/workspace/block-workspace.context.ts b/src/packages/block/block/workspace/block-workspace.context.ts index 1d1827445b..3794671862 100644 --- a/src/packages/block/block/workspace/block-workspace.context.ts +++ b/src/packages/block/block/workspace/block-workspace.context.ts @@ -16,13 +16,12 @@ import { observeMultiple, } from '@umbraco-cms/backoffice/observable-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UMB_MODAL_CONTEXT, type UmbModalContext } from '@umbraco-cms/backoffice/modal'; +import { UMB_MODAL_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { decodeFilePath, UmbReadOnlyVariantStateManager } from '@umbraco-cms/backoffice/utils'; import { UMB_BLOCK_ENTRIES_CONTEXT, UMB_BLOCK_MANAGER_CONTEXT, type UmbBlockWorkspaceOriginData, - type UmbBlockWorkspaceData, UMB_BLOCK_ENTRY_CONTEXT, } from '@umbraco-cms/backoffice/block'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @@ -40,7 +39,11 @@ export class UmbBlockWorkspaceContext; + #originData?: UmbBlockWorkspaceOriginData; + // Set the origin data for this workspace. Example used by inline editing which setups the workspace context it self. + setOriginData(data: UmbBlockWorkspaceOriginData) { + this.#originData = data; + } #retrieveModalContext; #entityType: string; @@ -80,7 +83,7 @@ export class UmbBlockWorkspaceContext { - this.#modalContext = context as any; + this.#originData = context?.data.originData; context.onSubmit().catch(this.#modalRejected); }).asPromise(); @@ -238,19 +241,15 @@ export class UmbBlockWorkspaceContext { @@ -357,14 +357,11 @@ export class UmbBlockWorkspaceContext { @@ -435,7 +432,7 @@ export class UmbBlockWorkspaceContext Date: Wed, 6 Nov 2024 12:44:23 +0000 Subject: [PATCH 131/170] [v14.2+] Fix Block Grid layoutStylesheet not using correct URL (#2512) * Update block-grid-manager.context.ts * Renames field to `serverUrl` Uses `URL()` object to handle slashes in constructing the URL path. * Tidied up imports --------- Co-authored-by: leekelleher --- .../context/block-grid-manager.context.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/packages/block/block-grid/context/block-grid-manager.context.ts b/src/packages/block/block-grid/context/block-grid-manager.context.ts index 2f411cfd2b..cd4b63e0a5 100644 --- a/src/packages/block/block-grid/context/block-grid-manager.context.ts +++ b/src/packages/block/block-grid/context/block-grid-manager.context.ts @@ -1,18 +1,19 @@ import type { UmbBlockGridLayoutModel, UmbBlockGridTypeModel } from '../types.js'; import type { UmbBlockGridWorkspaceOriginData } from '../index.js'; import { - UmbArrayState, - UmbBooleanState, appendToFrozenArray, pushAtToUniqueArray, + UmbArrayState, + UmbBooleanState, } from '@umbraco-cms/backoffice/observable-api'; -import { removeLastSlashFromPath, transformServerPathToClientPath } from '@umbraco-cms/backoffice/utils'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { transformServerPathToClientPath } from '@umbraco-cms/backoffice/utils'; +import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; -import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; -import { type UmbBlockDataModel, UmbBlockManagerContext } from '@umbraco-cms/backoffice/block'; +import type { UmbBlockDataModel } from '@umbraco-cms/backoffice/block'; import type { UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block-type'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models'; +import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; export const UMB_BLOCK_GRID_DEFAULT_LAYOUT_STYLESHEET = '/umbraco/backoffice/css/umbraco-blockgridlayout.css'; @@ -34,7 +35,9 @@ export class UmbBlockGridManagerContext< } #initAppUrl: Promise; - #appUrl?: string; + + #serverUrl?: string; + #blockGroups = new UmbArrayState(>[], (x) => x.key); public readonly blockGroups = this.#blockGroups.asObservable(); @@ -45,7 +48,8 @@ export class UmbBlockGridManagerContext< if (layoutStylesheet) { // Cause we await initAppUrl in setting the _editorConfiguration, we can trust the appUrl begin here. - return removeLastSlashFromPath(this.#appUrl!) + transformServerPathToClientPath(layoutStylesheet); + const url = new URL(transformServerPathToClientPath(layoutStylesheet), this.#serverUrl); + return url.href; } return undefined; }); @@ -85,7 +89,7 @@ export class UmbBlockGridManagerContext< super(host); this.#initAppUrl = this.getContext(UMB_APP_CONTEXT).then((appContext) => { - this.#appUrl = appContext.getServerUrl() + appContext.getBackofficePath(); + this.#serverUrl = appContext.getServerUrl(); }); } From 15242d03be76dd571157986286e03e058d08c307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Nov 2024 13:55:43 +0100 Subject: [PATCH 132/170] update destroy method --- .../block/block/workspace/block-workspace.context.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/packages/block/block/workspace/block-workspace.context.ts b/src/packages/block/block/workspace/block-workspace.context.ts index 3794671862..80ad8c64c6 100644 --- a/src/packages/block/block/workspace/block-workspace.context.ts +++ b/src/packages/block/block/workspace/block-workspace.context.ts @@ -348,7 +348,7 @@ export class UmbBlockWorkspaceContext { @@ -361,7 +361,7 @@ export class UmbBlockWorkspaceContext { @@ -499,9 +499,10 @@ export class UmbBlockWorkspaceContext Date: Wed, 6 Nov 2024 13:03:45 +0100 Subject: [PATCH 133/170] ensure scaffolding is done before initializing the redirect controller --- .../block-type/workspace/block-type-workspace.context.ts | 2 +- .../block/block/workspace/block-workspace.context.ts | 2 +- .../workspace/property-type-workspace.context.ts | 2 +- .../data-type/workspace/data-type-workspace.context.ts | 4 ++-- .../dictionary/workspace/dictionary-workspace.context.ts | 2 +- .../workspace/document-blueprint-workspace.context.ts | 2 +- .../workspace/document-type-workspace.context.ts | 4 ++-- .../documents/workspace/document-workspace.context.ts | 8 ++++++-- .../workspace/language/language-workspace.context.ts | 2 +- .../media-types/workspace/media-type-workspace.context.ts | 4 ++-- .../media/media/workspace/media-workspace.context.ts | 2 +- .../member-group/member-group-workspace.context.ts | 4 ++-- .../workspace/member-type-workspace.context.ts | 4 ++-- .../member/workspace/member/member-workspace.context.ts | 2 +- .../scripts/workspace/script-workspace.context.ts | 2 +- .../stylesheets/workspace/stylesheet-workspace.context.ts | 2 +- .../templates/workspace/template-workspace.context.ts | 4 ++-- .../workspace/user-group/user-group-workspace.context.ts | 4 ++-- .../workspace/webhook/webhook-workspace.context.ts | 2 +- 19 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/packages/block/block-type/workspace/block-type-workspace.context.ts b/src/packages/block/block-type/workspace/block-type-workspace.context.ts index 1d17eb81ec..4b99ed1c3b 100644 --- a/src/packages/block/block-type/workspace/block-type-workspace.context.ts +++ b/src/packages/block/block-type/workspace/block-type-workspace.context.ts @@ -54,7 +54,7 @@ export class UmbBlockTypeWorkspaceContext { + setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); + await this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/dictionary/workspace/dictionary-workspace.context.ts b/src/packages/dictionary/workspace/dictionary-workspace.context.ts index e85b75a67f..b329909230 100644 --- a/src/packages/dictionary/workspace/dictionary-workspace.context.ts +++ b/src/packages/dictionary/workspace/dictionary-workspace.context.ts @@ -32,7 +32,7 @@ export class UmbDictionaryWorkspaceContext setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); + await this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts index c3b5b3264f..29b346209b 100644 --- a/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts +++ b/src/packages/documents/document-blueprints/workspace/document-blueprint-workspace.context.ts @@ -194,7 +194,7 @@ export class UmbDocumentBlueprintWorkspaceContext const parentEntityType = info.match.params.parentEntityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; const documentTypeUnique = info.match.params.documentTypeUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); + await this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/packages/documents/document-types/workspace/document-type-workspace.context.ts index e1791d7ec0..57e2766b1c 100644 --- a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts +++ b/src/packages/documents/document-types/workspace/document-type-workspace.context.ts @@ -110,7 +110,7 @@ export class UmbDocumentTypeWorkspaceContext { path: UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN.toString(), component: UmbDocumentTypeWorkspaceEditorElement, - setup: (_component, info) => { + setup: async (_component, info) => { const params = info.match.params as unknown as UmbPathPatternTypeAsEncodedParamsType< typeof UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN.PARAMS >; @@ -120,7 +120,7 @@ export class UmbDocumentTypeWorkspaceContext if (parentUnique === undefined) { throw new Error('ParentUnique url parameter is required to create a document type'); } - this.create({ entityType: parentEntityType, unique: parentUnique }, presetAlias); + await this.create({ entityType: parentEntityType, unique: parentUnique }, presetAlias); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 4c21724833..0ca2b56303 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -253,7 +253,11 @@ export class UmbDocumentWorkspaceContext const documentTypeUnique = info.match.params.documentTypeUnique; const blueprintUnique = info.match.params.blueprintUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique, blueprintUnique); + await this.create( + { entityType: parentEntityType, unique: parentUnique }, + documentTypeUnique, + blueprintUnique, + ); new UmbWorkspaceIsNewRedirectController( this, this, @@ -268,7 +272,7 @@ export class UmbDocumentWorkspaceContext const parentEntityType = info.match.params.parentEntityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; const documentTypeUnique = info.match.params.documentTypeUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); + await this.create({ entityType: parentEntityType, unique: parentUnique }, documentTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/language/workspace/language/language-workspace.context.ts b/src/packages/language/workspace/language/language-workspace.context.ts index 97b2dc8507..00c28e9870 100644 --- a/src/packages/language/workspace/language/language-workspace.context.ts +++ b/src/packages/language/workspace/language/language-workspace.context.ts @@ -32,7 +32,7 @@ export class UmbLanguageWorkspaceContext path: 'create', component: UmbLanguageWorkspaceEditorElement, setup: async () => { - this.createScaffold({ parent: { entityType: UMB_LANGUAGE_ROOT_ENTITY_TYPE, unique: null } }); + await this.createScaffold({ parent: { entityType: UMB_LANGUAGE_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/media/media-types/workspace/media-type-workspace.context.ts b/src/packages/media/media-types/workspace/media-type-workspace.context.ts index e5c23009f2..ae9c12ae11 100644 --- a/src/packages/media/media-types/workspace/media-type-workspace.context.ts +++ b/src/packages/media/media-types/workspace/media-type-workspace.context.ts @@ -81,10 +81,10 @@ export class UmbMediaTypeWorkspaceContext { path: 'create/parent/:entityType/:parentUnique', component: UmbMediaTypeWorkspaceEditorElement, - setup: (_component, info) => { + setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/media/media/workspace/media-workspace.context.ts b/src/packages/media/media/workspace/media-workspace.context.ts index e22db20690..a5a2a5133d 100644 --- a/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/packages/media/media/workspace/media-workspace.context.ts @@ -196,7 +196,7 @@ export class UmbMediaWorkspaceContext const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; const mediaTypeUnique = info.match.params.mediaTypeUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }, mediaTypeUnique); + await this.create({ entityType: parentEntityType, unique: parentUnique }, mediaTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts b/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts index fd2daebf9e..7b8c8f5687 100644 --- a/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts +++ b/src/packages/members/member-group/workspace/member-group/member-group-workspace.context.ts @@ -29,8 +29,8 @@ export class UmbMemberGroupWorkspaceContext { path: 'create', component: UmbMemberGroupWorkspaceEditorElement, - setup: () => { - this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); + setup: async () => { + await this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/members/member-type/workspace/member-type-workspace.context.ts b/src/packages/members/member-type/workspace/member-type-workspace.context.ts index e791fc1e19..5cb6063562 100644 --- a/src/packages/members/member-type/workspace/member-type-workspace.context.ts +++ b/src/packages/members/member-type/workspace/member-type-workspace.context.ts @@ -77,10 +77,10 @@ export class UmbMemberTypeWorkspaceContext { path: 'create/parent/:entityType/:parentUnique', component: UmbMemberTypeWorkspaceEditorElement, - setup: (_component, info) => { + setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/packages/members/member/workspace/member/member-workspace.context.ts index 0c54e85606..788afe2c1b 100644 --- a/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -188,7 +188,7 @@ export class UmbMemberWorkspaceContext component: () => new UmbMemberWorkspaceEditorElement(), setup: async (_component, info) => { const memberTypeUnique = info.match.params.memberTypeUnique; - this.create(memberTypeUnique); + await this.create(memberTypeUnique); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/templating/scripts/workspace/script-workspace.context.ts b/src/packages/templating/scripts/workspace/script-workspace.context.ts index fd116f0efe..4bdc50a90a 100644 --- a/src/packages/templating/scripts/workspace/script-workspace.context.ts +++ b/src/packages/templating/scripts/workspace/script-workspace.context.ts @@ -33,7 +33,7 @@ export class UmbScriptWorkspaceContext setup: async (component: PageComponent, info: IRoutingInfo) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); + await this.createScaffold({ parent: { entityType: parentEntityType, unique: parentUnique } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts b/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts index d68dc8824c..118981c9f1 100644 --- a/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts +++ b/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts @@ -45,7 +45,7 @@ export class UmbStylesheetWorkspaceContext setup: async (component: PageComponent, info: IRoutingInfo) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/templating/templates/workspace/template-workspace.context.ts b/src/packages/templating/templates/workspace/template-workspace.context.ts index 86a68407b4..6636e43d5f 100644 --- a/src/packages/templating/templates/workspace/template-workspace.context.ts +++ b/src/packages/templating/templates/workspace/template-workspace.context.ts @@ -41,10 +41,10 @@ export class UmbTemplateWorkspaceContext { path: 'create/parent/:entityType/:parentUnique', component: UmbTemplateWorkspaceEditorElement, - setup: (component: PageComponent, info: IRoutingInfo) => { + setup: async (component: PageComponent, info: IRoutingInfo) => { const parentEntityType = info.match.params.entityType; const parentUnique = info.match.params.parentUnique === 'null' ? null : info.match.params.parentUnique; - this.create({ entityType: parentEntityType, unique: parentUnique }); + await this.create({ entityType: parentEntityType, unique: parentUnique }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts index 7650f9daa5..0e2d78241b 100644 --- a/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts +++ b/src/packages/user/user-group/workspace/user-group/user-group-workspace.context.ts @@ -42,8 +42,8 @@ export class UmbUserGroupWorkspaceContext { path: 'create', component: UmbUserGroupWorkspaceEditorElement, - setup: () => { - this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); + setup: async () => { + await this.createScaffold({ parent: { entityType: UMB_USER_GROUP_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, diff --git a/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts b/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts index d817275122..67da34f9a9 100644 --- a/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts +++ b/src/packages/webhook/workspace/webhook/webhook-workspace.context.ts @@ -28,7 +28,7 @@ export class UmbWebhookWorkspaceContext path: 'create', component: UmbWebhookWorkspaceEditorElement, setup: async () => { - this.createScaffold({ parent: { entityType: UMB_WEBHOOK_ROOT_ENTITY_TYPE, unique: null } }); + await this.createScaffold({ parent: { entityType: UMB_WEBHOOK_ROOT_ENTITY_TYPE, unique: null } }); new UmbWorkspaceIsNewRedirectController( this, From 558e1fa9dff28a8459ced662660be14510e69f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Nov 2024 14:05:17 +0100 Subject: [PATCH 134/170] comment on risky business --- .../block-grid-block-inline/block-grid-block-inline.element.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts index 38a103f3a2..06156a1b8f 100644 --- a/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts +++ b/src/packages/block/block-grid/components/block-grid-block-inline/block-grid-block-inline.element.ts @@ -87,6 +87,7 @@ export class UmbBlockGridBlockInlineElement extends UmbLitElement { (permitted, ctrl) => { const context = ctrl.api as typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE; if (permitted && context) { + // Risky business, cause here we are lucky that it seems to be consumed and set before this is called and there for this is acceptable for now. [NL] if (this.#parentUnique === undefined || this.#areaKey === undefined) { throw new Error('Parent unique and area key must be defined'); } From 82f837751285628e732e0e156384c0003af3d552 Mon Sep 17 00:00:00 2001 From: Rick Butterfield Date: Wed, 6 Nov 2024 13:41:56 +0000 Subject: [PATCH 135/170] Allow checking for `this._contentTypeAlias` before `#extensionSlotFilterMethod` runs --- .../block-list-entry.element.ts | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts b/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts index f23b039e1b..d3b58036f7 100644 --- a/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts +++ b/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts @@ -300,22 +300,24 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper } #renderBlock() { - return html` - ${this._inlineEditingMode ? this.#renderInlineBlock() : this.#renderRefBlock()} - - ${this.#renderEditContentAction()} ${this.#renderEditSettingsAction()} ${this.#renderDeleteAction()} - - ${!this._showContentEdit && this._contentInvalid - ? html`!` - : nothing} - `; + return this.contentKey && this._contentTypeAlias + ? html` + ${this._inlineEditingMode ? this.#renderInlineBlock() : this.#renderRefBlock()} + + ${this.#renderEditContentAction()} ${this.#renderEditSettingsAction()} ${this.#renderDeleteAction()} + + ${!this._showContentEdit && this._contentInvalid + ? html`!` + : nothing} + ` + : nothing; } #renderEditContentAction() { From 2799523b5991380fdc3ca7dea334cdb8e45a8263 Mon Sep 17 00:00:00 2001 From: marwaldv Date: Wed, 6 Nov 2024 16:28:48 +0100 Subject: [PATCH 136/170] Feature: Add Swiss backoffice localizations (#2503) * Add swiss languages as backoffice languages * Added Swiss localizations to manifest * De-duplicated localizations To reduce lines of duplicated code, (from the German, French and Italian localizations), those localizations are imported at runtime. --------- Co-authored-by: leekelleher --- src/assets/lang/de-ch.ts | 17 ++++++++++++ src/assets/lang/fr-ch.ts | 17 ++++++++++++ src/assets/lang/it-ch.ts | 17 ++++++++++++ src/packages/core/localization/manifests.ts | 30 +++++++++++++++++++++ 4 files changed, 81 insertions(+) create mode 100644 src/assets/lang/de-ch.ts create mode 100644 src/assets/lang/fr-ch.ts create mode 100644 src/assets/lang/it-ch.ts diff --git a/src/assets/lang/de-ch.ts b/src/assets/lang/de-ch.ts new file mode 100644 index 0000000000..cd33f22eab --- /dev/null +++ b/src/assets/lang/de-ch.ts @@ -0,0 +1,17 @@ +/** + * Creator Name: The Umbraco community + * Creator Link: https://docs.umbraco.com/umbraco-cms/extending/language-files + * + * Language Alias: de_CH + * Language Int Name: German Switzerland (DE-CH) + * Language Local Name: Deutsch Schweiz (DE-CH) + * Language LCID: 7 + * Language Culture: de-CH + */ +import de_de from './de-de.js'; +import type { UmbLocalizationDictionary } from '@umbraco-cms/backoffice/localization-api'; + +export default { + // NOTE: Imports and re-exports the German (Germany) localizations, so that any German (Switzerland) localizations can be override them. [LK] + ...de_de, +} as UmbLocalizationDictionary; diff --git a/src/assets/lang/fr-ch.ts b/src/assets/lang/fr-ch.ts new file mode 100644 index 0000000000..712e9fc0fd --- /dev/null +++ b/src/assets/lang/fr-ch.ts @@ -0,0 +1,17 @@ +/** + * Creator Name: The Umbraco community + * Creator Link: https://docs.umbraco.com/umbraco-cms/extending/language-files + * + * Language Alias: fr_ch + * Language Int Name: French Switzerland (FR-CH) + * Language Local Name: Français Suisse (FR-CH) + * Language LCID: 12 + * Language Culture: fr-CH + */ +import fr_fr from './fr-fr.js'; +import type { UmbLocalizationDictionary } from '@umbraco-cms/backoffice/localization-api'; + +export default { + // NOTE: Imports and re-exports the French (France) localizations, so that any French (Switzerland) localizations can be override them. [LK] + ...fr_fr, +} as UmbLocalizationDictionary; diff --git a/src/assets/lang/it-ch.ts b/src/assets/lang/it-ch.ts new file mode 100644 index 0000000000..bdba6cf8c1 --- /dev/null +++ b/src/assets/lang/it-ch.ts @@ -0,0 +1,17 @@ +/** + * Creator Name: The Umbraco community + * Creator Link: https://docs.umbraco.com/umbraco-cms/extending/language-files + * + * Language Alias: it_ch + * Language Int Name: Italian Switzerland (IT-CH) + * Language Local Name: Italiano Svizerra (IT-CH) + * Language LCID: 16 + * Language Culture: it-CH + */ +import it_it from './it-it.js'; +import type { UmbLocalizationDictionary } from '@umbraco-cms/backoffice/localization-api'; + +export default { + // NOTE: Imports and re-exports the Italian (Italy) localizations, so that any Italian (Switzerland) localizations can be override them. [LK] + ...it_it, +} as UmbLocalizationDictionary; diff --git a/src/packages/core/localization/manifests.ts b/src/packages/core/localization/manifests.ts index 576c677f65..e8741a538a 100644 --- a/src/packages/core/localization/manifests.ts +++ b/src/packages/core/localization/manifests.ts @@ -61,6 +61,16 @@ export const manifests: Array = [ }, js: () => import('../../../assets/lang/de-de.js'), }, + { + type: 'localization', + alias: 'Umb.Localization.De-CH', + weight: -100, + name: 'Deutsch (Schweiz)', + meta: { + culture: 'de-ch', + }, + js: () => import('../../../assets/lang/de-ch.js'), + }, { type: 'localization', alias: 'Umb.Localization.En-GB', @@ -101,6 +111,16 @@ export const manifests: Array = [ }, js: () => import('../../../assets/lang/fr-fr.js'), }, + { + type: 'localization', + alias: 'Umb.Localization.Fr-CH', + weight: -100, + name: 'Français (Suisse)', + meta: { + culture: 'fr-ch', + }, + js: () => import('../../../assets/lang/fr-ch.js'), + }, { type: 'localization', alias: 'Umb.Localization.He-IL', @@ -131,6 +151,16 @@ export const manifests: Array = [ }, js: () => import('../../../assets/lang/it-it.js'), }, + { + type: 'localization', + alias: 'Umb.Localization.It-CH', + weight: -100, + name: 'Italiano (Svizerra)', + meta: { + culture: 'it-ch', + }, + js: () => import('../../../assets/lang/it-ch.js'), + }, { type: 'localization', alias: 'Umb.Localization.Ja-JP', From 746f9705fef10bd7517572b9b54c9e94744127ee Mon Sep 17 00:00:00 2001 From: NguyenThuyLan <116753400+NguyenThuyLan@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:18:25 +0100 Subject: [PATCH 137/170] Fix bug: No matching error display between New password and Confirm password (#2384) * Fix bug: No matching error display between New password and Confirm password * Refactored to use built-in validation Wires up most localization keys. --------- Co-authored-by: Lan Nguyen Thuy Co-authored-by: leekelleher --- src/assets/lang/en.ts | 2 +- .../modal/change-password-modal.element.ts | 94 ++++++++++--------- .../user/change-password/modal/manifests.ts | 2 +- 3 files changed, 54 insertions(+), 44 deletions(-) diff --git a/src/assets/lang/en.ts b/src/assets/lang/en.ts index 27fb01708b..e5a5eeadc2 100644 --- a/src/assets/lang/en.ts +++ b/src/assets/lang/en.ts @@ -1978,7 +1978,7 @@ export default { passwordCurrent: 'Current password', passwordInvalid: 'Invalid current password', passwordIsDifferent: - 'There was a difference between the new password and the confirmed password. Please\n try again!\n ', + 'There was a difference between the new password and the confirmed password. Please try again!', passwordMismatch: "The confirmed password doesn't match the new password!", passwordRequiresDigit: "The password must have at least one digit ('0'-'9')", passwordRequiresLower: "The password must have at least one lowercase ('a'-'z')", diff --git a/src/packages/user/change-password/modal/change-password-modal.element.ts b/src/packages/user/change-password/modal/change-password-modal.element.ts index bdff723460..d0fcbf4afd 100644 --- a/src/packages/user/change-password/modal/change-password-modal.element.ts +++ b/src/packages/user/change-password/modal/change-password-modal.element.ts @@ -1,18 +1,24 @@ import type { UmbChangePasswordModalData, UmbChangePasswordModalValue } from './change-password-modal.token.js'; -import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; -import { UmbUserItemRepository } from '@umbraco-cms/backoffice/user'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit'; -import { css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, query, state, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbUserItemRepository } from '@umbraco-cms/backoffice/user'; +import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; +import type { UUIInputPasswordElement } from '@umbraco-cms/backoffice/external/uui'; @customElement('umb-change-password-modal') export class UmbChangePasswordModalElement extends UmbModalBaseElement< UmbChangePasswordModalData, UmbChangePasswordModalValue > { + @query('#newPassword') + private _newPasswordInput?: UUIInputPasswordElement; + + @query('#confirmPassword') + private _confirmPasswordInput?: UUIInputPasswordElement; + @state() - private _headline: string = 'Change password'; + private _headline: string = this.localize.term('general_changePassword'); @state() private _isCurrentUser: boolean = false; @@ -35,10 +41,8 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< const formData = new FormData(form); - // TODO: validate that the new password and confirm password match const oldPassword = formData.get('oldPassword') as string; const newPassword = formData.get('newPassword') as string; - //const confirmPassword = formData.get('confirmPassword') as string; this.value = { oldPassword, newPassword }; this.modalContext?.submit(); @@ -54,12 +58,7 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< } async #setIsCurrentUser() { - if (!this.data?.user.unique) { - this._isCurrentUser = false; - return; - } - - if (!this.#currentUserContext) { + if (!this.#currentUserContext || !this.data?.user.unique) { this._isCurrentUser = false; return; } @@ -67,7 +66,13 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< this._isCurrentUser = await this.#currentUserContext.isUserCurrentUser(this.data.user.unique); } - protected override async firstUpdated(): Promise { + protected override async firstUpdated() { + this._confirmPasswordInput?.addValidator( + 'customError', + () => this.localize.term('user_passwordMismatch'), + () => this._confirmPasswordInput?.value !== this._newPasswordInput?.value, + ); + if (!this.data?.user.unique) return; const { data } = await this.#userItemRepository.requestItems([this.data.user.unique]); @@ -81,55 +86,60 @@ export class UmbChangePasswordModalElement extends UmbModalBaseElement< return html` -
    - ${this._isCurrentUser ? this.#renderOldPasswordInput() : nothing} + + ${when( + this._isCurrentUser, + () => html` + + + Current password + + + + + `, + )} - New password + + New password + + required-message="New password is required"> + - Confirm password + + Confirm new password + + required-message="Confirm password is required"> +
    - - + + look="primary" + label=${this.localize.term('general_confirm')}>
    `; } - #renderOldPasswordInput() { - return html` - - Old password - - - `; - } - - static override styles: CSSResultGroup = [ + static override readonly styles = [ UmbTextStyles, css` uui-input-password { diff --git a/src/packages/user/change-password/modal/manifests.ts b/src/packages/user/change-password/modal/manifests.ts index f08d08322a..b3e3f0c901 100644 --- a/src/packages/user/change-password/modal/manifests.ts +++ b/src/packages/user/change-password/modal/manifests.ts @@ -3,6 +3,6 @@ export const manifests: Array = [ type: 'modal', alias: 'Umb.Modal.ChangePassword', name: 'Change Password Modal', - js: () => import('./change-password-modal.element.js'), + element: () => import('./change-password-modal.element.js'), }, ]; From cb54ad1783356a4bebff55054e4d2de87352f7c9 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Wed, 6 Nov 2024 19:35:38 +0000 Subject: [PATCH 138/170] Fixes duplicate alias that fails npm run compile Fixes issue when running `npm run compile` ``` examples/ufm-custom-component/index.ts:12:4 - error TS1117: An object literal cannot have multiple properties with the same name. 12 alias: 'myCustomComponent', ~~~~~ Found 1 error in examples/ufm-custom-component/index.ts:12 ``` --- examples/ufm-custom-component/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/ufm-custom-component/index.ts b/examples/ufm-custom-component/index.ts index 59efba5054..69cda7ce89 100644 --- a/examples/ufm-custom-component/index.ts +++ b/examples/ufm-custom-component/index.ts @@ -8,8 +8,7 @@ export const manifests: Array = [ api: () => import('./custom-ufm-component.js'), meta: { alias: 'myCustomComponent', - marker: '%', - alias: 'myCustomComponent', + marker: '%' }, }, ]; From 4cfd2cb828af69f5ddb6f0e168950a64f6d3a5f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Nov 2024 21:42:25 +0100 Subject: [PATCH 139/170] prevent context consumption of route-context from a modal that is not routable --- .../provide/context-boundary.controller.ts | 40 +++++++++++++ .../context-api/provide/context-boundary.ts | 60 +++++++++++++++++++ .../context-api/provide/context-provider.ts | 2 +- src/libs/context-api/provide/index.ts | 4 +- .../core/modal/component/modal.element.ts | 19 ++++-- .../modal-route-registration.controller.ts | 5 +- 6 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 src/libs/context-api/provide/context-boundary.controller.ts create mode 100644 src/libs/context-api/provide/context-boundary.ts diff --git a/src/libs/context-api/provide/context-boundary.controller.ts b/src/libs/context-api/provide/context-boundary.controller.ts new file mode 100644 index 0000000000..6fa5b7d1b1 --- /dev/null +++ b/src/libs/context-api/provide/context-boundary.controller.ts @@ -0,0 +1,40 @@ +import type { UmbContextToken } from '../token/index.js'; +import { UmbContextBoundary } from './context-boundary.js'; +import type { UmbControllerHost, UmbController } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbContextBoundaryController extends UmbContextBoundary implements UmbController { + #host: UmbControllerHost; + #controllerAlias: string; + + public get controllerAlias(): string { + return this.#controllerAlias; + } + + constructor(host: UmbControllerHost, contextAlias: string | UmbContextToken) { + super(host.getHostElement(), contextAlias); + this.#host = host; + // Makes the controllerAlias unique for this instance, this enables multiple Contexts to be provided under the same name. (This only makes sense cause of Context Token Discriminators) + // This does mean that if someone provides a context with the same name, but with a different instance, it will not override the previous instance. But its good since it enables extensions to provide contexts at the same scope of other contexts. + this.#controllerAlias = 'umbContextBoundary_' + contextAlias.toString(); + + // If this API is already provided with this alias? Then we do not want to register this controller: + const existingControllers = host.getUmbControllers((x) => x.controllerAlias === this.controllerAlias); + if (existingControllers.length > 0) { + // This just an additional awareness feature to make devs Aware, the alternative would be adding it anyway, but that would destroy existing controller of this alias. + // Back out, this instance is already provided, by another controller. + throw new Error( + `Context API: The context boundary of '${this.controllerAlias}' is already provided by another Context Provider Controller.`, + ); + } else { + host.addUmbController(this); + } + } + + public override destroy(): void { + if (this.#host) { + this.#host.removeUmbController(this); + (this.#host as unknown) = undefined; + } + super.destroy(); + } +} diff --git a/src/libs/context-api/provide/context-boundary.ts b/src/libs/context-api/provide/context-boundary.ts new file mode 100644 index 0000000000..a44f61af62 --- /dev/null +++ b/src/libs/context-api/provide/context-boundary.ts @@ -0,0 +1,60 @@ +import type { UmbContextRequestEvent } from '../consume/context-request.event.js'; +import type { UmbContextToken } from '../token/index.js'; +import { UMB_CONTENT_REQUEST_EVENT_TYPE } from '../consume/context-request.event.js'; +import { UmbContextProvideEventImplementation } from './context-provide.event.js'; + +/** + * @class UmbContextBoundary + */ +export class UmbContextBoundary { + #eventTarget: EventTarget; + + #contextAlias: string; + + /** + * Creates an instance of UmbContextBoundary. + * @param {EventTarget} eventTarget - the host element for this context provider + * @param {string | UmbContextToken} contextIdentifier - a string or token to identify the context + * @param {*} instance - the instance to provide + * @memberof UmbContextBoundary + */ + constructor(eventTarget: EventTarget, contextIdentifier: string | UmbContextToken) { + this.#eventTarget = eventTarget; + + const idSplit = contextIdentifier.toString().split('#'); + this.#contextAlias = idSplit[0]; + + this.#eventTarget.addEventListener(UMB_CONTENT_REQUEST_EVENT_TYPE, this.#handleContextRequest); + } + + /** + * @private + * @param {UmbContextRequestEvent} event - the event to handle + * @memberof UmbContextBoundary + */ + #handleContextRequest = ((event: UmbContextRequestEvent): void => { + if (event.contextAlias !== this.#contextAlias) return; + + if (event.stopAtContextMatch) { + // Since the alias matches, we will stop it from bubbling further up. But we still allow it to ask the other Contexts of the element. Hence not calling `event.stopImmediatePropagation();` + event.stopPropagation(); + } + }) as EventListener; + + /** + * @memberof UmbContextBoundary + */ + public hostConnected(): void { + //this.hostElement.addEventListener(UMB_CONTENT_REQUEST_EVENT_TYPE, this.#handleContextRequest); + this.#eventTarget.dispatchEvent(new UmbContextProvideEventImplementation(this.#contextAlias)); + } + + /** + * @memberof UmbContextBoundary + */ + public hostDisconnected(): void {} + + destroy(): void { + (this.#eventTarget as unknown) = undefined; + } +} diff --git a/src/libs/context-api/provide/context-provider.ts b/src/libs/context-api/provide/context-provider.ts index 31f62cdc8e..21a8aa9f86 100644 --- a/src/libs/context-api/provide/context-provider.ts +++ b/src/libs/context-api/provide/context-provider.ts @@ -46,7 +46,7 @@ export class UmbContextProvider { diff --git a/src/libs/context-api/provide/index.ts b/src/libs/context-api/provide/index.ts index 1b23b3d4ba..3690c440fd 100644 --- a/src/libs/context-api/provide/index.ts +++ b/src/libs/context-api/provide/index.ts @@ -1,3 +1,5 @@ +export * from './context-boundary.js'; +export * from './context-boundary.controller.js'; +export * from './context-provide.event.js'; export * from './context-provider.controller.js'; export * from './context-provider.js'; -export * from './context-provide.event.js'; diff --git a/src/packages/core/modal/component/modal.element.ts b/src/packages/core/modal/component/modal.element.ts index 165adbea9d..5bde58c3f0 100644 --- a/src/packages/core/modal/component/modal.element.ts +++ b/src/packages/core/modal/component/modal.element.ts @@ -13,10 +13,14 @@ import { type UUIModalDialogElement, type UUIModalSidebarElement, } from '@umbraco-cms/backoffice/external/uui'; -import type { UmbRouterSlotElement } from '@umbraco-cms/backoffice/router'; +import { UMB_ROUTE_CONTEXT, type UmbRouterSlotElement } from '@umbraco-cms/backoffice/router'; import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api'; import type { UmbContextRequestEvent } from '@umbraco-cms/backoffice/context-api'; -import { UMB_CONTENT_REQUEST_EVENT_TYPE, UmbContextProvider } from '@umbraco-cms/backoffice/context-api'; +import { + UMB_CONTENT_REQUEST_EVENT_TYPE, + UmbContextBoundary, + UmbContextProvider, +} from '@umbraco-cms/backoffice/context-api'; @customElement('umb-modal') export class UmbModalElement extends UmbLitElement { @@ -41,7 +45,7 @@ export class UmbModalElement extends UmbLitElement { #innerElement = new UmbBasicState(undefined); #modalExtensionObserver?: UmbObserverController; - #modalRouterElement: UmbRouterSlotElement = document.createElement('umb-router-slot'); + #modalRouterElement?: HTMLDivElement | UmbRouterSlotElement; #onClose = () => { this.element?.removeEventListener(UUIModalCloseEvent, this.#onClose); @@ -85,6 +89,7 @@ export class UmbModalElement extends UmbLitElement { * */ if (this.#modalContext.router) { + this.#modalRouterElement = document.createElement('umb-router-slot'); this.#modalRouterElement.routes = [ { path: '', @@ -92,9 +97,13 @@ export class UmbModalElement extends UmbLitElement { }, ]; this.#modalRouterElement.parent = this.#modalContext.router; + } else { + this.#modalRouterElement = document.createElement('div'); + new UmbContextBoundary(this.#modalRouterElement, UMB_ROUTE_CONTEXT).hostConnected(); } this.element.appendChild(this.#modalRouterElement); + this.#observeModal(this.#modalContext.alias.toString()); const provider = new UmbContextProvider(this.element, UMB_MODAL_CONTEXT, this.#modalContext); @@ -151,14 +160,14 @@ export class UmbModalElement extends UmbLitElement { } #appendInnerElement(element: HTMLElement) { - this.#modalRouterElement.appendChild(element); + this.#modalRouterElement!.appendChild(element); this.#innerElement.setValue(element); } #removeInnerElement() { const innerElement = this.#innerElement.getValue(); if (innerElement) { - this.#modalRouterElement.removeChild(innerElement); + this.#modalRouterElement!.removeChild(innerElement); this.#innerElement.setValue(undefined); } } diff --git a/src/packages/core/router/modal-registration/modal-route-registration.controller.ts b/src/packages/core/router/modal-registration/modal-route-registration.controller.ts index d487de0fff..1ee307a27a 100644 --- a/src/packages/core/router/modal-registration/modal-route-registration.controller.ts +++ b/src/packages/core/router/modal-registration/modal-route-registration.controller.ts @@ -259,9 +259,9 @@ export class UmbModalRouteRegistrationController< } public open(params: { [key: string]: string | number }, prepend?: string) { - if (this.active) return; + if (this.active || !this.#routeBuilder) return; - window.history.pushState({}, '', this.#routeBuilder?.(params) + (prepend ? `${prepend}` : '')); + window.history.pushState({}, '', this.#routeBuilder(params) + (prepend ? `${prepend}` : '')); } /** @@ -277,6 +277,7 @@ export class UmbModalRouteRegistrationController< return this; } public _internal_setRouteBuilder(urlBuilder: UmbModalRouteBuilder) { + if (!this.#routeContext) return; this.#routeBuilder = urlBuilder; this.#urlBuilderCallback?.(urlBuilder); } From fffd044e237b71ca5858baa093d533aac4bdda95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 10:01:59 +0100 Subject: [PATCH 140/170] style no-router --- src/packages/core/modal/component/modal.element.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/packages/core/modal/component/modal.element.ts b/src/packages/core/modal/component/modal.element.ts index 5bde58c3f0..ebd666a4c7 100644 --- a/src/packages/core/modal/component/modal.element.ts +++ b/src/packages/core/modal/component/modal.element.ts @@ -99,6 +99,9 @@ export class UmbModalElement extends UmbLitElement { this.#modalRouterElement.parent = this.#modalContext.router; } else { this.#modalRouterElement = document.createElement('div'); + // Notice inline styling here is used cause the element is not appended into this elements shadowDom but outside and there by gets into the element via a slot. + this.#modalRouterElement.style.position = 'relative'; + this.#modalRouterElement.style.height = '100%'; new UmbContextBoundary(this.#modalRouterElement, UMB_ROUTE_CONTEXT).hostConnected(); } From fb30dde7be552c9d8ad021303e7e7f39cac733a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 10:05:31 +0100 Subject: [PATCH 141/170] rename context consume event const --- src/libs/context-api/consume/context-consumer.test.ts | 6 +++--- src/libs/context-api/consume/context-request.event.ts | 9 +++++++-- src/libs/context-api/provide/context-boundary.ts | 4 ++-- src/libs/context-api/provide/context-provider.ts | 4 ++-- src/packages/core/modal/component/modal.element.ts | 4 ++-- .../components/input-tiny-mce/input-tiny-mce.defaults.ts | 4 ++-- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/libs/context-api/consume/context-consumer.test.ts b/src/libs/context-api/consume/context-consumer.test.ts index e45ea4170a..9ec2e235ee 100644 --- a/src/libs/context-api/consume/context-consumer.test.ts +++ b/src/libs/context-api/consume/context-consumer.test.ts @@ -2,7 +2,7 @@ import { UmbContextProvider } from '../provide/context-provider.js'; import { UmbContextToken } from '../token/context-token.js'; import { UmbContextConsumer } from './context-consumer.js'; import type { UmbContextRequestEventImplementation } from './context-request.event.js'; -import { UMB_CONTENT_REQUEST_EVENT_TYPE } from './context-request.event.js'; +import { UMB_CONTEXT_REQUEST_EVENT_TYPE } from './context-request.event.js'; import { expect, oneEvent } from '@open-wc/testing'; const testContextAlias = 'my-test-context'; @@ -38,13 +38,13 @@ describe('UmbContextConsumer', () => { describe('events', () => { it('dispatches context request event when constructed', async () => { - const listener = oneEvent(window, UMB_CONTENT_REQUEST_EVENT_TYPE); + const listener = oneEvent(window, UMB_CONTEXT_REQUEST_EVENT_TYPE); consumer.hostConnected(); const event = (await listener) as unknown as UmbContextRequestEventImplementation; expect(event).to.exist; - expect(event.type).to.eq(UMB_CONTENT_REQUEST_EVENT_TYPE); + expect(event.type).to.eq(UMB_CONTEXT_REQUEST_EVENT_TYPE); expect(event.contextAlias).to.eq(testContextAlias); consumer.hostDisconnected(); }); diff --git a/src/libs/context-api/consume/context-request.event.ts b/src/libs/context-api/consume/context-request.event.ts index 6371270e93..a2fa4d9975 100644 --- a/src/libs/context-api/consume/context-request.event.ts +++ b/src/libs/context-api/consume/context-request.event.ts @@ -1,4 +1,9 @@ -export const UMB_CONTENT_REQUEST_EVENT_TYPE = 'umb:context-request'; +export const UMB_CONTEXT_REQUEST_EVENT_TYPE = 'umb:context-request'; +/** + * @deprecated use UMB_CONTEXT_REQUEST_EVENT_TYPE + * This will be removed in Umbraco 17 + */ +export const UMB_CONTENT_REQUEST_EVENT_TYPE = UMB_CONTEXT_REQUEST_EVENT_TYPE; export const UMB_DEBUG_CONTEXT_EVENT_TYPE = 'umb:debug-contexts'; export type UmbContextCallback = (instance: T) => void; @@ -29,7 +34,7 @@ export class UmbContextRequestEventImplementation public readonly callback: (context: ResultType) => boolean, public readonly stopAtContextMatch: boolean = true, ) { - super(UMB_CONTENT_REQUEST_EVENT_TYPE, { bubbles: true, composed: true, cancelable: true }); + super(UMB_CONTEXT_REQUEST_EVENT_TYPE, { bubbles: true, composed: true, cancelable: true }); } clone() { diff --git a/src/libs/context-api/provide/context-boundary.ts b/src/libs/context-api/provide/context-boundary.ts index a44f61af62..56244997c6 100644 --- a/src/libs/context-api/provide/context-boundary.ts +++ b/src/libs/context-api/provide/context-boundary.ts @@ -1,6 +1,6 @@ import type { UmbContextRequestEvent } from '../consume/context-request.event.js'; import type { UmbContextToken } from '../token/index.js'; -import { UMB_CONTENT_REQUEST_EVENT_TYPE } from '../consume/context-request.event.js'; +import { UMB_CONTEXT_REQUEST_EVENT_TYPE } from '../consume/context-request.event.js'; import { UmbContextProvideEventImplementation } from './context-provide.event.js'; /** @@ -24,7 +24,7 @@ export class UmbContextBoundary { const idSplit = contextIdentifier.toString().split('#'); this.#contextAlias = idSplit[0]; - this.#eventTarget.addEventListener(UMB_CONTENT_REQUEST_EVENT_TYPE, this.#handleContextRequest); + this.#eventTarget.addEventListener(UMB_CONTEXT_REQUEST_EVENT_TYPE, this.#handleContextRequest); } /** diff --git a/src/libs/context-api/provide/context-provider.ts b/src/libs/context-api/provide/context-provider.ts index 21a8aa9f86..d801d764b6 100644 --- a/src/libs/context-api/provide/context-provider.ts +++ b/src/libs/context-api/provide/context-provider.ts @@ -1,6 +1,6 @@ import type { UmbContextRequestEvent } from '../consume/context-request.event.js'; import type { UmbContextToken } from '../token/index.js'; -import { UMB_CONTENT_REQUEST_EVENT_TYPE, UMB_DEBUG_CONTEXT_EVENT_TYPE } from '../consume/context-request.event.js'; +import { UMB_CONTEXT_REQUEST_EVENT_TYPE, UMB_DEBUG_CONTEXT_EVENT_TYPE } from '../consume/context-request.event.js'; import { UmbContextProvideEventImplementation } from './context-provide.event.js'; /** @@ -41,7 +41,7 @@ export class UmbContextProvider { + this.element.addEventListener(UMB_CONTEXT_REQUEST_EVENT_TYPE, ((event: UmbContextRequestEvent) => { if (!this.#modalContext) return; // Note for this hack (The if-sentence): [NL] // We do not currently have a good enough control to ensure that the proxy is last, meaning if another context is provided at this element, it might respond after the proxy event has been dispatched. diff --git a/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.defaults.ts b/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.defaults.ts index 4526ca07d5..ac1260b8ce 100644 --- a/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.defaults.ts +++ b/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.defaults.ts @@ -1,4 +1,4 @@ -import { UMB_CONTENT_REQUEST_EVENT_TYPE, type UmbContextRequestEvent } from '@umbraco-cms/backoffice/context-api'; +import { UMB_CONTEXT_REQUEST_EVENT_TYPE, type UmbContextRequestEvent } from '@umbraco-cms/backoffice/context-api'; import type { RawEditorOptions } from '@umbraco-cms/backoffice/external/tinymce'; import { UUIIconRequestEvent } from '@umbraco-cms/backoffice/external/uui'; @@ -34,7 +34,7 @@ export const defaultFallbackConfig: RawEditorOptions = { init_instance_callback: function (editor) { // The following code is the context api proxy. [NL] // It re-dispatches the context api request event to the origin target of this modal, in other words the element that initiated the modal. [NL] - editor.dom.doc.addEventListener(UMB_CONTENT_REQUEST_EVENT_TYPE, ((event: UmbContextRequestEvent) => { + editor.dom.doc.addEventListener(UMB_CONTEXT_REQUEST_EVENT_TYPE, ((event: UmbContextRequestEvent) => { if (!editor.iframeElement) return; event.stopImmediatePropagation(); From c3353677a4ab32be1361578b91aa703b6ce1409b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 11:20:01 +0100 Subject: [PATCH 142/170] remove circular dependency + deprecate export --- src/packages/core/content-type/index.ts | 7 ++++++- .../core/{content-type => content}/components/index.ts | 0 .../components/property-type-based-property/index.ts | 0 .../property-type-based-property.element.ts | 6 +++--- src/packages/core/content/index.ts | 2 ++ 5 files changed, 11 insertions(+), 4 deletions(-) rename src/packages/core/{content-type => content}/components/index.ts (100%) rename src/packages/core/{content-type => content}/components/property-type-based-property/index.ts (100%) rename src/packages/core/{content-type => content}/components/property-type-based-property/property-type-based-property.element.ts (95%) diff --git a/src/packages/core/content-type/index.ts b/src/packages/core/content-type/index.ts index 79f883296b..2a3cd65724 100644 --- a/src/packages/core/content-type/index.ts +++ b/src/packages/core/content-type/index.ts @@ -1,7 +1,12 @@ -export * from './components/index.js'; export * from './composition/index.js'; export * from './modals/index.js'; export * from './repository/index.js'; export * from './structure/index.js'; export * from './workspace/index.js'; export type * from './types.js'; + +/** + * @deprecated Use `UmbPropertyTypeBasedPropertyElement` from `@umbraco-cms/backoffice/content` instead. + * Export will be removed in version 17. + */ +export { UmbPropertyTypeBasedPropertyElement } from '../content/components/property-type-based-property/property-type-based-property.element.js'; diff --git a/src/packages/core/content-type/components/index.ts b/src/packages/core/content/components/index.ts similarity index 100% rename from src/packages/core/content-type/components/index.ts rename to src/packages/core/content/components/index.ts diff --git a/src/packages/core/content-type/components/property-type-based-property/index.ts b/src/packages/core/content/components/property-type-based-property/index.ts similarity index 100% rename from src/packages/core/content-type/components/property-type-based-property/index.ts rename to src/packages/core/content/components/property-type-based-property/index.ts diff --git a/src/packages/core/content-type/components/property-type-based-property/property-type-based-property.element.ts b/src/packages/core/content/components/property-type-based-property/property-type-based-property.element.ts similarity index 95% rename from src/packages/core/content-type/components/property-type-based-property/property-type-based-property.element.ts rename to src/packages/core/content/components/property-type-based-property/property-type-based-property.element.ts index 475188cd24..745b97c7c0 100644 --- a/src/packages/core/content-type/components/property-type-based-property/property-type-based-property.element.ts +++ b/src/packages/core/content/components/property-type-based-property/property-type-based-property.element.ts @@ -1,7 +1,6 @@ -import type { UmbPropertyEditorConfig } from '../../../property-editor/index.js'; -import type { UmbPropertyTypeModel } from '../../types.js'; +import { UmbContentPropertyContext } from '../../content-property.context.js'; +import type { UmbPropertyEditorConfig } from '@umbraco-cms/backoffice/property-editor'; import { css, customElement, html, ifDefined, property, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbContentPropertyContext } from '@umbraco-cms/backoffice/content'; import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -9,6 +8,7 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { UmbDataTypeDetailModel } from '@umbraco-cms/backoffice/data-type'; import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; import { UMB_UNSUPPORTED_EDITOR_SCHEMA_ALIASES } from '@umbraco-cms/backoffice/property'; +import type { UmbPropertyTypeModel } from '@umbraco-cms/backoffice/content-type'; @customElement('umb-property-type-based-property') export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { diff --git a/src/packages/core/content/index.ts b/src/packages/core/content/index.ts index f1bd92d5c0..338c9631c1 100644 --- a/src/packages/core/content/index.ts +++ b/src/packages/core/content/index.ts @@ -1,6 +1,8 @@ export { UMB_CONTENT_PROPERTY_CONTEXT } from './content-property.context-token.js'; export { UmbContentPropertyContext } from './content-property.context.js'; + export * from './collection/index.js'; +export * from './components/index.js'; export * from './constants.js'; export * from './controller/merge-content-variant-data.controller.js'; export * from './manager/index.js'; From ffc22e014853c2b3b53cf043dcde6ace3637a9cd Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 11:27:04 +0100 Subject: [PATCH 143/170] use relative imports inside a module --- .../content-type-design-editor-group.element.ts | 7 ++----- ...content-type-design-editor-properties.element.ts | 8 ++++---- .../content-type-design-editor-property.element.ts | 8 ++------ .../content-type-design-editor-tab.element.ts | 4 ++-- .../design/content-type-design-editor.element.ts | 13 ++++++------- 5 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts index ead29d145b..160866835c 100644 --- a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts +++ b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts @@ -1,12 +1,9 @@ +import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '../../../types.js'; +import type { UmbContentTypeContainerStructureHelper } from '../../../structure/index.js'; import { css, customElement, html, nothing, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { - UmbContentTypeContainerStructureHelper, - UmbContentTypeModel, - UmbPropertyTypeContainerModel, -} from '@umbraco-cms/backoffice/content-type'; import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import './content-type-design-editor-properties.element.js'; diff --git a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts index 65449ac606..e85a4f7d5b 100644 --- a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts +++ b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts @@ -1,4 +1,6 @@ import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '../../content-type-workspace.context-token.js'; +import type { UmbContentTypeModel, UmbPropertyTypeModel } from '../../../types.js'; +import { UmbContentTypePropertyStructureHelper } from '../../../structure/index.js'; import { UMB_CONTENT_TYPE_DESIGN_EDITOR_CONTEXT } from './content-type-design-editor.context.js'; import type { UmbContentTypeDesignEditorPropertyElement } from './content-type-design-editor-property.element.js'; import { @@ -13,17 +15,15 @@ import { } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UmbContentTypePropertyStructureHelper } from '@umbraco-cms/backoffice/content-type'; -import type { UmbContentTypeModel, UmbPropertyTypeModel } from '@umbraco-cms/backoffice/content-type'; import { type UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; - -import './content-type-design-editor-property.element.js'; import { UMB_CREATE_PROPERTY_TYPE_WORKSPACE_PATH_PATTERN, UMB_PROPERTY_TYPE_WORKSPACE_MODAL, } from '@umbraco-cms/backoffice/property-type'; +import './content-type-design-editor-property.element.js'; + const SORTER_CONFIG: UmbSorterConfig = { getUniqueOfElement: (element) => { return element.getAttribute('data-umb-property-id'); diff --git a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts index 02374f4f8a..571b9a3c69 100644 --- a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts +++ b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-property.element.ts @@ -1,3 +1,5 @@ +import type { UmbContentTypePropertyStructureHelper } from '../../../structure/index.js'; +import type { UmbContentTypeModel, UmbPropertyTypeModel, UmbPropertyTypeScaffoldModel } from '../../../types.js'; import { UmbPropertyTypeContext } from './content-type-design-editor-property.context.js'; import { css, html, customElement, property, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { generateAlias } from '@umbraco-cms/backoffice/utils'; @@ -6,12 +8,6 @@ import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_EDIT_PROPERTY_TYPE_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/property-type'; -import type { - UmbContentTypeModel, - UmbContentTypePropertyStructureHelper, - UmbPropertyTypeModel, - UmbPropertyTypeScaffoldModel, -} from '@umbraco-cms/backoffice/content-type'; import type { UUIInputElement, UUIInputLockElement, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; /** diff --git a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts index 3b18576327..363f959008 100644 --- a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts +++ b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts @@ -1,13 +1,13 @@ import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '../../content-type-workspace.context-token.js'; +import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '../../../types.js'; +import { UmbContentTypeContainerStructureHelper } from '../../../structure/index.js'; import { UMB_CONTENT_TYPE_DESIGN_EDITOR_CONTEXT } from './content-type-design-editor.context.js'; import type { UmbContentTypeWorkspaceViewEditGroupElement } from './content-type-design-editor-group.element.js'; import { css, customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbContentTypeContainerStructureHelper } from '@umbraco-cms/backoffice/content-type'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '@umbraco-cms/backoffice/content-type'; import type { UmbSorterConfig } from '@umbraco-cms/backoffice/sorter'; import './content-type-design-editor-properties.element.js'; diff --git a/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts b/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts index 9105d91fd0..50d10eef50 100644 --- a/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts +++ b/src/packages/core/content-type/workspace/views/design/content-type-design-editor.element.ts @@ -1,15 +1,14 @@ import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '../../content-type-workspace.context-token.js'; +import type { UmbContentTypeModel, UmbPropertyTypeContainerModel } from '../../../types.js'; +import { + UmbContentTypeContainerStructureHelper, + UmbContentTypeMoveRootGroupsIntoFirstTabHelper, +} from '../../../structure/index.js'; +import { UMB_COMPOSITION_PICKER_MODAL } from '../../../modals/index.js'; import type { UmbContentTypeDesignEditorTabElement } from './content-type-design-editor-tab.element.js'; import { UmbContentTypeDesignEditorContext } from './content-type-design-editor.context.js'; import { css, html, customElement, state, repeat, ifDefined, nothing } from '@umbraco-cms/backoffice/external/lit'; import type { UUIInputElement, UUIInputEvent, UUITabElement } from '@umbraco-cms/backoffice/external/uui'; -import { - UMB_COMPOSITION_PICKER_MODAL, - UmbContentTypeContainerStructureHelper, - UmbContentTypeMoveRootGroupsIntoFirstTabHelper, - type UmbContentTypeModel, - type UmbPropertyTypeContainerModel, -} from '@umbraco-cms/backoffice/content-type'; import { encodeFolderName } from '@umbraco-cms/backoffice/router'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { CompositionTypeModel } from '@umbraco-cms/backoffice/external/backend-api'; From 755db1848f8b13a6d26d79dc3cecc02967588b59 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 11:29:59 +0100 Subject: [PATCH 144/170] use relative imports inside module --- .../controller/merge-content-variant-data.controller.ts | 2 +- src/packages/core/content/manager/content-data-manager.ts | 2 +- src/packages/core/content/manager/element-data-manager.ts | 2 +- .../content/workspace/content-workspace-context.interface.ts | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/packages/core/content/controller/merge-content-variant-data.controller.ts b/src/packages/core/content/controller/merge-content-variant-data.controller.ts index aa50029af8..ae4e35af83 100644 --- a/src/packages/core/content/controller/merge-content-variant-data.controller.ts +++ b/src/packages/core/content/controller/merge-content-variant-data.controller.ts @@ -1,5 +1,5 @@ +import type { UmbContentLikeDetailModel, UmbPotentialContentValueModel } from '../types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; -import type { UmbContentLikeDetailModel, UmbPotentialContentValueModel } from '@umbraco-cms/backoffice/content'; import { createExtensionApi } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbVariantId, type UmbVariantDataModel } from '@umbraco-cms/backoffice/variant'; diff --git a/src/packages/core/content/manager/content-data-manager.ts b/src/packages/core/content/manager/content-data-manager.ts index 1a14bcee89..d8d375eb4c 100644 --- a/src/packages/core/content/manager/content-data-manager.ts +++ b/src/packages/core/content/manager/content-data-manager.ts @@ -1,5 +1,5 @@ +import type { UmbContentDetailModel } from '../types.js'; import { UmbElementWorkspaceDataManager } from './element-data-manager.js'; -import type { UmbContentDetailModel } from '@umbraco-cms/backoffice/content'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { appendToFrozenArray, jsonStringComparison } from '@umbraco-cms/backoffice/observable-api'; import { UmbVariantId, type UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; diff --git a/src/packages/core/content/manager/element-data-manager.ts b/src/packages/core/content/manager/element-data-manager.ts index 7dd3ddc91e..dfac318c5d 100644 --- a/src/packages/core/content/manager/element-data-manager.ts +++ b/src/packages/core/content/manager/element-data-manager.ts @@ -1,5 +1,5 @@ import { UmbMergeContentVariantDataController } from '../controller/merge-content-variant-data.controller.js'; -import type { UmbElementDetailModel } from '@umbraco-cms/backoffice/content'; +import type { UmbElementDetailModel } from '../types.js'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import { UmbEntityWorkspaceDataManager, type UmbWorkspaceDataManager } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/core/content/workspace/content-workspace-context.interface.ts b/src/packages/core/content/workspace/content-workspace-context.interface.ts index ecaeca41a7..ba1b17c59c 100644 --- a/src/packages/core/content/workspace/content-workspace-context.interface.ts +++ b/src/packages/core/content/workspace/content-workspace-context.interface.ts @@ -1,4 +1,5 @@ -import type { UmbContentDetailModel, UmbElementPropertyDataOwner } from '@umbraco-cms/backoffice/content'; +import type { UmbContentDetailModel } from '../types.js'; +import type { UmbElementPropertyDataOwner } from '../property-dataset-context/index.js'; import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; import type { UmbVariantId, UmbEntityVariantModel } from '@umbraco-cms/backoffice/variant'; From 7eb755234d11341fad034cd6ed51f5e2e0eff2af Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 11:35:57 +0100 Subject: [PATCH 145/170] fix circular import --- .../modals/document-type-picker-modal.token.ts | 7 ++----- src/packages/documents/document-types/tree/index.ts | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts b/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts index 9ab4a1ac6d..ca1cac6fad 100644 --- a/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts +++ b/src/packages/documents/document-types/modals/document-type-picker-modal.token.ts @@ -1,10 +1,7 @@ +import { UMB_DOCUMENT_TYPE_ENTITY_TYPE, UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE } from '../entity.js'; import { UMB_CREATE_DOCUMENT_TYPE_WORKSPACE_PATH_PATTERN } from '../paths.js'; +import type { UmbDocumentTypeTreeItemModel } from '../tree/index.js'; import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; -import { - UMB_DOCUMENT_TYPE_ENTITY_TYPE, - UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, - type UmbDocumentTypeTreeItemModel, -} from '@umbraco-cms/backoffice/document-type'; import { type UmbTreePickerModalValue, type UmbTreePickerModalData, diff --git a/src/packages/documents/document-types/tree/index.ts b/src/packages/documents/document-types/tree/index.ts index f2f1e85a61..a372c0b6a5 100644 --- a/src/packages/documents/document-types/tree/index.ts +++ b/src/packages/documents/document-types/tree/index.ts @@ -1,3 +1,4 @@ export { UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT } from './document-type.tree.store.context-token.js'; export { UMB_DOCUMENT_TYPE_TREE_REPOSITORY_ALIAS, UMB_DOCUMENT_TYPE_TREE_ALIAS } from './constants.js'; export * from './folder/index.js'; +export type * from './types.js'; From 59e3e91271339484788caccc0ddb6f66d85b4b81 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 11:56:35 +0100 Subject: [PATCH 146/170] use relative imports --- .../image-cropper-field.element.ts | 13 +++--- .../image-cropper-focus-setter.element.ts | 45 +++++++++++-------- .../image-cropper.element.ts | 14 ++++-- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/packages/media/media/components/input-image-cropper/image-cropper-field.element.ts b/src/packages/media/media/components/input-image-cropper/image-cropper-field.element.ts index 3ca9812849..5ba36c22b8 100644 --- a/src/packages/media/media/components/input-image-cropper/image-cropper-field.element.ts +++ b/src/packages/media/media/components/input-image-cropper/image-cropper-field.element.ts @@ -1,19 +1,20 @@ -import './image-cropper.element.js'; -import './image-cropper-focus-setter.element.js'; -import './image-cropper-preview.element.js'; import type { UmbImageCropperElement } from './image-cropper.element.js'; import type { UmbImageCropperCrop, UmbImageCropperCrops, UmbImageCropperFocalPoint, UmbImageCropperPropertyEditorValue, - UmbFocalPointChangeEvent, - UmbImageCropChangeEvent, -} from './index.js'; +} from './types.js'; +import type { UmbImageCropChangeEvent } from './crop-change.event.js'; +import type { UmbFocalPointChangeEvent } from './focalpoint-change.event.js'; import { css, customElement, html, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import './image-cropper.element.js'; +import './image-cropper-focus-setter.element.js'; +import './image-cropper-preview.element.js'; + @customElement('umb-image-cropper-field') export class UmbInputImageCropperFieldElement extends UmbLitElement { @property({ attribute: false }) diff --git a/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts b/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts index 0963940875..5951fe8079 100644 --- a/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts +++ b/src/packages/media/media/components/input-image-cropper/image-cropper-focus-setter.element.ts @@ -1,8 +1,19 @@ -import { type UmbImageCropperFocalPoint, UmbFocalPointChangeEvent } from './index.js'; import type { UmbFocalPointModel } from '../../types.js'; +import type { UmbImageCropperFocalPoint } from './types.js'; +import { UmbFocalPointChangeEvent } from './focalpoint-change.event.js'; import { drag } from '@umbraco-cms/backoffice/external/uui'; import { clamp } from '@umbraco-cms/backoffice/utils'; -import { css, customElement, classMap, ifDefined, html, nothing, state, property, query } from '@umbraco-cms/backoffice/external/lit'; +import { + css, + customElement, + classMap, + ifDefined, + html, + nothing, + state, + property, + query, +} from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit'; @@ -38,7 +49,7 @@ export class UmbImageCropperFocusSetterElement extends UmbLitElement { @property({ type: Boolean }) hideFocalPoint = false; - + @property({ type: Boolean, reflect: true }) disabled = false; @@ -84,7 +95,7 @@ export class UmbImageCropperFocusSetterElement extends UmbLitElement { } this.#resetCoords(); - + this.imageElement.style.aspectRatio = `${imageAspectRatio}`; this.wrapperElement.style.aspectRatio = `${imageAspectRatio}`; }; @@ -97,22 +108,21 @@ export class UmbImageCropperFocusSetterElement extends UmbLitElement { } #coordsToFactor(x: number, y: number) { - const top = (y / 100) / y * 50; - const left = (x / 100) / x * 50; + const top = (y / 100 / y) * 50; + const left = (x / 100 / x) * 50; - return { top, left }; + return { top, left }; } #setFocalPoint(x: number, y: number, width: number, height: number) { - - const left = clamp((x / width), 0, 1); - const top = clamp((y / height), 0, 1); + const left = clamp(x / width, 0, 1); + const top = clamp(y / height, 0, 1); this.#coordsToFactor(x, y); const focalPoint = { left, top } as UmbFocalPointModel; - console.log("setFocalPoint", focalPoint) + console.log('setFocalPoint', focalPoint); this.dispatchEvent(new UmbFocalPointChangeEvent(focalPoint)); } @@ -171,7 +181,7 @@ export class UmbImageCropperFocusSetterElement extends UmbLitElement { #handleGridKeyDown(event: KeyboardEvent) { if (this.disabled || this.hideFocalPoint) return; - + const increment = event.shiftKey ? 1 : 10; const grid = this.wrapperElement; @@ -207,14 +217,13 @@ export class UmbImageCropperFocusSetterElement extends UmbLitElement { override render() { if (!this.src) return nothing; return html` -
    +
    nothing} src=${this.src} alt="" /> -
    - - + +
    `; } From 0892de664deaecb7e11e16c1b0d33426c9ef99ed Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 12:00:33 +0100 Subject: [PATCH 147/170] use relative imports --- .../property-editor-ui-media-entity-picker.element.ts | 2 +- src/packages/media/media/tree/media-tree-picker-modal.token.ts | 2 +- .../views/info/media-workspace-view-info-reference.element.ts | 2 +- .../workspace/views/info/media-workspace-view-info.element.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/packages/media/media/property-editors/media-entity-picker/property-editor-ui-media-entity-picker.element.ts b/src/packages/media/media/property-editors/media-entity-picker/property-editor-ui-media-entity-picker.element.ts index 46e8af9c85..224b4cbdbc 100644 --- a/src/packages/media/media/property-editors/media-entity-picker/property-editor-ui-media-entity-picker.element.ts +++ b/src/packages/media/media/property-editors/media-entity-picker/property-editor-ui-media-entity-picker.element.ts @@ -1,8 +1,8 @@ +import type { UmbInputMediaElement } from '../../components/index.js'; import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models'; -import type { UmbInputMediaElement } from '@umbraco-cms/backoffice/media'; import type { UmbPropertyEditorConfigCollection, UmbPropertyEditorUiElement, diff --git a/src/packages/media/media/tree/media-tree-picker-modal.token.ts b/src/packages/media/media/tree/media-tree-picker-modal.token.ts index 2ba9bba5cd..30cae5a481 100644 --- a/src/packages/media/media/tree/media-tree-picker-modal.token.ts +++ b/src/packages/media/media/tree/media-tree-picker-modal.token.ts @@ -1,10 +1,10 @@ +import type { UmbMediaTreeItemModel } from './types.js'; import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; import { type UmbTreePickerModalValue, type UmbTreePickerModalData, UMB_TREE_PICKER_MODAL_ALIAS, } from '@umbraco-cms/backoffice/tree'; -import type { UmbMediaTreeItemModel } from '@umbraco-cms/backoffice/media'; export type UmbMediaTreePickerModalData = UmbTreePickerModalData; export type UmbMediaTreePickerModalValue = UmbTreePickerModalValue; diff --git a/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts b/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts index 90169d6666..4f9aaa6bb8 100644 --- a/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts +++ b/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts @@ -1,7 +1,7 @@ +import { UmbMediaReferenceRepository } from '../../../reference/index.js'; import { css, customElement, html, nothing, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; import { isDefaultReference, isDocumentReference, isMediaReference } from '@umbraco-cms/backoffice/relations'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UmbMediaReferenceRepository } from '@umbraco-cms/backoffice/media'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; diff --git a/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts b/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts index 529d781978..a46c096ad4 100644 --- a/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts +++ b/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts @@ -1,3 +1,4 @@ +import type { UMB_MEDIA_WORKSPACE_CONTEXT } from '../../media-workspace.context-token.js'; import { TimeOptions } from './utils.js'; import { css, customElement, html, ifDefined, nothing, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -5,7 +6,6 @@ import type { UmbMediaTypeItemModel } from '@umbraco-cms/backoffice/media-type'; import { UMB_MEDIA_TYPE_ENTITY_TYPE, UmbMediaTypeItemRepository } from '@umbraco-cms/backoffice/media-type'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UMB_MEDIA_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/media'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import type { MediaUrlInfoModel } from '@umbraco-cms/backoffice/external/backend-api'; From 60ee649fc1b2acd0e895f0141b661782c25a0b5b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 12:16:34 +0100 Subject: [PATCH 148/170] temp duplicate styling as we shouldn't depend on another elements styles unless we extend it --- .../input-rich-media.element.ts | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts b/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts index 24a92a2af8..c71255813e 100644 --- a/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts +++ b/src/packages/media/media/components/input-rich-media/input-rich-media.element.ts @@ -1,10 +1,9 @@ -import { UmbInputMediaElement } from '../input-media/index.js'; import { UmbMediaItemRepository } from '../../repository/index.js'; import { UMB_IMAGE_CROPPER_EDITOR_MODAL, UMB_MEDIA_PICKER_MODAL } from '../../modals/index.js'; import type { UmbCropModel, UmbMediaPickerPropertyValue } from '../../types.js'; import type { UmbMediaItemModel } from '../../repository/index.js'; import type { UmbUploadableItem } from '../../dropzone/types.js'; -import { customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { umbConfirmModal, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbId } from '@umbraco-cms/backoffice/id'; @@ -414,7 +413,42 @@ export class UmbInputRichMediaElement extends UUIFormControlMixin(UmbLitElement, `; } - static override styles = UmbInputMediaElement.styles; + static override styles = [ + css` + :host { + position: relative; + } + .container { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + grid-auto-rows: 150px; + gap: var(--uui-size-space-5); + } + + #btn-add { + text-align: center; + height: 100%; + } + + uui-icon { + display: block; + margin: 0 auto; + } + + uui-card-media umb-icon { + font-size: var(--uui-size-8); + } + + uui-card-media[drag-placeholder] { + opacity: 0.2; + } + img { + background-image: url('data:image/svg+xml;charset=utf-8,'); + background-size: 10px 10px; + background-repeat: repeat; + } + `, + ]; } export default UmbInputRichMediaElement; From 498ec8bfdfa2192ee6853b84d27c15e420856346 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 12:20:40 +0100 Subject: [PATCH 149/170] fix import --- .../workspace/views/info/media-workspace-view-info.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts b/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts index a46c096ad4..2e49276698 100644 --- a/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts +++ b/src/packages/media/media/workspace/views/info/media-workspace-view-info.element.ts @@ -1,4 +1,4 @@ -import type { UMB_MEDIA_WORKSPACE_CONTEXT } from '../../media-workspace.context-token.js'; +import { UMB_MEDIA_WORKSPACE_CONTEXT } from '../../media-workspace.context-token.js'; import { TimeOptions } from './utils.js'; import { css, customElement, html, ifDefined, nothing, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; From 4d378ae291549cc63dd44599f871bf902b9129b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 13:06:14 +0100 Subject: [PATCH 150/170] lint fixes --- .../workspace/manifests.ts | 3 +- .../workspace/views/manifests.ts | 2 +- .../block-grid/workspace/views/manifests.ts | 2 +- .../block-list/workspace/views/manifests.ts | 2 +- .../block-rte/workspace/views/manifests.ts | 2 +- .../block/block-type/workspace/manifests.ts | 3 +- .../block/block/workspace/manifests.ts | 3 +- src/packages/core/content/constants.ts | 2 +- ...r-validation-to-form-control.controller.ts | 3 +- .../core/workspace/conditions/const.ts | 1 - .../core/workspace/conditions/types.ts | 35 ++++++++++--------- .../conditions/workspace-alias.condition.ts | 2 +- .../entity-detail-workspace-base.ts | 1 - .../tree/folder/workspace/manifests.ts | 3 +- src/packages/data-type/workspace/manifests.ts | 3 +- .../dictionary/menu-item/manifests.ts | 2 +- .../dictionary/workspace/manifests.ts | 3 +- .../tree/folder/workspace/manifests.ts | 3 +- .../workspace/manifests.ts | 3 +- .../document-types/menu/manifests.ts | 2 +- .../tree/folder/workspace/manifests.ts | 3 +- .../document-types/workspace/manifests.ts | 3 +- .../documents/documents/menu/manifests.ts | 2 +- .../rollback/entity-action/manifests.ts | 2 +- .../extension-insights/workspace/manifests.ts | 2 +- .../workspace/language-root/manifests.ts | 4 +-- .../language/workspace/language/manifests.ts | 3 +- .../media/media-types/menu/manifests.ts | 2 +- .../tree/folder/workspace/manifests.ts | 3 +- .../media/media-types/workspace/manifests.ts | 4 +-- .../input-image-cropper/crop-change.event.ts | 2 +- .../focalpoint-change.event.ts | 2 +- src/packages/media/media/menu/manifests.ts | 2 +- .../media/media/workspace/manifests.ts | 3 +- .../workspace/member-group-root/manifests.ts | 2 +- .../workspace/member-group/manifests.ts | 3 +- .../members/member-type/menu/manifests.ts | 2 +- .../member-type/workspace/manifests.ts | 3 +- .../member/workspace/member-root/manifests.ts | 2 +- .../member/workspace/member/manifests.ts | 3 +- .../property-editors/collection/manifests.ts | 6 ++-- .../partial-views/menu/manifests.ts | 2 +- .../partial-views/workspace/manifests.ts | 3 +- .../templating/scripts/menu/manifests.ts | 2 +- .../templating/scripts/workspace/manifests.ts | 3 +- .../templating/stylesheets/menu/manifests.ts | 2 +- .../stylesheets/workspace/manifests.ts | 3 +- .../templating/templates/menu/manifests.ts | 2 +- .../templates/workspace/manifests.ts | 3 +- .../content-name/content-name.component.ts | 4 +-- .../workspace/user-group-root/manifests.ts | 2 +- .../workspace/user-group/manifests.ts | 3 +- .../user/workspace/user-root/manifests.ts | 2 +- .../user/user/workspace/user/manifests.ts | 3 +- .../workspace/webhook-root/manifests.ts | 2 +- .../webhook/workspace/webhook/manifests.ts | 3 +- 56 files changed, 76 insertions(+), 101 deletions(-) diff --git a/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/manifests.ts b/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/manifests.ts index 10eb00ca0a..315fd1ff4d 100644 --- a/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/manifests.ts +++ b/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/manifests.ts @@ -1,7 +1,6 @@ import { manifests as workspaceViewManifests } from './views/manifests.js'; import { UMB_BLOCK_GRID_AREA_TYPE_WORKSPACE_ALIAS } from './index.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ ...workspaceViewManifests, diff --git a/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/views/manifests.ts b/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/views/manifests.ts index ba7238c442..3bdf1271b9 100644 --- a/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/views/manifests.ts +++ b/src/packages/block/block-grid/components/block-grid-area-config-entry/workspace/views/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_BLOCK_GRID_AREA_TYPE_WORKSPACE_ALIAS } from '../index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import type { ManifestWorkspaceView } from '@umbraco-cms/backoffice/workspace'; export const workspaceViews: Array = [ diff --git a/src/packages/block/block-grid/workspace/views/manifests.ts b/src/packages/block/block-grid/workspace/views/manifests.ts index 8722b9f764..e14984f6c2 100644 --- a/src/packages/block/block-grid/workspace/views/manifests.ts +++ b/src/packages/block/block-grid/workspace/views/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_BLOCK_GRID_TYPE_WORKSPACE_ALIAS } from '../index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/block/block-list/workspace/views/manifests.ts b/src/packages/block/block-list/workspace/views/manifests.ts index 04d75d39ab..a019927e9c 100644 --- a/src/packages/block/block-list/workspace/views/manifests.ts +++ b/src/packages/block/block-list/workspace/views/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_BLOCK_LIST_TYPE_WORKSPACE_ALIAS } from '../index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/block/block-rte/workspace/views/manifests.ts b/src/packages/block/block-rte/workspace/views/manifests.ts index 5b8abf2041..f075a1e992 100644 --- a/src/packages/block/block-rte/workspace/views/manifests.ts +++ b/src/packages/block/block-rte/workspace/views/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_BLOCK_RTE_TYPE_WORKSPACE_ALIAS } from '../index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/block/block-type/workspace/manifests.ts b/src/packages/block/block-type/workspace/manifests.ts index 3fcdb6fb10..423d1a2a51 100644 --- a/src/packages/block/block-type/workspace/manifests.ts +++ b/src/packages/block/block-type/workspace/manifests.ts @@ -1,8 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_BLOCK_GRID_TYPE_WORKSPACE_ALIAS } from '../../block-grid/workspace/index.js'; import { UMB_BLOCK_LIST_TYPE_WORKSPACE_ALIAS } from '../../block-list/workspace/index.js'; import { UMB_BLOCK_RTE_TYPE_WORKSPACE_ALIAS } from '../../block-rte/workspace/index.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/block/block/workspace/manifests.ts b/src/packages/block/block/workspace/manifests.ts index 1b67a6e46e..89c0388d5a 100644 --- a/src/packages/block/block/workspace/manifests.ts +++ b/src/packages/block/block/workspace/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_BLOCK_WORKSPACE_ALIAS } from './index.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/core/content/constants.ts b/src/packages/core/content/constants.ts index cecd2baf55..05a27ced5d 100644 --- a/src/packages/core/content/constants.ts +++ b/src/packages/core/content/constants.ts @@ -1 +1 @@ -export const UMB_CONTENT_SECTION_ALIAS = 'Umb.Section.Content'; \ No newline at end of file +export const UMB_CONTENT_SECTION_ALIAS = 'Umb.Section.Content'; diff --git a/src/packages/core/validation/controllers/bind-server-validation-to-form-control.controller.ts b/src/packages/core/validation/controllers/bind-server-validation-to-form-control.controller.ts index e2951a2b78..5410e8caa0 100644 --- a/src/packages/core/validation/controllers/bind-server-validation-to-form-control.controller.ts +++ b/src/packages/core/validation/controllers/bind-server-validation-to-form-control.controller.ts @@ -12,7 +12,6 @@ const observeSymbol = Symbol(); * This controller will add a custom error to the form control if the validation context has any messages for the specified data path. */ export class UmbBindServerValidationToFormControl extends UmbControllerBase { - #context?: typeof UMB_VALIDATION_CONTEXT.TYPE; #control: UmbFormControlMixinInterface; @@ -41,7 +40,7 @@ export class UmbBindServerValidationToFormControl extends UmbControllerBase { } constructor(host: UmbControllerHost, formControl: UmbFormControlMixinInterface, dataPath: string) { - super(host,'umbFormControlValidation_'+simpleHashCode(dataPath)); + super(host, 'umbFormControlValidation_' + simpleHashCode(dataPath)); this.#control = formControl; this.consumeContext(UMB_VALIDATION_CONTEXT, (context) => { this.#context = context; diff --git a/src/packages/core/workspace/conditions/const.ts b/src/packages/core/workspace/conditions/const.ts index 00c36c7222..8a385d17ae 100644 --- a/src/packages/core/workspace/conditions/const.ts +++ b/src/packages/core/workspace/conditions/const.ts @@ -24,4 +24,3 @@ export const UMB_WORKSPACE_ENTITY_IS_NEW_CONDITION = UMB_WORKSPACE_ENTITY_IS_NEW * Workspace alias condition alias */ export const UMB_WORKSPACE_CONDITION_ALIAS = 'Umb.Condition.WorkspaceAlias'; - diff --git a/src/packages/core/workspace/conditions/types.ts b/src/packages/core/workspace/conditions/types.ts index e13151df82..a9a21e6ea9 100644 --- a/src/packages/core/workspace/conditions/types.ts +++ b/src/packages/core/workspace/conditions/types.ts @@ -1,21 +1,24 @@ -import type { UMB_WORKSPACE_CONDITION_ALIAS, UMB_WORKSPACE_ENTITY_IS_NEW_CONDITION_ALIAS, UMB_WORKSPACE_HAS_COLLECTION_CONDITION_ALIAS } from './const.js'; +import type { + UMB_WORKSPACE_CONDITION_ALIAS, + UMB_WORKSPACE_ENTITY_IS_NEW_CONDITION_ALIAS, + UMB_WORKSPACE_HAS_COLLECTION_CONDITION_ALIAS, +} from './const.js'; import type { UmbConditionConfigBase } from '@umbraco-cms/backoffice/extension-api'; -export interface WorkspaceAliasConditionConfig - extends UmbConditionConfigBase { - /** - * Define the workspace that this extension should be available in - * @example - * "Umb.Workspace.Document" - */ - match?: string; - /** - * Define one or more workspaces that this extension should be available in - * @example - * ["Umb.Workspace.Document", "Umb.Workspace.Media"] - */ - oneOf?: Array; - } +export interface WorkspaceAliasConditionConfig extends UmbConditionConfigBase { + /** + * Define the workspace that this extension should be available in + * @example + * "Umb.Workspace.Document" + */ + match?: string; + /** + * Define one or more workspaces that this extension should be available in + * @example + * ["Umb.Workspace.Document", "Umb.Workspace.Media"] + */ + oneOf?: Array; +} export type WorkspaceContentTypeAliasConditionConfig = UmbConditionConfigBase<'Umb.Condition.WorkspaceContentTypeAlias'> & { diff --git a/src/packages/core/workspace/conditions/workspace-alias.condition.ts b/src/packages/core/workspace/conditions/workspace-alias.condition.ts index 7e6c421ebf..71fe226054 100644 --- a/src/packages/core/workspace/conditions/workspace-alias.condition.ts +++ b/src/packages/core/workspace/conditions/workspace-alias.condition.ts @@ -1,10 +1,10 @@ import { UMB_WORKSPACE_CONTEXT } from '../workspace.context-token.js'; import type { UmbWorkspaceContext } from '../workspace-context.interface.js'; import type { WorkspaceAliasConditionConfig } from './types.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from './const.js'; import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry'; import type { UmbConditionControllerArguments, UmbExtensionCondition } from '@umbraco-cms/backoffice/extension-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from './const.js'; export class UmbWorkspaceAliasCondition extends UmbConditionBase diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index cce84e90f1..a99d194261 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -94,7 +94,6 @@ export abstract class UmbEntityDetailWorkspaceContextBase< /** * Get the unique * @returns { string | undefined } The unique identifier - * */ getUnique(): UmbEntityUnique | undefined { return this._data.getCurrent()?.unique; diff --git a/src/packages/data-type/tree/folder/workspace/manifests.ts b/src/packages/data-type/tree/folder/workspace/manifests.ts index 78447f41ce..f0aa6a013c 100644 --- a/src/packages/data-type/tree/folder/workspace/manifests.ts +++ b/src/packages/data-type/tree/folder/workspace/manifests.ts @@ -1,7 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DATA_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; import { UMB_DATA_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/data-type/workspace/manifests.ts b/src/packages/data-type/workspace/manifests.ts index c83c6cb153..61c6fb095f 100644 --- a/src/packages/data-type/workspace/manifests.ts +++ b/src/packages/data-type/workspace/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DATA_TYPE_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/dictionary/menu-item/manifests.ts b/src/packages/dictionary/menu-item/manifests.ts index f3a87bd76a..03da8a1d40 100644 --- a/src/packages/dictionary/menu-item/manifests.ts +++ b/src/packages/dictionary/menu-item/manifests.ts @@ -1,6 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DICTIONARY_ENTITY_TYPE } from '../entity.js'; import { UMB_DICTIONARY_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_TRANSLATION_MENU_ALIAS } from '@umbraco-cms/backoffice/translation'; export const manifests: Array = [ diff --git a/src/packages/dictionary/workspace/manifests.ts b/src/packages/dictionary/workspace/manifests.ts index a78e4a8ef3..7acd6dbcd7 100644 --- a/src/packages/dictionary/workspace/manifests.ts +++ b/src/packages/dictionary/workspace/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DICTIONARY_ENTITY_TYPE } from '../entity.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const UMB_DICTIONARY_WORKSPACE_ALIAS = 'Umb.Workspace.Dictionary'; diff --git a/src/packages/documents/document-blueprints/tree/folder/workspace/manifests.ts b/src/packages/documents/document-blueprints/tree/folder/workspace/manifests.ts index 52f6f4e34f..59a6f5ef40 100644 --- a/src/packages/documents/document-blueprints/tree/folder/workspace/manifests.ts +++ b/src/packages/documents/document-blueprints/tree/folder/workspace/manifests.ts @@ -1,7 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DOCUMENT_BLUEPRINT_FOLDER_ENTITY_TYPE } from '../../../entity.js'; import { UMB_DOCUMENT_BLUEPRINT_FOLDER_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/documents/document-blueprints/workspace/manifests.ts b/src/packages/documents/document-blueprints/workspace/manifests.ts index ba2884d0e4..06ec9abd48 100644 --- a/src/packages/documents/document-blueprints/workspace/manifests.ts +++ b/src/packages/documents/document-blueprints/workspace/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE } from '../entity.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const UMB_DOCUMENT_BLUEPRINT_WORKSPACE_ALIAS = 'Umb.Workspace.DocumentBlueprint'; diff --git a/src/packages/documents/document-types/menu/manifests.ts b/src/packages/documents/document-types/menu/manifests.ts index 73d7506420..35ea56aca9 100644 --- a/src/packages/documents/document-types/menu/manifests.ts +++ b/src/packages/documents/document-types/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DOCUMENT_TYPE_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts index d0a5f120c4..34dcbc13e2 100644 --- a/src/packages/documents/document-types/tree/folder/workspace/manifests.ts +++ b/src/packages/documents/document-types/tree/folder/workspace/manifests.ts @@ -1,7 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DOCUMENT_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; import { UMB_DOCUMENT_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/documents/document-types/workspace/manifests.ts b/src/packages/documents/document-types/workspace/manifests.ts index 028faf033a..3177e42a18 100644 --- a/src/packages/documents/document-types/workspace/manifests.ts +++ b/src/packages/documents/document-types/workspace/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../repository/composition/index.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.DocumentType'; diff --git a/src/packages/documents/documents/menu/manifests.ts b/src/packages/documents/documents/menu/manifests.ts index a842fa686c..dc76417093 100644 --- a/src/packages/documents/documents/menu/manifests.ts +++ b/src/packages/documents/documents/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DOCUMENT_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_CONTENT_MENU_ALIAS = 'Umb.Menu.Content'; diff --git a/src/packages/documents/documents/rollback/entity-action/manifests.ts b/src/packages/documents/documents/rollback/entity-action/manifests.ts index 2bed9b0321..4e7d45616a 100644 --- a/src/packages/documents/documents/rollback/entity-action/manifests.ts +++ b/src/packages/documents/documents/rollback/entity-action/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; import { UMB_USER_PERMISSION_DOCUMENT_ROLLBACK } from '../../user-permissions/index.js'; import { UMB_DOCUMENT_WORKSPACE_ALIAS } from '../../workspace/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS } from '@umbraco-cms/backoffice/recycle-bin'; export const manifests: Array = [ diff --git a/src/packages/extension-insights/workspace/manifests.ts b/src/packages/extension-insights/workspace/manifests.ts index 6cd95677fb..6ea2f304e3 100644 --- a/src/packages/extension-insights/workspace/manifests.ts +++ b/src/packages/extension-insights/workspace/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_EXTENSION_COLLECTION_ALIAS } from '../collection/manifests.js'; import { UMB_EXTENSION_ROOT_ENTITY_TYPE } from '../entity.js'; import { UMB_EXTENSION_ROOT_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/language/workspace/language-root/manifests.ts b/src/packages/language/workspace/language-root/manifests.ts index e0fef2efe7..92e59e4341 100644 --- a/src/packages/language/workspace/language-root/manifests.ts +++ b/src/packages/language/workspace/language-root/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_LANGUAGE_COLLECTION_ALIAS } from '../../collection/index.js'; import { UMB_LANGUAGE_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_LANGUAGE_ROOT_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { @@ -27,7 +27,7 @@ export const manifests: Array = [ }, conditions: [ { - alias:UMB_WORKSPACE_CONDITION_ALIAS, + alias: UMB_WORKSPACE_CONDITION_ALIAS, match: UMB_LANGUAGE_ROOT_WORKSPACE_ALIAS, }, ], diff --git a/src/packages/language/workspace/language/manifests.ts b/src/packages/language/workspace/language/manifests.ts index b0e3508017..e3e45525fa 100644 --- a/src/packages/language/workspace/language/manifests.ts +++ b/src/packages/language/workspace/language/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_LANGUAGE_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/media/media-types/menu/manifests.ts b/src/packages/media/media-types/menu/manifests.ts index 7295ae54db..b3a58cb417 100644 --- a/src/packages/media/media-types/menu/manifests.ts +++ b/src/packages/media/media-types/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEDIA_TYPE_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/media/media-types/tree/folder/workspace/manifests.ts b/src/packages/media/media-types/tree/folder/workspace/manifests.ts index 00f6310476..6fa8991742 100644 --- a/src/packages/media/media-types/tree/folder/workspace/manifests.ts +++ b/src/packages/media/media-types/tree/folder/workspace/manifests.ts @@ -1,7 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEDIA_TYPE_FOLDER_ENTITY_TYPE } from '../../../entity.js'; import { UMB_MEDIA_TYPE_FOLDER_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/media/media-types/workspace/manifests.ts b/src/packages/media/media-types/workspace/manifests.ts index 5fd768d67b..6076139d14 100644 --- a/src/packages/media/media-types/workspace/manifests.ts +++ b/src/packages/media/media-types/workspace/manifests.ts @@ -1,8 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEDIA_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../repository/index.js'; import { UMB_MEDIA_TYPE_WORKSPACE_ALIAS } from './constants.js'; - -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/media/media/components/input-image-cropper/crop-change.event.ts b/src/packages/media/media/components/input-image-cropper/crop-change.event.ts index 0c9b076fba..b812509444 100644 --- a/src/packages/media/media/components/input-image-cropper/crop-change.event.ts +++ b/src/packages/media/media/components/input-image-cropper/crop-change.event.ts @@ -5,4 +5,4 @@ export class UmbImageCropChangeEvent extends Event { // mimics the native change event super(UmbImageCropChangeEvent.TYPE, { bubbles: false, composed: false, cancelable: false, ...args }); } -} \ No newline at end of file +} diff --git a/src/packages/media/media/components/input-image-cropper/focalpoint-change.event.ts b/src/packages/media/media/components/input-image-cropper/focalpoint-change.event.ts index ba38c5e87f..596a03b559 100644 --- a/src/packages/media/media/components/input-image-cropper/focalpoint-change.event.ts +++ b/src/packages/media/media/components/input-image-cropper/focalpoint-change.event.ts @@ -10,4 +10,4 @@ export class UmbFocalPointChangeEvent extends Event { super(UmbFocalPointChangeEvent.TYPE, { bubbles: false, composed: false, cancelable: false, ...args }); this.focalPoint = focalPoint; } -} \ No newline at end of file +} diff --git a/src/packages/media/media/menu/manifests.ts b/src/packages/media/media/menu/manifests.ts index 1681aedd98..f9e666fec0 100644 --- a/src/packages/media/media/menu/manifests.ts +++ b/src/packages/media/media/menu/manifests.ts @@ -1,6 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEDIA_TREE_ALIAS } from '../tree/index.js'; import { UMB_MEDIA_MENU_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/media/media/workspace/manifests.ts b/src/packages/media/media/workspace/manifests.ts index a48480ee07..21daa964dd 100644 --- a/src/packages/media/media/workspace/manifests.ts +++ b/src/packages/media/media/workspace/manifests.ts @@ -1,7 +1,6 @@ -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS } from '@umbraco-cms/backoffice/recycle-bin'; import { UMB_CONTENT_HAS_PROPERTIES_WORKSPACE_CONDITION } from '@umbraco-cms/backoffice/content'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_MEDIA_WORKSPACE_ALIAS = 'Umb.Workspace.Media'; diff --git a/src/packages/members/member-group/workspace/member-group-root/manifests.ts b/src/packages/members/member-group/workspace/member-group-root/manifests.ts index a066e19b59..ce7e83d833 100644 --- a/src/packages/members/member-group/workspace/member-group-root/manifests.ts +++ b/src/packages/members/member-group/workspace/member-group-root/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEMBER_GROUP_COLLECTION_ALIAS } from '../../collection/manifests.js'; import { UMB_MEMBER_GROUP_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_MEMBER_GROUP_ROOT_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/members/member-group/workspace/member-group/manifests.ts b/src/packages/members/member-group/workspace/member-group/manifests.ts index ebfd58fccb..c5811568f3 100644 --- a/src/packages/members/member-group/workspace/member-group/manifests.ts +++ b/src/packages/members/member-group/workspace/member-group/manifests.ts @@ -4,8 +4,7 @@ import type { ManifestWorkspaceActions, ManifestWorkspaceView, } from '@umbraco-cms/backoffice/workspace'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_MEMBER_GROUP_WORKSPACE_ALIAS = 'Umb.Workspace.MemberGroup'; diff --git a/src/packages/members/member-type/menu/manifests.ts b/src/packages/members/member-type/menu/manifests.ts index 39f0b5b1e5..85ca885488 100644 --- a/src/packages/members/member-type/menu/manifests.ts +++ b/src/packages/members/member-type/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEMBER_TYPE_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/members/member-type/workspace/manifests.ts b/src/packages/members/member-type/workspace/manifests.ts index 1d9925c118..80d973d302 100644 --- a/src/packages/members/member-type/workspace/manifests.ts +++ b/src/packages/members/member-type/workspace/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEMBER_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../repository/index.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const UMB_MEMBER_TYPE_WORKSPACE_ALIAS = 'Umb.Workspace.MemberType'; diff --git a/src/packages/members/member/workspace/member-root/manifests.ts b/src/packages/members/member/workspace/member-root/manifests.ts index bfc4101ec5..6b3c12a77e 100644 --- a/src/packages/members/member/workspace/member-root/manifests.ts +++ b/src/packages/members/member/workspace/member-root/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_MEMBER_COLLECTION_ALIAS } from '../../collection/manifests.js'; import { UMB_MEMBER_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_MEMBER_ROOT_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/members/member/workspace/member/manifests.ts b/src/packages/members/member/workspace/member/manifests.ts index cb8be75248..c9bc98df24 100644 --- a/src/packages/members/member/workspace/member/manifests.ts +++ b/src/packages/members/member/workspace/member/manifests.ts @@ -4,9 +4,8 @@ import type { ManifestWorkspaceActions, ManifestWorkspaceView, } from '@umbraco-cms/backoffice/workspace'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_CONTENT_HAS_PROPERTIES_WORKSPACE_CONDITION } from '@umbraco-cms/backoffice/content'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_MEMBER_WORKSPACE_ALIAS = 'Umb.Workspace.Member'; diff --git a/src/packages/property-editors/collection/manifests.ts b/src/packages/property-editors/collection/manifests.ts index ae597d3610..eb32c743c8 100644 --- a/src/packages/property-editors/collection/manifests.ts +++ b/src/packages/property-editors/collection/manifests.ts @@ -50,19 +50,19 @@ const propertyEditorUiManifest: ManifestPropertyEditorUi = { { alias: 'icon', label: 'Workspace View icon', - description: 'The icon for the Collection\'s Workspace View.', + description: "The icon for the Collection's Workspace View.", propertyEditorUiAlias: 'Umb.PropertyEditorUi.IconPicker', }, { alias: 'tabName', label: 'Workspace View name', - description: 'The name of the Collection\'s Workspace View (default if empty: Child Items).', + description: "The name of the Collection's Workspace View (default if empty: Child Items).", propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox', }, { alias: 'showContentFirst', label: 'Show Content Workspace View First', - description: 'Enable this to show the Content Workspace View by default instead of the Collection\'s.', + description: "Enable this to show the Content Workspace View by default instead of the Collection's.", propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle', }, ], diff --git a/src/packages/templating/partial-views/menu/manifests.ts b/src/packages/templating/partial-views/menu/manifests.ts index de2147b6f0..414875d9d6 100644 --- a/src/packages/templating/partial-views/menu/manifests.ts +++ b/src/packages/templating/partial-views/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_PARTIAL_VIEW_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/templating/partial-views/workspace/manifests.ts b/src/packages/templating/partial-views/workspace/manifests.ts index 7e21cc0506..4ab987402a 100644 --- a/src/packages/templating/partial-views/workspace/manifests.ts +++ b/src/packages/templating/partial-views/workspace/manifests.ts @@ -1,5 +1,4 @@ -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_PARTIAL_VIEW_WORKSPACE_ALIAS = 'Umb.Workspace.PartialView'; diff --git a/src/packages/templating/scripts/menu/manifests.ts b/src/packages/templating/scripts/menu/manifests.ts index 9dd63daaa8..f4e55324a8 100644 --- a/src/packages/templating/scripts/menu/manifests.ts +++ b/src/packages/templating/scripts/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_SCRIPT_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_SCRIPT_MENU_ITEM_ALIAS = 'Umb.MenuItem.Script'; export const manifests: Array = [ diff --git a/src/packages/templating/scripts/workspace/manifests.ts b/src/packages/templating/scripts/workspace/manifests.ts index 13664d8a9c..ad7af55c21 100644 --- a/src/packages/templating/scripts/workspace/manifests.ts +++ b/src/packages/templating/scripts/workspace/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_SCRIPT_ENTITY_TYPE } from '../entity.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const UMB_SCRIPT_WORKSPACE_ALIAS = 'Umb.Workspace.Script'; export const UMB_SAVE_SCRIPT_WORKSPACE_ACTION_ALIAS = 'Umb.WorkspaceAction.Script.Save'; diff --git a/src/packages/templating/stylesheets/menu/manifests.ts b/src/packages/templating/stylesheets/menu/manifests.ts index 1a74c5f0f1..1b93c439a8 100644 --- a/src/packages/templating/stylesheets/menu/manifests.ts +++ b/src/packages/templating/stylesheets/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_STYLESHEET_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/templating/stylesheets/workspace/manifests.ts b/src/packages/templating/stylesheets/workspace/manifests.ts index 98911276c1..ee593b786d 100644 --- a/src/packages/templating/stylesheets/workspace/manifests.ts +++ b/src/packages/templating/stylesheets/workspace/manifests.ts @@ -1,5 +1,4 @@ -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_STYLESHEET_WORKSPACE_ALIAS = 'Umb.Workspace.Stylesheet'; diff --git a/src/packages/templating/templates/menu/manifests.ts b/src/packages/templating/templates/menu/manifests.ts index ab40f89560..3c63d3fe2b 100644 --- a/src/packages/templating/templates/menu/manifests.ts +++ b/src/packages/templating/templates/menu/manifests.ts @@ -1,5 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_TEMPLATE_TREE_ALIAS } from '../tree/index.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/templating/templates/workspace/manifests.ts b/src/packages/templating/templates/workspace/manifests.ts index fc2b33e8ce..8f9c84b800 100644 --- a/src/packages/templating/templates/workspace/manifests.ts +++ b/src/packages/templating/templates/workspace/manifests.ts @@ -1,5 +1,4 @@ -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_TEMPLATE_WORKSPACE_ALIAS = 'Umb.Workspace.Template'; diff --git a/src/packages/ufm/components/content-name/content-name.component.ts b/src/packages/ufm/components/content-name/content-name.component.ts index 49a84361e7..460befde95 100644 --- a/src/packages/ufm/components/content-name/content-name.component.ts +++ b/src/packages/ufm/components/content-name/content-name.component.ts @@ -9,8 +9,8 @@ export class UmbUfmContentNameComponent extends UmbUfmComponentBase { if (token.prefix === '~') { /* - * @deprecated since version 15.0-rc3 - */ + * @deprecated since version 15.0-rc3 + */ console.warn(`Please update your UFM syntax from \`${token.raw}\` to \`{umbContentName:${token.text}}\`.`); } diff --git a/src/packages/user/user-group/workspace/user-group-root/manifests.ts b/src/packages/user/user-group/workspace/user-group-root/manifests.ts index 0d528f9fc7..6291ed199a 100644 --- a/src/packages/user/user-group/workspace/user-group-root/manifests.ts +++ b/src/packages/user/user-group/workspace/user-group-root/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_USER_GROUP_COLLECTION_ALIAS } from '../../collection/index.js'; import { UMB_USER_GROUP_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_USER_GROUP_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/user/user-group/workspace/user-group/manifests.ts b/src/packages/user/user-group/workspace/user-group/manifests.ts index 3a2e096501..4738e15e07 100644 --- a/src/packages/user/user-group/workspace/user-group/manifests.ts +++ b/src/packages/user/user-group/workspace/user-group/manifests.ts @@ -1,5 +1,4 @@ -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UmbSubmitWorkspaceAction, UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const UMB_USER_GROUP_WORKSPACE_ALIAS = 'Umb.Workspace.UserGroup'; diff --git a/src/packages/user/user/workspace/user-root/manifests.ts b/src/packages/user/user/workspace/user-root/manifests.ts index 44217e9ba9..a4e5970e31 100644 --- a/src/packages/user/user/workspace/user-root/manifests.ts +++ b/src/packages/user/user/workspace/user-root/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_USER_COLLECTION_ALIAS } from '../../collection/constants.js'; import { UMB_USER_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_USER_ROOT_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/user/user/workspace/user/manifests.ts b/src/packages/user/user/workspace/user/manifests.ts index 1149050381..850cee09f9 100644 --- a/src/packages/user/user/workspace/user/manifests.ts +++ b/src/packages/user/user/workspace/user/manifests.ts @@ -1,7 +1,6 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_USER_ENTITY_TYPE } from '../../entity.js'; import { UMB_USER_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/webhook/workspace/webhook-root/manifests.ts b/src/packages/webhook/workspace/webhook-root/manifests.ts index c837a613e0..4ce0a1b821 100644 --- a/src/packages/webhook/workspace/webhook-root/manifests.ts +++ b/src/packages/webhook/workspace/webhook-root/manifests.ts @@ -1,7 +1,7 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_WEBHOOK_COLLECTION_ALIAS } from '../../collection/manifests.js'; import { UMB_WEBHOOK_ROOT_ENTITY_TYPE } from '../../entity.js'; import { UMB_WEBHOOK_ROOT_WORKSPACE_ALIAS } from './constants.js'; +import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { diff --git a/src/packages/webhook/workspace/webhook/manifests.ts b/src/packages/webhook/workspace/webhook/manifests.ts index ae338f664e..da58546d92 100644 --- a/src/packages/webhook/workspace/webhook/manifests.ts +++ b/src/packages/webhook/workspace/webhook/manifests.ts @@ -1,6 +1,5 @@ -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; import { UMB_WEBHOOK_ENTITY_TYPE, UMB_WEBHOOK_WORKSPACE_ALIAS } from '../../entity.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { From 5de88040099e942a8cd49fec1cf3dc11a54e2fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 13:53:06 +0100 Subject: [PATCH 151/170] sort props to align with data source --- .../core/content/workspace/content-detail-workspace-base.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/packages/core/content/workspace/content-detail-workspace-base.ts index 14d08ae9d6..3ae802cc25 100644 --- a/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -400,7 +400,8 @@ export abstract class UmbContentDetailWorkspaceContextBase< throw new Error(`Editor Alias of "${property.dataType.unique}" not found.`); } - const entry = { ...variantId.toObject(), alias, editorAlias, value } as UmbElementValueModel; + // Notice the order of the properties is important for our JSON String Compare function. [NL] + const entry = { editorAlias, alias, ...variantId.toObject(), value } as UmbElementValueModel; const currentData = this.getData(); if (currentData) { From 1c0d7a8af527a7c8b9f3a7bc7cc6a93ff063a074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 13:57:28 +0100 Subject: [PATCH 152/170] update member manifests --- src/packages/members/member/workspace/member/manifests.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/packages/members/member/workspace/member/manifests.ts b/src/packages/members/member/workspace/member/manifests.ts index c9bc98df24..aac2a61278 100644 --- a/src/packages/members/member/workspace/member/manifests.ts +++ b/src/packages/members/member/workspace/member/manifests.ts @@ -47,7 +47,7 @@ export const workspaceViews: Array = [ kind: 'contentEditor', alias: 'Umb.WorkspaceView.Member.Content', name: 'Member Workspace Content View', - weight: 100, + weight: 1000, meta: { label: '#general_details', pathname: 'content', @@ -68,10 +68,10 @@ export const workspaceViews: Array = [ alias: 'Umb.WorkspaceView.Member.Member', name: 'Member Workspace Member View', js: () => import('./views/member/member-workspace-view-member.element.js'), - weight: 200, + weight: 500, meta: { - label: '#treeHeaders_member', - pathname: 'member', + label: '#apps_umbInfo', + pathname: 'info', icon: 'icon-user', }, conditions: [ From 89e6c194b5cae780308e96b807489087f7f83bc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 14:01:11 +0100 Subject: [PATCH 153/170] move dictionary create action to top --- src/packages/dictionary/entity-action/manifests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/dictionary/entity-action/manifests.ts b/src/packages/dictionary/entity-action/manifests.ts index 8b70942952..66c2670c34 100644 --- a/src/packages/dictionary/entity-action/manifests.ts +++ b/src/packages/dictionary/entity-action/manifests.ts @@ -8,7 +8,7 @@ export const manifests: Array = [ kind: 'default', alias: 'Umb.EntityAction.Dictionary.Create', name: 'Create Dictionary Entity Action', - weight: 600, + weight: 1200, api: () => import('./create/create.action.js'), forEntityTypes: [UMB_DICTIONARY_ENTITY_TYPE, UMB_DICTIONARY_ROOT_ENTITY_TYPE], meta: { From fd176109ffaf2aeb9b71d53709479fec2f5bf339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 14:04:32 +0100 Subject: [PATCH 154/170] fix const name --- src/libs/context-api/provide/context-provider.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/context-api/provide/context-provider.ts b/src/libs/context-api/provide/context-provider.ts index 972addee89..56f231a2d2 100644 --- a/src/libs/context-api/provide/context-provider.ts +++ b/src/libs/context-api/provide/context-provider.ts @@ -68,7 +68,7 @@ export class UmbContextProvider Date: Thu, 7 Nov 2024 14:21:10 +0100 Subject: [PATCH 155/170] fix imports --- .../block-grid-areas-container.element.ts | 3 ++- .../block-grid-entries/block-grid-entries.element.ts | 2 +- .../components/block-grid-entry/block-grid-entry.element.ts | 3 ++- .../block-scale-handler/block-scale-handler.element.ts | 1 - 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts b/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts index 1f93598b92..adb7ceea0d 100644 --- a/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts +++ b/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts @@ -1,7 +1,8 @@ +import type { UmbBlockGridTypeAreaType } from '../../types.js'; +import { UMB_BLOCK_GRID_ENTRY_CONTEXT } from '../../context/index.js'; import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from '../../context/block-grid-manager.context-token.js'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { css, customElement, html, repeat, state } from '@umbraco-cms/backoffice/external/lit'; -import { UMB_BLOCK_GRID_ENTRY_CONTEXT, type UmbBlockGridTypeAreaType } from '@umbraco-cms/backoffice/block-grid'; import '../block-grid-entries/index.js'; /** diff --git a/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts b/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts index 6c4a76df0e..7e763cf82c 100644 --- a/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts +++ b/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts @@ -1,5 +1,6 @@ import { UmbBlockGridEntriesContext } from '../../context/block-grid-entries.context.js'; import type { UmbBlockGridEntryElement } from '../block-grid-entry/index.js'; +import type { UmbBlockGridLayoutModel } from '../../types.js'; import { getAccumulatedValueOfIndex, getInterpolatedIndexOfPositionInWeightMap, @@ -16,7 +17,6 @@ import { type UmbFormControlValidatorConfig, } from '@umbraco-cms/backoffice/validation'; import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models'; -import type { UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block-grid'; /** * Notice this utility method is not really shareable with others as it also takes areas into account. [NL] diff --git a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts index 4e39f774d5..9c4b68ccef 100644 --- a/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts +++ b/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts @@ -1,10 +1,11 @@ import { UmbBlockGridEntryContext } from '../../context/block-grid-entry.context.js'; +import type { UmbBlockGridLayoutModel } from '../../types.js'; +import { UMB_BLOCK_GRID } from '../../constants.js'; import { UmbLitElement, umbDestroyOnDisconnect } from '@umbraco-cms/backoffice/lit-element'; import { html, css, customElement, property, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor'; import { stringOrStringArrayContains } from '@umbraco-cms/backoffice/utils'; -import { UMB_BLOCK_GRID, type UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block-grid'; import '../block-grid-block-inline/index.js'; import '../block-grid-block/index.js'; diff --git a/src/packages/block/block-grid/components/block-scale-handler/block-scale-handler.element.ts b/src/packages/block/block-grid/components/block-scale-handler/block-scale-handler.element.ts index b8c25d1732..31c59b5002 100644 --- a/src/packages/block/block-grid/components/block-scale-handler/block-scale-handler.element.ts +++ b/src/packages/block/block-grid/components/block-scale-handler/block-scale-handler.element.ts @@ -1,7 +1,6 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { html, css, customElement } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor'; -import '../block-grid-block/index.js'; /** * @element umb-block-scale-handler From 2e3c8bf55abe928b0b8bc934a4a74f9aa840f0c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 14:31:25 +0100 Subject: [PATCH 156/170] await request before submit gets resolved --- .../workspace/entity-detail/entity-detail-workspace-base.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index e98b1c527a..943616355f 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -133,9 +133,9 @@ export abstract class UmbEntityDetailWorkspaceContextBase< } if (this.getIsNew()) { - this.#create(currentData); + await this.#create(currentData); } else { - this.#update(currentData); + await this.#update(currentData); } } From 023e5587c6bb9b81ea12ebd9f0ad1c8daaa09a75 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 15:35:35 +0100 Subject: [PATCH 157/170] manual merges --- .../boolean-table-column-layout.element.ts | 19 --------- .../boolean-table-column-view.element.ts | 5 +-- .../core/collection/components/index.ts | 1 - ...ity-actions-table-column-layout.element.ts | 41 ------------------- .../entity-action/global-components/index.ts | 1 - ...tree-item-table-collection-view.element.ts | 6 +-- .../workspace/document-type/manifests.ts | 12 +++--- 7 files changed, 11 insertions(+), 74 deletions(-) delete mode 100644 src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts delete mode 100644 src/packages/core/entity-action/global-components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts diff --git a/src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts b/src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts deleted file mode 100644 index 282498668d..0000000000 --- a/src/packages/core/collection/components/boolean-table-column-layout/boolean-table-column-layout.element.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -const elementName = 'umb-boolean-table-column-layout'; -@customElement(elementName) -export class UmbBooleanTableColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value = false; - - override render() { - return this.value ? html`` : nothing; - } -} - -declare global { - interface HTMLElementTagNameMap { - [elementName]: UmbBooleanTableColumnLayoutElement; - } -} diff --git a/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts b/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts index cecfee1d0d..6c457ee8d9 100644 --- a/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts +++ b/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts @@ -1,8 +1,7 @@ import { html, nothing, customElement, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -const elementName = 'umb-boolean-table-column-view'; -@customElement(elementName) +@customElement('umb-boolean-table-column-view') export class UmbBooleanTableColumnViewElement extends UmbLitElement { @property({ attribute: false }) value = false; @@ -14,6 +13,6 @@ export class UmbBooleanTableColumnViewElement extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - [elementName]: UmbBooleanTableColumnViewElement; + ['umb-boolean-table-column-view']: UmbBooleanTableColumnViewElement; } } diff --git a/src/packages/core/collection/components/index.ts b/src/packages/core/collection/components/index.ts index 2a5ff379ba..a440030db1 100644 --- a/src/packages/core/collection/components/index.ts +++ b/src/packages/core/collection/components/index.ts @@ -1,4 +1,3 @@ -import './boolean-table-column-layout/boolean-table-column-layout.element.js'; import './boolean-table-column-view/boolean-table-column-view.element.js'; import './collection-action-bundle.element.js'; import './collection-filter-field.element.js'; diff --git a/src/packages/core/entity-action/global-components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts b/src/packages/core/entity-action/global-components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts deleted file mode 100644 index ef715a08dd..0000000000 --- a/src/packages/core/entity-action/global-components/entity-actions-table-column-layout/entity-actions-table-column-layout.element.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -import { html, nothing, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; -import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; - -const elementName = 'umb-entity-actions-table-column-layout'; -@customElement(elementName) -export class UmbEntityActionsTableColumnLayoutElement extends UmbLitElement { - @property({ attribute: false }) - value?: UmbEntityModel; - - @state() - _isOpen = false; - - #onActionExecuted() { - this._isOpen = false; - } - - #onClick(event: Event) { - event.stopPropagation(); - } - - override render() { - if (!this.value) return nothing; - - return html` - - - - - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - [elementName]: UmbEntityActionsTableColumnLayoutElement; - } -} diff --git a/src/packages/core/entity-action/global-components/index.ts b/src/packages/core/entity-action/global-components/index.ts index dfa9d13d59..841ca85af1 100644 --- a/src/packages/core/entity-action/global-components/index.ts +++ b/src/packages/core/entity-action/global-components/index.ts @@ -1,2 +1 @@ -import './entity-actions-table-column-layout/entity-actions-table-column-layout.element.js'; import './entity-actions-table-column-view/entity-actions-table-column-view.element.js'; diff --git a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts index 6ad5f637a7..a455008f29 100644 --- a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts @@ -94,15 +94,15 @@ export class UmbDocumentTypeTreeItemTableCollectionViewElement extends UmbLitEle }, { columnAlias: 'isElementType', - value: html``, + value: html``, }, { columnAlias: 'entityActions', - value: html``, + }}>`, }, ], }; diff --git a/src/packages/documents/document-types/workspace/document-type/manifests.ts b/src/packages/documents/document-types/workspace/document-type/manifests.ts index 81b4a8d3d3..b4644169cb 100644 --- a/src/packages/documents/document-types/workspace/document-type/manifests.ts +++ b/src/packages/documents/document-types/workspace/document-type/manifests.ts @@ -1,6 +1,6 @@ import { UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../../repository/composition/index.js'; import { UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS } from './constants.js'; -import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; +import { UMB_WORKSPACE_CONDITION_ALIAS, UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; export const manifests: Array = [ { @@ -26,7 +26,7 @@ export const manifests: Array = [ }, conditions: [ { - alias: 'Umb.Condition.WorkspaceAlias', + alias: UMB_WORKSPACE_CONDITION_ALIAS, match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, }, ], @@ -44,7 +44,7 @@ export const manifests: Array = [ }, conditions: [ { - alias: 'Umb.Condition.WorkspaceAlias', + alias: UMB_WORKSPACE_CONDITION_ALIAS, match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, }, ], @@ -62,7 +62,7 @@ export const manifests: Array = [ }, conditions: [ { - alias: 'Umb.Condition.WorkspaceAlias', + alias: UMB_WORKSPACE_CONDITION_ALIAS, match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, }, ], @@ -80,7 +80,7 @@ export const manifests: Array = [ }, conditions: [ { - alias: 'Umb.Condition.WorkspaceAlias', + alias: UMB_WORKSPACE_CONDITION_ALIAS, match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, }, ], @@ -98,7 +98,7 @@ export const manifests: Array = [ }, conditions: [ { - alias: 'Umb.Condition.WorkspaceAlias', + alias: UMB_WORKSPACE_CONDITION_ALIAS, match: UMB_DOCUMENT_TYPE_WORKSPACE_ALIAS, }, ], From 82de9c697d95033bdeeab5ea7e663ee43744ea1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 15:45:45 +0100 Subject: [PATCH 158/170] clean up --- examples/modal-routed/dashboard.element.ts | 19 +------ examples/modal-routed/dashboard2.element.ts | 4 +- .../modal/example-modal.element.ts | 53 ++++++------------- 3 files changed, 19 insertions(+), 57 deletions(-) diff --git a/examples/modal-routed/dashboard.element.ts b/examples/modal-routed/dashboard.element.ts index 6fcae676ba..9794dcb785 100644 --- a/examples/modal-routed/dashboard.element.ts +++ b/examples/modal-routed/dashboard.element.ts @@ -21,31 +21,16 @@ export class UmbDashboardElement extends UmbElementMixin(LitElement) { }, ]; - /** - * - */ - constructor() { - super(); - console.log('modal element loaded'); - } - override render() { return html`
    - umb-example modal + Dashboard 1
    - { - console.log('tab routes init', event); - }} - @change=${(event: UmbRouterSlotChangeEvent) => { - console.log('modal routes change', event); - }}> +
    `; } diff --git a/examples/modal-routed/dashboard2.element.ts b/examples/modal-routed/dashboard2.element.ts index aedf64759c..2a3f02e7bf 100644 --- a/examples/modal-routed/dashboard2.element.ts +++ b/examples/modal-routed/dashboard2.element.ts @@ -17,9 +17,7 @@ export class UmbDashboard2Element extends UmbElementMixin(LitElement) { Clicking this link will not load the slots inside the modal, however, going to the "Modal Dashboard", clicking on tab 2 and opening the modal from there will work.

    - Open Modal Route + Open Modal Route
    `; } diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index 453935be03..29f70ed38e 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -6,48 +6,27 @@ import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from @customElement('umb-example-modal') export class UmbExampleModal extends UmbModalBaseElement { @state() - private _routes: UmbRoute[] = []; - - /** - * - */ - constructor() { - super(); - console.log('modal element loaded'); - } - - override connectedCallback(): void { - super.connectedCallback(); - this._routes = [ - { - path: `overview`, - component: () => import('./steps/example-modal-step1.element.js'), - }, - { - path: `details`, - component: () => import('./steps/example-modal-step2.element.js'), - }, - // NL: There is a problem with this one, but there is more problems as the modal does not close when navigating the browser history. - /*{ - path: '', - redirectTo: 'overview', - },*/ - ]; - } + private _routes: UmbRoute[] = [ + { + path: `overview`, + component: () => import('./steps/example-modal-step1.element.js'), + }, + { + path: `details`, + component: () => import('./steps/example-modal-step2.element.js'), + }, + { + path: '', + redirectTo: 'overview', + }, + ]; override render() { return html`
    - umb-example modal + umb-example modal element
    - { - console.log('modal route init fired', event); - }} - @change=${(event: UmbRouterSlotChangeEvent) => { - console.log('modal routes change', event); - }}> +
    `; } From f8e6648e015e092e24684c4ad3f03f3946f1ed06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 15:46:08 +0100 Subject: [PATCH 159/170] fix firstUpdated callback in case where parent is also newly created --- src/external/router-slot/router-slot.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/external/router-slot/router-slot.ts b/src/external/router-slot/router-slot.ts index 06fddd335b..b93152ba63 100644 --- a/src/external/router-slot/router-slot.ts +++ b/src/external/router-slot/router-slot.ts @@ -162,9 +162,11 @@ export class RouterSlot extends HTMLElement implements IRouter this._setParent(null); } } - if (this.parent && this.parent.match !== null && this.match === null) { + if (this.parent) { requestAnimationFrame(() => { - this.render(); + if (this.parent && this.parent.match !== null && this.match === null) { + this.render(); + } }); } } From eb90d8dcddecce053aa38a829325e7222869eaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 15:46:21 +0100 Subject: [PATCH 160/170] call _updateRouterPath --- src/packages/core/router/router-slot.element.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/packages/core/router/router-slot.element.ts b/src/packages/core/router/router-slot.element.ts index f1dab85e56..e2bc6353c9 100644 --- a/src/packages/core/router/router-slot.element.ts +++ b/src/packages/core/router/router-slot.element.ts @@ -94,13 +94,7 @@ export class UmbRouterSlotElement extends UmbLitElement { protected override firstUpdated(_changedProperties: PropertyValueMap | Map): void { super.firstUpdated(_changedProperties); - this._routerPath = this._constructAbsoluteRouterPath(); - this.#routeContext._internal_routerGotBasePath(this._routerPath); - this.dispatchEvent(new UmbRouterSlotInitEvent()); - const newActiveLocalPath = this._constructLocalRouterPath(); - if (this._activeLocalPath !== newActiveLocalPath) { - this.#router.routes = [...this.#router.routes]; - } + this._updateRouterPath(); } protected _updateRouterPath() { From f6ed4d2aa16382b8d86641a56d0ab36625259f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 15:55:34 +0100 Subject: [PATCH 161/170] clean up --- examples/modal-routed/dashboard.element.ts | 2 +- examples/modal-routed/modal/example-modal-token.ts | 4 ++-- examples/modal-routed/modal/example-modal.element.ts | 6 +++--- examples/modal-routed/tabs/tab2.element.ts | 5 ++++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/modal-routed/dashboard.element.ts b/examples/modal-routed/dashboard.element.ts index 9794dcb785..967a4a7a88 100644 --- a/examples/modal-routed/dashboard.element.ts +++ b/examples/modal-routed/dashboard.element.ts @@ -1,7 +1,7 @@ import { css, html, LitElement, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; -import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; +import type { UmbRoute } from '@umbraco-cms/backoffice/router'; @customElement('umb-dashboard') export class UmbDashboardElement extends UmbElementMixin(LitElement) { diff --git a/examples/modal-routed/modal/example-modal-token.ts b/examples/modal-routed/modal/example-modal-token.ts index b44e2f4ae9..1755a7ef3a 100644 --- a/examples/modal-routed/modal/example-modal-token.ts +++ b/examples/modal-routed/modal/example-modal-token.ts @@ -1,9 +1,9 @@ import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; export type Data = object; -export type RetData = object; +export type ModalValue = object; -export const EXAMPLE_ROUTED_MODAL = new UmbModalToken( +export const EXAMPLE_ROUTED_MODAL = new UmbModalToken( 'example.routed.modal', // this needs to match the alias of the modal registered in manifest.ts { modal: { diff --git a/examples/modal-routed/modal/example-modal.element.ts b/examples/modal-routed/modal/example-modal.element.ts index 29f70ed38e..e1f0f5bdd4 100644 --- a/examples/modal-routed/modal/example-modal.element.ts +++ b/examples/modal-routed/modal/example-modal.element.ts @@ -1,14 +1,14 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -import type { UmbRoute, UmbRouterSlotChangeEvent, UmbRouterSlotInitEvent } from '@umbraco-cms/backoffice/router'; +import type { UmbRoute } from '@umbraco-cms/backoffice/router'; @customElement('umb-example-modal') export class UmbExampleModal extends UmbModalBaseElement { @state() private _routes: UmbRoute[] = [ { - path: `overview`, + path: `modalOverview`, component: () => import('./steps/example-modal-step1.element.js'), }, { @@ -17,7 +17,7 @@ export class UmbExampleModal extends UmbModalBaseElement { }, { path: '', - redirectTo: 'overview', + redirectTo: 'modalOverview', }, ]; diff --git a/examples/modal-routed/tabs/tab2.element.ts b/examples/modal-routed/tabs/tab2.element.ts index 11799d01b0..7dca0365ac 100644 --- a/examples/modal-routed/tabs/tab2.element.ts +++ b/examples/modal-routed/tabs/tab2.element.ts @@ -6,7 +6,10 @@ import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/rou @customElement('umb-dashboard-tab2') export class UmbDashboardTab2Element extends UmbElementMixin(LitElement) { - #workspaceModal?: UmbModalRouteRegistrationController; + #workspaceModal?: UmbModalRouteRegistrationController< + typeof EXAMPLE_ROUTED_MODAL.DATA, + typeof EXAMPLE_ROUTED_MODAL.VALUE + >; @state() _editLinkPath?: string; From 9beab6a502cfacc925e01a95166567d34c3820b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 16:50:46 +0100 Subject: [PATCH 162/170] use match.route.path --- src/packages/core/router/route.context.ts | 2 +- src/packages/core/router/router-slot.element.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/core/router/route.context.ts b/src/packages/core/router/route.context.ts index 7fda170903..f8f15291d4 100644 --- a/src/packages/core/router/route.context.ts +++ b/src/packages/core/router/route.context.ts @@ -123,7 +123,7 @@ export class UmbRouteContext extends UmbContextBase { if (this.#activeModalPath) { // If if there is a modal using the old path. const activeModal = this.#modalRegistrations.find((registration) => { - return registration.generateModalPath() === this.#activeModalPath; + return '/' + registration.generateModalPath() === this.#activeModalPath; }); if (activeModal) { this.#modalContext?.close(activeModal.key); diff --git a/src/packages/core/router/router-slot.element.ts b/src/packages/core/router/router-slot.element.ts index e2bc6353c9..a78f0e2ac6 100644 --- a/src/packages/core/router/router-slot.element.ts +++ b/src/packages/core/router/router-slot.element.ts @@ -122,7 +122,7 @@ export class UmbRouterSlotElement extends UmbLitElement { this.dispatchEvent(new UmbRouterSlotChangeEvent()); } } else if (event.detail.slot === this.#modalRouter) { - const newActiveModalLocalPath = this.#modalRouter.match?.fragments.consumed ?? ''; + const newActiveModalLocalPath = this.#modalRouter.match?.route.path ?? ''; this.#routeContext._internal_modalRouterChanged(newActiveModalLocalPath); } }; From 3cf9fc87a8986bccec59148aa4415935dd34faee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 16:52:53 +0100 Subject: [PATCH 163/170] simplifying --- examples/modal-routed/tabs/tab2.element.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/modal-routed/tabs/tab2.element.ts b/examples/modal-routed/tabs/tab2.element.ts index 7dca0365ac..66346df3de 100644 --- a/examples/modal-routed/tabs/tab2.element.ts +++ b/examples/modal-routed/tabs/tab2.element.ts @@ -39,9 +39,6 @@ export class UmbDashboardTab2Element extends UmbElementMixin(LitElement) {

    This element hosts the UmbModalRouteRegistrationController

    Open modal -
    - - Path: ${this._editLinkPath}
    `; } From f5099a322eaa4030769eefd3210b6069d7e1a907 Mon Sep 17 00:00:00 2001 From: Steve Morgan Date: Thu, 7 Nov 2024 17:51:32 +0000 Subject: [PATCH 164/170] Bugfix: Corrects "Public access" notification typo (#2524) Spelling correction --- .../public-access/repository/public-access.repository.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/packages/documents/documents/entity-actions/public-access/repository/public-access.repository.ts b/src/packages/documents/documents/entity-actions/public-access/repository/public-access.repository.ts index df0b349e33..c6799310be 100644 --- a/src/packages/documents/documents/entity-actions/public-access/repository/public-access.repository.ts +++ b/src/packages/documents/documents/entity-actions/public-access/repository/public-access.repository.ts @@ -27,7 +27,7 @@ export class UmbDocumentPublicAccessRepository extends UmbControllerBase impleme const { error } = await this.#dataSource.create(unique, data); if (!error) { - const notification = { data: { message: `Public acccess setting created` } }; + const notification = { data: { message: `Public access setting created` } }; this.#notificationContext?.peek('positive', notification); } return { error }; @@ -46,7 +46,7 @@ export class UmbDocumentPublicAccessRepository extends UmbControllerBase impleme const { error } = await this.#dataSource.update(unique, data); if (!error) { - const notification = { data: { message: `Public acccess setting updated` } }; + const notification = { data: { message: `Public access setting updated` } }; this.#notificationContext?.peek('positive', notification); } return { error }; @@ -57,7 +57,7 @@ export class UmbDocumentPublicAccessRepository extends UmbControllerBase impleme const { error } = await this.#dataSource.delete(unique); if (!error) { - const notification = { data: { message: `Public acccess setting deleted` } }; + const notification = { data: { message: `Public access setting deleted` } }; this.#notificationContext?.peek('positive', notification); } return { error }; From 554ce0e0e89d23a9bc6708b528ac28997342a127 Mon Sep 17 00:00:00 2001 From: Steve Morgan Date: Thu, 7 Nov 2024 18:06:52 +0000 Subject: [PATCH 165/170] Bugfix: creating new doc type properties sort order doesn't count existing properties - puts it at top (+1) (#2523) Bug 17457 https://github.com/umbraco/Umbraco-CMS/issues/17457 Creating new doc type properties sort order doesn't count existing properties. Looking at this it seems that the hardwork is done to workout the sort order and assign it to preset but it's not returned undefined was (probably as a dev placeholder that's gone unnoticed!). --- .../design/content-type-design-editor-properties.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts index e85a4f7d5b..932df6aad2 100644 --- a/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts +++ b/src/packages/core/content-type/workspace/views/design/content-type-design-editor-properties.element.ts @@ -193,7 +193,7 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement { } preset.sortOrder = sortOrderInt; } - return { data: { contentTypeUnique: this._ownerContentTypeUnique, preset: undefined } }; + return { data: { contentTypeUnique: this._ownerContentTypeUnique, preset: preset } }; }) .observeRouteBuilder((routeBuilder) => { this._newPropertyPath = From dd499a5ae15914bb0e1f374cf4649c15d890ac37 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 19:55:18 +0100 Subject: [PATCH 166/170] add todo --- .../document-type-tree-item-children-collection.repository.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts index fb8d23aeee..04df143d35 100644 --- a/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts @@ -10,6 +10,7 @@ export class UmbDocumentTypeTreeItemChildrenCollectionRepository #treeRepository = new UmbDocumentTypeTreeRepository(this); async requestCollection(filter: UmbCollectionFilterModel) { + // TODO: get parent from args const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); if (!entityContext) throw new Error('Entity context not found'); From d1a4a5ddf9dc08b397e1cf3ffea86d026b1b0174 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 7 Nov 2024 19:57:12 +0100 Subject: [PATCH 167/170] fix lint errors --- .../workspace/entity-detail/entity-detail-workspace-base.ts | 2 +- .../document-type-tree-item-table-collection-view.element.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 322d4957e7..f177eab76c 100644 --- a/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -11,7 +11,7 @@ import { } from '@umbraco-cms/backoffice/entity-action'; import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry, type ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; -import type { UmbDetailRepository, UmbRepositoryResponseWithAsObservable } from '@umbraco-cms/backoffice/repository'; +import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; export interface UmbEntityDetailWorkspaceContextArgs { entityType: string; diff --git a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts index a455008f29..ff8f006f37 100644 --- a/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/views/document-type-tree-item-table-collection-view.element.ts @@ -4,7 +4,7 @@ import type { UmbDocumentTypeTreeItemModel } from '../../../types.js'; import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection'; import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection'; import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components'; -import { css, html, customElement, state, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController, type UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router'; From 2395981ad67c40b89064e2433bee18e94da5fc8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 21:13:41 +0100 Subject: [PATCH 168/170] remove [] --- .../boolean-table-column-view.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts b/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts index 6c457ee8d9..856e202deb 100644 --- a/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts +++ b/src/packages/core/collection/components/boolean-table-column-view/boolean-table-column-view.element.ts @@ -13,6 +13,6 @@ export class UmbBooleanTableColumnViewElement extends UmbLitElement { declare global { interface HTMLElementTagNameMap { - ['umb-boolean-table-column-view']: UmbBooleanTableColumnViewElement; + 'umb-boolean-table-column-view': UmbBooleanTableColumnViewElement; } } From 929bec8a6d87ee360308a90401d31f507de03ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 7 Nov 2024 21:21:07 +0100 Subject: [PATCH 169/170] remove destroy function --- ...document-type-tree-item-children-collection.repository.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts index 04df143d35..5968a3aef1 100644 --- a/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts +++ b/src/packages/documents/document-types/tree/tree-item-children/collection/repository/document-type-tree-item-children-collection.repository.ts @@ -28,11 +28,6 @@ export class UmbDocumentTypeTreeItemChildrenCollectionRepository return this.#treeRepository.requestTreeItemsOf({ parent, skip: filter.skip, take: filter.take }); } } - - override destroy(): void { - this.#treeRepository.destroy(); - super.destroy(); - } } export { UmbDocumentTypeTreeItemChildrenCollectionRepository as api }; From 0616a43ed2e6785662f88330eb6c663d6863c542 Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Thu, 7 Nov 2024 20:31:31 +0000 Subject: [PATCH 170/170] Bugfix: Disables Link Picker modal submit button (#2521) Link Picker modal, disables submit button if URL or querystring are not set. --- .../link-picker-modal/link-picker-modal.element.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/packages/multi-url-picker/link-picker-modal/link-picker-modal.element.ts b/src/packages/multi-url-picker/link-picker-modal/link-picker-modal.element.ts index 39c8a87112..4da0e7161a 100644 --- a/src/packages/multi-url-picker/link-picker-modal/link-picker-modal.element.ts +++ b/src/packages/multi-url-picker/link-picker-modal/link-picker-modal.element.ts @@ -5,13 +5,14 @@ import type { UmbLinkPickerModalValue, } from './link-picker-modal.token.js'; import { css, customElement, html, nothing, query, state, when } from '@umbraco-cms/backoffice/external/lit'; +import { isUmbracoFolder, UmbMediaTypeStructureRepository } from '@umbraco-cms/backoffice/media-type'; +import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; import { UmbDocumentDetailRepository } from '@umbraco-cms/backoffice/document'; import { UmbMediaDetailRepository } from '@umbraco-cms/backoffice/media'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import type { UmbInputDocumentElement } from '@umbraco-cms/backoffice/document'; import type { UmbInputMediaElement } from '@umbraco-cms/backoffice/media'; import type { UUIBooleanInputEvent, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; -import { isUmbracoFolder, UmbMediaTypeStructureRepository } from '@umbraco-cms/backoffice/media-type'; type UmbInputPickerEvent = CustomEvent & { target: { value?: string } }; @@ -56,8 +57,10 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement @@ -169,7 +173,8 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement + @change=${this.#onLinkUrlInput} + ${umbFocus()}> ${when(