From a1ae404cbdbe325eb5c430474ad90f7c0a4e1ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 15 May 2024 09:59:41 +0200 Subject: [PATCH 01/43] expose uniques and aliases --- .../structure/content-type-structure-manager.class.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts index c6218caef2..2e80104b45 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-manager.class.ts @@ -46,6 +46,8 @@ export class UmbContentTypeStructureManager< private readonly _contentTypeContainers = this.#contentTypes.asObservablePart((x) => x.flatMap((x) => x.containers ?? []), ); + readonly contentTypeUniques = this.#contentTypes.asObservablePart((x) => x.map((y) => y.unique)); + readonly contentTypeAliases = this.#contentTypes.asObservablePart((x) => x.map((y) => y.alias)); #containers: UmbArrayState = new UmbArrayState( [], @@ -205,6 +207,12 @@ export class UmbContentTypeStructureManager< getContentTypes() { return this.#contentTypes.getValue(); } + getContentTypeUniques() { + return this.#contentTypes.getValue().map((x) => x.unique); + } + getContentTypeAliases() { + return this.#contentTypes.getValue().map((x) => x.alias); + } // TODO: We could move the actions to another class? From b46e276ecf4652706d223711115baab75ee16b8e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 29 May 2024 09:55:48 +0200 Subject: [PATCH 02/43] implement interim eslint rule --- src/Umbraco.Web.UI.Client/.eslintrc.json | 1 + ...o-relative-import-to-import-map-module.cjs | 98 +++++++++++++++++++ .../eslint-local-rules.cjs | 2 + 3 files changed, 101 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs diff --git a/src/Umbraco.Web.UI.Client/.eslintrc.json b/src/Umbraco.Web.UI.Client/.eslintrc.json index ca3b358d25..f8a724d5c1 100644 --- a/src/Umbraco.Web.UI.Client/.eslintrc.json +++ b/src/Umbraco.Web.UI.Client/.eslintrc.json @@ -48,6 +48,7 @@ "local-rules/prefer-import-aliases": "error", "local-rules/prefer-static-styles-last": "warn", "local-rules/umb-class-prefix": "error", + "local-rules/no-relative-import-to-import-map-module": "error", "local-rules/enforce-umbraco-external-imports": [ "error", { diff --git a/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs b/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs new file mode 100644 index 0000000000..104e9123bf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs @@ -0,0 +1,98 @@ +// TODO: figure out how to automatically generate this list of module paths +const modulePathIdentifiers = [ + '/core/action/', + '/core/audit-log/', + '/core/auth/', + '/core/collection/', + '/core/components/', + '/core/content-type/', + '/core/content/', + '/core/culture/', + '/core/debug/', + '/core/entity-action/', + '/core/entity-bulk-action/', + '/core/entity/', + '/core/event/', + '/core/extension-registry/', + '/core/icon-registry/', + '/core/id/', + '/core/lit-element/', + '/core/localization/', + '/core/menu/', + '/core/modal/', + '/core/models/', + '/core/notification/', + '/core/picker-input/', + '/core/property/', + '/core/property-editor/', + '/core/recycle-bin/', + '/core/repository/', + '/core/resources/', + '/core/router/', + '/core/section/', + '/core/server-file-system/', + '/core/settings/', + '/core/sorter/', + '/core/store/', + '/core/style/', + '/core/temporary-file/', + '/core/themes/', + '/core/tree/', + '/core/utils/', + '/core/validation/', + '/core/variant/', + '/core/workspace/', + '/class-api/', + '/context-api/', + '/controller-api/', + '/element-api/', + '/extension-api/', + '/formatting-api/', + '/localization-api/', + '/observable-api/', + '/backend-api/', + '/base64-js/', + '/diff/', + '/dompurify/', + '/lit/', + '/marked/', + '/monaco-editor/', + '/openid/', + '/router-slot/', + '/rxjs/', + '/tinymce/', + '/uui/', + '/uuid/', +]; + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'Prevent relative import to a module that is in the import map.', + category: 'Best Practices', + recommended: true, + }, + schema: [], + messages: { + unexpectedValue: 'Relative import paths should include "{{value}}".', + }, + }, + create: function (context) { + return { + ImportDeclaration(node) { + const importPath = node.source.value; + + if (importPath.startsWith('./') || importPath.startsWith('../')) { + if (modulePathIdentifiers.some((moduleName) => importPath.includes(moduleName))) { + context.report({ + node, + message: 'Use the correct import map alias instead of a relative import path: ' + importPath, + }); + } + } + }, + }; + }, +}; diff --git a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs index 6f720a1a7d..ed3c3364ff 100644 --- a/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs +++ b/src/Umbraco.Web.UI.Client/eslint-local-rules.cjs @@ -10,6 +10,7 @@ const noDirectApiImportRule = require('./devops/eslint/rules/no-direct-api-impor const preferImportAliasesRule = require('./devops/eslint/rules/prefer-import-aliases.cjs'); const preferStaticStylesLastRule = require('./devops/eslint/rules/prefer-static-styles-last.cjs'); const umbClassPrefixRule = require('./devops/eslint/rules/umb-class-prefix.cjs'); +const noRelativeImportToImportMapModule = require('./devops/eslint/rules/no-relative-import-to-import-map-module.cjs'); module.exports = { 'bad-type-import': badTypeImportRule, @@ -22,4 +23,5 @@ module.exports = { 'prefer-import-aliases': preferImportAliasesRule, 'prefer-static-styles-last': preferStaticStylesLastRule, 'umb-class-prefix': umbClassPrefixRule, + 'no-relative-import-to-import-map-module': noRelativeImportToImportMapModule, }; From 7b3806e043fc83cc85489a4fbee56420ffd4d41a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 29 May 2024 12:13:09 +0200 Subject: [PATCH 03/43] fix sorter to handle if model changes while sorting --- .../packages/core/sorter/sorter.controller.ts | 72 +++++++++++++------ 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts index dd5201daee..37f501f27d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.ts @@ -72,16 +72,21 @@ export type resolvePlacementArgs = { pointerY: number; }; +type UniqueType = string | symbol | number; + +/** + * Internal type, which is adjusted to become the public one. + * @internal */ type INTERNAL_UmbSorterConfig = { /** * Define how to retrive the unique identifier of an element. If this method returns undefined, the move will be cancelled. */ - getUniqueOfElement: (element: ElementType) => string | null | symbol | number | undefined; - getUniqueOfModel: (modeEntry: T) => string | null | symbol | number | undefined; + getUniqueOfElement: (element: ElementType) => UniqueType | null | undefined; + getUniqueOfModel: (modeEntry: T) => UniqueType | null | undefined; /** * Optionally define a unique identifier for each sorter experience, all Sorters that uses the same identifier to connect with other sorters. */ - identifier: string | symbol; + identifier: UniqueType; /** * A query selector for the item element. */ @@ -107,6 +112,7 @@ type INTERNAL_UmbSorterConfig = { * The selector to find the draggable element within the item. */ draggableSelector?: string; + //boundarySelector?: string; dataTransferResolver?: (dataTransfer: DataTransfer | null, currentItem: T) => void; onStart?: (argument: { item: T; element: ElementType }) => void; @@ -166,7 +172,7 @@ type INTERNAL_UmbSorterConfig = { performItemRemove?: (argument: { item: T }) => Promise | boolean; }; -// External type with some properties optional, as they have defaults: +// External type with some properties optional, as they have fallback values: export type UmbSorterConfig = Omit< INTERNAL_UmbSorterConfig, 'ignorerSelector' | 'containerSelector' | 'identifier' @@ -178,6 +184,19 @@ export type UmbSorterConfig = * @class UmbSorterController * @implements {UmbControllerInterface} * @description This controller can make user able to sort items. + * @example + * + * This example shows how to setup a sorter controller with no special needs. + * Assuming your declaring this on a Umbraco Element(UmbControllerHostElement): + * + * ```ts + * const sorter = new UmbSorterController(this, { + * itemSelector: '.item', + * containerSelector: '.container', + * getUniqueOfElement: (element) => element.dataset.id, + * getUniqueOfModel: (model) => model.id + * }); + * ``` */ export class UmbSorterController extends UmbControllerBase { // @@ -274,16 +293,13 @@ export class UmbSorterController this.#config.getUniqueOfModel(x) === unique) !== undefined; } - /* - getItem(unique: string) { - if (!unique) return undefined; + getItem(unique: UniqueType) { return this.#model.find((x) => this.#config.getUniqueOfModel(x) === unique); } - */ hostConnected() { this.#isConnected = true; @@ -453,7 +469,7 @@ export class UmbSorterController; + // Notice, it is acceptable here to get index via object reference, but only cause there has been no change at this stage, otherwise we cannot trust the object instance is represented in the model — it could have mutated or been cloned [NL] UmbSorterController.originalIndex = this.#model.indexOf(UmbSorterController.activeItem); if (!UmbSorterController.activeItem) { @@ -478,7 +495,7 @@ export class UmbSorterController) { - const item = UmbSorterController.activeItem; + public async moveItemInModel(newIndex: number, fromCtrl: UmbSorterController) { + if (!UmbSorterController.activeItem) { + console.error('There is no active item to move'); + return false; + } + const itemUnique = this.#config.getUniqueOfModel(UmbSorterController.activeItem); + if (!itemUnique) { + console.error('Failed to retrieve active item unique'); + return false; + } + // We use the getItem method to find the current item/object of this entry, as we cannot trust the object instance(activeItem) to be the same as in the model. [NL] + // So notice, item in this method is the real modal entry reference, where in many other cases we use the activeItem which might not be up to date with the real entry of the model. [NL] + const item = fromCtrl.getItem(itemUnique); if (!item) { - console.error('Could not find item of sync item'); + console.error('Could not find item of model to move', itemUnique, this.#model); return false; } if (this.notifyRequestDrop({ item }) === false) { @@ -819,10 +847,9 @@ export class UmbSorterController, }); this.#config.onChange?.({ model: newModel, item }); - } - // If everything went well, we can set new activeSorter to this: - UmbSorterController.activeSorter = this as unknown as UmbSorterController; - UmbSorterController.activeIndex = newIndex; + // If everything went well, we can set the new activeSorter (and dropSorter) to this, as we are switching container. [NL] + UmbSorterController.activeSorter = this as unknown as UmbSorterController; + UmbSorterController.dropSorter = this as unknown as UmbSorterController; + UmbSorterController.activeIndex = newIndex; + } } return true; From 203a8b9efbb8493d2cb635eba806c7eaed9bb84a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 29 May 2024 13:02:20 +0200 Subject: [PATCH 04/43] exclude tests and stories --- .../eslint/rules/no-relative-import-to-import-map-module.cjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs b/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs index 104e9123bf..f642e35506 100644 --- a/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs +++ b/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs @@ -82,6 +82,11 @@ module.exports = { create: function (context) { return { ImportDeclaration(node) { + // exclude test and story files + if (context.filename.endsWith('.test.ts') || context.filename.endsWith('.stories.ts')) { + return {}; + } + const importPath = node.source.value; if (importPath.startsWith('./') || importPath.startsWith('../')) { From 6407317c5dadb13d06b2795eae5318e44f91c048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 29 May 2024 13:12:48 +0200 Subject: [PATCH 05/43] Correct timing of adjustment so it happens in the right order --- .../block/block-grid/context/block-grid-entry.context.ts | 6 +++--- .../src/packages/block/block/context/block-entry.context.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts index 2b026e2e92..4f58426a82 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts @@ -206,9 +206,9 @@ export class UmbBlockGridEntryContext // Secure columnSpan fits options: this.observe( - observeMultiple([this.layout, this.columnSpan, this.relevantColumnSpanOptions, this._entries.layoutColumns]), - ([layout, columnSpan, relevantColumnSpanOptions, layoutColumns]) => { - if (!layout || !layoutColumns) return; + observeMultiple([this.columnSpan, this.relevantColumnSpanOptions, this._entries.layoutColumns]), + ([columnSpan, relevantColumnSpanOptions, layoutColumns]) => { + if (!layoutColumns) return; const newColumnSpan = this.#calcColumnSpan( columnSpan ?? layoutColumns, relevantColumnSpanOptions, diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts index 422391fe62..c4c814e876 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts @@ -146,15 +146,15 @@ export abstract class UmbBlockEntryContext< // Consume block manager: this.consumeContext(blockManagerContextToken, (manager) => { this._manager = manager; - this.#gotManager(); this._gotManager(); + this.#gotManager(); }); // Consume block entries: this.consumeContext(blockEntriesContextToken, (entries) => { this._entries = entries; - this.#gotEntries(); this._gotEntries(); + this.#gotEntries(); }); // Observe UDI: From 75ba49a626a428d3ab40423e62859950de0f05fd Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 29 May 2024 13:26:59 +0200 Subject: [PATCH 06/43] fix: use correct translations for the "Custom" status --- .../packages/documents/documents/workspace/views/info/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/utils.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/utils.ts index 5a4f3cac89..5dc112913f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/utils.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/utils.ts @@ -127,7 +127,7 @@ export function getDocumentHistoryTagStyleAndText(type: UmbDocumentAuditLogType) case UmbDocumentAuditLog.CUSTOM: return { style: { look: 'placeholder', color: 'default' }, - text: { label: 'auditTrails_custom', desc: '' }, + text: { label: 'auditTrails_smallCustom', desc: 'auditTrails_custom' }, }; default: From 78e92e9c39e6cf720b979537b59efd48e54cf68c Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 29 May 2024 13:27:39 +0200 Subject: [PATCH 07/43] build: make sure the unused-language-keys.js script only looks at files --- .../devops/localization/unused-language-keys.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/devops/localization/unused-language-keys.js b/src/Umbraco.Web.UI.Client/devops/localization/unused-language-keys.js index 6fa81fc45e..f462faf4c3 100644 --- a/src/Umbraco.Web.UI.Client/devops/localization/unused-language-keys.js +++ b/src/Umbraco.Web.UI.Client/devops/localization/unused-language-keys.js @@ -26,7 +26,7 @@ const mainMap = buildMap(mainKeys); const keys = Array.from(mainMap.keys()); const usedKeys = new Set(); -const elementAndControllerFiles = await glob(`${__dirname}/../../src/**/*.ts`); +const elementAndControllerFiles = await glob(`${__dirname}/../../src/**/*.ts`, { filesOnly: true }); console.log(`Checking ${elementAndControllerFiles.length} files for unused keys`); From 4b7a49b9d2873b0085698def61dd37eb2aeea69a Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 29 May 2024 13:31:45 +0200 Subject: [PATCH 08/43] sets default values when creating a datatype --- .../src/packages/property-editors/slider/Umbraco.Slider.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts index 5a363f63be..12aa8f86f0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts @@ -23,7 +23,8 @@ export const manifest: ManifestPropertyEditorSchema = { ], defaultData: [ { alias: 'minVal', value: 0 }, - { alias: 'maxVal', value: 0 }, + { alias: 'maxVal', value: 100 }, + { alias: 'step', value: 1 }, ], }, }, From c6bb2c412aa23828ae1ee19fd67af9d9db0bea43 Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 29 May 2024 13:31:57 +0200 Subject: [PATCH 09/43] some config logic --- .../property-editor-ui-slider.element.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts index 511382b107..7a4df169fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts @@ -5,13 +5,15 @@ import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-ed import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; +export type UmbSliderValue = { from: number; to: number } | undefined; + /** * @element umb-property-editor-ui-slider */ @customElement('umb-property-editor-ui-slider') export class UmbPropertyEditorUISliderElement extends UmbLitElement implements UmbPropertyEditorUiElement { @property({ type: Object }) - value: { to?: number; from?: number } | undefined = undefined; + value: UmbSliderValue | undefined; @state() _enableRange = false; @@ -37,9 +39,20 @@ export class UmbPropertyEditorUISliderElement extends UmbLitElement implements U this._enableRange = Boolean(config.getValueByAlias('enableRange')) ?? false; this._initVal1 = Number(config.getValueByAlias('initVal1')); this._initVal2 = Number(config.getValueByAlias('initVal2')); - this._step = Number(config.getValueByAlias('step')) ?? 1; + + // Make sure that step is higher than 0. + const step = (config.getValueByAlias('step') ?? 1) as number; + this._step = step > 0 ? step : 1; + this._min = Number(config.getValueByAlias('minVal')) ?? 0; this._max = Number(config.getValueByAlias('maxVal')) ?? 100; + + if (this._min === this._max) { + // Why is the configuration giving us a 0 as default, rather than just undefined..? + + console.log(this._min, this._max, this._step, this._initVal1, this._initVal2); + throw new Error('Property Editor Slider: min and max are currently equal. Please change your configuration.'); + } } #getValueObject(value: string) { @@ -56,7 +69,7 @@ export class UmbPropertyEditorUISliderElement extends UmbLitElement implements U return html` Date: Wed, 29 May 2024 14:49:22 +0200 Subject: [PATCH 10/43] generate the list based on folders --- ...o-relative-import-to-import-map-module.cjs | 85 +++++-------------- 1 file changed, 19 insertions(+), 66 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs b/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs index f642e35506..03e99fc901 100644 --- a/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs +++ b/src/Umbraco.Web.UI.Client/devops/eslint/rules/no-relative-import-to-import-map-module.cjs @@ -1,69 +1,22 @@ -// TODO: figure out how to automatically generate this list of module paths -const modulePathIdentifiers = [ - '/core/action/', - '/core/audit-log/', - '/core/auth/', - '/core/collection/', - '/core/components/', - '/core/content-type/', - '/core/content/', - '/core/culture/', - '/core/debug/', - '/core/entity-action/', - '/core/entity-bulk-action/', - '/core/entity/', - '/core/event/', - '/core/extension-registry/', - '/core/icon-registry/', - '/core/id/', - '/core/lit-element/', - '/core/localization/', - '/core/menu/', - '/core/modal/', - '/core/models/', - '/core/notification/', - '/core/picker-input/', - '/core/property/', - '/core/property-editor/', - '/core/recycle-bin/', - '/core/repository/', - '/core/resources/', - '/core/router/', - '/core/section/', - '/core/server-file-system/', - '/core/settings/', - '/core/sorter/', - '/core/store/', - '/core/style/', - '/core/temporary-file/', - '/core/themes/', - '/core/tree/', - '/core/utils/', - '/core/validation/', - '/core/variant/', - '/core/workspace/', - '/class-api/', - '/context-api/', - '/controller-api/', - '/element-api/', - '/extension-api/', - '/formatting-api/', - '/localization-api/', - '/observable-api/', - '/backend-api/', - '/base64-js/', - '/diff/', - '/dompurify/', - '/lit/', - '/marked/', - '/monaco-editor/', - '/openid/', - '/router-slot/', - '/rxjs/', - '/tinymce/', - '/uui/', - '/uuid/', -]; +const fs = require('fs'); +const path = require('path'); + +const getDirectories = (source) => + fs + .readdirSync(source, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => dirent.name); + +// TODO: get the correct list of modules. This is a temporary solution where we assume that a directory is equivalent to a module +// TODO: include package modules in this list +const coreRoot = path.join(__dirname, '../../../', 'src/packages/core'); +const externalRoot = path.join(__dirname, '../../../', 'src/external'); +const libsRoot = path.join(__dirname, '../../../', 'src/libs'); +const coreModules = getDirectories(coreRoot).map((dir) => `/core/${dir}/`); +const externalModules = getDirectories(externalRoot).map((dir) => `/${dir}/`); +const libsModules = getDirectories(libsRoot).map((dir) => `/${dir}/`); + +const modulePathIdentifiers = [...coreModules, ...externalModules, ...libsModules]; /** @type {import('eslint').Rule.RuleModule} */ module.exports = { From a2cc72facfbdd0b407f50c6a421e6d3be537183a Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 29 May 2024 14:51:52 +0200 Subject: [PATCH 11/43] default values --- .../src/packages/property-editors/slider/Umbraco.Slider.ts | 1 - .../src/packages/property-editors/slider/manifests.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts index 12aa8f86f0..763780b667 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/Umbraco.Slider.ts @@ -24,7 +24,6 @@ export const manifest: ManifestPropertyEditorSchema = { defaultData: [ { alias: 'minVal', value: 0 }, { alias: 'maxVal', value: 100 }, - { alias: 'step', value: 1 }, ], }, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts index 52a4dfe8d4..16600162ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/manifests.ts @@ -50,7 +50,7 @@ export const manifests: Array = [ }, { alias: 'step', - value: 0, + value: 1, }, ], }, From b4bc2149c1c3cddd39787d8490a6c71c001fe117 Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 29 May 2024 14:52:08 +0200 Subject: [PATCH 12/43] set init values --- .../property-editor-ui-slider.element.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts index 7a4df169fc..16e4427846 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts @@ -19,10 +19,10 @@ export class UmbPropertyEditorUISliderElement extends UmbLitElement implements U _enableRange = false; @state() - _initVal1?: number; + _initVal1: number = 0; @state() - _initVal2?: number; + _initVal2: number = 1; @state() _step = 1; @@ -37,21 +37,23 @@ export class UmbPropertyEditorUISliderElement extends UmbLitElement implements U if (!config) return; this._enableRange = Boolean(config.getValueByAlias('enableRange')) ?? false; - this._initVal1 = Number(config.getValueByAlias('initVal1')); - this._initVal2 = Number(config.getValueByAlias('initVal2')); - // Make sure that step is higher than 0. + // Make sure that step is higher than 0 (decimals ok). const step = (config.getValueByAlias('step') ?? 1) as number; this._step = step > 0 ? step : 1; + this._initVal1 = Number(config.getValueByAlias('initVal1')) ?? 0; + this._initVal2 = Number(config.getValueByAlias('initVal2')) ?? this._initVal1 + this._step; + this._min = Number(config.getValueByAlias('minVal')) ?? 0; this._max = Number(config.getValueByAlias('maxVal')) ?? 100; if (this._min === this._max) { - // Why is the configuration giving us a 0 as default, rather than just undefined..? - - console.log(this._min, this._max, this._step, this._initVal1, this._initVal2); - throw new Error('Property Editor Slider: min and max are currently equal. Please change your configuration.'); + this._max = this._min + 100; + //TODO Maybe we want to show some kind of error element rather than trying to fix the mistake made by the user...? + throw new Error( + `Property Editor Slider: min and max are currently equal. Please change your data type configuration. To render the slider correctly, we changed this slider to: min = ${this._min}, max = ${this._max}`, + ); } } @@ -68,8 +70,8 @@ export class UmbPropertyEditorUISliderElement extends UmbLitElement implements U render() { return html` Date: Wed, 29 May 2024 15:01:04 +0200 Subject: [PATCH 13/43] Update relative module imports --- .../src/libs/class-api/class.interface.ts | 2 +- .../src/libs/class-api/context-base.class.ts | 4 ++-- .../src/libs/class-api/context.interface.ts | 2 +- .../src/libs/class-api/controller-base.class.ts | 2 +- .../src/libs/controller-api/controller-host.mixin.ts | 2 +- .../src/libs/element-api/element.interface.ts | 2 +- .../collection/property-editor-ui-collection.element.ts | 2 +- .../date-picker/property-editor-ui-date-picker.element.ts | 4 ++-- .../property-editor-ui-multiple-text-string.element.ts | 2 +- .../number-range/property-editor-ui-number-range.element.ts | 4 +--- .../property-editor-ui-radio-button-list.element.ts | 4 +--- .../slider/property-editor-ui-slider.element.ts | 2 +- .../toggle/property-editor-ui-toggle.element.ts | 2 +- .../components/input-tiny-mce/input-tiny-mce.element.ts | 2 +- 14 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/libs/class-api/class.interface.ts b/src/Umbraco.Web.UI.Client/src/libs/class-api/class.interface.ts index 8b46eb957f..3439b5650e 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/class-api/class.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/class-api/class.interface.ts @@ -3,7 +3,7 @@ import type { UmbContextConsumerController, UmbContextProviderController, UmbContextToken, -} from '../context-api/index.js'; +} from '@umbraco-cms/backoffice/context-api'; import type { UmbControllerAlias, UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { ObserverCallback, UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; diff --git a/src/Umbraco.Web.UI.Client/src/libs/class-api/context-base.class.ts b/src/Umbraco.Web.UI.Client/src/libs/class-api/context-base.class.ts index 779189dc30..17739ff1fd 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/class-api/context-base.class.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/class-api/context-base.class.ts @@ -1,7 +1,7 @@ -import type { UmbContextToken } from '../context-api/index.js'; -import type { UmbControllerHost } from '../controller-api/index.js'; import type { UmbContext } from './context.interface.js'; import { UmbControllerBase } from './controller-base.class.js'; +import type { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; /** * This base provides the necessary for a class to become a context-api controller. diff --git a/src/Umbraco.Web.UI.Client/src/libs/class-api/context.interface.ts b/src/Umbraco.Web.UI.Client/src/libs/class-api/context.interface.ts index 23181093ad..4eef3599b9 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/class-api/context.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/class-api/context.interface.ts @@ -1,3 +1,3 @@ -import type { UmbController } from '../controller-api/controller.interface.js'; +import type { UmbController } from '@umbraco-cms/backoffice/controller-api'; export interface UmbContext extends UmbController {} diff --git a/src/Umbraco.Web.UI.Client/src/libs/class-api/controller-base.class.ts b/src/Umbraco.Web.UI.Client/src/libs/class-api/controller-base.class.ts index 3229af0c06..27cde55d9e 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/class-api/controller-base.class.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/class-api/controller-base.class.ts @@ -1,5 +1,5 @@ -import type { UmbController } from '../controller-api/controller.interface.js'; import { UmbClassMixin } from './class.mixin.js'; +import type { UmbController } from '@umbraco-cms/backoffice/controller-api'; import type { ClassConstructor } from '@umbraco-cms/backoffice/extension-api'; /** diff --git a/src/Umbraco.Web.UI.Client/src/libs/controller-api/controller-host.mixin.ts b/src/Umbraco.Web.UI.Client/src/libs/controller-api/controller-host.mixin.ts index f42e775260..befc05c0d5 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/controller-api/controller-host.mixin.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/controller-api/controller-host.mixin.ts @@ -1,6 +1,6 @@ -import type { ClassConstructor } from '../extension-api/types/utils.js'; import type { UmbControllerHost } from './controller-host.interface.js'; import type { UmbController } from './controller.interface.js'; +import type { ClassConstructor } from '@umbraco-cms/backoffice/extension-api'; interface UmbControllerHostBaseDeclaration extends Omit { hostConnected(): void; diff --git a/src/Umbraco.Web.UI.Client/src/libs/element-api/element.interface.ts b/src/Umbraco.Web.UI.Client/src/libs/element-api/element.interface.ts index ca72552a06..210ea06167 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/element-api/element.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/element-api/element.interface.ts @@ -1,4 +1,4 @@ -import type { UmbControllerHostElement } from '../controller-api/controller-host-element.interface.js'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import type { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; import type { UmbClassInterface } from '@umbraco-cms/backoffice/class-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/property-editor-ui-collection.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/property-editor-ui-collection.element.ts index e975d5b11d..ed74a58ac3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/property-editor-ui-collection.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/collection/property-editor-ui-collection.element.ts @@ -1,4 +1,4 @@ -import type { UmbPropertyEditorConfigCollection } from '../../core/property-editor/config/index.js'; +import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UMB_DOCUMENT_COLLECTION_ALIAS } from '@umbraco-cms/backoffice/document'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts index 87736d5c83..81e54500ca 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/date-picker/property-editor-ui-date-picker.element.ts @@ -1,5 +1,5 @@ -import { UmbPropertyValueChangeEvent } from '../../core/property-editor/index.js'; -import type { UmbPropertyEditorConfigCollection } from '../../core/property-editor/index.js'; +import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; +import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbInputDateElement } from '@umbraco-cms/backoffice/components'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts index 3a3d41ca74..70f10ae02d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/multiple-text-string/property-editor-ui-multiple-text-string.element.ts @@ -1,4 +1,4 @@ -import { UmbPropertyValueChangeEvent } from '../../core/property-editor/index.js'; +import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/number-range/property-editor-ui-number-range.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/number-range/property-editor-ui-number-range.element.ts index 8afc35ad70..d317b7b816 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/number-range/property-editor-ui-number-range.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/number-range/property-editor-ui-number-range.element.ts @@ -1,4 +1,4 @@ -import type { UmbInputNumberRangeElement } from '../../core/components/input-number-range/input-number-range.element.js'; +import type { UmbInputNumberRangeElement } from '@umbraco-cms/backoffice/components'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -7,8 +7,6 @@ import type { UmbNumberRangeValueType } from '@umbraco-cms/backoffice/models'; import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; -import '../../core/components/input-number-range/input-number-range.element.js'; - /** * @element umb-property-editor-ui-number-range */ diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts index f7c285a9bb..98a5424a45 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts @@ -1,12 +1,10 @@ -import type { UmbInputRadioButtonListElement } from '../../core/components/input-radio-button-list/input-radio-button-list.element.js'; +import type { UmbInputRadioButtonListElement } from '@umbraco-cms/backoffice/components'; 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 { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; -import '../../core/components/input-radio-button-list/input-radio-button-list.element.js'; - /** * @element umb-property-editor-ui-radio-button-list */ diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts index 511382b107..c5b361e42c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/slider/property-editor-ui-slider.element.ts @@ -1,4 +1,4 @@ -import type { UmbInputSliderElement } from '../../core/components/input-slider/input-slider.element.js'; +import type { UmbInputSliderElement } from '@umbraco-cms/backoffice/components'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts index c5b580da44..41502a8a45 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/toggle/property-editor-ui-toggle.element.ts @@ -1,4 +1,4 @@ -import type { UmbInputToggleElement } from '../../core/components/input-toggle/input-toggle.element.js'; +import type { UmbInputToggleElement } from '@umbraco-cms/backoffice/components'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.element.ts index 0f0ed46715..8e12f17c43 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiny-mce/components/input-tiny-mce/input-tiny-mce.element.ts @@ -1,9 +1,9 @@ -import { loadManifestApi } from '../../../../libs/extension-api/functions/load-manifest-api.function.js'; import { availableLanguages } from './input-tiny-mce.languages.js'; import { defaultFallbackConfig } from './input-tiny-mce.defaults.js'; import { pastePreProcessHandler } from './input-tiny-mce.handlers.js'; import { uriAttributeSanitizer } from './input-tiny-mce.sanitizer.js'; import type { TinyMcePluginArguments, UmbTinyMcePluginBase } from './tiny-mce-plugin.js'; +import { loadManifestApi } from '@umbraco-cms/backoffice/extension-api'; import { css, customElement, html, property, query, state } from '@umbraco-cms/backoffice/external/lit'; import { firstValueFrom } from '@umbraco-cms/backoffice/external/rxjs'; import { getProcessedImageUrl } from '@umbraco-cms/backoffice/utils'; From 6684bf97507aa1997ff43685a819b917c34bda8f Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Wed, 29 May 2024 15:39:07 +0200 Subject: [PATCH 14/43] fixes https://github.com/umbraco/Umbraco-CMS/issues/16451 --- .../partial-views/workspace/partial-view-workspace.context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts index 2a520a2f87..1b677ac99b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-view-workspace.context.ts @@ -171,8 +171,8 @@ export class UmbPartialViewWorkspaceContext if (error) { throw new Error(error.message); } - this.setIsNew(false); this.#data.setValue(data); + this.setIsNew(false); // 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); From 0207e9833b1395294ad5005d5f7753f7026ebe4e Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 29 May 2024 15:44:47 +0100 Subject: [PATCH 15/43] Bugfix: Localizes the name and alias input placeholders --- .../input-with-alias/input-with-alias.element.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts index 6d35011fb7..b3cfdca6cc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts @@ -6,7 +6,7 @@ import { type UUIInputElement, UUIInputEvent } from '@umbraco-cms/backoffice/ext import { generateAlias } from '@umbraco-cms/backoffice/utils'; @customElement('umb-input-with-alias') -export class UmbInputWithAliasElement extends UmbFormControlMixin(UmbLitElement) { +export class UmbInputWithAliasElement extends UmbFormControlMixin(UmbLitElement) { @property({ type: String }) label: string = ''; @@ -68,9 +68,13 @@ export class UmbInputWithAliasElement extends UmbFormControlMixin(UmbLit } render() { - // Localizations: [NL] return html` - + (UmbLit label="alias" @input=${this.#onAliasChange} .value=${this.alias} - placeholder="Enter alias..." + placeholder=${this.localize.term('placeholders_enterAlias')} ?disabled=${this._aliasLocked && !this.aliasReadonly} ?readonly=${this.aliasReadonly}> From 9bed18c154c5429d7a1ffc4b2acac9c61006b36e Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 29 May 2024 17:11:14 +0100 Subject: [PATCH 16/43] Aligned the `label` and `placeholder` text --- .../components/input-with-alias/input-with-alias.element.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts index b3cfdca6cc..68a205addb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts @@ -68,6 +68,8 @@ export class UmbInputWithAliasElement extends UmbFormControlMixin From 94bfc2b6dba57b0749799d87a5df40406ee19bc0 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 29 May 2024 17:12:06 +0100 Subject: [PATCH 17/43] Updated the `label` text to use the localization Aligns across Document Type, Media Type, Member Type and User Groups. --- .../components/input-with-alias/input-with-alias.element.ts | 5 +++-- .../workspace/document-type-workspace-editor.element.ts | 2 +- .../workspace/media-type-workspace-editor.element.ts | 2 +- .../workspace/member-type-workspace-editor.element.ts | 2 +- .../workspace/user-group-workspace-editor.element.ts | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts index 68a205addb..8034bca4d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts @@ -68,13 +68,14 @@ export class UmbInputWithAliasElement extends UmbFormControlMixin diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts index 8d382274bf..a09b53143b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts @@ -85,7 +85,7 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement {
Date: Wed, 29 May 2024 20:07:33 +0200 Subject: [PATCH 18/43] load global components in tests --- src/Umbraco.Web.UI.Client/web-test-runner.config.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs index 9285bb97af..bb99c1da29 100644 --- a/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs +++ b/src/Umbraco.Web.UI.Client/web-test-runner.config.mjs @@ -34,7 +34,7 @@ export default { }, }), commonjs({ - include: ['node_modules/base64-js/**/*', 'node_modules/tinymce/**/*'] + include: ['node_modules/base64-js/**/*', 'node_modules/tinymce/**/*'], }), esbuildPlugin({ ts: true, tsconfig: './tsconfig.json', target: 'auto', json: true }), ], @@ -53,6 +53,9 @@ export default { + From cb870f7e8007d1a8c87a48916ff79a4c661da239 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 May 2024 10:51:22 +0200 Subject: [PATCH 19/43] add option to set folders only for a moveTo manifest --- .../core/extension-registry/models/entity-action.model.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-action.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-action.model.ts index 1b49c71c2e..590cb7e3df 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-action.model.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/entity-action.model.ts @@ -134,6 +134,7 @@ export interface MetaEntityActionMoveToKind extends MetaEntityActionDefaultKind moveRepositoryAlias: string; treeRepositoryAlias: string; treeAlias: string; + foldersOnly?: boolean; } // FOLDER From 326f8df2624ca72dd2a042eee1d2bec46134b8cb Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 May 2024 10:51:42 +0200 Subject: [PATCH 20/43] set folders only for data type move to --- .../src/packages/data-type/entity-actions/move-to/manifests.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/entity-actions/move-to/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/entity-actions/move-to/manifests.ts index 06d1faa568..a9a684e94f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/entity-actions/move-to/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/entity-actions/move-to/manifests.ts @@ -15,6 +15,7 @@ const entityActions: Array = [ treeRepositoryAlias: UMB_DATA_TYPE_TREE_REPOSITORY_ALIAS, moveRepositoryAlias: UMB_MOVE_DATA_TYPE_REPOSITORY_ALIAS, treeAlias: UMB_DATA_TYPE_TREE_ALIAS, + foldersOnly: true, }, }, ]; From 740ef3f12131e36f6905e1ee5cf12f4265f10eaf Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 May 2024 10:52:06 +0200 Subject: [PATCH 21/43] pass folders only config setting to tree picker modal --- .../core/tree/entity-actions/move/move-to.action.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/entity-actions/move/move-to.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/entity-actions/move/move-to.action.ts index bd6137e492..19bab1d19f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/entity-actions/move/move-to.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/entity-actions/move/move-to.action.ts @@ -13,8 +13,12 @@ export class UmbMoveToEntityAction extends UmbEntityActionBase Date: Thu, 30 May 2024 10:52:45 +0200 Subject: [PATCH 22/43] accept folders only setting in tree picker modal --- .../packages/core/tree/tree-picker/tree-picker-modal.token.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts index 0613c85b46..d7d77ee764 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.token.ts @@ -21,6 +21,7 @@ export interface UmbTreePickerModalData< // Consider if it makes sense to move this into the UmbPickerModalData interface, but for now this is a TreePicker feature. [NL] createAction?: UmbTreePickerModalCreateActionData; startNode?: UmbTreeStartNode; + foldersOnly?: boolean; } export interface UmbTreePickerModalValue extends UmbPickerModalValue {} From b1872eeddf8ba20467e5ca307577c554024455a8 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 May 2024 10:53:11 +0200 Subject: [PATCH 23/43] pass folders only to tree element --- .../packages/core/tree/tree-picker/tree-picker-modal.element.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts index 54a97e4b36..a73c25404b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-picker/tree-picker-modal.element.ts @@ -101,6 +101,7 @@ export class UmbTreePickerModalElement Date: Thu, 30 May 2024 10:53:56 +0200 Subject: [PATCH 24/43] handle folders only setting and pass to root end points --- .../core/tree/default/default-tree.context.ts | 45 +++++++++++++++---- .../core/tree/default/default-tree.element.ts | 7 +++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts index 20d50e8b97..22c09925d9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.context.ts @@ -49,6 +49,9 @@ export class UmbDefaultTreeContext< #startNode = new UmbObjectState(undefined); startNode = this.#startNode.asObservable(); + #foldersOnly = new UmbBooleanState(false); + foldersOnly = this.#foldersOnly.asObservable(); + #manifest?: ManifestTree; #repository?: UmbTreeRepository; #actionEventContext?: UmbActionEventContext; @@ -178,6 +181,7 @@ export class UmbDefaultTreeContext< // If we have a start node get children of that instead of the root const startNode = this.getStartNode(); + const foldersOnly = this.#foldersOnly.getValue(); const additionalArgs = this.#additionalRequestArgs.getValue(); const { data } = startNode?.unique @@ -187,11 +191,13 @@ export class UmbDefaultTreeContext< unique: startNode.unique, entityType: startNode.entityType, }, + foldersOnly, skip, take, }) : await this.#repository!.requestTreeRootItems({ ...additionalArgs, + foldersOnly, skip, take, }); @@ -241,6 +247,36 @@ export class UmbDefaultTreeContext< this.loadTree(); } + /** + * Gets the startNode config + * @return {UmbTreeStartNode} + * @memberof UmbDefaultTreeContext + */ + getStartNode() { + return this.#startNode.getValue(); + } + + /** + * Sets the foldersOnly config + * @param {boolean} foldersOnly + * @memberof UmbDefaultTreeContext + */ + setFoldersOnly(foldersOnly: boolean) { + this.#foldersOnly.setValue(foldersOnly); + // we need to reset the tree if this config changes + this.#resetTree(); + this.loadTree(); + } + + /** + * Gets the foldersOnly config + * @return {boolean} + * @memberof UmbDefaultTreeContext + */ + getFoldersOnly() { + return this.#foldersOnly.getValue(); + } + /** * Updates the requestArgs config and reloads the tree. */ @@ -254,15 +290,6 @@ export class UmbDefaultTreeContext< return this.#additionalRequestArgs.getValue(); } - /** - * Gets the startNode config - * @return {UmbTreeStartNode} - * @memberof UmbDefaultTreeContext - */ - getStartNode() { - return this.#startNode.getValue(); - } - #resetTree() { this.#treeRoot.setValue(undefined); this.#rootItems.setValue([]); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.element.ts index bbef0c7435..6bc36ee679 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/default/default-tree.element.ts @@ -31,6 +31,9 @@ export class UmbDefaultTreeElement extends UmbLitElement { @property({ type: Object, attribute: false }) startNode?: UmbTreeStartNode; + @property({ type: Boolean, attribute: false }) + foldersOnly?: boolean = false; + @property({ attribute: false }) selectableFilter: (item: UmbTreeItemModelBase) => boolean = () => true; @@ -87,6 +90,10 @@ export class UmbDefaultTreeElement extends UmbLitElement { this.#treeContext!.setHideTreeRoot(this.hideTreeRoot); } + if (_changedProperties.has('foldersOnly')) { + this.#treeContext!.setFoldersOnly(this.foldersOnly ?? false); + } + if (_changedProperties.has('selectableFilter')) { this.#treeContext!.selectableFilter = this.selectableFilter; } From 9150dd9c1cb8947a0970464e7ff10a066c7f0c5b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 May 2024 10:54:22 +0200 Subject: [PATCH 25/43] add optional folders only prop to tree request args types --- src/Umbraco.Web.UI.Client/src/packages/core/tree/data/types.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/data/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/data/types.ts index b4a8bddb39..e461571522 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/data/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/data/types.ts @@ -1,12 +1,14 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; export interface UmbTreeRootItemsRequestArgs { + foldersOnly?: boolean; skip?: number; take?: number; } export interface UmbTreeChildrenOfRequestArgs { parent: UmbEntityModel; + foldersOnly?: boolean; skip?: number; take?: number; } From 1ca04e204af134397bd2b9878f9cfbf86fdc5472 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 May 2024 10:54:36 +0200 Subject: [PATCH 26/43] pass folders only to server --- .../data-type/tree/data-type-tree.server.data-source.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts index b78a1482e5..f7172b9032 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.server.data-source.ts @@ -50,7 +50,11 @@ export class UmbDataTypeTreeServerDataSource extends UmbTreeServerDataSourceBase const getRootItems = async (args: UmbTreeRootItemsRequestArgs) => { // eslint-disable-next-line local-rules/no-direct-api-import - return DataTypeService.getTreeDataTypeRoot({ skip: args.skip, take: args.take }); + return DataTypeService.getTreeDataTypeRoot({ + foldersOnly: args.foldersOnly, + skip: args.skip, + take: args.take, + }); }; const getChildrenOf = (args: UmbTreeChildrenOfRequestArgs) => { @@ -60,6 +64,7 @@ const getChildrenOf = (args: UmbTreeChildrenOfRequestArgs) => { // eslint-disable-next-line local-rules/no-direct-api-import return DataTypeService.getTreeDataTypeChildren({ parentId: args.parent.unique, + foldersOnly: args.foldersOnly, skip: args.skip, take: args.take, }); From a9be8d619c3fc010c0c14c9264059c1414fc04a5 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 May 2024 10:54:51 +0200 Subject: [PATCH 27/43] handle folders only in tree items --- .../tree-item-base/tree-item-context-base.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-context-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-context-base.ts index ca3b601430..09e62088c6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-context-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-context-base.ts @@ -65,6 +65,9 @@ export abstract class UmbTreeItemContextBase< #path = new UmbStringState(''); readonly path = this.#path.asObservable(); + #foldersOnly = new UmbBooleanState(false); + readonly foldersOnly = this.#foldersOnly.asObservable(); + treeContext?: UmbDefaultTreeContext; #sectionContext?: UmbSectionContext; #sectionSidebarContext?: UmbSectionSidebarContext; @@ -175,6 +178,7 @@ export abstract class UmbTreeItemContextBase< const skip = loadMore ? this.#paging.skip : 0; const take = loadMore ? this.#paging.take : this.pagination.getCurrentPageNumber() * this.#paging.take; + const foldersOnly = this.#foldersOnly.getValue(); const additionalArgs = this.treeContext?.getAdditionalRequestArgs(); const { data } = await repository.requestTreeItemsOf({ @@ -182,6 +186,7 @@ export abstract class UmbTreeItemContextBase< unique: this.unique, entityType: this.entityType, }, + foldersOnly, skip, take, ...additionalArgs, @@ -240,6 +245,7 @@ export abstract class UmbTreeItemContextBase< this.treeContext = treeContext; this.#observeIsSelectable(); this.#observeIsSelected(); + this.#observeFoldersOnly(); }); this.consumeContext(UMB_ACTION_EVENT_CONTEXT, (instance) => { @@ -311,6 +317,18 @@ export abstract class UmbTreeItemContextBase< ); } + #observeFoldersOnly() { + if (!this.treeContext || this.unique === undefined) return; + + this.observe( + this.treeContext.foldersOnly, + (foldersOnly) => { + this.#foldersOnly.setValue(foldersOnly); + }, + 'observeFoldersOnly', + ); + } + #observeSectionPath() { if (!this.#sectionContext) return; From 7f485ec3b8ccee2e4d730b1655e8e71edc7fc6aa Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 30 May 2024 10:48:01 +0100 Subject: [PATCH 28/43] Bugfix: Media workspace info references correct localization for "this item has no references". Fixes https://github.com/umbraco/Umbraco-CMS/issues/16485 --- .../views/info/media-workspace-view-info-reference.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts index 2704b72704..ce209f523e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts @@ -135,7 +135,7 @@ export class UmbMediaWorkspaceViewInfoReferenceElement extends UmbLitElement { } #renderItems() { - if (!this._items?.length) return html`

