collection context

This commit is contained in:
Jesper Møller Jensen
2022-12-20 14:36:56 +01:00
parent 4ef2752d51
commit 9d40402a27
5 changed files with 156 additions and 10 deletions

View File

@@ -0,0 +1,43 @@
import { BehaviorSubject, Observable } from 'rxjs';
export interface UmbCollectionContext {
readonly selectable: Observable<boolean>;
readonly selection: Observable<Array<string>>;
readonly entityKey: string;
setSelectable(value: boolean): void;
setSelection(value: Array<string>): void;
select(key: string): void;
}
export class UmbCollectionContextBase implements UmbCollectionContext {
private _selectable: BehaviorSubject<boolean> = new BehaviorSubject(false);
public readonly selectable: Observable<boolean> = this._selectable.asObservable();
private _selection: BehaviorSubject<Array<string>> = new BehaviorSubject(<Array<string>>[]);
public readonly selection: Observable<Array<string>> = this._selection.asObservable();
public entityKey = '';
constructor(entityKey: string) {
this.entityKey = entityKey;
}
public setSelectable(value: boolean) {
this._selectable.next(value);
}
public setSelection(value: Array<string>) {
if (!value) return;
this._selection.next(value);
}
public select(key: string) {
const selection = [...this._selection.getValue(), key];
this._selection.next(selection);
}
public deselect(key: string) {
const selection = this._selection.getValue();
this._selection.next(selection.filter((x) => x !== key));
}
}

View File

