Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Entity Bulk Action moveTo kind #2121

Merged
merged 8 commits into from
Jul 17, 2024
1 change: 1 addition & 0 deletions src/packages/core/entity-bulk-action/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './move-to/index.js';
2 changes: 2 additions & 0 deletions src/packages/core/entity-bulk-action/common/move-to/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export type { UmbBulkMoveToRepository } from './move-to-repository.interface.js';
export type { UmbBulkMoveToRequestArgs } from './types.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { manifest as moveToKindManifest } from './move-to.action.kind.js';
import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<ManifestTypes | UmbBackofficeManifestKind> = [moveToKindManifest];
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { UmbRepositoryErrorResponse } from '../../../repository/types.js';
import type { UmbBulkMoveToRequestArgs } from './types.js';
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';

export interface UmbBulkMoveToRepository extends UmbApi {
requestBulkMoveTo(args: UmbBulkMoveToRequestArgs): Promise<UmbRepositoryErrorResponse>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '../../default/default.action.kind.js';
import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifest: UmbBackofficeManifestKind = {
type: 'kind',
alias: 'Umb.Kind.EntityBulkAction.MoveTo',
matchKind: 'moveTo',
matchType: 'entityBulkAction',
manifest: {
...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest,
type: 'entityBulkAction',
kind: 'moveTo',
api: () => import('./move-to.action.js'),
weight: 700,
forEntityTypes: [],
meta: {
label: '#actions_move',
bulkMoveRepositoryAlias: '',
treeAlias: '',
},
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { UmbBulkMoveToRepository } from './move-to-repository.interface.js';
import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry';
import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action';
import {
UmbRequestReloadChildrenOfEntityEvent,
UmbRequestReloadStructureForEntityEvent,
} from '@umbraco-cms/backoffice/entity-action';
import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action';
import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UMB_TREE_PICKER_MODAL } from '@umbraco-cms/backoffice/tree';
import type { MetaEntityBulkActionMoveToKind } from '@umbraco-cms/backoffice/extension-registry';

export class UmbMediaMoveEntityBulkAction extends UmbEntityBulkActionBase<MetaEntityBulkActionMoveToKind> {
async execute() {
if (this.selection?.length === 0) return;

const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT);

const modalContext = modalManager.open(this, UMB_TREE_PICKER_MODAL, {
data: {
foldersOnly: this.args.meta.foldersOnly,
hideTreeRoot: this.args.meta.hideTreeRoot,
treeAlias: this.args.meta.treeAlias,
},
});

const value = await modalContext.onSubmit().catch(() => undefined);
if (!value?.selection?.length) return;

const destinationUnique = value.selection[0];
if (destinationUnique === undefined) throw new Error('Destination Unique is not available');

const bulkMoveRepository = await createExtensionApiByAlias<UmbBulkMoveToRepository>(
this,
this.args.meta.bulkMoveRepositoryAlias,
);
if (!bulkMoveRepository) throw new Error('Bulk Move Repository is not available');

await bulkMoveRepository.requestBulkMoveTo({ uniques: this.selection, destination: { unique: destinationUnique } });

const entityContext = await this.getContext(UMB_ENTITY_CONTEXT);
if (!entityContext) throw new Error('Entity Context is not available');

const entityType = entityContext.getEntityType();
const unique = entityContext.getUnique();

if (entityType && unique !== undefined) {
const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT);
if (!eventContext) throw new Error('Event Context is not available');

const args = { entityType, unique };

const reloadChildren = new UmbRequestReloadChildrenOfEntityEvent(args);
eventContext.dispatchEvent(reloadChildren);

const reloadStructure = new UmbRequestReloadStructureForEntityEvent(args);
eventContext.dispatchEvent(reloadStructure);
}
}
}

