From 270cd20083e7aaae763064672aaad1eea0ff639e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 15 Apr 2024 21:09:15 +0200 Subject: [PATCH 01/18] bind server feedback with validation system --- .../server-model-validation.context.ts | 40 +++++-------------- .../document-validation.repository.ts | 8 +--- .../document-validation.server.data-source.ts | 16 +------- 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts index ca7834b738..8a39682c50 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts @@ -4,7 +4,7 @@ import { UMB_VALIDATION_CONTEXT } from './validation.context-token.js'; import { UMB_SERVER_MODEL_VALIDATION_CONTEXT } from './server-model-validation.context-token.js'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { ApiError, CancelError } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository'; type ServerFeedbackEntry = { path: string; messages: Array }; @@ -40,10 +40,7 @@ export class UmbServerModelValidationContext }); } - async askServerForValidation( - data: unknown, - requestPromise: Promise<{ data: unknown; error: ApiError | CancelError | undefined }>, - ): Promise { + async askServerForValidation(data: unknown, requestPromise: Promise>): Promise { this.#context?.messages.removeMessagesByType('server'); this.#serverFeedback = []; @@ -54,38 +51,22 @@ export class UmbServerModelValidationContext }); // Ask the server for validation... - //const { data: feedback, error } = await requestPromise; - await requestPromise; - - //console.log('VALIDATE — Got server response:'); - //console.log(data, error); + const { error } = await requestPromise; // Store this state of the data for translator look ups: this.#data = data; - /* - const fixedData = { - type: 'Error', - title: 'Validation failed', - status: 400, - detail: 'One or more properties did not pass validation', - operationStatus: 'PropertyValidationError', - errors: { - '$.values[0].value': ['#validation.invalidPattern'], - } as Record>, - missingProperties: [], - }; - Object.keys(fixedData.errors).forEach((path) => { - this.#serverFeedback.push({ path, messages: fixedData.errors[path] }); - });*/ + // We are missing some typing here, but we will just go wild: [NL] + const readErrorBody = (error as any).body; + Object.keys(readErrorBody.errors).forEach((path) => { + this.#serverFeedback.push({ path, messages: readErrorBody.errors[path] }); + }); - //this.#isValid = data ? true : false; - //this.#isValid = false; - this.#isValid = true; + this.#isValid = data ? true : false; this.#validatePromiseResolve?.(); this.#validatePromiseResolve = undefined; - //this.#validatePromise = undefined; + // Translate feedback: this.#serverFeedback = this.#serverFeedback.flatMap(this.#executeTranslatorsOnFeedback); } @@ -113,6 +94,7 @@ export class UmbServerModelValidationContext if (this.#translators.indexOf(translator) === -1) { this.#translators.push(translator); } + // execute translators here? } removeTranslator(translator: UmbValidationMessageTranslator): void { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts index e58c62e3ea..8ec8e6ea73 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts @@ -24,9 +24,7 @@ export class UmbDocumentValidationRepository extends UmbRepositoryBase { async validateCreate(model: DetailModelType, parentUnique: string | null) { if (!model) throw new Error('Data is missing'); - const { data, error } = await this.#validationDataSource.validateCreate(model, parentUnique); - - return { data, error }; + return this.#validationDataSource.validateCreate(model, parentUnique); } /** @@ -39,8 +37,6 @@ export class UmbDocumentValidationRepository extends UmbRepositoryBase { if (!model) throw new Error('Data is missing'); if (!model.unique) throw new Error('Unique is missing'); - const { data, error } = await this.#validationDataSource.validateUpdate(model); - - return { data, error }; + return this.#validationDataSource.validateUpdate(model); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts index cfedd19c97..02b354d9b1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts @@ -45,18 +45,12 @@ export class UmbDocumentValidationServerDataSource { }; // Maybe use: tryExecuteAndNotify - const { data, error } = await tryExecute( + return tryExecute( //this.#host, DocumentService.postDocumentValidate({ requestBody, }), ); - - if (data) { - return { data }; - } - - return { error }; } /** @@ -75,18 +69,12 @@ export class UmbDocumentValidationServerDataSource { }; // Maybe use: tryExecuteAndNotify - const { data, error } = await tryExecute( + return tryExecute( //this.#host, DocumentService.putDocumentByIdValidate({ id: model.unique, requestBody, }), ); - - if (!error) { - return { data }; - } - - return { error }; } } From 2c7199fda00006903cba5c0360d90b82c02d3fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 15 Apr 2024 21:29:36 +0200 Subject: [PATCH 02/18] translation refactor --- .../server-model-validation.context.ts | 5 ++-- ...validation-message-translator.interface.ts | 3 +-- ...alidation-message-translator.controller.ts | 27 ++++++++++++------- .../workspace/document-workspace.context.ts | 8 ++++++ 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts index 8a39682c50..2c0d51cd08 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts @@ -72,9 +72,8 @@ export class UmbServerModelValidationContext #executeTranslatorsOnFeedback = (feedback: ServerFeedbackEntry) => { return this.#translators.flatMap((translator) => { - if (translator.match(feedback.path)) { - const newPath = translator.translate(feedback.path); - + let newPath: string | undefined; + if ((newPath = translator.translate(feedback.path))) { // TODO: I might need to restructure this part for adjusting existing feedback with a part-translation. // Detect if some part is unhandled? // If so only make a partial translation on the feedback, add a message for the handled part. diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/validation-message-translator.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/validation-message-translator.interface.ts index 0004a924f3..80b66fa608 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/validation-message-translator.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/validation-message-translator.interface.ts @@ -1,4 +1,3 @@ export interface UmbValidationMessageTranslator { - match(message: string): boolean; - translate(message: string): string; + translate(message: string): undefined | string; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/variant-values-validation-message-translator.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/variant-values-validation-message-translator.controller.ts index 2cc965eace..709c534a77 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/variant-values-validation-message-translator.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/translators/variant-values-validation-message-translator.controller.ts @@ -17,15 +17,24 @@ export class UmbVariantValuesValidationMessageTranslator this.#context = context; } - match(message: string): boolean { - //return message.startsWith('values['); - // regex match, which starts with "$.values[" and then a number and then continues: - return message.indexOf('$.values[') === 0; - } - translate(path: string): string { - // retrieve the number from the message values index: - const index = parseInt(path.substring(9, path.indexOf(']'))); - // + translate(path: string) { + if (path.indexOf('$.values[') !== 0) { + // No translation anyway. + return; + } + const pathEnd = path.indexOf(']'); + if (pathEnd === -1) { + // No translation anyway. + return; + } + // retrieve the number from the message values index: [NL] + const index = parseInt(path.substring(9, pathEnd)); + + if (isNaN(index)) { + // No translation anyway. + return; + } + // Get the data from the validation request, the context holds that for us: [NL] const data = this.#context.getData(); const specificValue = data.values[index]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index c41e96a116..2c4d81cb51 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -54,6 +54,7 @@ import { UmbVariantValuesValidationMessageTranslator, } from '@umbraco-cms/backoffice/validation'; import { UmbDocumentBlueprintDetailRepository } from '@umbraco-cms/backoffice/document-blueprint'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; type EntityType = UmbDocumentDetailModel; export class UmbDocumentWorkspaceContext @@ -649,6 +650,13 @@ export class UmbDocumentWorkspaceContext async () => { // If data of the selection is not valid Then just save: await this.#performSaveOrCreate(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. + // TODO: Translate this message [NL] + notificationContext.peek('danger', { + data: { message: 'Document was not published, but we saved it for you.' }, + }); // Reject even thought the save was successful, but we did not publish, which is what we want to symbolize here. [NL] return await Promise.reject(); }, From ece9ba408bbd40081a35b5043f5baa9f2163365a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 15 Apr 2024 22:06:02 +0200 Subject: [PATCH 03/18] retrieve messages --- .../property-layout/property-layout.element.ts | 10 ++++++++++ .../core/property/property/property.element.ts | 11 +++++++---- .../context/server-model-validation.context.ts | 18 ++++++++++-------- .../context/validation-messages.manager.ts | 4 ++-- .../observe-validation-state.controller.ts | 9 +++++++-- 5 files changed, 36 insertions(+), 16 deletions(-) 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 cdc2c5fc07..2b28c03dba 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 @@ -56,6 +56,16 @@ export class UmbPropertyLayoutElement extends LitElement { @property({ type: Boolean, reflect: true }) public invalid?: boolean; + /** + * @description Describe why the property is invalid. + * @type {boolean} + * @attr + * @default undefined + */ + @property({ type: String, attribute: 'invalid-message' }) + public invalidMessage?: string; + // TODO: put the invalidMessage in some hover tooltip or something. [NL] + render() { // TODO: Only show alias on label if user has access to DocumentType within settings: return html` diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts index e6397911a7..c3d3cb72b3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts @@ -109,8 +109,10 @@ export class UmbPropertyElement extends UmbLitElement { @property({ type: String, attribute: false }) public set dataPath(dataPath: string | undefined) { this.#dataPath = dataPath; - new UmbObserveValidationStateController(this, dataPath, (invalid) => { - this._invalid = invalid; + new UmbObserveValidationStateController(this, dataPath, (feedback) => { + // TODO: Join in a pretty way, and localized way(how to join one or more items varies depending on the language. [NL] + // TODO: Also wrap in a general localized message, like "Contains these errors: ..."; [NL] + this._validationMessage = feedback.length > 0 ? feedback.map((x) => x.message).join(', ') : undefined; }); } public get dataPath(): string | undefined { @@ -125,7 +127,7 @@ export class UmbPropertyElement extends UmbLitElement { private _element?: ManifestPropertyEditorUi['ELEMENT_TYPE']; @state() - private _invalid?: boolean; + private _validationMessage?: string; @state() private _alias?: string; @@ -276,7 +278,8 @@ export class UmbPropertyElement extends UmbLitElement { alias="${ifDefined(this._alias)}" label="${ifDefined(this._label)}" description="${ifDefined(this._description)}" - ?invalid=${this._invalid}> + ?invalid=${this._validationMessage !== undefined} + .invalidMessage=${this._validationMessage}> ${this._renderPropertyActionMenu()} ${this._variantDifference ? html`${this._variantDifference}` diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts index 2c0d51cd08..21f0d827fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/server-model-validation.context.ts @@ -50,19 +50,21 @@ export class UmbServerModelValidationContext this.#validatePromiseResolve = resolve; }); + // Store this state of the data for translator look ups: + this.#data = data; // Ask the server for validation... const { error } = await requestPromise; - // Store this state of the data for translator look ups: - this.#data = data; + this.#isValid = error ? false : true; - // We are missing some typing here, but we will just go wild: [NL] - const readErrorBody = (error as any).body; - Object.keys(readErrorBody.errors).forEach((path) => { - this.#serverFeedback.push({ path, messages: readErrorBody.errors[path] }); - }); + if (!this.#isValid) { + // We are missing some typing here, but we will just go wild with 'as any': [NL] + const readErrorBody = (error as any).body; + Object.keys(readErrorBody.errors).forEach((path) => { + this.#serverFeedback.push({ path, messages: readErrorBody.errors[path] }); + }); + } - this.#isValid = data ? true : false; this.#validatePromiseResolve?.(); this.#validatePromiseResolve = undefined; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts index 4a26bf1b10..03b31ce790 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts @@ -34,7 +34,7 @@ export class UmbValidationMessagesManager { return this.#messages.getValue().length !== 0; } - /*messagesOf(path: string): Observable> { + messagesOfPathAndDescendant(path: string): Observable> { // Find messages that starts with the given path, if the path is longer then require a dot or [ as the next character. using a more performant way than Regex: return this.#messages.asObservablePart((msgs) => msgs.filter( @@ -43,7 +43,7 @@ export class UmbValidationMessagesManager { (x.path.length === path.length || x.path[path.length] === '.' || x.path[path.length] === '['), ), ); - }*/ + } messagesOfTypeAndPath(type: UmbValidationMessageType, path: string): Observable> { // Find messages that matches the given type and path. diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts index 737c26f1dd..e31d8b720f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts @@ -1,4 +1,5 @@ import { UMB_VALIDATION_CONTEXT } from '../context/validation.context-token.js'; +import type { UmbValidationMessage } from '../context/validation-messages.manager.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; @@ -6,11 +7,15 @@ const CtrlSymbol = Symbol(); const ObserveSymbol = Symbol(); export class UmbObserveValidationStateController extends UmbControllerBase { - constructor(host: UmbControllerHost, dataPath: string | undefined, callback: (invalid: boolean) => void) { + constructor( + host: UmbControllerHost, + dataPath: string | undefined, + callback: (messages: Array) => void, + ) { super(host, CtrlSymbol); if (dataPath) { this.consumeContext(UMB_VALIDATION_CONTEXT, (context) => { - this.observe(context.messages.hasMessagesOfPathAndDescendant(dataPath), callback, ObserveSymbol); + this.observe(context.messages.messagesOfPathAndDescendant(dataPath), callback, ObserveSymbol); }); } } From 6e0fd5a8d8e8b0143f779602f1353e018ade044b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 15 Apr 2024 22:14:22 +0200 Subject: [PATCH 04/18] clean up --- .../property-layout/property-layout.element.ts | 10 ---------- .../core/property/property/property.element.ts | 11 ++++------- 2 files changed, 4 insertions(+), 17 deletions(-) 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 2b28c03dba..cdc2c5fc07 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 @@ -56,16 +56,6 @@ export class UmbPropertyLayoutElement extends LitElement { @property({ type: Boolean, reflect: true }) public invalid?: boolean; - /** - * @description Describe why the property is invalid. - * @type {boolean} - * @attr - * @default undefined - */ - @property({ type: String, attribute: 'invalid-message' }) - public invalidMessage?: string; - // TODO: put the invalidMessage in some hover tooltip or something. [NL] - render() { // TODO: Only show alias on label if user has access to DocumentType within settings: return html` diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts index c3d3cb72b3..e6397911a7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property/property/property.element.ts @@ -109,10 +109,8 @@ export class UmbPropertyElement extends UmbLitElement { @property({ type: String, attribute: false }) public set dataPath(dataPath: string | undefined) { this.#dataPath = dataPath; - new UmbObserveValidationStateController(this, dataPath, (feedback) => { - // TODO: Join in a pretty way, and localized way(how to join one or more items varies depending on the language. [NL] - // TODO: Also wrap in a general localized message, like "Contains these errors: ..."; [NL] - this._validationMessage = feedback.length > 0 ? feedback.map((x) => x.message).join(', ') : undefined; + new UmbObserveValidationStateController(this, dataPath, (invalid) => { + this._invalid = invalid; }); } public get dataPath(): string | undefined { @@ -127,7 +125,7 @@ export class UmbPropertyElement extends UmbLitElement { private _element?: ManifestPropertyEditorUi['ELEMENT_TYPE']; @state() - private _validationMessage?: string; + private _invalid?: boolean; @state() private _alias?: string; @@ -278,8 +276,7 @@ export class UmbPropertyElement extends UmbLitElement { alias="${ifDefined(this._alias)}" label="${ifDefined(this._label)}" description="${ifDefined(this._description)}" - ?invalid=${this._validationMessage !== undefined} - .invalidMessage=${this._validationMessage}> + ?invalid=${this._invalid}> ${this._renderPropertyActionMenu()} ${this._variantDifference ? html`${this._variantDifference}` From 07d64bdcf27113dd488407858ea1815b4e0660cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 15 Apr 2024 22:15:11 +0200 Subject: [PATCH 05/18] clean up --- .../core/validation/context/validation-messages.manager.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts index 03b31ce790..252f716e92 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/context/validation-messages.manager.ts @@ -34,6 +34,7 @@ export class UmbValidationMessagesManager { return this.#messages.getValue().length !== 0; } + /* messagesOfPathAndDescendant(path: string): Observable> { // Find messages that starts with the given path, if the path is longer then require a dot or [ as the next character. using a more performant way than Regex: return this.#messages.asObservablePart((msgs) => @@ -44,6 +45,7 @@ export class UmbValidationMessagesManager { ), ); } + */ messagesOfTypeAndPath(type: UmbValidationMessageType, path: string): Observable> { // Find messages that matches the given type and path. From dfb7620254bee556d7428f897b55c133af93a73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 15 Apr 2024 22:16:30 +0200 Subject: [PATCH 06/18] use hasMessagesOfPathAndDescendant --- .../controllers/observe-validation-state.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts index e31d8b720f..2b2c66e66a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts @@ -15,7 +15,7 @@ export class UmbObserveValidationStateController extends UmbControllerBase { super(host, CtrlSymbol); if (dataPath) { this.consumeContext(UMB_VALIDATION_CONTEXT, (context) => { - this.observe(context.messages.messagesOfPathAndDescendant(dataPath), callback, ObserveSymbol); + this.observe(context.messages.hasMessagesOfPathAndDescendant(dataPath), callback, ObserveSymbol); }); } } From 040fe1e9f083ebf2c613197a198b7624cbad1b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 15 Apr 2024 22:46:21 +0200 Subject: [PATCH 07/18] boolean --- .../controllers/observe-validation-state.controller.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts index 2b2c66e66a..3c4ee10667 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/controllers/observe-validation-state.controller.ts @@ -1,5 +1,4 @@ import { UMB_VALIDATION_CONTEXT } from '../context/validation.context-token.js'; -import type { UmbValidationMessage } from '../context/validation-messages.manager.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; @@ -7,11 +6,7 @@ const CtrlSymbol = Symbol(); const ObserveSymbol = Symbol(); export class UmbObserveValidationStateController extends UmbControllerBase { - constructor( - host: UmbControllerHost, - dataPath: string | undefined, - callback: (messages: Array) => void, - ) { + constructor(host: UmbControllerHost, dataPath: string | undefined, callback: (messages: boolean) => void) { super(host, CtrlSymbol); if (dataPath) { this.consumeContext(UMB_VALIDATION_CONTEXT, (context) => { From 02cbfb80754225efcd94e3bee34a2ae7ca9b6ec4 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:56:06 +0200 Subject: [PATCH 08/18] check for available providers even earlier --- .../src/apps/app/app-auth.controller.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts index baaceaf0a0..876a63fe03 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts @@ -74,6 +74,10 @@ export class UmbAppAuthController extends UmbControllerBase { // Figure out which providers are available const availableProviders = await firstValueFrom(this.#authContext.getAuthProviders()); + if (availableProviders.length === 0) { + throw new Error('[Fatal] No auth providers available'); + } + // If the user is timed out, we can show the login modal directly if (userLoginState === 'timedOut') { const selected = await this.#showLoginModal(userLoginState, availableProviders); @@ -85,10 +89,6 @@ export class UmbAppAuthController extends UmbControllerBase { return this.#updateState(); } - if (availableProviders.length === 0) { - throw new Error('[Fatal] No auth providers available'); - } - if (availableProviders.length === 1) { // One provider available (most likely the Umbraco provider), so initiate the authorization request to the default provider this.#authContext.makeAuthorizationRequest(availableProviders[0].forProviderName); From 8c74bb2b542d906626ce17ef713943daf6563f8a Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:56:35 +0200 Subject: [PATCH 09/18] use relative import to avoid cyclic dependency --- .../src/packages/core/auth/modals/umb-app-auth-modal.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts index 9fb5122908..897e7ebecc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/modals/umb-app-auth-modal.element.ts @@ -1,7 +1,7 @@ import { UmbModalBaseElement } from '../../modal/index.js'; +import { UmbTextStyles } from '../../style/text-style.style.js'; import type { UmbModalAppAuthConfig, UmbModalAppAuthValue } from './umb-app-auth-modal.token.js'; import { css, customElement, html } from '@umbraco-cms/backoffice/external/lit'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @customElement('umb-app-auth-modal') export class UmbAppAuthModalElement extends UmbModalBaseElement { From aa95ce241f9f0bb33ad8d0b494418771ec259414 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:59:33 +0200 Subject: [PATCH 10/18] fix: make sure the UmbAuthContext receives a reference to the extensions registry and not rely on the instance itself the context is new'ed up before the extensions registry is available --- src/Umbraco.Web.UI.Client/package.json | 7 ++++--- .../src/apps/app/app-auth.controller.ts | 2 +- .../src/packages/core/auth/auth.context.ts | 8 +++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index bd7d764b3f..b427665a06 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -149,6 +149,7 @@ "prepack": "tsc-alias -f -p src/tsconfig.build.json && npm run generate:jsonschema:dist && npm run wc-analyze && npm run wc-analyze:vscode && node ./devops/publish/cleanse-pkg.js", "preview": "vite preview --open", "storybook:build": "npm run wc-analyze && storybook build", + "storybook:preview": "npm run wc-analyze && storybook build && npx serve storybook-static", "storybook": "npm run wc-analyze && storybook dev -p 6006", "test:e2e": "npm run backoffice:test:e2e", "test:dev": "web-test-runner --config ./web-test-runner.dev.config.mjs", @@ -239,9 +240,9 @@ "typedoc": "^0.25.10", "typescript": "^5.3.3", "typescript-json-schema": "^0.63.0", - "vite": "^5.1.7", - "vite-plugin-static-copy": "^1.0.1", - "vite-tsconfig-paths": "^4.3.1", + "vite": "^5.2.9", + "vite-plugin-static-copy": "^1.0.2", + "vite-tsconfig-paths": "^4.3.2", "web-component-analyzer": "^2.0.0" }, "msw": { diff --git a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts index 876a63fe03..370489684d 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/app/app-auth.controller.ts @@ -72,7 +72,7 @@ export class UmbAppAuthController extends UmbControllerBase { } // Figure out which providers are available - const availableProviders = await firstValueFrom(this.#authContext.getAuthProviders()); + const availableProviders = await firstValueFrom(this.#authContext.getAuthProviders(umbExtensionsRegistry)); if (availableProviders.length === 0) { throw new Error('[Fatal] No auth providers available'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts index be37177cc0..370bd3d124 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/auth/auth.context.ts @@ -1,4 +1,4 @@ -import { umbExtensionsRegistry } from '../extension-registry/index.js'; +import type { UmbBackofficeExtensionRegistry, ManifestAuthProvider } from '../extension-registry/index.js'; import { UmbAuthFlow } from './auth-flow.js'; import { UMB_AUTH_CONTEXT } from './auth.context.token.js'; import type { UmbOpenApiConfiguration } from './models/openApiConfiguration.js'; @@ -162,8 +162,10 @@ export class UmbAuthContext extends UmbContextBase { this.#isInitialized.next(true); } - getAuthProviders() { - return this.isInitialized.pipe(switchMap(() => umbExtensionsRegistry.byType('authProvider'))); + getAuthProviders(extensionsRegistry: UmbBackofficeExtensionRegistry) { + return this.isInitialized.pipe( + switchMap(() => extensionsRegistry.byType<'authProvider', ManifestAuthProvider>('authProvider')), + ); } getRedirectUrl() { From 19baa55ba372b3ee35afa99ab33e757db45ca530 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:03:14 +0200 Subject: [PATCH 11/18] upgrade storybook vite dependencies --- src/Umbraco.Web.UI.Client/package-lock.json | 252 +++++++++++--------- 1 file changed, 134 insertions(+), 118 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index ee3c1ade14..16d7b1e953 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -81,9 +81,9 @@ "typedoc": "^0.25.10", "typescript": "^5.3.3", "typescript-json-schema": "^0.63.0", - "vite": "^5.1.7", - "vite-plugin-static-copy": "^1.0.1", - "vite-tsconfig-paths": "^4.3.1", + "vite": "^5.2.9", + "vite-plugin-static-copy": "^1.0.2", + "vite-tsconfig-paths": "^4.3.2", "web-component-analyzer": "^2.0.0" }, "engines": { @@ -17207,9 +17207,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -17228,7 +17228,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -18652,9 +18652,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -19520,9 +19520,9 @@ } }, "node_modules/tsconfck": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.1.tgz", - "integrity": "sha512-7ppiBlF3UEddCLeI1JRx5m2Ryq+xk4JrZuq4EuYXykipebaq1dV0Fhgr1hb7CkmHt32QSgOZlcqVLEtHBG4/mg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.0.3.tgz", + "integrity": "sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==", "dev": true, "bin": { "tsconfck": "bin/tsconfck.js" @@ -20341,14 +20341,14 @@ } }, "node_modules/vite": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.7.tgz", - "integrity": "sha512-sgnEEFTZYMui/sTlH1/XEnVNHMujOahPLGMxn1+5sIT45Xjng1Ec1K78jRP15dSmVgg5WBin9yO81j3o9OxofA==", + "version": "5.2.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.9.tgz", + "integrity": "sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==", "dev": true, "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" @@ -20396,9 +20396,9 @@ } }, "node_modules/vite-plugin-static-copy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.1.tgz", - "integrity": "sha512-3eGL4mdZoPJMDBT68pv/XKIHR4MgVolStIxxv1gIBP4R8TpHn9C9EnaU0hesqlseJ4ycLGUxckFTu/jpuJXQlA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.2.tgz", + "integrity": "sha512-AfmEF+a/mfjsUsrgjbCkhzUCeIUF4EKQXXt3Ie1cour9MBpy6f6GphbdW2td28oYfOrwCyRzFCksgLkpk58q6Q==", "dev": true, "dependencies": { "chokidar": "^3.5.3", @@ -20414,14 +20414,14 @@ } }, "node_modules/vite-tsconfig-paths": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.1.tgz", - "integrity": "sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz", + "integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==", "dev": true, "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", - "tsconfck": "^3.0.1" + "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" @@ -20432,10 +20432,26 @@ } } }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -20449,9 +20465,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -20465,9 +20481,9 @@ } }, "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -20481,9 +20497,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -20497,9 +20513,9 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -20513,9 +20529,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -20529,9 +20545,9 @@ } }, "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -20545,9 +20561,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -20561,9 +20577,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -20577,9 +20593,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -20593,9 +20609,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -20609,9 +20625,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -20625,9 +20641,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -20641,9 +20657,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -20657,9 +20673,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -20673,9 +20689,9 @@ } }, "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -20689,9 +20705,9 @@ } }, "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -20705,9 +20721,9 @@ } }, "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -20721,9 +20737,9 @@ } }, "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -20737,9 +20753,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -20753,9 +20769,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -20769,9 +20785,9 @@ } }, "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -20785,9 +20801,9 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, "bin": { @@ -20797,29 +20813,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/vscode-oniguruma": { From 99d678932b20f540c1f2a67aec36e66a53f5ef8c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Apr 2024 13:24:05 +0200 Subject: [PATCH 12/18] export element class --- .../src/packages/language/components/index.ts | 2 ++ src/Umbraco.Web.UI.Client/src/packages/language/index.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/language/components/index.ts index 7a11bfea9c..6f6f6e19f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/components/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/components/index.ts @@ -1 +1,3 @@ import './input-language/input-language.element.js'; + +export { UmbInputLanguageElement } from './input-language/input-language.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/index.ts b/src/Umbraco.Web.UI.Client/src/packages/language/index.ts index dab1b93f1b..6e58bcd0b4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/index.ts @@ -1,5 +1,7 @@ import './components/index.js'; +export { UmbInputLanguageElement } from './components/index.js'; + export * from './repository/index.js'; export * from './collection/index.js'; export * from './global-contexts/index.js'; From d16396d229c273be698c0506f321d605c3e3b64e Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:24:49 +0200 Subject: [PATCH 13/18] add the new icons folder to the storybook builder so we can serve up icons --- src/Umbraco.Web.UI.Client/.storybook/main.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/.storybook/main.ts b/src/Umbraco.Web.UI.Client/.storybook/main.ts index 47e2a92d14..060d5d4316 100644 --- a/src/Umbraco.Web.UI.Client/.storybook/main.ts +++ b/src/Umbraco.Web.UI.Client/.storybook/main.ts @@ -22,7 +22,14 @@ const config: StorybookConfig = { name: '@storybook/web-components-vite', options: {}, }, - staticDirs: ['../public-assets', '../public'], + staticDirs: [ + '../public-assets', + '../public', + { + from: '../src/packages/core/icon-registry/icons', + to: 'assets/icons', + }, + ], typescript: { check: true, }, From caa2b9bff0eb03cde8979dc4b505e2d7a9415257 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Apr 2024 13:26:33 +0200 Subject: [PATCH 14/18] persist language permissions --- .../user-group-workspace-editor.element.ts | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts index 1677018db2..99a968f205 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts @@ -1,7 +1,7 @@ import type { UmbUserGroupDetailModel } from '../index.js'; import { UMB_USER_GROUP_ENTITY_TYPE } from '../index.js'; import { UMB_USER_GROUP_WORKSPACE_CONTEXT } from './user-group-workspace.context-token.js'; -import type { UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; +import type { UUIBooleanInputEvent, UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; import { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; import { css, html, nothing, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; @@ -14,6 +14,7 @@ import { UMB_ICON_PICKER_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/b import './components/user-group-entity-user-permission-list.element.js'; import './components/user-group-granular-permission-list.element.js'; +import type { UmbInputLanguageElement } from '@umbraco-cms/backoffice/language'; @customElement('umb-user-group-workspace-editor') export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { @@ -29,6 +30,12 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { @state() private _sections: UmbUserGroupDetailModel['sections'] = []; + @state() + private _languages: UmbUserGroupDetailModel['languages'] = []; + + @state() + private _hasAccessToAllLanguages: UmbUserGroupDetailModel['hasAccessToAllLanguages'] = false; + @state() private _documentStartNode?: UmbUserGroupDetailModel['documentStartNode']; @@ -52,6 +59,13 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { this.observe(this.#workspaceContext.name, (value) => (this._name = value), '_observeName'); this.observe(this.#workspaceContext.icon, (value) => (this._icon = value), '_observeIcon'); this.observe(this.#workspaceContext.sections, (value) => (this._sections = value), '_observeSections'); + this.observe(this.#workspaceContext.languages, (value) => (this._languages = value), '_observeLanguages'); + this.observe( + this.#workspaceContext.hasAccessToAllLanguages, + (value) => (this._hasAccessToAllLanguages = value), + '_observeHasAccessToAllLanguages', + ); + this.observe( this.#workspaceContext.documentStartNode, (value) => (this._documentStartNode = value), @@ -70,6 +84,18 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { this.#workspaceContext?.updateProperty('sections', target.selection); } + #onAllowAllLanguagesChange(event: UUIBooleanInputEvent) { + event.stopPropagation(); + const target = event.target; + this.#workspaceContext?.updateProperty('hasAccessToAllLanguages', target.checked); + } + + #onLanguagePermissionChange(event: UmbChangeEvent) { + event.stopPropagation(); + const target = event.target as UmbInputLanguageElement; + this.#workspaceContext?.updateProperty('languages', target.selection); + } + #onDocumentStartNodeChange(event: CustomEvent) { event.stopPropagation(); const target = event.target as UmbInputDocumentElement; @@ -152,6 +178,7 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { return html`
+ @@ -160,6 +187,9 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { .selection=${this._sections} @change=${this.#onSectionsChange}> + + ${this.#renderLanguagePermissions()} + @@ -169,6 +199,7 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { .selection=${this._documentStartNode?.unique ? [this._documentStartNode.unique] : []} @change=${this.#onDocumentStartNodeChange}> + @@ -195,6 +226,31 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { `; } + #renderLanguagePermissions() { + return html` + +
+ + + ${this._hasAccessToAllLanguages === false + ? html` + + ` + : nothing} +
+
+ `; + } + #renderRightColumn() { return html` Date: Tue, 16 Apr 2024 13:27:38 +0200 Subject: [PATCH 15/18] cleanup --- .../user-group/workspace/user-group-workspace-editor.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts index 99a968f205..fcc6b523ac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts @@ -11,10 +11,10 @@ import type { UmbInputSectionElement } from '@umbraco-cms/backoffice/section'; import type { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import type { UmbInputMediaElement } from '@umbraco-cms/backoffice/media'; import { UMB_ICON_PICKER_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import type { UmbInputLanguageElement } from '@umbraco-cms/backoffice/language'; import './components/user-group-entity-user-permission-list.element.js'; import './components/user-group-granular-permission-list.element.js'; -import type { UmbInputLanguageElement } from '@umbraco-cms/backoffice/language'; @customElement('umb-user-group-workspace-editor') export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { From d109d45e3b7c9f2c6d90f6e0c28cd274e31f8985 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 16 Apr 2024 13:30:11 +0200 Subject: [PATCH 16/18] no need to double slot --- .../user-group/workspace/user-group-workspace-editor.element.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts index fcc6b523ac..f3f794a314 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/workspace/user-group-workspace-editor.element.ts @@ -241,7 +241,6 @@ export class UmbUserGroupWorkspaceEditorElement extends UmbLitElement { ${this._hasAccessToAllLanguages === false ? html` ` From d8dd78dd4ffb6bc07710057b63912a36d8798446 Mon Sep 17 00:00:00 2001 From: Lone Iversen <108085781+loivsen@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:56:33 +0200 Subject: [PATCH 17/18] Bugfix: Create a document when no blueprint available --- .../create/document-create-options-modal.element.ts | 5 ++--- .../documents/workspace/document-workspace.context.ts | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts index eb4361a1ec..da98aa2e2f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts @@ -78,7 +78,7 @@ export class UmbDocumentCreateOptionsModalElement extends UmbModalBaseElement< history.pushState( null, '', - `section/content/workspace/document/create/parent/${this.data?.parent.entityType}/${this.data?.parent.unique ?? 'null'}/${documentTypeUnique}/${blueprintUnique}`, + `section/content/workspace/document/create/parent/${this.data?.parent.entityType}/${this.data?.parent.unique ?? 'null'}/${documentTypeUnique}/blueprint/${blueprintUnique}`, ); } this._submitModal(); @@ -90,9 +90,8 @@ export class UmbDocumentCreateOptionsModalElement extends UmbModalBaseElement< /** TODO: Fix this to use the correct endpoint when it becomes available */ const { data } = await this.#documentBlueprintItemRepository.requestItems([]); - if (!data?.length) return; - this._availableBlueprints = data.filter((blueprint) => blueprint.documentType.unique === documentTypeUnique); + this._availableBlueprints = data?.filter((blueprint) => blueprint.documentType.unique === documentTypeUnique) ?? []; if (!this._availableBlueprints.length) { this.#onNavigate(documentTypeUnique); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index c41e96a116..30c3780d38 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -160,7 +160,7 @@ export class UmbDocumentWorkspaceContext this.routes.setRoutes([ { - path: 'create/parent/:entityType/:parentUnique/:documentTypeUnique/:blueprintUnique', + path: 'create/parent/:entityType/:parentUnique/:documentTypeUnique/blueprint/:blueprintUnique', component: () => import('./document-workspace-editor.element.js'), setup: async (_component, info) => { const parentEntityType = info.match.params.entityType; @@ -248,8 +248,7 @@ export class UmbDocumentWorkspaceContext this.resetState(); this.#parent.setValue(parent); - /**TODO Explore bug: A way to make blueprintUnique undefined/null when no unique is given, rather than setting it to invariant */ - if (blueprintUnique && blueprintUnique.toLowerCase() !== 'invariant') { + if (blueprintUnique) { const { data } = await this.#blueprintRepository.requestByUnique(blueprintUnique); this.#getDataPromise = this.repository.createScaffold({ From ccd64c8d66166b358c2e65153cb7a9f5c02cd417 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:14:42 +0200 Subject: [PATCH 18/18] bump version to 14.0.0-rc1 --- src/Umbraco.Web.UI.Client/package-lock.json | 4 ++-- src/Umbraco.Web.UI.Client/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 16d7b1e953..f62365f367 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -1,12 +1,12 @@ { "name": "@umbraco-cms/backoffice", - "version": "14.0.0-beta004", + "version": "14.0.0-rc1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@umbraco-cms/backoffice", - "version": "14.0.0-beta004", + "version": "14.0.0-rc1", "license": "MIT", "dependencies": { "@types/diff": "^5.0.9", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index b427665a06..fb41cc1d76 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -1,7 +1,7 @@ { "name": "@umbraco-cms/backoffice", "license": "MIT", - "version": "14.0.0-beta004", + "version": "14.0.0-rc1", "type": "module", "exports": { ".": null,