@@ -2,6 +2,7 @@ import { UUITextStyles } from '@umbraco-ui/uui-css';
import { css, html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { UmbCollectionContext } from '../collection.context';
import type { MediaDetails } from '@umbraco-cms/models';
import { UmbMediaStore } from '@umbraco-cms/stores/media/media.store';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
@@ -68,6 +69,8 @@ export class UmbCollectionLayoutMediaGridElement extends UmbContextConsumerMixin
@state()
private _mediaItems: Array<MediaDetails> = [];
private _collectionContext?: UmbCollectionContext;
private _mediaStore?: UmbMediaStore;
constructor() {
super();
@@ -81,19 +84,23 @@ export class UmbCollectionLayoutMediaGridElement extends UmbContextConsumerMixin
e.preventDefault();
this.toggleAttribute('dragging', false);
});
this.consumeContext('umbMediaStore', (store: UmbMediaStore) => {
this._mediaStore = store;
this.consumeAllContexts(['umbMediaStore', 'umbCollectionContext'], (instance) => {
this._mediaStore = instance['umbMediaStore'];
this._collectionContext = instance['umbCollectionContext'];
this._observeMediaItems();
});
}
private _observeMediaItems() {
if (!this._mediaStore) return;
if (!this._mediaStore || !this._collectionContext) return;
this.observe<Array<MediaDetails>>(this._mediaStore?.getTreeRoot(), (items) => {
this._mediaItems = items;
console.log('media store', this._mediaStore);
});
this.observe<Array<MediaDetails>>(
this._mediaStore?.getTreeItemChildren(this._collectionContext.entityKey),
(items) => {
this._mediaItems = items;
console.log('media store', this._mediaStore);
}
);
}
private _handleOpenItem(key: string) {

View File

@@ -1,6 +1,6 @@
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { css, html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { customElement, property, state } from 'lit/decorators.js';
import '../../components/collection/collection-toolbar.element';
import '../../components/collection/collection-selection-actions.element';
import '../../components/collection/collection-view.element';
@@ -11,6 +11,7 @@ import { UmbContextConsumerMixin, UmbContextProviderMixin } from '@umbraco-cms/c
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import { umbExtensionsRegistry } from '@umbraco-cms/extensions-registry';
import { createExtensionElement } from '@umbraco-cms/extensions-api';
import { UmbCollectionContextBase } from '@umbraco-cms/components/collection/collection.context';
@customElement('umb-dashboard-media-management')
export class UmbDashboardMediaManagementElement extends UmbContextProviderMixin(
@@ -33,6 +34,20 @@ export class UmbDashboardMediaManagementElement extends UmbContextProviderMixin(
@state()
private _routes: Array<any> = [];
private _entityKey = '';
@property()
public get entityKey() {
return this._entityKey;
}
public set entityKey(value: string) {
const oldValue = this._entityKey;
if (oldValue === value) return;
this._entityKey = value;
this.requestUpdate('entityKey', oldValue);
this.provideContext('umbCollectionContext', new UmbCollectionContextBase(this.entityKey));
}
@state()
private _collectionLayouts: Array<ManifestCollectionLayout> = [];
@@ -41,7 +56,6 @@ export class UmbDashboardMediaManagementElement extends UmbContextProviderMixin(
constructor() {
super();
this.provideContext('umbMediaContext', this);
this._observeCollectionLayouts();
}

View File

@@ -36,6 +36,19 @@ export class UmbWorkspaceMediaElement extends UmbContextConsumerMixin(UmbContext
private _registerWorkspaceViews() {
const dashboards: Array<ManifestWorkspaceView> = [
{
type: 'workspaceView',
alias: 'Umb.WorkspaceView.Media.Collection',
name: 'Media Workspace Collection View',
loader: () => import('../shared/workspace-content/views/collection/workspace-view-content-collection.element'),
weight: 300,
meta: {
workspaces: ['Umb.Workspace.Media'],
label: 'Media',
pathname: 'collection',
icon: 'umb:grid',
},
},
{
type: 'workspaceView',
alias: 'Umb.WorkspaceView.Media.Edit',
@@ -71,7 +84,9 @@ export class UmbWorkspaceMediaElement extends UmbContextConsumerMixin(UmbContext
}
render() {
return html`<umb-workspace-content .entityKey=${this.entityKey} alias="Umb.Workspace.Media"></umb-workspace-content>`;
return html`<umb-workspace-content
.entityKey=${this.entityKey}
alias="Umb.Workspace.Media"></umb-workspace-content>`;
}
}

View File

@@ -0,0 +1,67 @@
import { css, html, LitElement, nothing } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, state } from 'lit/decorators.js';
import { distinctUntilChanged } from 'rxjs';
import { UmbNodeContext } from '../../node.context';
import { UmbContextConsumerMixin } from '@umbraco-cms/context-api';
import { UmbObserverMixin } from '@umbraco-cms/observable-api';
import type { ContentProperty, ContentPropertyData, DocumentDetails, MediaDetails } from '@umbraco-cms/models';
import '../../../../../components/content-property/content-property.element';
import 'src/backoffice/dashboards/media-management/dashboard-media-management.element';
@customElement('umb-workspace-view-content-collection')
export class UmbWorkspaceViewContentCollectionElement extends UmbContextConsumerMixin(UmbObserverMixin(LitElement)) {
static styles = [
UUITextStyles,
css`
:host {
display: block;
margin: var(--uui-size-layout-1);
}
`,
];
@state()
_properties: ContentProperty[] = [];
@state()
_data: ContentPropertyData[] = [];
@state()
private _key = '';
private _nodeContext?: UmbNodeContext;
constructor() {
super();
this.consumeContext('umbNodeContext', (nodeContext) => {
this._nodeContext = nodeContext;
this._observeContent();
});
}
private _observeContent() {
if (!this._nodeContext) return;
this.observe<DocumentDetails | MediaDetails>(this._nodeContext.data.pipe(distinctUntilChanged()), (content) => {
this._properties = content.properties;
this._data = content.data;
this._key = content.key;
});
}
render() {
if (!this._key) return nothing;
return html`<umb-dashboard-media-management .entityKey=${this._key}></umb-dashboard-media-management>`;
}
}
export default UmbWorkspaceViewContentCollectionElement;
declare global {
interface HTMLElementTagNameMap {
'umb-workspace-view-content-collection': UmbWorkspaceViewContentCollectionElement;
}
}