Document/Media Recycle Bin: Add missing root workspace views (#20494) (#20569)

* add document recycle bin root workspace

* add media recycle bin root workspace

* export consts
This commit is contained in:
Mads Rasmussen
2025-10-20 16:42:52 +02:00
committed by GitHub
parent 94692cccb7
commit c666c00ac5
45 changed files with 627 additions and 25 deletions

View File

@@ -1,4 +1,4 @@
export * from './menu/constants.js';
export * from './repository/constants.js';
export * from './root/constants.js';
export * from './tree/constants.js';
export const UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE = 'document-recycle-bin-root';

View File

@@ -1,6 +1,7 @@
import { manifests as entityActionManifests } from './entity-action/manifests.js';
import { manifests as menuManifests } from './menu/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
import { manifests as rootManifests } from './root/manifests.js';
import { manifests as treeManifests } from './tree/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [
@@ -13,5 +14,6 @@ export const manifests: Array<UmbExtensionManifest> = [
...entityActionManifests,
...menuManifests,
...repositoryManifests,
...rootManifests,
...treeManifests,
];

View File

@@ -0,0 +1,2 @@
export { UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE } from './entity.js';
export * from './workspace/constants.js';

View File

@@ -0,0 +1,3 @@
export const UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE = 'document-recycle-bin-root';
export type UmbDocumentRecycleBinRootEntityType = typeof UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE;

View File

@@ -0,0 +1,3 @@
import { manifests as workspaceManifests } from './workspace/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [...workspaceManifests];

View File

@@ -0,0 +1 @@
export const UMB_DOCUMENT_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS = 'Umb.Workspace.Document.RecycleBin.Root';

View File

@@ -0,0 +1,35 @@
import { UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from '../../tree/constants.js';
import { UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE } from '../entity.js';
import { UMB_DOCUMENT_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS } from './constants.js';
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'workspace',
kind: 'default',
alias: UMB_DOCUMENT_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS,
name: 'Document Recycle Bin Root Workspace',
meta: {
entityType: UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE,
headline: '#general_recycleBin',
},
},
{
type: 'workspaceView',
kind: 'collection',
alias: 'Umb.WorkspaceView.DocumentRecycleBinRoot.Root',
name: 'Document Recycle Bin Root Collection Workspace View',
meta: {
label: 'Collection',
pathname: 'collection',
icon: 'icon-layers',
collectionAlias: UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
},
conditions: [
{
alias: UMB_WORKSPACE_CONDITION_ALIAS,
match: UMB_DOCUMENT_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS,
},
],
},
];

View File

@@ -6,3 +6,5 @@ export const UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_ALIAS = 'Umb.Store.Document.Rec
export const UMB_DOCUMENT_RECYCLE_BIN_TREE_ALIAS = 'Umb.Tree.Document.RecycleBin';
export { UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_CONTEXT } from './data/document-recycle-bin-tree.store.context-token.js';
export * from './tree-item-children/constants.js';

View File

@@ -1,8 +1,8 @@
import { UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE } from '../constants.js';
import { UMB_DOCUMENT_RECYCLE_BIN_TREE_ALIAS, UMB_DOCUMENT_RECYCLE_BIN_TREE_REPOSITORY_ALIAS } from './constants.js';
import { manifests as dataManifests } from './data/manifests.js';
import { manifests as reloadTreeItemChildrenManifests } from './reload-tree-item-children/manifests.js';
import { manifests as rootTreeItemManifests } from './tree-item/manifests.js';
import { manifests as treeItemChildrenManifests } from './tree-item-children/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [
{
@@ -14,17 +14,8 @@ export const manifests: Array<UmbExtensionManifest> = [
repositoryAlias: UMB_DOCUMENT_RECYCLE_BIN_TREE_REPOSITORY_ALIAS,
},
},
{
type: 'workspace',
kind: 'default',
alias: 'Umb.Workspace.Document.RecycleBin.Root',
name: 'Document Recycle Bin Root Workspace',
meta: {
entityType: UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE,
headline: '#general_recycleBin',
},
},
...dataManifests,
...reloadTreeItemChildrenManifests,
...rootTreeItemManifests,
...treeItemChildrenManifests,
];