export { UmbMediaMoveEntityBulkAction as api };
6 changes: 6 additions & 0 deletions src/packages/core/entity-bulk-action/common/move-to/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface UmbBulkMoveToRequestArgs {
uniques: Array<string>;
destination: {
unique: string | null;
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST: UmbBackofficeManifestKind = {
type: 'kind',
alias: 'Umb.Kind.EntityBulkAction.Default',
matchKind: 'default',
matchType: 'entityBulkAction',
manifest: {
type: 'entityBulkAction',
kind: 'default',
weight: 1000,
element: () => import('../entity-bulk-action.element.js'),
meta: {
label: 'Default Entity Bulk Action',
},
},
};

export const manifest = UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST;
4 changes: 4 additions & 0 deletions src/packages/core/entity-bulk-action/default/manifests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { manifest as defaultKindManifest } from './default.action.kind.js';
import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<ManifestTypes | UmbBackofficeManifestKind> = [defaultKindManifest];
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';

export interface UmbEntityBulkActionElement extends UmbControllerHostElement {}
43 changes: 28 additions & 15 deletions src/packages/core/entity-bulk-action/entity-bulk-action.element.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import type { UmbEntityBulkActionBase } from './entity-bulk-action-base.js';
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
import type { UmbEntityBulkAction } from './entity-bulk-action.interface.js';
import type { UmbEntityBulkActionElement } from './entity-bulk-action-element.interface.js';
import { html, ifDefined, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import type { ManifestEntityBulkAction, MetaEntityBulkAction } from '@umbraco-cms/backoffice/extension-registry';
import { UmbActionExecutedEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type {
ManifestEntityBulkAction,
MetaEntityBulkActionDefaultKind,
} from '@umbraco-cms/backoffice/extension-registry';

@customElement('umb-entity-bulk-action')
export class UmbEntityBulkActionElement<
MetaType extends MetaEntityBulkAction = MetaEntityBulkAction,
ApiType extends UmbEntityBulkActionBase<MetaType> = UmbEntityBulkActionBase<MetaType>,
> extends UmbLitElement {
const elementName = 'umb-entity-bulk-action';

@customElement(elementName)
export class UmbEntityBulkActionDefaultElement<
MetaType extends MetaEntityBulkActionDefaultKind = MetaEntityBulkActionDefaultKind,
ApiType extends UmbEntityBulkAction<MetaType> = UmbEntityBulkAction<MetaType>,
>
extends UmbLitElement
implements UmbEntityBulkActionElement
{
@property({ attribute: false })
manifest?: ManifestEntityBulkAction<MetaEntityBulkAction>;
manifest?: ManifestEntityBulkAction<MetaType>;

api?: ApiType;

Expand All @@ -22,16 +31,20 @@ export class UmbEntityBulkActionElement<
}

override render() {
return html`<uui-button
@click=${this.#onClick}
label=${ifDefined(this.manifest?.meta.label)}
color="default"
look="secondary"></uui-button>`;
return html`
<uui-button
color="default"
label=${ifDefined(this.localize.string(this.manifest?.meta.label ?? ''))}
look="secondary"
@click=${this.#onClick}></uui-button>
`;
}
}

export default UmbEntityBulkActionDefaultElement;

declare global {
interface HTMLElementTagNameMap {
'umb-entity-bulk-action': UmbEntityBulkActionElement;
[elementName]: UmbEntityBulkActionDefaultElement;
}
}
4 changes: 4 additions & 0 deletions src/packages/core/entity-bulk-action/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export * from './types.js';
export * from './common/index.js';
export * from './entity-bulk-action-base.js';
export * from './entity-bulk-action.element.js';
export * from './entity-bulk-action.interface.js';
export type * from './entity-bulk-action-element.interface.js';

export { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from './default/default.action.kind.js';
8 changes: 8 additions & 0 deletions src/packages/core/entity-bulk-action/manifests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { manifests as defaultEntityBulkActionManifests } from './default/manifests.js';
import { manifests as moveToEntityBulkActionManifests } from './common/move-to/manifests.js';
import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';

export const manifests: Array<ManifestTypes | UmbBackofficeManifestKind> = [
...defaultEntityBulkActionManifests,
...moveToEntityBulkActionManifests,
];
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import type { ConditionTypes } from '../conditions/types.js';
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
import type { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action';
import type { UmbEntityBulkActionElement } from '../../entity-bulk-action/entity-bulk-action-element.interface.js';
import type { UmbEntityBulkAction } from '@umbraco-cms/backoffice/entity-bulk-action';
import type { ManifestElementAndApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api';

/**
* An action to perform on multiple entities
* For example for content you may wish to move one or more documents in bulk
*/
export interface ManifestEntityBulkAction<MetaType extends MetaEntityBulkAction = MetaEntityBulkAction>
extends ManifestElementAndApi<UmbControllerHostElement, UmbEntityBulkActionBase<MetaType>>,
extends ManifestElementAndApi<UmbEntityBulkActionElement, UmbEntityBulkAction<MetaType>>,
ManifestWithDynamicConditions<ConditionTypes> {
type: 'entityBulkAction';
forEntityTypes: Array<string>;
meta: MetaType;
}

export interface MetaEntityBulkAction {
export interface MetaEntityBulkAction {}

export interface ManifestEntityBulkActionDefaultKind extends ManifestEntityBulkAction<MetaEntityBulkActionDefaultKind> {
type: 'entityBulkAction';
kind: 'default';
}

export interface MetaEntityBulkActionDefaultKind extends MetaEntityBulkAction {
/**
* The friendly name of the action to perform
*
Expand All @@ -26,3 +33,16 @@ export interface MetaEntityBulkAction {
*/
label?: string;
}

// MOVE TO
export interface ManifestEntityBulkActionMoveToKind extends ManifestEntityBulkAction<MetaEntityBulkActionMoveToKind> {
type: 'entityBulkAction';
kind: 'moveTo';
}

export interface MetaEntityBulkActionMoveToKind extends MetaEntityBulkActionDefaultKind {
bulkMoveRepositoryAlias: string;
hideTreeRoot?: boolean;
foldersOnly?: boolean;
treeAlias: string;
}
2 changes: 2 additions & 0 deletions src/packages/core/manifests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { manifests as contentTypeManifests } from './content-type/manifests.js';
import { manifests as cultureManifests } from './culture/manifests.js';
import { manifests as debugManifests } from './debug/manifests.js';
import { manifests as entityActionManifests } from './entity-action/manifests.js';
import { manifests as entityBulkActionManifests } from './entity-bulk-action/manifests.js';
import { manifests as extensionManifests } from './extension-registry/manifests.js';
import { manifests as iconRegistryManifests } from './icon-registry/manifests.js';
import { manifests as localizationManifests } from './localization/manifests.js';
Expand Down Expand Up @@ -38,6 +39,7 @@ export const manifests: Array<ManifestTypes | UmbBackofficeManifestKind> = [
...settingsManifests,
...modalManifests,
...entityActionManifests,
...entityBulkActionManifests,
...propertyActionManifests,
...serverFileSystemManifests,
...debugManifests,
Expand Down
32 changes: 9 additions & 23 deletions src/packages/media/media/entity-bulk-actions/manifests.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/index.js';
import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js';
import { manifests as moveToManifests } from './move-to/manifests.js';
import {
UMB_COLLECTION_ALIAS_CONDITION,
UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION,
} from '@umbraco-cms/backoffice/collection';
import type { ManifestEntityBulkAction, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection';

export const manifests: Array<ManifestTypes> = [
const entityBulkActions: Array<ManifestEntityBulkAction> = [
{
type: 'entityBulkAction',
alias: 'Umb.EntityBulkAction.Media.Duplicate',
name: 'Duplicate Media Entity Bulk Action',
weight: 30,
api: () => import('./duplicate/duplicate.action.js'),
forEntityTypes: [UMB_MEDIA_ENTITY_TYPE],
meta: {
label: 'Duplicate',
},
Expand All @@ -27,32 +30,13 @@ export const manifests: Array<ManifestTypes> = [
},
],
},
{
type: 'entityBulkAction',
alias: 'Umb.EntityBulkAction.Media.MoveTo',
name: 'Move Media Entity Bulk Action',
weight: 20,
api: () => import('./move/move.action.js'),
meta: {
label: 'Move',
},
conditions: [
{
alias: UMB_COLLECTION_ALIAS_CONDITION,
match: UMB_MEDIA_COLLECTION_ALIAS,
},
{
alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION,
match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkMove,
},
],
},
{
type: 'entityBulkAction',
alias: 'Umb.EntityBulkAction.Media.Delete',
name: 'Delete Media Entity Bulk Action',
weight: 10,
api: () => import('./delete/delete.action.js'),
forEntityTypes: [UMB_MEDIA_ENTITY_TYPE],
meta: {
label: 'Delete',
},
Expand All @@ -68,3 +52,5 @@ export const manifests: Array<ManifestTypes> = [
],
},
];

export const manifests: Array<ManifestTypes> = [...entityBulkActions, ...moveToManifests];
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { UmbBulkMoveToMediaRepository, UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS } from './repository/index.js';
36 changes: 36 additions & 0 deletions src/packages/media/media/entity-bulk-actions/move-to/manifests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { UMB_MEDIA_COLLECTION_ALIAS } from '../../collection/index.js';
import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js';
import { UMB_MEDIA_TREE_ALIAS } from '../../tree/constants.js';
import { UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS } from './repository/constants.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
import {
UMB_COLLECTION_ALIAS_CONDITION,
UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION,
} from '@umbraco-cms/backoffice/collection';
import type { UmbCollectionBulkActionPermissions } from '@umbraco-cms/backoffice/collection';
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';

const bulkMoveAction: ManifestTypes = {
type: 'entityBulkAction',
kind: 'moveTo',
alias: 'Umb.EntityBulkAction.Media.MoveTo',
name: 'Move Media Entity Bulk Action',
weight: 20,
forEntityTypes: [UMB_MEDIA_ENTITY_TYPE],
meta: {
bulkMoveRepositoryAlias: UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS,
treeAlias: UMB_MEDIA_TREE_ALIAS,
},
conditions: [
{
alias: UMB_COLLECTION_ALIAS_CONDITION,
match: UMB_MEDIA_COLLECTION_ALIAS,
},
{
alias: UMB_COLLECTION_BULK_ACTION_PERMISSION_CONDITION,
match: (permissions: UmbCollectionBulkActionPermissions) => permissions.allowBulkMove,
},
],
};

export const manifests: Array<ManifestTypes> = [bulkMoveAction, ...repositoryManifests];
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS = 'Umb.Repository.Media.BulkMove';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { UmbBulkMoveToMediaRepository } from './move-to.repository.js';
export { UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS } from './constants.js';
Loading
Loading