Merge branch 'feature/tree-navigator' of https://github.com/umbraco/Umbraco.CMS.Backoffice into feature/tree-navigator
This commit is contained in:
@@ -4,7 +4,7 @@ import { customElement, state } from 'lit/decorators.js';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import { UmbSectionContext } from '../section.context';
|
||||
import '../../tree/actions.service';
|
||||
import '../../tree/actions/actions.service';
|
||||
|
||||
@customElement('umb-section-sidebar')
|
||||
export class UmbSectionSidebar extends UmbContextConsumerMixin(LitElement) {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { css, html } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { UmbActionService } from './actions.service';
|
||||
import { UmbContextConsumerMixin } from '../../core/context';
|
||||
import type { ManifestEntityAction } from '../../core/models';
|
||||
import './actions/tree-action.element';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import type { ManifestEntityAction } from '../../../core/models';
|
||||
import UmbActionElement from './action.element';
|
||||
|
||||
@customElement('umb-actions-modal')
|
||||
export class UmbActionsModal extends UmbContextConsumerMixin(LitElement) {
|
||||
@customElement('umb-action-list-page')
|
||||
export class UmbActionListPageElement extends UmbActionElement {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
@@ -26,9 +24,7 @@ export class UmbActionsModal extends UmbContextConsumerMixin(LitElement) {
|
||||
`,
|
||||
];
|
||||
|
||||
@property()
|
||||
name = '';
|
||||
|
||||
//TODO Replace with real data
|
||||
private _actionList: Array<ManifestEntityAction & { loader?: () => Promise<object | HTMLElement> }> = [
|
||||
{
|
||||
name: 'create',
|
||||
@@ -38,7 +34,7 @@ export class UmbActionsModal extends UmbContextConsumerMixin(LitElement) {
|
||||
icon: 'add',
|
||||
weight: 10,
|
||||
},
|
||||
loader: () => import('./actions/tree-action-create.element'),
|
||||
loader: () => import('./tree-action-create.element'),
|
||||
type: 'entityAction',
|
||||
},
|
||||
{
|
||||
@@ -49,7 +45,7 @@ export class UmbActionsModal extends UmbContextConsumerMixin(LitElement) {
|
||||
icon: 'delete',
|
||||
weight: 20,
|
||||
},
|
||||
loader: () => import('./actions/tree-action-delete.element'),
|
||||
loader: () => import('./tree-action-delete.element'),
|
||||
type: 'entityAction',
|
||||
},
|
||||
{
|
||||
@@ -60,7 +56,7 @@ export class UmbActionsModal extends UmbContextConsumerMixin(LitElement) {
|
||||
icon: 'sync',
|
||||
weight: 30,
|
||||
},
|
||||
loader: () => import('./actions/tree-action-reload.element'),
|
||||
loader: () => import('./tree-action-reload.element'),
|
||||
type: 'entityAction',
|
||||
},
|
||||
];
|
||||
@@ -76,7 +72,7 @@ export class UmbActionsModal extends UmbContextConsumerMixin(LitElement) {
|
||||
render() {
|
||||
return html`
|
||||
<div id="title">
|
||||
<h3>${this.name}</h3>
|
||||
<h3>${this._entity.name}</h3>
|
||||
</div>
|
||||
<div id="action-list">${this.renderActions()}</div>
|
||||
`;
|
||||
@@ -85,6 +81,6 @@ export class UmbActionsModal extends UmbContextConsumerMixin(LitElement) {
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-actions-modal': UmbActionsModal;
|
||||
'umb-action-list-page': UmbActionListPageElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, LitElement, nothing, PropertyValueMap } from 'lit';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { UmbContextProviderMixin } from '../../../core/context';
|
||||
import UmbActionElement, { ActionPageEntity } from './action.element';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
// TODO how do we dynamically import this so we don't have to import every page that could potentially be used?
|
||||
|
||||
@customElement('umb-action-page-service')
|
||||
export class UmbActionPageService extends UmbContextProviderMixin(LitElement) {
|
||||
static styles = [UUITextStyles, css``];
|
||||
|
||||
@property({ type: Object })
|
||||
public actionEntity: ActionPageEntity = { key: '', name: '' };
|
||||
|
||||
private _entity: BehaviorSubject<ActionPageEntity> = new BehaviorSubject({ key: '', name: '' });
|
||||
public readonly entity: Observable<ActionPageEntity> = this._entity.asObservable();
|
||||
|
||||
@state()
|
||||
private _pages: Array<HTMLElement> = [];
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.provideContext('umbActionPageService', this);
|
||||
this.openFreshPage('umb-action-list-page');
|
||||
}
|
||||
|
||||
protected updated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
||||
super.updated(_changedProperties);
|
||||
|
||||
if (_changedProperties.has('actionEntity')) {
|
||||
this._entity.next(this.actionEntity);
|
||||
//TODO: Move back to first page
|
||||
this.openFreshPage('umb-action-list-page');
|
||||
}
|
||||
}
|
||||
|
||||
public openPage(elementName: string) {
|
||||
const element = document.createElement(elementName) as UmbActionElement;
|
||||
this._pages.push(element);
|
||||
this.requestUpdate('_pages');
|
||||
}
|
||||
|
||||
public openFreshPage(elementName: string) {
|
||||
this._pages = [];
|
||||
this.openPage(elementName);
|
||||
}
|
||||
|
||||
public closeTopPage() {
|
||||
this._pages.pop();
|
||||
this.requestUpdate('_pages');
|
||||
}
|
||||
|
||||
private _renderTopPage() {
|
||||
if (this._pages.length === 0) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return this._pages[this._pages.length - 1];
|
||||
}
|
||||
|
||||
render() {
|
||||
return this._renderTopPage();
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-action-page-service': UmbActionPageService;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { LitElement } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import { UmbActionPageService } from './action-page.service';
|
||||
import { UmbActionService } from './actions.service';
|
||||
|
||||
export type ActionPageEntity = {
|
||||
key: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
@customElement('umb-action')
|
||||
export default class UmbActionElement extends UmbContextConsumerMixin(LitElement) {
|
||||
@state()
|
||||
protected _entity: ActionPageEntity = { name: '', key: '' };
|
||||
|
||||
protected _actionService?: UmbActionService;
|
||||
protected _actionPageService?: UmbActionPageService;
|
||||
private _actionPageSubscription?: Subscription;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.consumeContext('umbActionService', (actionService: UmbActionService) => {
|
||||
this._actionService = actionService;
|
||||
});
|
||||
|
||||
this.consumeContext('umbActionPageService', (actionPageService: UmbActionPageService) => {
|
||||
this._actionPageService = actionPageService;
|
||||
|
||||
this._actionPageSubscription?.unsubscribe();
|
||||
this._actionPageService?.entity.subscribe((entity: ActionPageEntity) => {
|
||||
this._entity = entity;
|
||||
console.log('entity changed', this._entity);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
disconnectCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._actionPageSubscription?.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-action': UmbActionElement;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html, LitElement, nothing } from 'lit';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { UmbContextProviderMixin } from '../../core/context';
|
||||
import type { ManifestEntityAction } from '../../core/models';
|
||||
import { customElement, query, state } from 'lit/decorators.js';
|
||||
import { UmbContextProviderMixin } from '../../../core/context';
|
||||
|
||||
import './actions-modal.element';
|
||||
import './actions/tree-action-create-page.element';
|
||||
import './actions/tree-action-create-page-2.element';
|
||||
import { ActionPageEntity } from './action.element';
|
||||
import { UmbActionPageService } from '.';
|
||||
import '.';
|
||||
|
||||
// import './actions-modal.element';
|
||||
// import './tree-action-create-page.element';
|
||||
// import './tree-action-create-page-2.element';
|
||||
// import './action-page.service';
|
||||
// TODO how do we dynamically import this so we don't have to import every page that could potentially be used?
|
||||
|
||||
@customElement('umb-action-service')
|
||||
@@ -53,50 +57,27 @@ export class UmbActionService extends UmbContextProviderMixin(LitElement) {
|
||||
`,
|
||||
];
|
||||
|
||||
@query('umb-action-page-service')
|
||||
private _actionPageService!: UmbActionPageService;
|
||||
|
||||
@state()
|
||||
private _modalOpen = false;
|
||||
|
||||
@state()
|
||||
private _name = '';
|
||||
|
||||
public key = '';
|
||||
|
||||
@state()
|
||||
private _pages: Array<HTMLElement> = [];
|
||||
private entity: { name: string; key: string } = { name: '', key: '' };
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.provideContext('umbActionService', this);
|
||||
}
|
||||
|
||||
public open(name: string, key: string) {
|
||||
this._name = name;
|
||||
this.key = key;
|
||||
public open(entity: ActionPageEntity) {
|
||||
this.entity = entity;
|
||||
this._modalOpen = true;
|
||||
}
|
||||
|
||||
public close() {
|
||||
this._modalOpen = false;
|
||||
this._pages = [];
|
||||
}
|
||||
|
||||
public openPage(elementName: string) {
|
||||
const element = document.createElement(elementName);
|
||||
this._pages.push(element);
|
||||
this.requestUpdate('_pages');
|
||||
}
|
||||
|
||||
public closeTopPage() {
|
||||
this._pages.pop();
|
||||
this.requestUpdate('_pages');
|
||||
}
|
||||
|
||||
private _renderTopPage() {
|
||||
if (this._pages.length === 0) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return this._pages[this._pages.length - 1];
|
||||
}
|
||||
|
||||
private _renderBackdrop() {
|
||||
@@ -106,11 +87,7 @@ export class UmbActionService extends UmbContextProviderMixin(LitElement) {
|
||||
|
||||
private _renderModal() {
|
||||
return this._modalOpen
|
||||
? html` <div id="action-modal">
|
||||
${this._pages.length === 0
|
||||
? html`<umb-actions-modal .name=${this._name}></umb-actions-modal>`
|
||||
: this._renderTopPage()}
|
||||
</div>`
|
||||
? html`<umb-action-page-service id="action-modal" .actionEntity=${this.entity}></umb-action-page-service>`
|
||||
: nothing;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export * from './action-list-page.element';
|
||||
export * from './action-page.service';
|
||||
export * from './actions.service';
|
||||
export * from './tree-action.element';
|
||||
|
||||
// We need these to make it work, even though they have import errors. // TODO: Fix later
|
||||
export * from './tree-action-create-page.element';
|
||||
export * from './tree-action-create-page-2.element';
|
||||
export * from './tree-action-create.element';
|
||||
export * from './tree-action-delete.element';
|
||||
export * from './tree-action-reload.element';
|
||||
@@ -1,34 +1,22 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import type { ManifestEntityAction } from '../../../core/models';
|
||||
import { UmbActionService } from '../actions.service';
|
||||
import { css, html } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import UmbActionElement from './action.element';
|
||||
|
||||
@customElement('umb-tree-action-create-page-2')
|
||||
export default class UmbTreeActionCreatePageElement extends UmbContextConsumerMixin(LitElement) {
|
||||
export class UmbTreeActionCreatePageElement extends UmbActionElement {
|
||||
static styles = [UUITextStyles, css``];
|
||||
|
||||
private _actionService?: UmbActionService;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbActionService', (actionService: UmbActionService) => {
|
||||
this._actionService = actionService;
|
||||
});
|
||||
}
|
||||
|
||||
private _save() {
|
||||
this._actionService?.close();
|
||||
}
|
||||
|
||||
private _back() {
|
||||
this._actionService?.closeTopPage();
|
||||
this._actionPageService?.closeTopPage();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<h2>Create page 2</h2>
|
||||
return html`<h2>Create page 2 for entity: ${this._entity.name}</h2>
|
||||
<p>This is the last create page, here you can go back og save (it just closes the modal for now)</p>
|
||||
<uui-button label="Back" look="secondary" @click=${this._back}></uui-button>
|
||||
<uui-button label="Save" look="primary" color="positive" @click=${this._save}></uui-button>`;
|
||||
|
||||
@@ -1,34 +1,22 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import type { ManifestEntityAction } from '../../../core/models';
|
||||
import { UmbActionService } from '../actions.service';
|
||||
import { css, html } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
import UmbActionElement from './action.element';
|
||||
|
||||
@customElement('umb-tree-action-create-page')
|
||||
export default class UmbTreeActionCreatePageElement extends UmbContextConsumerMixin(LitElement) {
|
||||
export class UmbTreeActionCreatePageElement extends UmbActionElement {
|
||||
static styles = [UUITextStyles, css``];
|
||||
|
||||
private _actionService?: UmbActionService;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbActionService', (actionService: UmbActionService) => {
|
||||
this._actionService = actionService;
|
||||
});
|
||||
}
|
||||
|
||||
private _next() {
|
||||
this._actionService?.openPage('umb-tree-action-create-page-2');
|
||||
this._actionPageService?.openPage('umb-tree-action-create-page-2');
|
||||
}
|
||||
|
||||
private _back() {
|
||||
this._actionService?.closeTopPage();
|
||||
this._actionPageService?.closeTopPage();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<h2>Create page 1</h2>
|
||||
return html`<h2>Create page 1 for entity: ${this._entity.name}</h2>
|
||||
<p>This is the first create page, here you can go next or back (it just closes the modal for now)</p>
|
||||
<uui-button label="Back" look="secondary" @click=${this._back}></uui-button>
|
||||
<uui-button label="Next" look="primary" @click=${this._next}></uui-button>`;
|
||||
|
||||
@@ -1,30 +1,19 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { css, html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import type { ManifestEntityAction } from '../../../core/models';
|
||||
import { UmbActionService } from '../actions.service';
|
||||
import UmbActionElement from './action.element';
|
||||
|
||||
@customElement('umb-tree-action-create')
|
||||
export default class UmbTreeActionCreateElement extends UmbContextConsumerMixin(LitElement) {
|
||||
export default class UmbTreeActionCreateElement extends UmbActionElement {
|
||||
static styles = [UUITextStyles, css``];
|
||||
|
||||
@property({ attribute: false })
|
||||
public treeAction?: ManifestEntityAction;
|
||||
|
||||
private _actionService?: UmbActionService;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbActionService', (actionService: UmbActionService) => {
|
||||
this._actionService = actionService;
|
||||
});
|
||||
}
|
||||
|
||||
private _handleLabelClick() {
|
||||
console.log(this.treeAction, 'label clicked');
|
||||
this._actionService?.openPage('umb-tree-action-create-page');
|
||||
this._actionPageService?.openPage('umb-tree-action-create-page');
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { css, html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import type { ManifestEntityAction } from '../../../core/models';
|
||||
import { UmbModalService } from '../../../core/services/modal';
|
||||
import { UmbNodeStore } from '../../../core/stores/node.store';
|
||||
import { UmbActionService } from '../actions.service';
|
||||
import UmbActionElement from './action.element';
|
||||
|
||||
@customElement('umb-tree-action-delete')
|
||||
export default class UmbTreeActionDeleteElement extends UmbContextConsumerMixin(LitElement) {
|
||||
export default class UmbTreeActionDeleteElement extends UmbActionElement {
|
||||
static styles = [UUITextStyles, css``];
|
||||
|
||||
@property({ attribute: false })
|
||||
public treeAction?: ManifestEntityAction;
|
||||
|
||||
private _actionService?: UmbActionService;
|
||||
private _modalService?: UmbModalService;
|
||||
private _nodeStore?: UmbNodeStore;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext('umbActionService', (actionService: UmbActionService) => {
|
||||
this._actionService = actionService;
|
||||
});
|
||||
|
||||
this.consumeContext('umbModalService', (modalService: UmbModalService) => {
|
||||
this._modalService = modalService;
|
||||
});
|
||||
@@ -43,7 +37,7 @@ export default class UmbTreeActionDeleteElement extends UmbContextConsumerMixin(
|
||||
|
||||
modalHandler?.onClose.then(({ confirmed }: any) => {
|
||||
if (confirmed && this._actionService) {
|
||||
this._nodeStore?.trash(this._actionService.key);
|
||||
this._nodeStore?.trash(this._entity.key);
|
||||
this._actionService.close();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { css, html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { UmbContextConsumerMixin } from '../../../core/context';
|
||||
import type { ManifestEntityAction } from '../../../core/models';
|
||||
import UmbActionElement from './action.element';
|
||||
|
||||
@customElement('umb-tree-action-reload')
|
||||
export default class UmbTreeActionReloadElement extends UmbContextConsumerMixin(LitElement) {
|
||||
export default class UmbTreeActionReloadElement extends UmbActionElement {
|
||||
static styles = [UUITextStyles, css``];
|
||||
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -7,7 +7,7 @@ import { UUIMenuItemEvent } from '@umbraco-ui/uui';
|
||||
import { UmbSectionContext } from '../../sections/section.context';
|
||||
import { map, Subscription } from 'rxjs';
|
||||
import { Entity } from '../../../mocks/data/entity.data';
|
||||
import { UmbActionService } from '../actions.service';
|
||||
import { UmbActionService } from '../actions/actions.service';
|
||||
|
||||
@customElement('umb-tree-item')
|
||||
export class UmbTreeItem extends UmbContextConsumerMixin(LitElement) {
|
||||
@@ -143,7 +143,7 @@ export class UmbTreeItem extends UmbContextConsumerMixin(LitElement) {
|
||||
}
|
||||
|
||||
private _openActions() {
|
||||
this._actionService?.open(this.label, this.itemKey);
|
||||
this._actionService?.open({ name: this.label, key: this.itemKey });
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
Reference in New Issue
Block a user