View File

@@ -0,0 +1,3 @@
export const UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS =
'Umb.Collection.DocumentRecycleBin.TreeItemChildren';
export * from './repository/constants.js';

View File

@@ -0,0 +1,2 @@
export * from './constants.js';
export * from './repository/index.js';

View File

@@ -0,0 +1,18 @@
import { manifests as repositoryManifests } from './repository/manifests.js';
import { manifests as viewManifests } from './views/manifests.js';
import { UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './constants.js';
import { UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS } from './repository/index.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'collection',
kind: 'default',
alias: UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
name: 'Document Recycle Bin Tree Item Children Collection',
meta: {
repositoryAlias: UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS,
},
},
...repositoryManifests,
...viewManifests,
];

View File

@@ -0,0 +1,2 @@
export const UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS =
'Umb.Repository.DocumentRecycleBin.TreeItemChildrenCollection';

View File

@@ -0,0 +1,33 @@
import { UmbDocumentRecycleBinTreeRepository } from '../../../index.js';
import type { UmbCollectionFilterModel, UmbCollectionRepository } from '@umbraco-cms/backoffice/collection';
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
import { UMB_ENTITY_CONTEXT, type UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export class UmbDocumentRecycleBinTreeItemChildrenCollectionRepository
extends UmbRepositoryBase
implements UmbCollectionRepository
{
#treeRepository = new UmbDocumentRecycleBinTreeRepository(this);
async requestCollection(filter: UmbCollectionFilterModel) {
// TODO: get parent from args
const entityContext = await this.getContext(UMB_ENTITY_CONTEXT);
if (!entityContext) throw new Error('Entity context not found');
const entityType = entityContext.getEntityType();
const unique = entityContext.getUnique();
if (!entityType) throw new Error('Entity type not found');
if (unique === undefined) throw new Error('Unique not found');
const parent: UmbEntityModel = { entityType, unique };
if (parent.unique === null) {
return this.#treeRepository.requestTreeRootItems({ skip: filter.skip, take: filter.take });
} else {
return this.#treeRepository.requestTreeItemsOf({ parent, skip: filter.skip, take: filter.take });
}
}
}
export { UmbDocumentRecycleBinTreeItemChildrenCollectionRepository as api };

View File

@@ -0,0 +1,10 @@
import { UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS } from './constants.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'repository',
alias: UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS,
name: 'Document Recycle Bin Tree Item Children Collection Repository',
api: () => import('./document-recycle-bin-tree-item-children-collection.repository.js'),
},
];

View File

@@ -0,0 +1,6 @@
import type { UmbCollectionFilterModel } from '@umbraco-cms/backoffice/collection';
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export interface UmbDocumentRecycleBinTreeItemChildrenCollectionFilterModel extends UmbCollectionFilterModel {
parent: UmbEntityModel;
}

View File

