add move functionality

This commit is contained in:
Jesper Møller Jensen
2023-01-26 01:52:16 +01:00
parent cdc56ce13a
commit 520cc5a3fa
5 changed files with 65 additions and 23 deletions

View File

@@ -6,7 +6,6 @@ import { createObservablePart, ArrayState } from '@umbraco-cms/observable-api';
import { UmbStoreBase } from '@umbraco-cms/store';
import { UmbControllerHostInterface } from '@umbraco-cms/controller';
export const UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbMediaTreeStore>('UmbMediaTreeStore');
// TODO: Stop using ContentTreeItem
@@ -19,12 +18,8 @@ export type MediaTreeItem = ContentTreeItem;
* @description - Data Store for Media
*/
export class UmbMediaTreeStore extends UmbStoreBase {
#data = new ArrayState<MediaTreeItem>([], (x) => x.key);
constructor(host: UmbControllerHostInterface) {
super(host, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN.toString());
}
@@ -44,6 +39,19 @@ export class UmbMediaTreeStore extends UmbStoreBase {
this.#data.append(data);
}
async move(keys: Array<string>, destination: string) {
// TODO: use backend cli when available.
const res = await fetch('/umbraco/management/api/v1/media/move', {
method: 'POST',
body: JSON.stringify({ keys, destination }),
headers: {
'Content-Type': 'application/json',
},
});
const data = await res.json();
this.#data.append(data);
}
getTreeRoot(): Observable<Array<MediaTreeItem>> {
tryExecuteAndNotify(this._host, MediaResource.getTreeMediaRoot({})).then(({ data }) => {
if (data) {
@@ -54,7 +62,9 @@ export class UmbMediaTreeStore extends UmbStoreBase {
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.
return createObservablePart(this.#data, (items) => items.filter((item) => item.parentKey === null && !item.isTrashed));
return createObservablePart(this.#data, (items) =>
items.filter((item) => item.parentKey === null && !item.isTrashed)
);
}
getTreeItemChildren(key: string): Observable<Array<MediaTreeItem>> {
@@ -72,7 +82,9 @@ export class UmbMediaTreeStore extends UmbStoreBase {
// TODO: how do we handle trashed items?
// TODO: remove ignore when we know how to handle trashed items.
return createObservablePart(this.#data, (items) => items.filter((item) => item.parentKey === key && !item.isTrashed));
return createObservablePart(this.#data, (items) =>
items.filter((item) => item.parentKey === key && !item.isTrashed)
);
}
getTreeItems(keys: Array<string>): Observable<Array<MediaTreeItem>> {

View File

@@ -9,6 +9,7 @@ import { UmbModalService, UMB_MODAL_SERVICE_CONTEXT_TOKEN } from '../../../../co
import { UmbMediaTreeStore, UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN } from '../../../media/media/media.tree.store';
import { UmbLitElement } from '@umbraco-cms/element';
import type { ManifestCollectionBulkAction, MediaDetails } from '@umbraco-cms/models';
import { UmbMediaDetailStore } from 'src/backoffice/media/media/media.detail.store';
@customElement('umb-collection-bulk-action-media-move')
export class UmbCollectionBulkActionMoveElement extends UmbLitElement {
@@ -20,7 +21,7 @@ export class UmbCollectionBulkActionMoveElement extends UmbLitElement {
public manifest?: ManifestCollectionBulkAction;
#modalService?: UmbModalService;
#mediaStore?: UmbMediaTreeStore;
#mediaTreeStore?: UmbMediaTreeStore;
constructor() {
super();
@@ -34,23 +35,23 @@ export class UmbCollectionBulkActionMoveElement extends UmbLitElement {
});
this.consumeContext(UMB_MEDIA_TREE_STORE_CONTEXT_TOKEN, (instance) => {
this.#mediaStore = instance;
this.#mediaTreeStore = instance;
});
}
#handleClick(event: Event) {
const selectionSubscription = this.#collectionContext?.selection.subscribe((selection) => {
const dataSubscription = this.#collectionContext?.data
.pipe(map((items) => items.filter((item) => selection.includes(item.key))))
.subscribe((items: Array<MediaDetails>) => {
const modalHandler = this.#modalService?.contentPicker({
selection: [],
alias: 'Umb.Tree.Media',
});
modalHandler?.onClose().then((data) => {
console.log('data', data);
});
});
const modalHandler = this.#modalService?.contentPicker({
selection: [],
alias: 'Umb.Tree.Media',
});
modalHandler?.onClose().then((data) => {
if (selection.length > 0) {
this.#mediaTreeStore?.move(selection, data.selection[0]);
}
selectionSubscription?.unsubscribe();
this.#collectionContext?.clearSelection();
});
});
}

View File

@@ -116,8 +116,6 @@ export class UmbCollectionViewsMediaGridElement extends UmbLitElement {
}
private _handleOpenItem(mediaItem: MediaTreeItem) {
console.log('MEDIA ITEM', mediaItem);
//TODO: Fix when we have dynamic routing
history.pushState(null, '', 'section/media/media/edit/' + mediaItem.key);
}

View File

@@ -10,7 +10,7 @@ export class UmbEntityData<T extends Entity> extends UmbData<T> {
getByKey(key: string) {
return this.data.find((item) => item.key === key);
}
getByKeys(keys: Array<string>) {
return this.data.filter((item) => keys.includes(item.key));
}
@@ -31,6 +31,25 @@ export class UmbEntityData<T extends Entity> extends UmbData<T> {
return saveItems;
}
move(keys: Array<string>, destination: string) {
const movedItems: Array<T> = [];
keys.forEach((key) => {
const item = this.getByKey(key);
if (!item) return;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
item.parentKey = destination;
this.updateData(item);
movedItems.push(item);
});
console.log('data', this.data, 'movedItems', movedItems, 'destination', destination);
return movedItems;
}
trash(keys: Array<string>) {
const trashedItems: Array<T> = [];

View File

@@ -24,6 +24,18 @@ export const handlers = [
return res(ctx.status(200), ctx.json(saved));
}),
rest.post<MediaDetails[]>('/umbraco/management/api/v1/media/move', async (req, res, ctx) => {
console.warn('Please move to schema');
const data = await req.json();
if (!data) return;
console.log('HANDLER', data);
const moved = umbMediaData.move(data.keys, data.destination);
return res(ctx.status(200), ctx.json(moved));
}),
rest.post<string[]>('/umbraco/management/api/v1/media/trash', async (req, res, ctx) => {
console.warn('Please move to schema');
const keys = await req.json();