Skip to content

Commit 60c6366

Browse files
committed
publish modal, require not published mandatory languages
1 parent a07f6d9 commit 60c6366

File tree

4 files changed

+71
-23
lines changed

4 files changed

+71
-23
lines changed

src/packages/documents/documents/modals/publish-modal/document-publish-modal.element.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../../types.js';
2+
import { isNotPublishedMandatory } from '../utils.js';
23
import type { UmbDocumentPublishModalData, UmbDocumentPublishModalValue } from './document-publish-modal.token.js';
34
import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit';
45
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
@@ -17,6 +18,9 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement<
1718
@state()
1819
_options: Array<UmbDocumentVariantOptionModel> = [];
1920

21+
@state()
22+
_hasNotSelectedMandatory?: boolean;
23+
2024
override firstUpdated() {
2125
this.#configureSelectionManager();
2226
}
@@ -25,25 +29,40 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement<
2529
this.#selectionManager.setMultiple(true);
2630
this.#selectionManager.setSelectable(true);
2731

28-
// Only display variants that are relevant to pick from, i.e. variants that are draft or published with pending changes:
32+
// Only display variants that are relevant to pick from, i.e. variants that are draft, not-published-mandatory or published with pending changes:
2933
this._options =
3034
this.data?.options.filter(
31-
(option) => option.variant && option.variant.state !== UmbDocumentVariantState.NOT_CREATED,
35+
(option) => isNotPublishedMandatory(option) || option.variant?.state !== UmbDocumentVariantState.NOT_CREATED,
3236
) ?? [];
3337

3438
let selected = this.value?.selection ?? [];
3539

3640
// Filter selection based on options:
3741
selected = selected.filter((s) => this._options.some((o) => o.unique === s));
3842

39-
this.#selectionManager.setSelection(selected);
40-
4143
// Additionally select mandatory languages:
44+
// [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.
45+
/*
4246
this._options.forEach((variant) => {
4347
if (variant.language?.isMandatory) {
44-
this.#selectionManager.select(variant.unique);
48+
selected.push(variant.unique);
4549
}
4650
});
51+
*/
52+
53+
this.#selectionManager.setSelection(selected);
54+
55+
this.observe(
56+
this.#selectionManager.selection,
57+
(selection: Array<string>) => {
58+
if (!this._options && !selection) return;
59+
60+
//Getting not published mandatory options — the options that are mandatory and not currently published.
61+
const missingMandatoryOptions = this._options.filter(isNotPublishedMandatory);
62+
this._hasNotSelectedMandatory = missingMandatoryOptions.some((option) => !selection.includes(option.unique));
63+
},
64+
'observeSelection',
65+
);
4766
}
4867