${this.localize.term('references_DataTypeNoReferences')}

`; + if (!this._items?.length) return html`

${this.localize.term('references_itemHasNoReferences')}

`; return html` From f3e00c2fbc0bd389bc8e358b3665622c43ad9ead Mon Sep 17 00:00:00 2001 From: leekelleher Date: Thu, 30 May 2024 10:53:05 +0100 Subject: [PATCH 29/43] Bugfix: Property description, sets `max-width` for child items e.g. typically for `` tags. --- .../core/property/property-layout/property-layout.element.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-layout/property-layout.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-layout/property-layout.element.ts index fac6cc9d24..cff1078368 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property-layout/property-layout.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property-layout/property-layout.element.ts @@ -130,6 +130,10 @@ export class UmbPropertyLayoutElement extends UmbLitElement { color: var(--uui-color-text-alt); } + #description * { + max-width: 100%; + } + #editorColumn { margin-top: var(--uui-size-space-3); } From 722f97aa33b174a12d8e014a20e47261e71fa88b Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Thu, 30 May 2024 11:08:52 +0100 Subject: [PATCH 30/43] Update src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../views/info/media-workspace-view-info-reference.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts index ce209f523e..cdf8996e68 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/views/info/media-workspace-view-info-reference.element.ts @@ -135,7 +135,7 @@ export class UmbMediaWorkspaceViewInfoReferenceElement extends UmbLitElement { } #renderItems() { - if (!this._items?.length) return html`

