From 9242047f95bbe5e86755824f7069477b5fa8fb4f Mon Sep 17 00:00:00 2001 From: EmanuelGustafzon Date: Sat, 10 Aug 2024 12:51:43 +0200 Subject: [PATCH 01/12] add local time for when user logged in last --- .../collection/views/grid/user-grid-collection-view.element.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts index 00a816ed97..ff5448c4ed 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/collection/views/grid/user-grid-collection-view.element.ts @@ -148,10 +148,13 @@ export class UmbUserGridCollectionViewElement extends UmbLitElement { if (!user.lastLoginDate) { return html`
${`${user.name} ${this.localize.term('user_noLogin')}`}
`; } + const lastLoggedinLocalTime: Date = new Date(user.lastLoginDate); + const formattedTime = lastLoggedinLocalTime.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); return html`

${this.localize.date(user.lastLoginDate)} + ${formattedTime}
`; } From b39670716c2247cdba0d2a327eba58720f633285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:12:28 +0200 Subject: [PATCH 02/12] publish modal, require not published mandatory languages --- .../document-publish-modal.element.ts | 31 ++++++++++++++++--- ...ocument-variant-language-picker.element.ts | 29 +++++++++++------ .../documents/documents/modals/utils.ts | 14 +++++++++ .../workspace/document-workspace.context.ts | 28 +++++++++-------- 4 files changed, 75 insertions(+), 27 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/utils.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-modal/document-publish-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-modal/document-publish-modal.element.ts index ce6e111fa3..6fd010b295 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-modal/document-publish-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-modal/document-publish-modal.element.ts @@ -1,4 +1,5 @@ import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../../types.js'; +import { isNotPublishedMandatory } from '../utils.js'; import type { UmbDocumentPublishModalData, UmbDocumentPublishModalValue } from './document-publish-modal.token.js'; import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; @@ -17,6 +18,9 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement< @state() _options: Array = []; + @state() + _hasNotSelectedMandatory?: boolean; + override firstUpdated() { this.#configureSelectionManager(); } @@ -25,10 +29,10 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement< this.#selectionManager.setMultiple(true); this.#selectionManager.setSelectable(true); - // Only display variants that are relevant to pick from, i.e. variants that are draft or published with pending changes: + // Only display variants that are relevant to pick from, i.e. variants that are draft, not-published-mandatory or published with pending changes: this._options = this.data?.options.filter( - (option) => option.variant && option.variant.state !== UmbDocumentVariantState.NOT_CREATED, + (option) => isNotPublishedMandatory(option) || option.variant?.state !== UmbDocumentVariantState.NOT_CREATED, ) ?? []; let selected = this.value?.selection ?? []; @@ -36,14 +40,29 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement< // Filter selection based on options: selected = selected.filter((s) => this._options.some((o) => o.unique === s)); - this.#selectionManager.setSelection(selected); - // Additionally select mandatory languages: + // [NL]: I think for now lets make it an active choice to select the languages. If you just made them, they would be selected. So it just to underline the act of actually selecting these languages. + /* this._options.forEach((variant) => { if (variant.language?.isMandatory) { - this.#selectionManager.select(variant.unique); + selected.push(variant.unique); } }); + */ + + this.#selectionManager.setSelection(selected); + + this.observe( + this.#selectionManager.selection, + (selection: Array) => { + if (!this._options && !selection) return; + + //Getting not published mandatory options — the options that are mandatory and not currently published. + const missingMandatoryOptions = this._options.filter(isNotPublishedMandatory); + this._hasNotSelectedMandatory = missingMandatoryOptions.some((option) => !selection.includes(option.unique)); + }, + 'observeSelection', + ); } #submit() { @@ -63,6 +82,7 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement<
@@ -71,6 +91,7 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement< label="${this.localize.term('buttons_saveAndPublish')}" look="primary" color="positive" + ?disabled=${this._hasNotSelectedMandatory} @click=${this.#submit}>
`; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts index ccfd6c36d4..49d878e16c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts @@ -25,7 +25,7 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement { this.#selectionManager = value; this.observe( this.selectionManager.selection, - async (selection) => { + (selection) => { this._selection = selection; }, '_selectionManager', @@ -46,6 +46,14 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement { @property({ attribute: false }) public pickableFilter?: (item: UmbDocumentVariantOptionModel) => boolean; + /** + * A filter function that determines if an item should be highlighted as a must select. + * @memberof UmbDocumentVariantLanguagePickerElement + * @returns {boolean} - True if the item is pickableFilter, false otherwise. + */ + @property({ attribute: false }) + public requiredFilter?: (item: UmbDocumentVariantOptionModel) => boolean; + protected override updated(_changedProperties: PropertyValues): void { super.updated(_changedProperties); @@ -71,25 +79,28 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement { #renderItem(option: UmbDocumentVariantOptionModel) { const pickable = this.pickableFilter ? this.pickableFilter(option) : () => true; + const selected = this._selection.includes(option.unique); + const mustSelect = (!selected && this.requiredFilter?.(option)) ?? false; return html` this.selectionManager.select(option.unique)} @deselected=${() => this.selectionManager.deselect(option.unique)} - ?selected=${this._selection.includes(option.unique)}> + ?selected=${selected}> - ${UmbDocumentVariantLanguagePickerElement.renderLabel(option)} + ${this.renderLabel(option, mustSelect)} `; } - static renderLabel(option: UmbDocumentVariantOptionModel) { + renderLabel(option: UmbDocumentVariantOptionModel, mustSelect: boolean) { return html`
${option.language.name}
${UmbDocumentVariantLanguagePickerElement.renderVariantStatus(option)}
- ${option.language.isMandatory && option.variant?.state !== UmbDocumentVariantState.PUBLISHED + ${option.language.isMandatory && mustSelect ? html`
Mandatory language
` @@ -106,17 +117,17 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement { case UmbDocumentVariantState.DRAFT: return html`Draft`; case UmbDocumentVariantState.NOT_CREATED: - return html`Not created`; default: - return nothing; + return html`Not created`; } } static override styles = [ UmbTextStyles, css` - #subtitle { - margin-top: 0; + .required { + color: var(--uui-color-danger); + --uui-menu-item-color-hover: var(--uui-color-danger-emphasis); } .label { padding: 0.5rem 0; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/utils.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/utils.ts new file mode 100644 index 0000000000..c5457fe1b9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/utils.ts @@ -0,0 +1,14 @@ +import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../types.js'; + +/** + * @function isNotPublishedMandatory + * @param {UmbDocumentVariantOptionModel} option - the option to check. + * @returns {boolean} boolean + */ +export function isNotPublishedMandatory(option: UmbDocumentVariantOptionModel): boolean { + return ( + option.language.isMandatory && + option.variant?.state !== UmbDocumentVariantState.PUBLISHED && + option.variant?.state !== UmbDocumentVariantState.PUBLISHED_PENDING_CHANGES + ); +} 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 a082d780ae..17a2d3e0ce 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 @@ -489,23 +489,21 @@ export class UmbDocumentWorkspaceContext }; async #determineVariantOptions() { - const activeVariants = this.splitView.getActiveVariants(); - - const activeVariantIds = activeVariants.map((activeVariant) => UmbVariantId.Create(activeVariant)); - // TODO: We need to filter the selected array, so it only contains one of each variantId. [NL] - const changedVariantIds = this.#data.getChangedVariants(); - const selected = activeVariantIds.concat(changedVariantIds); - // Selected can contain entries that are not part of the options, therefor the modal filters selection based on options. - - const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture); - const selectedCultures = selected.map((x) => x.toString()).filter((v, i, a) => a.indexOf(v) === i); - const writable = selectedCultures.filter((x) => readOnlyCultures.includes(x) === false); - const options = await firstValueFrom(this.variantOptions); + const activeVariants = this.splitView.getActiveVariants(); + const activeVariantIds = activeVariants.map((activeVariant) => UmbVariantId.Create(activeVariant)); + const changedVariantIds = this.#data.getChangedVariants(); + const selectedVariantIds = activeVariantIds.concat(changedVariantIds); + + // Selected can contain entries that are not part of the options, therefor the modal filters selection based on options. + const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture); + let selected = selectedVariantIds.map((x) => x.toString()).filter((v, i, a) => a.indexOf(v) === i); + selected = selected.filter((x) => readOnlyCultures.includes(x) === false); + return { options, - selected: writable, + selected, }; } @@ -787,6 +785,8 @@ export class UmbDocumentWorkspaceContext if (!result?.selection.length) return; + // TODO: Validate content & Save changes for the selected variants? — Or be clear that changes are not part of this action. [NL] + // Map to the correct format for the API (UmbDocumentVariantPublishModel) const variants = result?.selection.map((x) => ({ @@ -833,6 +833,8 @@ export class UmbDocumentWorkspaceContext if (!variantIds.length) return; + // TODO: Validate content & Save changes for the selected variants? — Or be clear that changes are not part of this action. [NL] + const unique = this.getUnique(); if (!unique) throw new Error('Unique is missing'); await this.publishingRepository.publishWithDescendants( From 8b2228594acceea0da7d0f15813cd56838eb32d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:13:05 +0200 Subject: [PATCH 03/12] publish with descendants require mandatory languages --- ...-publish-with-descendants-modal.element.ts | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts index 1c1899711c..c9cb75c085 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/publish-with-descendants-modal/document-publish-with-descendants-modal.element.ts @@ -1,4 +1,5 @@ import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../../types.js'; +import { isNotPublishedMandatory } from '../utils.js'; import type { UmbDocumentPublishWithDescendantsModalData, UmbDocumentPublishWithDescendantsModalValue, @@ -21,6 +22,9 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE @state() _options: Array = []; + @state() + _hasNotSelectedMandatory?: boolean; + override firstUpdated() { this.#configureSelectionManager(); } @@ -29,10 +33,10 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE this.#selectionManager.setMultiple(true); this.#selectionManager.setSelectable(true); - // Only display variants that are relevant to pick from, i.e. variants that are draft or published with pending changes: + // Only display variants that are relevant to pick from, i.e. variants that are draft, not-published-mandatory or published with pending changes: this._options = this.data?.options.filter( - (option) => option.variant && option.variant.state !== UmbDocumentVariantState.NOT_CREATED, + (option) => isNotPublishedMandatory(option) || option.variant?.state !== UmbDocumentVariantState.NOT_CREATED, ) ?? []; let selected = this.value?.selection ?? []; @@ -40,14 +44,29 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE // Filter selection based on options: selected = selected.filter((s) => this._options.some((o) => o.unique === s)); - this.#selectionManager.setSelection(selected); - // Additionally select mandatory languages: + // [NL]: I think for now lets make it an active choice to select the languages. If you just made them, they would be selected. So it just to underline the act of actually selecting these languages. + /* this._options.forEach((variant) => { if (variant.language?.isMandatory) { - this.#selectionManager.select(variant.unique); + selected.push(variant.unique); } }); + */ + + this.#selectionManager.setSelection(selected); + + this.observe( + this.#selectionManager.selection, + (selection: Array) => { + if (!this._options && !selection) return; + + //Getting not published mandatory options — the options that are mandatory and not currently published. + const missingMandatoryOptions = this._options.filter(isNotPublishedMandatory); + this._hasNotSelectedMandatory = missingMandatoryOptions.some((option) => !selection.includes(option.unique)); + }, + 'observeSelection', + ); } #submit() { @@ -83,6 +102,7 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE @@ -99,6 +119,7 @@ export class UmbDocumentPublishWithDescendantsModalElement extends UmbModalBaseE label="${this.localize.term('buttons_publishDescendants')}" look="primary" color="positive" + ?disabled=${this._hasNotSelectedMandatory} @click=${this.#submit}>
`; From e7d838f29db46be8282f59d79e39d01aacfeefb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:39:33 +0200 Subject: [PATCH 04/12] make static again --- .../modals/shared/document-variant-language-picker.element.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts index 49d878e16c..97eea72eeb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts @@ -91,12 +91,12 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement { @deselected=${() => this.selectionManager.deselect(option.unique)} ?selected=${selected}> - ${this.renderLabel(option, mustSelect)} + ${UmbDocumentVariantLanguagePickerElement.renderLabel(option, mustSelect)} `; } - renderLabel(option: UmbDocumentVariantOptionModel, mustSelect: boolean) { + static renderLabel(option: UmbDocumentVariantOptionModel, mustSelect?: boolean) { return html`
${option.language.name}
${UmbDocumentVariantLanguagePickerElement.renderVariantStatus(option)}
From 14b0a8b7dfee74bf668bda60f9289dc09de39c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:39:39 +0200 Subject: [PATCH 05/12] JSDocs --- .../workspace/document-workspace.context.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 17a2d3e0ce..96e427d399 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 @@ -418,9 +418,9 @@ export class UmbDocumentWorkspaceContext /** * @function propertyValueByAlias - * @param {string} propertyAlias - * @param {UmbVariantId} variantId - * @returns {Promise | undefined>} + * @param {string} propertyAlias - The alias of the property + * @param {UmbVariantId} variantId - The variant + * @returns {Promise | undefined>} - An observable for the value of the property * @description Get an Observable for the value of this property. */ async propertyValueByAlias( @@ -436,9 +436,9 @@ export class UmbDocumentWorkspaceContext /** * Get the current value of the property with the given alias and variantId. - * @param alias - * @param variantId - * @returns The value or undefined if not set or found. + * @param {string} alias - The alias of the property + * @param {UmbVariantId | undefined} variantId - The variant id of the property + * @returns {ReturnType | undefined} The value or undefined if not set or found. */ getPropertyValue(alias: string, variantId?: UmbVariantId) { const currentData = this.#data.getCurrent(); From a8659208f447c6ffb589ed50a7b70e3aa48008bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:44:21 +0200 Subject: [PATCH 06/12] mark word as begin okay --- src/Umbraco.Web.UI.Client/.vscode/settings.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/.vscode/settings.json b/src/Umbraco.Web.UI.Client/.vscode/settings.json index be101f1365..840f194429 100644 --- a/src/Umbraco.Web.UI.Client/.vscode/settings.json +++ b/src/Umbraco.Web.UI.Client/.vscode/settings.json @@ -26,6 +26,7 @@ "Uncategorized", "uninitialize", "unprovide", + "Unpublishing", "variantable" ], "exportall.config.folderListener": [], From 2baf64597bf56d4774f485f8d03d05a4522713bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:44:33 +0200 Subject: [PATCH 07/12] TODO --- .../modals/schedule-modal/document-schedule-modal.element.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts index dc850eb0ad..9665b023c0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/schedule-modal/document-schedule-modal.element.ts @@ -51,6 +51,7 @@ export class UmbDocumentScheduleModalElement extends UmbModalBaseElement< } // Only display variants that are relevant to pick from, i.e. variants that are draft or published with pending changes: + // TODO:[NL] I would say we should change this, the act of scheduling should be equivalent to save & publishing. Resulting in content begin saved as part of carrying out the action. (But this requires a update in the workspace.) this._options = this.data?.options.filter( (option) => option.variant && option.variant.state !== UmbDocumentVariantState.NOT_CREATED, From 1c76ed4e18f9b34694f95532ae986f21cf9b0736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:44:56 +0200 Subject: [PATCH 08/12] require all or no mandatory for unpublishing --- .../document-unpublish-modal.element.ts | 59 ++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/unpublish-modal/document-unpublish-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/unpublish-modal/document-unpublish-modal.element.ts index 141b7cfbc6..e9a32c905c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/unpublish-modal/document-unpublish-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/unpublish-modal/document-unpublish-modal.element.ts @@ -12,48 +12,72 @@ import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; import '../shared/document-variant-language-picker.element.js'; +/** + * @function isPublished + * @param {UmbDocumentVariantOptionModel} option - the option to check. + * @returns {boolean} boolean + */ +export function isPublished(option: UmbDocumentVariantOptionModel): boolean { + return ( + option.variant?.state === UmbDocumentVariantState.PUBLISHED || + option.variant?.state === UmbDocumentVariantState.PUBLISHED_PENDING_CHANGES + ); +} + @customElement('umb-document-unpublish-modal') export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< UmbDocumentUnpublishModalData, UmbDocumentUnpublishModalValue > { - #selectionManager = new UmbSelectionManager(this); + protected readonly _selectionManager = new UmbSelectionManager(this); #referencesRepository = new UmbDocumentReferenceRepository(this); @state() _options: Array = []; + @state() + _selection: Array = []; + @state() _hasReferences = false; @state() _hasUnpublishPermission = true; + @state() + _hasInvalidSelection = true; + override firstUpdated() { this.#configureSelectionManager(); this.#getReferences(); } async #configureSelectionManager() { - this.#selectionManager.setMultiple(true); - this.#selectionManager.setSelectable(true); + this._selectionManager.setMultiple(true); + this._selectionManager.setSelectable(true); // Only display variants that are relevant to pick from, i.e. variants that are draft or published with pending changes: - this._options = - this.data?.options.filter( - (option) => - option.variant && - (!option.variant.state || - option.variant.state === UmbDocumentVariantState.PUBLISHED || - option.variant.state === UmbDocumentVariantState.PUBLISHED_PENDING_CHANGES), - ) ?? []; + this._options = this.data?.options.filter((option) => isPublished(option)) ?? []; let selected = this.value?.selection ?? []; // Filter selection based on options: selected = selected.filter((s) => this._options.some((o) => o.unique === s)); - this.#selectionManager.setSelection(selected); + this._selectionManager.setSelection(selected); + + this.observe( + this._selectionManager.selection, + (selection) => { + this._selection = selection; + const selectionHasMandatory = this._options.some((o) => o.language.isMandatory && selection.includes(o.unique)); + const selectionDoesNotHaveAllMandatory = this._options.some( + (o) => o.language.isMandatory && !selection.includes(o.unique), + ); + this._hasInvalidSelection = selectionHasMandatory && selectionDoesNotHaveAllMandatory; + }, + 'observeSelection', + ); } async #getReferences() { @@ -80,7 +104,7 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< #submit() { if (this._hasUnpublishPermission) { - this.value = { selection: this.#selectionManager.getSelection() }; + this.value = { selection: this._selection }; this.modalContext?.submit(); return; } @@ -91,6 +115,10 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< this.modalContext?.reject(); } + private _requiredFilter = (variantOption: UmbDocumentVariantOptionModel): boolean => { + return variantOption.language.isMandatory && !this._selection.includes(variantOption.unique); + }; + override render() { return html`

@@ -100,8 +128,9 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<

@@ -130,7 +159,7 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement< From d0bbc7e85097329aacd3a35f157c62320c0a8ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:48:33 +0200 Subject: [PATCH 09/12] Update settings.json --- src/Umbraco.Web.UI.Client/.vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/.vscode/settings.json b/src/Umbraco.Web.UI.Client/.vscode/settings.json index 840f194429..2b3d645ee9 100644 --- a/src/Umbraco.Web.UI.Client/.vscode/settings.json +++ b/src/Umbraco.Web.UI.Client/.vscode/settings.json @@ -26,7 +26,7 @@ "Uncategorized", "uninitialize", "unprovide", - "Unpublishing", + "unpublishing", "variantable" ], "exportall.config.folderListener": [], From 1f76a3a2998fd2bbaed2a4145302f960739d49dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 20:57:04 +0200 Subject: [PATCH 10/12] use nothing --- .../modals/shared/document-variant-language-picker.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts index 97eea72eeb..6e7bda4068 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts @@ -104,7 +104,7 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement { ? html`

Mandatory language
` - : ''} + : nothing}
`; } From 65fa26a440454e68e7f6f4b0bf768867e2d90205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 3 Oct 2024 21:04:07 +0200 Subject: [PATCH 11/12] move comments --- .../documents/workspace/document-workspace.context.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 96e427d399..8f1da5da13 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 @@ -785,8 +785,6 @@ export class UmbDocumentWorkspaceContext if (!result?.selection.length) return; - // TODO: Validate content & Save changes for the selected variants? — Or be clear that changes are not part of this action. [NL] - // Map to the correct format for the API (UmbDocumentVariantPublishModel) const variants = result?.selection.map((x) => ({ @@ -796,6 +794,8 @@ export class UmbDocumentWorkspaceContext if (!variants.length) return; + // TODO: Validate content & Save changes for the selected variants — This was how it worked in v.13 [NL] + const unique = this.getUnique(); if (!unique) throw new Error('Unique is missing'); await this.publishingRepository.publish(unique, variants); @@ -833,7 +833,7 @@ export class UmbDocumentWorkspaceContext if (!variantIds.length) return; - // TODO: Validate content & Save changes for the selected variants? — Or be clear that changes are not part of this action. [NL] + // TODO: Validate content & Save changes for the selected variants — This was how it worked in v.13 [NL] const unique = this.getUnique(); if (!unique) throw new Error('Unique is missing'); From c6ebbc706bf7dc3e4a841aeb5a0fa87085268045 Mon Sep 17 00:00:00 2001 From: asawyermarathon <87725234+asawyermarathon@users.noreply.github.com> Date: Fri, 4 Oct 2024 02:58:22 -0400 Subject: [PATCH 12/12] feat: Added more padding/gap in context menu, #16696 (#2407) --- .../section-sidebar-context-menu.element.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts index f8630085e4..55c96788cc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-sidebar-context-menu/section-sidebar-context-menu.element.ts @@ -154,6 +154,9 @@ export class UmbSectionSidebarContextMenuElement extends UmbLitElement { display: flex; align-items: center; } + #action-modal umb-entity-action-list{ + --uui-menu-item-flat-structure: 0; + } `, ]; }