Feature: DataType tracked references
Wires up the server endpoint. Fixes https://github.com/umbraco/Umbraco-CMS/issues/16390
This commit is contained in:
@@ -0,0 +1 @@
|
||||
export * from './repository/index.js';
|
||||
@@ -0,0 +1,4 @@
|
||||
import { manifests as repositoryManifests } from './repository/manifests.js';
|
||||
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<ManifestTypes> = [...repositoryManifests];
|
||||
@@ -0,0 +1,38 @@
|
||||
import { UmbDataTypeReferenceServerDataSource } from './data-type-reference.server.data.js';
|
||||
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
|
||||
import type { DataTypeReferenceResponseModel } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
export type UmbDataTypeReferenceModel = {
|
||||
unique: string;
|
||||
entityType: string;
|
||||
properties: Array<{ name: string; alias: string }>;
|
||||
};
|
||||
|
||||
export class UmbDataTypeReferenceRepository extends UmbControllerBase {
|
||||
#referenceSource: UmbDataTypeReferenceServerDataSource;
|
||||
|
||||
constructor(host: UmbControllerHost) {
|
||||
super(host);
|
||||
this.#referenceSource = new UmbDataTypeReferenceServerDataSource(this);
|
||||
}
|
||||
|
||||
async requestReferencedBy(unique: string) {
|
||||
if (!unique) throw new Error(`unique is required`);
|
||||
|
||||
const { data } = await this.#referenceSource.getReferencedBy(unique);
|
||||
if (!data) return;
|
||||
|
||||
return data.map(mapper);
|
||||
}
|
||||
}
|
||||
|
||||
const mapper = (item: DataTypeReferenceResponseModel): UmbDataTypeReferenceModel => {
|
||||
return {
|
||||
unique: item.id,
|
||||
entityType: item.type,
|
||||
properties: item.properties,
|
||||
};
|
||||
};
|
||||
|
||||
export default UmbDataTypeReferenceRepository;
|
||||
@@ -0,0 +1,31 @@
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources';
|
||||
import { DataTypeService } from '@umbraco-cms/backoffice/external/backend-api';
|
||||
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @class UmbDataTypeReferenceServerDataSource
|
||||
* @implements {RepositoryDetailDataSource}
|
||||
*/
|
||||
export class UmbDataTypeReferenceServerDataSource {
|
||||
#host: UmbControllerHost;
|
||||
|
||||
/**
|
||||
* Creates an instance of UmbDataTypeReferenceServerDataSource.
|
||||
* @param {UmbControllerHost} host
|
||||
* @memberof UmbDataTypeReferenceServerDataSource
|
||||
*/
|
||||
constructor(host: UmbControllerHost) {
|
||||
this.#host = host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the item for the given unique from the server
|
||||
* @param {string} id
|
||||
* @return {*}
|
||||
* @memberof UmbDataTypeReferenceServerDataSource
|
||||
*/
|
||||
async getReferencedBy(id: string) {
|
||||
return await tryExecuteAndNotify(this.#host, DataTypeService.getDataTypeByIdReferences({ id }));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './data-type-reference.repository.js';
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const UMB_DATA_TYPE_REFERENCE_REPOSITORY_ALIAS = 'Umb.Repository.DataType.Reference';
|
||||
|
||||
const repository: ManifestRepository = {
|
||||
type: 'repository',
|
||||
alias: UMB_DATA_TYPE_REFERENCE_REPOSITORY_ALIAS,
|
||||
name: 'Data Type Reference Repository',
|
||||
api: () => import('./data-type-reference.repository.js'),
|
||||
};
|
||||
|
||||
export const manifests: Array<ManifestTypes> = [repository];
|
||||
@@ -0,0 +1,117 @@
|
||||
import { UmbDataTypeReferenceRepository } from '../../../reference/index.js';
|
||||
import type { UmbDataTypeReferenceModel } from '../../../reference/index.js';
|
||||
import { css, html, customElement, state, repeat, property, when } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router';
|
||||
import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router';
|
||||
|
||||
const elementName = 'umb-data-type-workspace-view-info-reference';
|
||||
|
||||
@customElement(elementName)
|
||||
export class UmbDataTypeWorkspaceViewInfoReferenceElement extends UmbLitElement {
|
||||
#referenceRepository = new UmbDataTypeReferenceRepository(this);
|
||||
|
||||
#routeBuilder?: UmbModalRouteBuilder;
|
||||
|
||||
@property()
|
||||
dataTypeUnique = '';
|
||||
|
||||
@state()
|
||||
private _loading = true;
|
||||
|
||||
@state()
|
||||
private _items?: Array<UmbDataTypeReferenceModel> = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL)
|
||||
.addAdditionalPath(':entityType')
|
||||
.onSetup((params) => {
|
||||
return { data: { entityType: params.entityType, preset: {} } };
|
||||
})
|
||||
.observeRouteBuilder((routeBuilder) => {
|
||||
this.#routeBuilder = routeBuilder;
|
||||
});
|
||||
}
|
||||
|
||||
protected firstUpdated() {
|
||||
this.#getReferences();
|
||||
}
|
||||
|
||||
async #getReferences() {
|
||||
this._loading = true;
|
||||
|
||||
const items = await this.#referenceRepository.requestReferencedBy(this.dataTypeUnique);
|
||||
if (!items) return;
|
||||
|
||||
this._items = items;
|
||||
this._loading = false;
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<uui-box headline=${this.localize.term('references_tabName')}>
|
||||
${when(
|
||||
this._loading,
|
||||
() => html`<uui-loader></uui-loader>`,
|
||||
() => this.#renderItems(),
|
||||
)}
|
||||
</uui-box>
|
||||
`;
|
||||
}
|
||||
|
||||
#getEditPath(item: UmbDataTypeReferenceModel) {
|
||||
// TODO: [LK] Ask NL for a reminder on how the route constants work.
|
||||
return this.#routeBuilder ? this.#routeBuilder({ entityType: item.entityType }) + `edit/${item.unique}` : '#';
|
||||
}
|
||||
|
||||
#renderItems() {
|
||||
if (!this._items?.length) return html`<p>${this.localize.term('references_DataTypeNoReferences')}</p>`;
|
||||
return html`
|
||||
<uui-table>
|
||||
<uui-table-head>
|
||||
<uui-table-head-cell><umb-localize key="general_name">Name</umb-localize></uui-table-head-cell>
|
||||
<uui-table-head-cell><umb-localize key="general_type">Type</umb-localize></uui-table-head-cell>
|
||||
<uui-table-head-cell>
|
||||
<umb-localize key="references_usedByProperties">Referenced by</umb-localize>
|
||||
</uui-table-head-cell>
|
||||
</uui-table-head>
|
||||
${repeat(
|
||||
this._items,
|
||||
(item) => item.unique,
|
||||
(item) => html`
|
||||
<uui-table-row>
|
||||
<uui-table-cell>
|
||||
<uui-ref-node-document-type href=${this.#getEditPath(item)} name=${item.unique}>
|
||||
<umb-icon slot="icon" name="icon-document"></umb-icon>
|
||||
</uui-ref-node-document-type>
|
||||
</uui-table-cell>
|
||||
<uui-table-cell>${item.entityType}</uui-table-cell>
|
||||
<uui-table-cell>${item.properties.map((prop) => prop.name).join(', ')}</uui-table-cell>
|
||||
</uui-table-row>
|
||||
`,
|
||||
)}
|
||||
</uui-table>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
UmbTextStyles,
|
||||
css`
|
||||
uui-table-cell {
|
||||
color: var(--uui-color-text-alt);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
export { UmbDataTypeWorkspaceViewInfoReferenceElement as element };
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[elementName]: UmbDataTypeWorkspaceViewInfoReferenceElement;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import { css, html, customElement, state } from '@umbraco-cms/backoffice/externa
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbWorkspaceViewElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
import './data-type-workspace-view-info-reference.element.js';
|
||||
|
||||
@customElement('umb-workspace-view-data-type-info')
|
||||
export class UmbWorkspaceViewDataTypeInfoElement extends UmbLitElement implements UmbWorkspaceViewElement {
|
||||
@state()
|
||||
_unique?: string;
|
||||
_unique: string = '';
|
||||
|
||||
@state()
|
||||
_schemaAlias?: string;
|
||||
@@ -30,7 +32,7 @@ export class UmbWorkspaceViewDataTypeInfoElement extends UmbLitElement implement
|
||||
if (!this._workspaceContext) return;
|
||||
|
||||
this.observe(this._workspaceContext.unique, (unique) => {
|
||||
this._unique = unique;
|
||||
this._unique = unique!;
|
||||
});
|
||||
|
||||
this.observe(this._workspaceContext.propertyEditorSchemaAlias, (schemaAlias) => {
|
||||
@@ -43,36 +45,63 @@ export class UmbWorkspaceViewDataTypeInfoElement extends UmbLitElement implement
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` ${this._renderGeneralInfo()}${this._renderReferences()} `;
|
||||
}
|
||||
|
||||
private _renderGeneralInfo() {
|
||||
return html`
|
||||
<uui-box headline="General" style="margin-bottom: 20px;">
|
||||
<umb-property-layout label="Id">
|
||||
<div slot="editor">${this._unique}</div>
|
||||
</umb-property-layout>
|
||||
<umb-property-layout label="Property Editor Alias">
|
||||
<div slot="editor">${this._schemaAlias}</div>
|
||||
</umb-property-layout>
|
||||
|
||||
<umb-property-layout label="Property Editor UI Alias">
|
||||
<div slot="editor">${this._uiAlias}</div>
|
||||
</umb-property-layout>
|
||||
</uui-box>
|
||||
<div class="container">
|
||||
<umb-data-type-workspace-view-info-reference
|
||||
.dataTypeUnique=${this._unique}></umb-data-type-workspace-view-info-reference>
|
||||
</div>
|
||||
<div class="container">${this.#renderGeneralInfo()}</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _renderReferences() {
|
||||
return html` <uui-box headline="References"> </uui-box> `;
|
||||
#renderGeneralInfo() {
|
||||
return html`
|
||||
<uui-box id="general-section" headline="General">
|
||||
<div class="general-item">
|
||||
<strong><umb-localize key="template_id">Id</umb-localize></strong>
|
||||
<span>${this._unique}</span>
|
||||
</div>
|
||||
<div class="general-item">
|
||||
<strong>Property Editor Schema Alias</strong>
|
||||
<span>${this._schemaAlias}</span>
|
||||
</div>
|
||||
<div class="general-item">
|
||||
<strong>Property Editor UI Alias</strong>
|
||||
<span>${this._uiAlias}</span>
|
||||
</div>
|
||||
</uui-box>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
UmbTextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
display: grid;
|
||||
gap: var(--uui-size-layout-1);
|
||||
padding: var(--uui-size-layout-1);
|
||||
grid-template-columns: 1fr 350px;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--uui-size-layout-1);
|
||||
}
|
||||
|
||||
#general-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.general-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--uui-size-space-1);
|
||||
}
|
||||
|
||||
.general-item:not(:last-child) {
|
||||
margin-bottom: var(--uui-size-space-6);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user