@@ -0,0 +1,101 @@
import type { UmbDocumentRecycleBinTreeItemModel } from '../../../types.js';
import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection';
import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection';
import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components';
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin';
import './trashed-document-name-table-column.element.js';
@customElement('umb-document-recycle-bin-tree-item-table-collection-view')
export class UmbDocumentRecycleBinTreeItemTableCollectionViewElement extends UmbLitElement {
@state()
private _tableConfig: UmbTableConfig = {
allowSelection: false,
};
@state()
private _tableColumns: Array<UmbTableColumn> = [
{
name: this.localize.term('general_name'),
alias: 'name',
elementName: 'umb-trashed-document-name-table-column',
},
{
name: '',
alias: 'entityActions',
align: 'right',
},
];
@state()
private _tableItems: Array<UmbTableItem> = [];
#collectionContext?: UmbDefaultCollectionContext;
#isTrashedContext = new UmbIsTrashedEntityContext(this);
constructor() {
super();
this.#isTrashedContext.setIsTrashed(true);
this.consumeContext(UMB_COLLECTION_CONTEXT, (instance) => {
this.#collectionContext = instance;
this.#observeCollectionItems();
});
}
#observeCollectionItems() {
if (!this.#collectionContext) return;
this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver');
}
#createTableItems(items: Array<UmbDocumentRecycleBinTreeItemModel>) {
this._tableItems = items.map((item) => {
return {
id: item.unique,
icon: item.documentType.icon,
data: [
{
columnAlias: 'name',
value: item,
},
{
columnAlias: 'entityActions',
value: html`<umb-entity-actions-table-column-view
.value=${{
entityType: item.entityType,
unique: item.unique,
name: item.name,
}}></umb-entity-actions-table-column-view>`,
},
],
};
});
}
override render() {
return html`
<umb-table .config=${this._tableConfig} .columns=${this._tableColumns} .items=${this._tableItems}></umb-table>
`;
}
static override styles = [
UmbTextStyles,
css`
:host {
display: flex;
flex-direction: column;
}
`,
];
}
export { UmbDocumentRecycleBinTreeItemTableCollectionViewElement as element };
declare global {
interface HTMLElementTagNameMap {
['umb-document-recycle-bin-tree-item-table-collection-view']: UmbDocumentRecycleBinTreeItemTableCollectionViewElement;
}
}

View File

@@ -0,0 +1,23 @@
import { UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from '../constants.js';
import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'collectionView',
alias: 'Umb.CollectionView.DocumentRecycleBin.TreeItem.Table',
name: 'Document Recycle Bin Tree Item Table Collection View',
element: () => import('./document-recycle-bin-tree-item-table-collection-view.element.js'),
weight: 300,
meta: {
label: 'Table',
icon: 'icon-list',
pathName: 'table',
},
conditions: [
{
alias: UMB_COLLECTION_ALIAS_CONDITION,
match: UMB_DOCUMENT_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
},
],
},
];

View File