${this.localize.term('references_itemHasNoReferences')}

`; + if (!this._items?.length) return html`

This item has no references.

`; return html` From 174a16018790d9150ee5bd9b217838c34359e448 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Tue, 28 May 2024 16:47:39 +0100 Subject: [PATCH 31/43] Document Type Workspace, icon picker styling Adds button outline look, with square constraints. --- .../workspace/document-type-workspace-editor.element.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts index a09b53143b..aef99e3bfd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/workspace/document-type-workspace-editor.element.ts @@ -78,7 +78,7 @@ export class UmbDocumentTypeWorkspaceEditorElement extends UmbLitElement { return html` - ${!this._sortModeActive - ? html` html` + - Add property - ` - : ''} + look="placeholder"> + `, + )} ` : ''; } @@ -217,8 +228,9 @@ export class UmbContentTypeDesignEditorPropertiesElement extends UmbLitElement { static styles = [ UmbTextStyles, css` - #add { + #btn-add { width: 100%; + --uui-button-height: var(--uui-size-14); } #property-list[sort-mode-active]:not(:has(umb-content-type-design-editor-property)) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts index a56eed116b..234555b07d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-tab.element.ts @@ -1,19 +1,17 @@ import { UMB_CONTENT_TYPE_WORKSPACE_CONTEXT } from '../../content-type-workspace.context-token.js'; -import type { UmbContentTypeWorkspaceViewEditGroupElement } from './content-type-design-editor-group.element.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 { css, html, customElement, property, state, repeat, nothing } from '@umbraco-cms/backoffice/external/lit'; -import { - UmbContentTypeContainerStructureHelper, - type UmbContentTypeModel, - type UmbPropertyTypeContainerModel, -} from '@umbraco-cms/backoffice/content-type'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; +import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/modal'; +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'; import './content-type-design-editor-group.element.js'; -import { type UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter'; -import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/modal'; -import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; const SORTER_CONFIG: UmbSorterConfig = { getUniqueOfElement: (element) => element.group?.id, @@ -120,6 +118,7 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { this._editContentTypePath = routeBuilder({}); }); }); + this.consumeContext(UMB_CONTENT_TYPE_DESIGN_EDITOR_CONTEXT, (context) => { this.observe( context.isSorting, @@ -134,6 +133,7 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { '_observeIsSorting', ); }); + this.observe( this.#groupStructureHelper.mergedContainers, (groups) => { @@ -142,6 +142,7 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { }, null, ); + this.observe( this.#groupStructureHelper.hasProperties, (hasProperties) => { @@ -194,13 +195,13 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { #renderAddGroupButton() { if (this._sortModeActive) return; - return html` - ${this.localize.term('contentTypeEditor_addGroup')} - `; + return html` + + `; } static styles = [ @@ -213,12 +214,9 @@ export class UmbContentTypeDesignEditorTabElement extends UmbLitElement { visibility: hidden; } - #add { + #btn-add { width: 100%; - } - - #add:first-child { - margin-top: var(--uui-size-layout-1); + --uui-button-height: var(--uui-size-24); } uui-box, From c78c84ee39c450aa484f342ee0d89476882c3eb1 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Tue, 28 May 2024 18:06:47 +0100 Subject: [PATCH 35/43] Document Type Workspace, property group name input Lets the property-group input take the full-width, and makes the border transparent (border appears on hover), to align with v13 cosmetics. --- ...ontent-type-design-editor-group.element.ts | 86 ++++++++++++------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts index f8d140f75d..bf9bd28de3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/workspace/views/design/content-type-design-editor-group.element.ts @@ -1,15 +1,15 @@ -import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; +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 { css, html, customElement, property, state, nothing, repeat } from '@umbraco-cms/backoffice/external/lit'; +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'; -import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @customElement('umb-content-type-design-editor-group') export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { @@ -147,64 +147,78 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { } render() { - return this._inherited !== undefined && this._groupId - ? html` - - ${this.#renderContainerHeader()} - - - ` - : ''; + if (this._inherited === undefined || !this._groupId) return nothing; + return html` + + ${this.#renderContainerHeader()} + + + `; } // TODO: impl UMB_EDIT_DOCUMENT_TYPE_PATH_PATTERN, but we need either a generic type or a way to get the path pattern.... [NL] #renderContainerHeader() { - return html`
+ return html` +
- ${this.sortModeActive && this._hasOwnerContainer ? html`` : null} + ${when( + this.sortModeActive && this._hasOwnerContainer, + () => html``, + )}
- ${this._hasOwnerContainer === false && this._inheritedFrom - ? html` + ${when( + this._hasOwnerContainer === false && this._inheritedFrom, + () => html` + ${this.localize.term('contentTypeEditor_inheritedFrom')} ${repeat( - this._inheritedFrom, + this._inheritedFrom!, (inherited) => inherited.unique, (inherited) => html` ${inherited.name} `, )} - ` - : null} - ${!this._inherited && !this.sortModeActive - ? html` + + `, + )} + ${when( + !this._inherited && !this.sortModeActive, + () => html` + - ` - : nothing} - ${this.sortModeActive - ? html` + `, + )} + ${when( + this.sortModeActive, + () => html` + - this._singleValueUpdate('sortOrder', parseInt(e.target.value as string) || 0)} .value=${this.group!.sortOrder ?? 0} - ?disabled=${!this._hasOwnerContainer}>` - : nothing} -
`; + ?disabled=${!this._hasOwnerContainer} + @change=${(e: UUIInputEvent) => + this._singleValueUpdate('sortOrder', parseInt(e.target.value as string) || 0)}> + `, + )} +
+ `; } static styles = [ @@ -229,6 +243,12 @@ export class UmbContentTypeWorkspaceViewEditGroupElement extends UmbLitElement { display: flex; align-items: center; gap: var(--uui-size-3); + width: 100%; + } + + #group-name { + --uui-input-border-color: transparent; + width: 100%; } uui-input[type='number'] { From 4d714ca6c295f49d8045ba2ebb1979f69ab49ec5 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Tue, 28 May 2024 18:30:15 +0100 Subject: [PATCH 36/43] Document Type Workspace, adds `auto-width` to alias input --- .../input-with-alias.element.ts | 62 +++++++++++-------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts index 8034bca4d3..1ca1c9f063 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-with-alias/input-with-alias.element.ts @@ -31,36 +31,37 @@ export class UmbInputWithAliasElement extends UmbFormControlMixin + ?readonly=${this.aliasReadonly} + @input=${this.#onAliasChange}> ${this.aliasReadonly ? nothing - : html`
''} id="alias-lock" slot="prepend"> - -
`} + : html` +
''} id="alias-lock" slot="prepend"> + +
+ `}
`; @@ -106,6 +110,10 @@ export class UmbInputWithAliasElement extends UmbFormControlMixin uui-input { + max-width: 50%; + } + :host(:invalid:not([pristine])) { color: var(--uui-color-danger); } From 51fa631abfe00e2cde8607a7d7a32c2dc93a589c Mon Sep 17 00:00:00 2001 From: leekelleher Date: Wed, 29 May 2024 17:50:07 +0100 Subject: [PATCH 37/43] Aligned header cosmetics from Document Type workspace to Media Type, Member Type and User Group workspaces. --- .../media-type-workspace-editor.element.ts | 55 ++++++++++--------- .../member-type-workspace-editor.element.ts | 15 ++--- .../user-group-workspace-editor.element.ts | 18 ++++-- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts index 952daff1fa..946706326f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts @@ -80,32 +80,34 @@ export class UmbMediaTypeWorkspaceEditorElement extends UmbLitElement { } render() { - return html` -