Merge branch 'main' into feature/auth-providers

This commit is contained in:
Jacob Overgaard
2024-04-09 17:17:48 +02:00
committed by GitHub
9 changed files with 180 additions and 9 deletions

View File

@@ -34,6 +34,7 @@
"./document-type": "./dist-cms/packages/documents/document-types/index.js",
"./document": "./dist-cms/packages/documents/documents/index.js",
"./dynamic-root": "./dist-cms/packages/dynamic-root/index.js",
"./entity": "./dist-cms/packages/core/entity/index.js",
"./entity-action": "./dist-cms/packages/core/entity-action/index.js",
"./entity-bulk-action": "./dist-cms/packages/core/entity-bulk-action/index.js",
"./event": "./dist-cms/packages/core/event/index.js",

View File

@@ -1,3 +1,4 @@
import { UmbEntityContext } from '@umbraco-cms/backoffice/entity';
import type { UmbEntityActionArgs } from './types.js';
import { html, customElement, property, state, css } from '@umbraco-cms/backoffice/external/lit';
import type { ManifestEntityAction, MetaEntityAction } from '@umbraco-cms/backoffice/extension-registry';
@@ -43,8 +44,13 @@ export class UmbEntityActionListElement extends UmbLitElement {
[UmbEntityActionArgs<MetaEntityAction>]
>;
#entityContext = new UmbEntityContext(this);
#generateApiArgs() {
if (!this._props.entityType || this._props.unique !== undefined) return;
if (!this._props.entityType || this._props.unique === undefined) return;
this.#entityContext.setEntityType(this._props.entityType);
this.#entityContext.setUnique(this._props.unique);
this._apiArgs = (manifest: ManifestEntityAction<MetaEntityAction>) => {
return [{ entityType: this._props.entityType!, unique: this._props.unique!, meta: manifest.meta }];
@@ -59,7 +65,7 @@ export class UmbEntityActionListElement extends UmbLitElement {
.filter=${this._filter}
.elementProps=${this._props}
.apiArgs=${this._apiArgs}></umb-extension-with-api-slot>
`
`
: '';
}

View File

@@ -0,0 +1,4 @@
import type { UmbEntityContext } from './entity.context.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
export const UMB_ENTITY_CONTEXT = new UmbContextToken<UmbEntityContext>('UmbEntityContext');

View File

@@ -0,0 +1,77 @@
import { expect } from '@open-wc/testing';
import { UmbEntityContext } from './entity.context.js';
import { UMB_ENTITY_CONTEXT } from './entity.context-token.js';
import { Observable } from '@umbraco-cms/backoffice/external/rxjs';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
@customElement('umb-test-host')
export class UmbTestHostElement extends UmbElementMixin(HTMLElement) {}
@customElement('umb-test-child')
export class UmbTestChildElement extends UmbElementMixin(HTMLElement) {}
describe('UmbEntityContext', () => {
let context: UmbEntityContext;
let host: UmbTestHostElement;
let child: UmbTestChildElement;
beforeEach(() => {
host = new UmbTestHostElement();
child = new UmbTestChildElement();
host.appendChild(child);
document.body.appendChild(host);
context = new UmbEntityContext(host);
});
describe('Public API', () => {
describe('properties', () => {
it('has a entity type property', () => {
expect(context).to.have.property('entityType').to.be.an.instanceOf(Observable);
});
it('has a unique property', () => {
expect(context).to.have.property('unique').to.be.an.instanceOf(Observable);
});
});
describe('methods', () => {
it('has a getEntityType method', () => {
expect(context).to.have.property('getEntityType').that.is.a('function');
});
it('has a setEntityType method', () => {
expect(context).to.have.property('setEntityType').that.is.a('function');
});
it('has a getUnique method', () => {
expect(context).to.have.property('getUnique').that.is.a('function');
});
it('has a setUnique method', () => {
expect(context).to.have.property('setUnique').that.is.a('function');
});
});
});
describe('set and get entity type', () => {
it('should set entity type', () => {
context.setEntityType('entity-type');
expect(context.getEntityType()).to.equal('entity-type');
});
});
describe('set and get unique', () => {
it('should set unique', () => {
context.setUnique('unique-value');
expect(context.getUnique()).to.equal('unique-value');
});
});
describe('it is provided as a context', () => {
it('should be provided as a context', async () => {
const providedContext = await child.getContext(UMB_ENTITY_CONTEXT);
expect(providedContext).to.equal(context);
});
});
});

View File

@@ -0,0 +1,63 @@
import { UMB_ENTITY_CONTEXT } from './entity.context-token.js';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbStringState } from '@umbraco-cms/backoffice/observable-api';
/**
* Provides the entity context
* @export
* @class UmbEntityContext
* @extends {UmbContextBase<UmbEntityContext>}
*/
export class UmbEntityContext extends UmbContextBase<UmbEntityContext> {
#entityType = new UmbStringState<string | undefined>(undefined);
public readonly entityType = this.#entityType.asObservable();
#unique = new UmbStringState<string | null | undefined>(undefined);
public readonly unique = this.#unique.asObservable();
/**
* Creates an instance of UmbEntityContext.
* @param {UmbControllerHost} host
* @memberof UmbEntityContext
*/
constructor(host: UmbControllerHost) {
super(host, UMB_ENTITY_CONTEXT);
}
/**
* Set the entity type
* @param {string | undefined} entityType
* @memberof UmbEntityContext
*/
setEntityType(entityType: string | undefined) {
this.#entityType.setValue(entityType);
}
/**
* Get the entity type
* @returns {string | undefined}
* @memberof UmbEntityContext
*/
getEntityType(): string | undefined {
return this.#entityType.getValue();
}
/**
* Set the unique
* @param {string | null | undefined} unique
* @memberof UmbEntityContext
*/
setUnique(unique: string | null | undefined) {
this.#unique.setValue(unique);
}
/**
* Get the unique
* @returns {string | null | undefined}
* @memberof UmbEntityContext
*/
getUnique() {
return this.#unique.getValue();
}
}

View File

@@ -0,0 +1,2 @@
export { UMB_ENTITY_CONTEXT } from './entity.context-token.js';
export { UmbEntityContext } from './entity.context.js';

View File

@@ -3,6 +3,7 @@ import { UMB_SECTION_SIDEBAR_CONTEXT } from '../section-sidebar/index.js';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, nothing, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { observeMultiple } from '@umbraco-cms/backoffice/observable-api';
@customElement('umb-section-sidebar-context-menu')
export class UmbSectionSidebarContextMenuElement extends UmbLitElement {
@@ -25,26 +26,37 @@ export class UmbSectionSidebarContextMenuElement extends UmbLitElement {
this.consumeContext(UMB_SECTION_SIDEBAR_CONTEXT, (instance) => {
this.#sectionSidebarContext = instance;
this.#observeEntityModel();
if (this.#sectionSidebarContext) {
// make prettier not break the lines on the next 4 lines:
// prettier-ignore
this.observe( this.#sectionSidebarContext.contextMenuIsOpen, (value) => (this._isOpen = value), '_observeContextMenuIsOpen');
// prettier-ignore
this.observe(this.#sectionSidebarContext.unique, (value) => (this._unique = value), '_observeUnique');
// prettier-ignore
this.observe(this.#sectionSidebarContext.entityType, (value) => (this._entityType = value), '_observeEntityType');
// prettier-ignore
this.observe(this.#sectionSidebarContext.headline, (value) => (this._headline = value), '_observeHeadline');
} else {
this.removeUmbControllerByAlias('_observeContextMenuIsOpen');
this.removeUmbControllerByAlias('_observeUnique');
this.removeUmbControllerByAlias('_observeEntityType');
this.removeUmbControllerByAlias('_observeHeadline');
}
});
}
#observeEntityModel() {
if (!this.#sectionSidebarContext) {
this.removeUmbControllerByAlias('_observeEntityModel');
return;
}
this.observe(
observeMultiple([this.#sectionSidebarContext.unique, this.#sectionSidebarContext.entityType]),
(values) => {
this._unique = values[0];
this._entityType = values[1];
},
),
'_observeEntityModel';
}
#closeContextMenu() {
this.#sectionSidebarContext?.closeContextMenu();
}
@@ -70,7 +82,6 @@ export class UmbSectionSidebarContextMenuElement extends UmbLitElement {
return this._isOpen ? html`<div id="backdrop" @click=${this.#closeContextMenu}></div>` : nothing;
}
// TODO: allow different views depending on left or right click
#renderModal() {
return this._isOpen && this._unique !== undefined && this._entityType
? html`<div id="action-modal">

View File

@@ -1,3 +1,4 @@
import { UmbEntityContext } from '@umbraco-cms/backoffice/entity';
import { UmbDocumentTypeDetailRepository } from '../../document-types/repository/detail/document-type-detail.repository.js';
import { UmbDocumentPropertyDataContext } from '../property-dataset-context/document-property-dataset-context.js';
import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js';
@@ -132,6 +133,9 @@ export class UmbDocumentWorkspaceContext
},
);
// TODO: this should be set up for all entity workspace contexts in a base class
#entityContext = new UmbEntityContext(this);
constructor(host: UmbControllerHost) {
super(host, UMB_DOCUMENT_WORKSPACE_ALIAS);
@@ -162,6 +166,8 @@ export class UmbDocumentWorkspaceContext
component: () => import('./document-workspace-editor.element.js'),
setup: (_component, info) => {
const unique = info.match.params.unique;
this.#entityContext.setEntityType(UMB_DOCUMENT_ENTITY_TYPE);
this.#entityContext.setUnique(unique);
this.load(unique);
},
},

View File

@@ -52,6 +52,7 @@
"@umbraco-cms/backoffice/document-type": ["./src/packages/documents/document-types/index.ts"],
"@umbraco-cms/backoffice/document": ["./src/packages/documents/documents/index.ts"],
"@umbraco-cms/backoffice/dynamic-root": ["./src/packages/dynamic-root/index.ts"],
"@umbraco-cms/backoffice/entity": ["./src/packages/core/entity/index.ts"],
"@umbraco-cms/backoffice/entity-action": ["./src/packages/core/entity-action/index.ts"],
"@umbraco-cms/backoffice/entity-bulk-action": ["./src/packages/core/entity-bulk-action/index.ts"],
"@umbraco-cms/backoffice/event": ["./src/packages/core/event/index.ts"],