@@ -0,0 +1,62 @@
import { UmbDocumentItemDataResolver } from '../../../../../item/index.js';
import type { UmbDocumentRecycleBinTreeItemModel } from '../../../types.js';
import { UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN } from '../../../../../paths.js';
import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components';
@customElement('umb-trashed-document-name-table-column')
export class UmbTrashedDocumentNameTableColumnElement extends UmbLitElement implements UmbTableColumnLayoutElement {
#resolver = new UmbDocumentItemDataResolver(this);
@state()
private _name = '';
@state()
private _editPath = '';
column!: UmbTableColumn;
item!: UmbTableItem;
@property({ attribute: false })
public set value(value: UmbDocumentRecycleBinTreeItemModel) {
this.#value = value;
if (value) {
this.#resolver.setData(value);
this._editPath = UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN.generateAbsolute({
unique: value.unique,
});
}
}
public get value(): UmbDocumentRecycleBinTreeItemModel {
return this.#value;
}
#value!: UmbDocumentRecycleBinTreeItemModel;
constructor() {
super();
this.#resolver.observe(this.#resolver.name, (name) => (this._name = name || ''));
}
override render() {
if (!this.value) return nothing;
if (!this._name) return nothing;
return html`<uui-button compact href=${this._editPath} label=${this._name}></uui-button>`;
}
static override styles = [
css`
uui-button {
text-align: left;
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
'umb-trashed-document-name-table-column': UmbTrashedDocumentNameTableColumnElement;
}
}

View File

@@ -0,0 +1 @@
export * from './collection/constants.js';

View File

@@ -0,0 +1,3 @@
import { manifests as collectionManifests } from './collection/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [...collectionManifests];

View File

@@ -1,4 +1,4 @@
export * from './menu/constants.js';
export * from './repository/constants.js';
export * from './tree/constants.js';
export const UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE = 'media-recycle-bin-root';
export * from './root/constants.js';

View File

@@ -2,9 +2,10 @@ import {
UMB_MEDIA_ITEM_REPOSITORY_ALIAS,
UMB_MEDIA_TREE_PICKER_MODAL,
UMB_MEDIA_ENTITY_TYPE,
UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS,
} from '../../constants.js';
import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE, UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS } from '../constants.js';
import { UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS } from '../../reference/constants.js';
import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE } from '../root/entity.js';
import { manifests as bulkTrashManifests } from './bulk-trash/manifests.js';
import { UMB_ENTITY_HAS_CHILDREN_CONDITION_ALIAS } from '@umbraco-cms/backoffice/entity-action';
import {

View File

@@ -1,6 +1,7 @@
import { manifests as entityActionManifests } from './entity-action/manifests.js';
import { manifests as menuManifests } from './menu/manifests.js';
import { manifests as repositoryManifests } from './repository/manifests.js';
import { manifests as rootManifests } from './root/manifests.js';
import { manifests as treeManifests } from './tree/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [
@@ -13,5 +14,6 @@ export const manifests: Array<UmbExtensionManifest> = [
...entityActionManifests,
...menuManifests,
...repositoryManifests,
...rootManifests,
...treeManifests,
];

View File

@@ -0,0 +1,2 @@
export { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE } from './entity.js';
export * from './workspace/constants.js';

View File

@@ -0,0 +1,3 @@
export const UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE = 'media-recycle-bin-root';
export type UmbMediaRecycleBinRootEntityType = typeof UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE;

View File

@@ -0,0 +1,3 @@
import { manifests as workspaceManifests } from './workspace/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [...workspaceManifests];

View File

@@ -0,0 +1 @@
export const UMB_MEDIA_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS = 'Umb.Workspace.Media.RecycleBin.Root';

View File

@@ -0,0 +1,35 @@
import { UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from '../../tree/constants.js';
import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE } from '../entity.js';
import { UMB_MEDIA_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS } from './constants.js';
import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'workspace',
kind: 'default',
alias: UMB_MEDIA_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS,
name: 'Media Recycle Bin Root Workspace',
meta: {
entityType: UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE,
headline: '#general_recycleBin',
},
},
{
type: 'workspaceView',
kind: 'collection',
alias: 'Umb.WorkspaceView.Media.RecycleBin.Root',
name: 'Media Recycle Bin Root Collection Workspace View',
meta: {
label: 'Collection',
pathname: 'collection',
icon: 'icon-layers',
collectionAlias: UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
},
conditions: [
{
alias: UMB_WORKSPACE_CONDITION_ALIAS,
match: UMB_MEDIA_RECYCLE_BIN_ROOT_WORKSPACE_ALIAS,
},
],
},
];

View File

@@ -6,3 +6,5 @@ export const UMB_MEDIA_RECYCLE_BIN_TREE_STORE_ALIAS = 'Umb.Store.Media.RecycleBi
export const UMB_MEDIA_RECYCLE_BIN_TREE_ALIAS = 'Umb.Tree.Media.RecycleBin';
export { UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT } from './media-recycle-bin-tree.store.context-token.js';
export * from './tree-item-children/constants.js';

View File

@@ -1,11 +1,12 @@
import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js';
import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE } from '../constants.js';
import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE } from '../root/entity.js';
import {
UMB_MEDIA_RECYCLE_BIN_TREE_ALIAS,
UMB_MEDIA_RECYCLE_BIN_TREE_REPOSITORY_ALIAS,
UMB_MEDIA_RECYCLE_BIN_TREE_STORE_ALIAS,
} from './constants.js';
import { manifests as reloadTreeItemChildrenManifests } from './reload-tree-item-children/manifests.js';
import { manifests as treeItemChildrenManifests } from './tree-item-children/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [
{
@@ -39,15 +40,6 @@ export const manifests: Array<UmbExtensionManifest> = [
supportedEntityTypes: [UMB_MEDIA_ENTITY_TYPE],
},
},
{
type: 'workspace',
kind: 'default',
alias: 'Umb.Workspace.Media.RecycleBin.Root',
name: 'Media Recycle Bin Root Workspace',
meta: {
entityType: UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE,
headline: '#general_recycleBin',
},
},
...reloadTreeItemChildrenManifests,
...treeItemChildrenManifests,
];

View File

@@ -0,0 +1,3 @@
export const UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS =
'Umb.Collection.Media.RecycleBin.TreeItemChildren';
export * from './repository/constants.js';

View File

@@ -0,0 +1,2 @@
export * from './constants.js';
export * from './repository/index.js';

View File

@@ -0,0 +1,18 @@
import { manifests as repositoryManifests } from './repository/manifests.js';
import { manifests as viewManifests } from './views/manifests.js';
import { UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from './constants.js';
import { UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS } from './repository/index.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'collection',
kind: 'default',
alias: UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
name: 'Media Recycle Bin Tree Item Children Collection',
meta: {
repositoryAlias: UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS,
},
},
...repositoryManifests,
...viewManifests,
];

View File

@@ -0,0 +1,2 @@
export const UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS =
'Umb.Repository.Media.RecycleBin.TreeItemChildrenCollection';

View File

@@ -0,0 +1,10 @@
import { UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS } from './constants.js';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'repository',
alias: UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_REPOSITORY_ALIAS,
name: 'Media Recycle Bin Tree Item Children Collection Repository',
api: () => import('./media-recycle-bin-tree-item-children-collection.repository.js'),
},
];

View File

@@ -0,0 +1,33 @@
import { UmbMediaRecycleBinTreeRepository } from '../../../index.js';
import type { UmbCollectionFilterModel, UmbCollectionRepository } from '@umbraco-cms/backoffice/collection';
import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository';
import { UMB_ENTITY_CONTEXT, type UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export class UmbMediaRecycleBinTreeItemChildrenCollectionRepository
extends UmbRepositoryBase
implements UmbCollectionRepository
{
#treeRepository = new UmbMediaRecycleBinTreeRepository(this);
async requestCollection(filter: UmbCollectionFilterModel) {
// TODO: get parent from args
const entityContext = await this.getContext(UMB_ENTITY_CONTEXT);
if (!entityContext) throw new Error('Entity context not found');
const entityType = entityContext.getEntityType();
const unique = entityContext.getUnique();
if (!entityType) throw new Error('Entity type not found');
if (unique === undefined) throw new Error('Unique not found');
const parent: UmbEntityModel = { entityType, unique };
if (parent.unique === null) {
return this.#treeRepository.requestTreeRootItems({ skip: filter.skip, take: filter.take });
} else {
return this.#treeRepository.requestTreeItemsOf({ parent, skip: filter.skip, take: filter.take });
}
}
}
export { UmbMediaRecycleBinTreeItemChildrenCollectionRepository as api };

View File

@@ -0,0 +1,6 @@
import type { UmbCollectionFilterModel } from '@umbraco-cms/backoffice/collection';
import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity';
export interface UmbMediaRecycleBinTreeItemChildrenCollectionFilterModel extends UmbCollectionFilterModel {
parent: UmbEntityModel;
}

View File

@@ -0,0 +1,23 @@
import { UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS } from '../constants.js';
import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection';
export const manifests: Array<UmbExtensionManifest> = [
{
type: 'collectionView',
alias: 'Umb.CollectionView.Media.RecycleBin.TreeItem.Table',
name: 'Media Recycle Bin Tree Item Table Collection View',
element: () => import('./media-recycle-bin-tree-item-table-collection-view.element.js'),
weight: 300,
meta: {
label: 'Table',
icon: 'icon-list',
pathName: 'table',
},
conditions: [
{
alias: UMB_COLLECTION_ALIAS_CONDITION,
match: UMB_MEDIA_RECYCLE_BIN_TREE_ITEM_CHILDREN_COLLECTION_ALIAS,
},
],
},
];

View File

@@ -0,0 +1,101 @@
import type { UmbMediaRecycleBinTreeItemModel } from '../../../types.js';
import type { UmbDefaultCollectionContext } from '@umbraco-cms/backoffice/collection';
import { UMB_COLLECTION_CONTEXT } from '@umbraco-cms/backoffice/collection';
import type { UmbTableColumn, UmbTableConfig, UmbTableItem } from '@umbraco-cms/backoffice/components';
import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin';
import './trashed-media-name-table-column.element.js';
@customElement('umb-media-recycle-bin-tree-item-table-collection-view')
export class UmbMediaRecycleBinTreeItemTableCollectionViewElement extends UmbLitElement {
@state()
private _tableConfig: UmbTableConfig = {
allowSelection: false,
};
@state()
private _tableColumns: Array<UmbTableColumn> = [
{
name: this.localize.term('general_name'),
alias: 'name',
elementName: 'umb-trashed-media-name-table-column',
},
{
name: '',
alias: 'entityActions',
align: 'right',
},
];
@state()
private _tableItems: Array<UmbTableItem> = [];
#collectionContext?: UmbDefaultCollectionContext;
#isTrashedContext = new UmbIsTrashedEntityContext(this);
constructor() {
super();
this.#isTrashedContext.setIsTrashed(true);
this.consumeContext(UMB_COLLECTION_CONTEXT, (instance) => {
this.#collectionContext = instance;
this.#observeCollectionItems();
});
}
#observeCollectionItems() {
if (!this.#collectionContext) return;
this.observe(this.#collectionContext.items, (items) => this.#createTableItems(items), 'umbCollectionItemsObserver');
}
#createTableItems(items: Array<UmbMediaRecycleBinTreeItemModel>) {
this._tableItems = items.map((item) => {
return {
id: item.unique,
icon: item.mediaType.icon,
data: [
{
columnAlias: 'name',
value: item,
},
{
columnAlias: 'entityActions',
value: html`<umb-entity-actions-table-column-view
.value=${{
entityType: item.entityType,
unique: item.unique,
name: item.name,
}}></umb-entity-actions-table-column-view>`,
},
],
};
});
}
override render() {
return html`
<umb-table .config=${this._tableConfig} .columns=${this._tableColumns} .items=${this._tableItems}></umb-table>
`;
}
static override styles = [
UmbTextStyles,
css`
:host {
display: flex;
flex-direction: column;
}
`,
];
}
export { UmbMediaRecycleBinTreeItemTableCollectionViewElement as element };
declare global {
interface HTMLElementTagNameMap {
['umb-media-recycle-bin-tree-item-table-collection-view']: UmbMediaRecycleBinTreeItemTableCollectionViewElement;
}
}

View File

@@ -0,0 +1,54 @@
import type { UmbMediaRecycleBinTreeItemModel } from '../../../types.js';
import { UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../../../../../paths.js';
import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components';
@customElement('umb-trashed-media-name-table-column')
export class UmbTrashedMediaNameTableColumnElement extends UmbLitElement implements UmbTableColumnLayoutElement {
@state()
private _name = '';
@state()
private _editPath = '';
column!: UmbTableColumn;
item!: UmbTableItem;
@property({ attribute: false })
public set value(value: UmbMediaRecycleBinTreeItemModel) {
this.#value = value;
if (value) {
this._name = value.variants[0]?.name || '';
this._editPath = UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN.generateAbsolute({
unique: value.unique,
});
}
}
public get value(): UmbMediaRecycleBinTreeItemModel {
return this.#value;
}
#value!: UmbMediaRecycleBinTreeItemModel;
override render() {
if (!this.value) return nothing;
if (!this._name) return nothing;
return html`<uui-button compact href=${this._editPath} label=${this._name}></uui-button>`;
}
static override styles = [
css`
uui-button {
text-align: left;
}
`,
];
}
declare global {
interface HTMLElementTagNameMap {
'umb-trashed-media-name-table-column': UmbTrashedMediaNameTableColumnElement;
}
}

View File

@@ -0,0 +1 @@
export * from './collection/constants.js';

View File

@@ -0,0 +1,3 @@
import { manifests as collectionManifests } from './collection/manifests.js';
export const manifests: Array<UmbExtensionManifest> = [...collectionManifests];