4968
#submit() {
@@ -63,6 +82,7 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement<
6382
<umb-document-variant-language-picker
6483
.selectionManager=${this.#selectionManager}
6584
.variantLanguageOptions=${this._options}
85+
.requiredFilter=${isNotPublishedMandatory}
6686
.pickableFilter=${this.data?.pickableFilter}></umb-document-variant-language-picker>
6787
6888
<div slot="actions">
@@ -71,6 +91,7 @@ export class UmbDocumentPublishModalElement extends UmbModalBaseElement<
7191
label="${this.localize.term('buttons_saveAndPublish')}"
7292
look="primary"
7393
color="positive"
94+
?disabled=${this._hasNotSelectedMandatory}
7495
@click=${this.#submit}></uui-button>
7596
</div>
7697
</umb-body-layout> `;

src/packages/documents/documents/modals/shared/document-variant-language-picker.element.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement {
2525
this.#selectionManager = value;
2626
this.observe(
2727
this.selectionManager.selection,
28-
async (selection) => {
28+
(selection) => {
2929
this._selection = selection;
3030
},
3131
'_selectionManager',
@@ -46,6 +46,14 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement {
4646
@property({ attribute: false })
4747
public pickableFilter?: (item: UmbDocumentVariantOptionModel) => boolean;
4848

49+
/**
50+
* A filter function that determines if an item should be highlighted as a must select.
51+
* @memberof UmbDocumentVariantLanguagePickerElement
52+
* @returns {boolean} - True if the item is pickableFilter, false otherwise.
53+
*/
54+
@property({ attribute: false })
55+
public requiredFilter?: (item: UmbDocumentVariantOptionModel) => boolean;
56+
4957
protected override updated(_changedProperties: PropertyValues): void {
5058
super.updated(_changedProperties);
5159

@@ -71,25 +79,28 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement {
7179

7280
#renderItem(option: UmbDocumentVariantOptionModel) {
7381
const pickable = this.pickableFilter ? this.pickableFilter(option) : () => true;
82+
const selected = this._selection.includes(option.unique);
83+
const mustSelect = (!selected && this.requiredFilter?.(option)) ?? false;
7484
return html`
7585
<uui-menu-item
86+
class=${mustSelect ? 'required' : ''}
7687
?selectable=${pickable}
7788
?disabled=${!pickable}
7889
label=${option.variant?.name ?? option.language.name}
7990
@selected=${() => this.selectionManager.select(option.unique)}
8091
@deselected=${() => this.selectionManager.deselect(option.unique)}
81-
?selected=${this._selection.includes(option.unique)}>
92+
?selected=${selected}>
8293
<uui-icon slot="icon" name="icon-globe"></uui-icon>
83-
${UmbDocumentVariantLanguagePickerElement.renderLabel(option)}
94+
${this.renderLabel(option, mustSelect)}
8495
</uui-menu-item>
8596
`;
8697
}
8798

88-
static renderLabel(option: UmbDocumentVariantOptionModel) {
99+
renderLabel(option: UmbDocumentVariantOptionModel, mustSelect: boolean) {
89100
return html`<div class="label" slot="label">
90101
<strong> ${option.language.name} </strong>
91102
<div class="label-status">${UmbDocumentVariantLanguagePickerElement.renderVariantStatus(option)}</div>
92-
${option.language.isMandatory && option.variant?.state !== UmbDocumentVariantState.PUBLISHED
103+
${option.language.isMandatory && mustSelect
93104
? html`<div class="label-status">
94105
<umb-localize key="languages_mandatoryLanguage">Mandatory language</umb-localize>
95106
</div>`
@@ -106,17 +117,17 @@ export class UmbDocumentVariantLanguagePickerElement extends UmbLitElement {
106117
case UmbDocumentVariantState.DRAFT:
107118
return html`<umb-localize key="content_unpublished">Draft</umb-localize>`;
108119
case UmbDocumentVariantState.NOT_CREATED:
109-
return html`<umb-localize key="content_notCreated">Not created</umb-localize>`;
110120
default:
111-
return nothing;
121+
return html`<umb-localize key="content_notCreated">Not created</umb-localize>`;
112122
}
113123
}
114124

115125
static override styles = [
116126
UmbTextStyles,
117127
css`
118-
#subtitle {
119-
margin-top: 0;
128+
.required {
129+
color: var(--uui-color-danger);
130+
--uui-menu-item-color-hover: var(--uui-color-danger-emphasis);
120131
}
121132
.label {
122133
padding: 0.5rem 0;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../types.js';
2+
3+
/**
4+
* @function isNotPublishedMandatory
5+
* @param {UmbDocumentVariantOptionModel} option - the option to check.
6+
* @returns {boolean} boolean
7+
*/
8+
export function isNotPublishedMandatory(option: UmbDocumentVariantOptionModel): boolean {
9+
return (
10+
option.language.isMandatory &&
11+
option.variant?.state !== UmbDocumentVariantState.PUBLISHED &&
12+
option.variant?.state !== UmbDocumentVariantState.PUBLISHED_PENDING_CHANGES
13+
);
14+
}

src/packages/documents/documents/workspace/document-workspace.context.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -489,23 +489,21 @@ export class UmbDocumentWorkspaceContext
489489
};
490490

491491
async #determineVariantOptions() {
492-
const activeVariants = this.splitView.getActiveVariants();
492+
const options = await firstValueFrom(this.variantOptions);
493493

494+
const activeVariants = this.splitView.getActiveVariants();
494495
const activeVariantIds = activeVariants.map((activeVariant) => UmbVariantId.Create(activeVariant));
495-
// TODO: We need to filter the selected array, so it only contains one of each variantId. [NL]
496496
const changedVariantIds = this.#data.getChangedVariants();
497-
const selected = activeVariantIds.concat(changedVariantIds);
498-
// Selected can contain entries that are not part of the options, therefor the modal filters selection based on options.
497+
const selectedVariantIds = activeVariantIds.concat(changedVariantIds);
499498

499+
// Selected can contain entries that are not part of the options, therefor the modal filters selection based on options.
500500
const readOnlyCultures = this.readOnlyState.getStates().map((s) => s.variantId.culture);
501-
const selectedCultures = selected.map((x) => x.toString()).filter((v, i, a) => a.indexOf(v) === i);
502-
const writable = selectedCultures.filter((x) => readOnlyCultures.includes(x) === false);
503-
504-
const options = await firstValueFrom(this.variantOptions);
501+
let selected = selectedVariantIds.map((x) => x.toString()).filter((v, i, a) => a.indexOf(v) === i);
502+
selected = selected.filter((x) => readOnlyCultures.includes(x) === false);
505503

506504
return {
507505
options,
508-
selected: writable,
506+
selected,
509507
};
510508
}
511509

@@ -787,6 +785,8 @@ export class UmbDocumentWorkspaceContext
787785

788786
if (!result?.selection.length) return;
789787

788+
// TODO: Validate content & Save changes for the selected variants? — Or be clear that changes are not part of this action. [NL]
789+
790790
// Map to the correct format for the API (UmbDocumentVariantPublishModel)
791791
const variants =
792792
result?.selection.map<UmbDocumentVariantPublishModel>((x) => ({
@@ -833,6 +833,8 @@ export class UmbDocumentWorkspaceContext
833833

834834
if (!variantIds.length) return;
835835

836+
// TODO: Validate content & Save changes for the selected variants? — Or be clear that changes are not part of this action. [NL]
837+
836838
const unique = this.getUnique();
837839
if (!unique) throw new Error('Unique is missing');
838840
await this.publishingRepository.publishWithDescendants(

0 commit comments

Comments
 (0)