Unpublish Document: Align UX of referenced items with trash and delete (#18860)
* Added member reference type model. * Updated client-side types and sdk. * Render member relations on the member info view. * Add relation type for related member with migration. * Extend tests for track relations to include member relations. * Extend tests for relation repository. * Extend tests for relation service. * Addressed comments from Copilot review. * Add relation notification to member deletion. * Removed unused import. * Updates from code review. * make ref element globally available * align naming * use new reference list * add interfaces for config * export const * Fixed failing integration tests. * apply interface * deprecate interface with wrong name * fix import * disable unpublish button when item or descendants are referenced --------- Co-authored-by: Andy Butland <abutland73@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { UmbDocumentVariantState, type UmbDocumentVariantOptionModel } from '../../../types.js';
|
||||
import { UmbDocumentReferenceRepository } from '../../../reference/index.js';
|
||||
import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from '../../../constants.js';
|
||||
import { UMB_DOCUMENT_CONFIGURATION_CONTEXT } from '../../../global-contexts/index.js';
|
||||
import type {
|
||||
UmbDocumentUnpublishModalData,
|
||||
@@ -9,6 +9,11 @@ import { css, customElement, html, nothing, state } from '@umbraco-cms/backoffic
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils';
|
||||
import type {
|
||||
UmbConfirmActionModalEntityReferencesConfig,
|
||||
UmbConfirmActionModalEntityReferencesElement,
|
||||
} from '@umbraco-cms/backoffice/relations';
|
||||
import type { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
|
||||
import '../../../modals/shared/document-variant-language-picker.element.js';
|
||||
|
||||
@@ -30,7 +35,6 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
UmbDocumentUnpublishModalValue
|
||||
> {
|
||||
protected readonly _selectionManager = new UmbSelectionManager<string>(this);
|
||||
#referencesRepository = new UmbDocumentReferenceRepository(this);
|
||||
|
||||
@state()
|
||||
_options: Array<UmbDocumentVariantOptionModel> = [];
|
||||
@@ -39,10 +43,7 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
_selection: Array<string> = [];
|
||||
|
||||
@state()
|
||||
_hasReferences = false;
|
||||
|
||||
@state()
|
||||
_hasUnpublishPermission = true;
|
||||
_canUnpublish = true;
|
||||
|
||||
@state()
|
||||
_hasInvalidSelection = true;
|
||||
@@ -50,6 +51,9 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
@state()
|
||||
_isInvariant = false;
|
||||
|
||||
@state()
|
||||
_referencesConfig?: UmbConfirmActionModalEntityReferencesConfig;
|
||||
|
||||
#pickableFilter = (option: UmbDocumentVariantOptionModel) => {
|
||||
if (!option.variant) {
|
||||
return false;
|
||||
@@ -58,7 +62,7 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
};
|
||||
|
||||
override firstUpdated() {
|
||||
this.#getReferences();
|
||||
this.#configureReferences();
|
||||
|
||||
// If invariant, don't display the variant selection component.
|
||||
if (this.data?.options.length === 1 && this.data.options[0].unique === 'invariant') {
|
||||
@@ -70,6 +74,16 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
this.#configureSelectionManager();
|
||||
}
|
||||
|
||||
#configureReferences() {
|
||||
if (!this.data?.documentUnique) return;
|
||||
|
||||
this._referencesConfig = {
|
||||
itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS,
|
||||
referenceRepositoryAlias: UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS,
|
||||
unique: this.data.documentUnique,
|
||||
};
|
||||
}
|
||||
|
||||
async #configureSelectionManager() {
|
||||
this._selectionManager.setMultiple(true);
|
||||
this._selectionManager.setSelectable(true);
|
||||
@@ -103,30 +117,8 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
);
|
||||
}
|
||||
|
||||
async #getReferences() {
|
||||
if (!this.data?.documentUnique) return;
|
||||
|
||||
const { data, error } = await this.#referencesRepository.requestReferencedBy(this.data?.documentUnique, 0, 1);
|
||||
|
||||
if (error) {
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data) return;
|
||||
|
||||
this._hasReferences = data.total > 0;
|
||||
|
||||
// If there are references, we also want to check if we are allowed to unpublish the document:
|
||||
if (this._hasReferences) {
|
||||
const documentConfigurationContext = await this.getContext(UMB_DOCUMENT_CONFIGURATION_CONTEXT);
|
||||
this._hasUnpublishPermission =
|
||||
(await documentConfigurationContext.getDocumentConfiguration())?.disableUnpublishWhenReferenced === false;
|
||||
}
|
||||
}
|
||||
|
||||
#submit() {
|
||||
if (this._hasUnpublishPermission) {
|
||||
if (this._canUnpublish) {
|
||||
const selection = this._isInvariant ? ['invariant'] : this._selection;
|
||||
this.value = { selection };
|
||||
this.modalContext?.submit();
|
||||
@@ -139,6 +131,19 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
this.modalContext?.reject();
|
||||
}
|
||||
|
||||
async #onReferencesChange(event: UmbChangeEvent) {
|
||||
event.stopPropagation();
|
||||
const target = event.target as UmbConfirmActionModalEntityReferencesElement;
|
||||
const getReferencedByTotal = target.getTotalReferencedBy();
|
||||
const descendantsWithReferencesTotal = target.getTotalDescendantsWithReferences();
|
||||
const total = getReferencedByTotal + descendantsWithReferencesTotal;
|
||||
|
||||
if (total > 0) {
|
||||
const context = await this.getContext(UMB_DOCUMENT_CONFIGURATION_CONTEXT);
|
||||
this._canUnpublish = (await context.getDocumentConfiguration())?.disableUnpublishWhenReferenced === false;
|
||||
}
|
||||
}
|
||||
|
||||
private _requiredFilter = (variantOption: UmbDocumentVariantOptionModel): boolean => {
|
||||
return variantOption.language.isMandatory && !this._selection.includes(variantOption.unique);
|
||||
};
|
||||
@@ -166,20 +171,10 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
</umb-localize>
|
||||
</p>
|
||||
|
||||
${this.data?.documentUnique
|
||||
? html`
|
||||
<umb-document-reference-table
|
||||
id="references"
|
||||
unique=${this.data?.documentUnique}></umb-document-reference-table>
|
||||
`
|
||||
: nothing}
|
||||
${this._hasReferences
|
||||
? html`<uui-box id="references-warning">
|
||||
<umb-localize key="references_unpublishWarning">
|
||||
This item or its descendants is being referenced. Unpublishing can lead to broken links on your website.
|
||||
Please take the appropriate actions.
|
||||
</umb-localize>
|
||||
</uui-box>`
|
||||
${this._referencesConfig
|
||||
? html`<umb-confirm-action-modal-entity-references
|
||||
.config=${this._referencesConfig}
|
||||
@change=${this.#onReferencesChange}></umb-confirm-action-modal-entity-references>`
|
||||
: nothing}
|
||||
|
||||
<div slot="actions">
|
||||
@@ -187,7 +182,7 @@ export class UmbDocumentUnpublishModalElement extends UmbModalBaseElement<
|
||||
<uui-button
|
||||
label="${this.localize.term('actions_unpublish')}"
|
||||
?disabled=${this._hasInvalidSelection ||
|
||||
!this._hasUnpublishPermission ||
|
||||
!this._canUnpublish ||
|
||||
(!this._isInvariant && this._selection.length === 0)}
|
||||
look="primary"
|
||||
color="warning"
|
||||
|
||||
@@ -9,7 +9,12 @@ import {
|
||||
isMemberReference,
|
||||
isDefaultReference,
|
||||
} from '@umbraco-cms/backoffice/relations';
|
||||
import { UmbDeprecation } from '@umbraco-cms/backoffice/utils';
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated from 15.4. The element will be removed in v17.0.0. For modals use the <umb-confirm-action-modal-entity-references> or <umb-confirm-bulk-action-modal-entity-references> element instead
|
||||
* @class UmbDocumentReferenceTableElement
|
||||
*/
|
||||
@customElement('umb-document-reference-table')
|
||||
export class UmbDocumentReferenceTableElement extends UmbLitElement {
|
||||
#documentReferenceRepository = new UmbDocumentReferenceRepository(this);
|
||||
@@ -32,6 +37,13 @@ export class UmbDocumentReferenceTableElement extends UmbLitElement {
|
||||
_errorMessage = '';
|
||||
|
||||
override firstUpdated() {
|
||||
new UmbDeprecation({
|
||||
removeInVersion: '17',
|
||||
deprecated: '<umb-document-reference-table> element',
|
||||
solution:
|
||||
'For modals use the <umb-confirm-action-modal-entity-references> or <umb-confirm-bulk-action-modal-entity-references> element instead',
|
||||
}).warn();
|
||||
|
||||
this.#getReferences();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { UmbConfirmBulkActionModalEntityReferencesConfig } from '../../../global-components/types.js';
|
||||
import type {
|
||||
UmbBulkDeleteWithRelationConfirmModalData,
|
||||
UmbBulkDeleteWithRelationConfirmModalValue,
|
||||
@@ -15,16 +16,13 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
// import of local component
|
||||
import '../../local-components/confirm-bulk-action-entity-references.element.js';
|
||||
|
||||
@customElement('umb-bulk-delete-with-relation-confirm-modal')
|
||||
export class UmbBulkDeleteWithRelationConfirmModalElement extends UmbModalBaseElement<
|
||||
UmbBulkDeleteWithRelationConfirmModalData,
|
||||
UmbBulkDeleteWithRelationConfirmModalValue
|
||||
> {
|
||||
@state()
|
||||
_referencesConfig?: any;
|
||||
_referencesConfig?: UmbConfirmBulkActionModalEntityReferencesConfig;
|
||||
|
||||
protected override firstUpdated(_changedProperties: PropertyValues): void {
|
||||
super.firstUpdated(_changedProperties);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { UmbConfirmBulkActionModalEntityReferencesConfig } from '../../../global-components/types.js';
|
||||
import type {
|
||||
UmbBulkTrashWithRelationConfirmModalData,
|
||||
UmbBulkTrashWithRelationConfirmModalValue,
|
||||
@@ -15,16 +16,13 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
// import of local component
|
||||
import '../../local-components/confirm-bulk-action-entity-references.element.js';
|
||||
|
||||
@customElement('umb-bulk-trash-with-relation-confirm-modal')
|
||||
export class UmbBulkTrashWithRelationConfirmModalElement extends UmbModalBaseElement<
|
||||
UmbBulkTrashWithRelationConfirmModalData,
|
||||
UmbBulkTrashWithRelationConfirmModalValue
|
||||
> {
|
||||
@state()
|
||||
_referencesConfig?: any;
|
||||
_referencesConfig?: UmbConfirmBulkActionModalEntityReferencesConfig;
|
||||
|
||||
protected override firstUpdated(_changedProperties: PropertyValues): void {
|
||||
super.firstUpdated(_changedProperties);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { UmbConfirmActionModalEntityReferencesConfig } from '../../../global-components/types.js';
|
||||
import type {
|
||||
UmbDeleteWithRelationConfirmModalData,
|
||||
UmbDeleteWithRelationConfirmModalValue,
|
||||
@@ -17,8 +18,6 @@ import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
import '../../local-components/confirm-action-entity-references.element.js';
|
||||
|
||||
@customElement('umb-delete-with-relation-confirm-modal')
|
||||
export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElement<
|
||||
UmbDeleteWithRelationConfirmModalData,
|
||||
@@ -28,7 +27,7 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen
|
||||
_name?: string;
|
||||
|
||||
@state()
|
||||
_referencesConfig?: any;
|
||||
_referencesConfig?: UmbConfirmActionModalEntityReferencesConfig;
|
||||
|
||||
#itemRepository?: UmbItemRepository<any>;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { UmbConfirmActionModalEntityReferencesConfig } from '../../../global-components/types.js';
|
||||
import type {
|
||||
UmbTrashWithRelationConfirmModalData,
|
||||
UmbTrashWithRelationConfirmModalValue,
|
||||
@@ -17,9 +18,6 @@ import { umbFocus } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
// import of local component
|
||||
import '../../local-components/confirm-action-entity-references.element.js';
|
||||
|
||||
@customElement('umb-trash-with-relation-confirm-modal')
|
||||
export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement<
|
||||
UmbTrashWithRelationConfirmModalData,
|
||||
@@ -29,7 +27,7 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement
|
||||
_name?: string;
|
||||
|
||||
@state()
|
||||
_referencesConfig?: any;
|
||||
_referencesConfig?: UmbConfirmActionModalEntityReferencesConfig;
|
||||
|
||||
#itemRepository?: UmbItemRepository<any>;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../reference/types.js';
|
||||
import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../reference/types.js';
|
||||
import {
|
||||
html,
|
||||
customElement,
|
||||
@@ -12,16 +12,18 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
|
||||
export interface UmbConfirmActionModalEntityReferencesConfig {
|
||||
itemRepositoryAlias: string;
|
||||
referenceRepositoryAlias: string;
|
||||
unique: string;
|
||||
}
|
||||
|
||||
@customElement('umb-confirm-action-modal-entity-references')
|
||||
export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement {
|
||||
@property({ type: Object, attribute: false })
|
||||
config?: {
|
||||
itemRepositoryAlias: string;
|
||||
referenceRepositoryAlias: string;
|
||||
entityType: string;
|
||||
unique: string;
|
||||
};
|
||||
config?: UmbConfirmActionModalEntityReferencesConfig;
|
||||
|
||||
@state()
|
||||
_referencedByItems: Array<UmbReferenceItemModel> = [];
|
||||
@@ -40,6 +42,14 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement
|
||||
|
||||
#limitItems = 3;
|
||||
|
||||
getTotalReferencedBy() {
|
||||
return this._totalReferencedByItems;
|
||||
}
|
||||
|
||||
getTotalDescendantsWithReferences() {
|
||||
return this._totalDescendantsWithReferences;
|
||||
}
|
||||
|
||||
protected override firstUpdated(_changedProperties: PropertyValues): void {
|
||||
super.firstUpdated(_changedProperties);
|
||||
this.#initData();
|
||||
@@ -88,6 +98,7 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement
|
||||
if (data) {
|
||||
this._referencedByItems = [...data.items];
|
||||
this._totalReferencedByItems = data.total;
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +129,7 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement
|
||||
const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array<string>;
|
||||
const { data: items } = await this.#itemRepository.requestItems(uniques);
|
||||
this._descendantsWithReferences = items ?? [];
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,8 +175,6 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement
|
||||
];
|
||||
}
|
||||
|
||||
export { UmbConfirmActionModalEntityReferencesElement as element };
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-confirm-action-modal-entity-references': UmbConfirmActionModalEntityReferencesElement;
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { UmbEntityReferenceRepository } from '../../reference/types.js';
|
||||
import type { UmbEntityReferenceRepository } from '../reference/types.js';
|
||||
import {
|
||||
html,
|
||||
customElement,
|
||||
@@ -13,6 +13,12 @@ import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository';
|
||||
import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
export interface UmbConfirmBulkActionModalEntityReferencesConfig {
|
||||
uniques: Array<string>;
|
||||
itemRepositoryAlias: string;
|
||||
referenceRepositoryAlias: string;
|
||||
}
|
||||
|
||||
@customElement('umb-confirm-bulk-action-modal-entity-references')
|
||||
export class UmbConfirmBulkActionModalEntityReferencesElement extends UmbLitElement {
|
||||
@property({ type: Object, attribute: false })
|
||||
@@ -125,8 +131,6 @@ export class UmbConfirmBulkActionModalEntityReferencesElement extends UmbLitElem
|
||||
];
|
||||
}
|
||||
|
||||
export { UmbConfirmBulkActionModalEntityReferencesElement as element };
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-confirm-bulk-action-modal-entity-references': UmbConfirmBulkActionModalEntityReferencesElement;
|
||||
@@ -0,0 +1,5 @@
|
||||
import './confirm-action-modal-entity-references.element.js';
|
||||
import './confirm-bulk-action-modal-entity-references.element.js';
|
||||
|
||||
export * from './confirm-action-modal-entity-references.element.js';
|
||||
export * from './confirm-bulk-action-modal-entity-references.element.js';
|
||||
@@ -0,0 +1,2 @@
|
||||
export type * from './confirm-action-modal-entity-references.element.js';
|
||||
export type * from './confirm-bulk-action-modal-entity-references.element.js';
|
||||
@@ -1,6 +1,7 @@
|
||||
export * from './constants.js';
|
||||
export * from './collection/index.js';
|
||||
export * from './constants.js';
|
||||
export * from './entity.js';
|
||||
export * from './global-components/index.js';
|
||||
export * from './utils.js';
|
||||
|
||||
export type * from './types.js';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { UmbRelationEntityType } from './entity.js';
|
||||
export type * from './global-components/types.js';
|
||||
export type * from './reference/types.js';
|
||||
|
||||
export interface UmbRelationDetailModel {
|
||||
|
||||
Reference in New Issue
Block a user