initial version
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
import { UmbModalToken } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
export interface UmbDataTypePickerFlowDataTypePickerModalData {
|
||||
selection?: Array<string>;
|
||||
propertyEditorUiAlias: string;
|
||||
}
|
||||
|
||||
export type UmbDataTypePickerFlowDataTypePickerModalResult = undefined;
|
||||
export type UmbDataTypePickerFlowDataTypePickerModalResult = {
|
||||
dataTypeId?: string;
|
||||
createNew?: boolean;
|
||||
};
|
||||
|
||||
export const UMB_DATA_TYPE_PICKER_FLOW_DATA_TYPE_PICKER_MODAL = new UmbModalToken<
|
||||
UmbDataTypePickerFlowDataTypePickerModalData,
|
||||
|
||||
@@ -2,10 +2,9 @@ import { UmbDataTypeRepository } from '../../repository/data-type.repository.js'
|
||||
import { css, html, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui';
|
||||
import {
|
||||
UmbPropertyEditorUIPickerModalData,
|
||||
UmbPropertyEditorUIPickerModalResult,
|
||||
UmbModalHandler,
|
||||
UmbDataTypePickerFlowDataTypePickerModalData,
|
||||
UmbDataTypePickerFlowDataTypePickerModalResult,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { FolderTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api';
|
||||
@@ -18,15 +17,11 @@ export class UmbDataTypePickerFlowDataTypePickerModalElement extends UmbLitEleme
|
||||
@state()
|
||||
private _dataTypes?: Array<FolderTreeItemResponseModel>;
|
||||
|
||||
@state()
|
||||
private _selection: Array<string> = [];
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
if (!this.data) return;
|
||||
|
||||
this._selection = this.data.selection ?? [];
|
||||
this._observeDataTypesOf(this.data.propertyEditorUiAlias);
|
||||
}
|
||||
|
||||
@@ -35,36 +30,45 @@ export class UmbDataTypePickerFlowDataTypePickerModalElement extends UmbLitEleme
|
||||
|
||||
const dataTypeRepository = new UmbDataTypeRepository(this);
|
||||
|
||||
// TODO: This is a hack to get the data types of a property editor ui alias.
|
||||
// TODO: Make sure filtering works data-type that does not have a property editor ui, but should be using the default property editor UI for those.
|
||||
// TODO: make an end-point just retrieving the data types using a given property editor ui alias.
|
||||
await dataTypeRepository.requestRootTreeItems();
|
||||
const { data } = await dataTypeRepository.requestRootTreeItems();
|
||||
|
||||
if (!data) return;
|
||||
|
||||
await Promise.all(
|
||||
data.items.map((item) => {
|
||||
if (item.id) {
|
||||
return dataTypeRepository.requestById(item.id);
|
||||
}
|
||||
return Promise.resolve();
|
||||
})
|
||||
);
|
||||
|
||||
// TODO: Use the asObservable from above onces end-point has been made.
|
||||
const source = await dataTypeRepository.treeItemsByPropertyEditorUiAlias(propertyEditorUiAlias);
|
||||
const source = await dataTypeRepository.byPropertyEditorUiAlias(propertyEditorUiAlias);
|
||||
this.observe(source, (dataTypes) => {
|
||||
console.log('observe got', dataTypes);
|
||||
this._dataTypes = dataTypes;
|
||||
});
|
||||
}
|
||||
|
||||
private _handleClick(dataType: FolderTreeItemResponseModel) {
|
||||
if (dataType.id) {
|
||||
this._select(dataType.id);
|
||||
this.modalHandler?.submit({ dataTypeId: dataType.id });
|
||||
}
|
||||
}
|
||||
|
||||
private _select(alias: string) {
|
||||
this._selection = [alias];
|
||||
}
|
||||
|
||||
private _close() {
|
||||
this.modalHandler?.reject();
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
modalHandler?: UmbModalHandler<UmbPropertyEditorUIPickerModalData, UmbPropertyEditorUIPickerModalResult>;
|
||||
|
||||
private _submit() {
|
||||
this.modalHandler?.submit({ selection: this._selection });
|
||||
}
|
||||
modalHandler?: UmbModalHandler<
|
||||
UmbDataTypePickerFlowDataTypePickerModalData,
|
||||
UmbDataTypePickerFlowDataTypePickerModalResult
|
||||
>;
|
||||
|
||||
render() {
|
||||
return html`
|
||||
@@ -85,7 +89,7 @@ export class UmbDataTypePickerFlowDataTypePickerModalElement extends UmbLitEleme
|
||||
(dataType) => dataType.id,
|
||||
(dataType) =>
|
||||
dataType.id
|
||||
? html` <li class="item" ?selected=${this._selection.includes(dataType.id)}>
|
||||
? html` <li class="item">
|
||||
<button type="button" @click="${() => this._handleClick(dataType)}">
|
||||
<uui-icon name="${dataType.icon}" class="icon"></uui-icon>
|
||||
${dataType.name}
|
||||
|
||||
@@ -4,9 +4,12 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { groupBy } from '@umbraco-cms/backoffice/external/lodash';
|
||||
import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
|
||||
import {
|
||||
UMB_DATA_TYPE_PICKER_FLOW_DATA_TYPE_PICKER_MODAL,
|
||||
UmbDataTypePickerFlowModalData,
|
||||
UmbDataTypePickerFlowModalResult,
|
||||
UmbModalHandler,
|
||||
UmbModalRouteBuilder,
|
||||
UmbModalRouteRegistrationController,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
import { ManifestPropertyEditorUi, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
@@ -43,6 +46,9 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement {
|
||||
@state()
|
||||
private _submitLabel = 'Select';
|
||||
|
||||
@state()
|
||||
private _dataTypePickerModalRouteBuilder?: UmbModalRouteBuilder;
|
||||
|
||||
#repository;
|
||||
#dataTypes: Array<EntityTreeItemResponseModel> = [];
|
||||
#propertyEditorUIs: Array<ManifestPropertyEditorUi> = [];
|
||||
@@ -54,6 +60,21 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement {
|
||||
super();
|
||||
this.#repository = new UmbDataTypeRepository(this);
|
||||
|
||||
new UmbModalRouteRegistrationController(this, UMB_DATA_TYPE_PICKER_FLOW_DATA_TYPE_PICKER_MODAL)
|
||||
.addAdditionalPath(':uiAlias')
|
||||
.onSetup((routingInfo) => {
|
||||
return {
|
||||
propertyEditorUiAlias: routingInfo.uiAlias,
|
||||
};
|
||||
})
|
||||
.onSubmit((submitData) => {
|
||||
console.log('got', submitData);
|
||||
})
|
||||
.observeRouteBuilder((routeBuilder) => {
|
||||
this._dataTypePickerModalRouteBuilder = routeBuilder;
|
||||
this.requestUpdate('_dataTypePickerModalRouteBuilder');
|
||||
});
|
||||
|
||||
this.#init();
|
||||
}
|
||||
|
||||
@@ -74,10 +95,6 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private _handleUiClick(propertyEditorUi: ManifestPropertyEditorUi) {
|
||||
// Open a modal of available data types for the selected Property Editor UI.
|
||||
}
|
||||
|
||||
private _handleDataTypeClick(dataType: EntityTreeItemResponseModel) {
|
||||
if (dataType.id) {
|
||||
this._select(dataType.id);
|
||||
@@ -193,16 +210,20 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement {
|
||||
|
||||
private _renderGroupUIs(uis: Array<ManifestPropertyEditorUi>) {
|
||||
return html` <ul id="item-grid">
|
||||
${repeat(
|
||||
uis,
|
||||
(propertyEditorUI) => propertyEditorUI.alias,
|
||||
(propertyEditorUI) => html` <li class="item">
|
||||
<button type="button" @click="${() => this._handleUiClick(propertyEditorUI)}">
|
||||
<uui-icon name="${propertyEditorUI.meta.icon}" class="icon"></uui-icon>
|
||||
${propertyEditorUI.meta.label || propertyEditorUI.name}
|
||||
</button>
|
||||
</li>`
|
||||
)}
|
||||
${this._dataTypePickerModalRouteBuilder
|
||||
? repeat(
|
||||
uis,
|
||||
(propertyEditorUI) => propertyEditorUI.alias,
|
||||
(propertyEditorUI) => html` <li class="item">
|
||||
<uui-button
|
||||
type="button"
|
||||
href=${this._dataTypePickerModalRouteBuilder!({ uiAlias: propertyEditorUI.alias })}>
|
||||
<uui-icon name="${propertyEditorUI.meta.icon}" class="icon"></uui-icon>
|
||||
${propertyEditorUI.meta.label || propertyEditorUI.name}
|
||||
</uui-button>
|
||||
</li>`
|
||||
)
|
||||
: ''}
|
||||
</ul>`;
|
||||
}
|
||||
|
||||
@@ -242,21 +263,8 @@ export class UmbDataTypePickerFlowModalElement extends UmbLitElement {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#item-grid .item[selected] button {
|
||||
background: var(--uui-color-selected);
|
||||
color: var(--uui-color-selected-contrast);
|
||||
}
|
||||
|
||||
#item-grid .item button {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
#item-grid .item uui-button {
|
||||
padding: var(--uui-size-space-3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
font-size: 0.8rem;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: var(--uui-color-interactive);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import type { UmbDataTypePickerFlowModalElement } from './data-type-picker-flow-modal.element.js';
|
||||
import { html } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbPropertyEditorUIPickerModalData } from '@umbraco-cms/backoffice/modal';
|
||||
|
||||
import './data-type-picker-flow-modal.element.js';
|
||||
import '../../../../core/components/body-layout/body-layout.element.js';
|
||||
|
||||
export default {
|
||||
title: 'API/Modals/Layouts/Data Type Picker Flow',
|
||||
component: 'umb-data-type-picker-flow-modal',
|
||||
id: 'umb-data-type-picker-flow-modal',
|
||||
} as Meta;
|
||||
|
||||
const data: UmbPropertyEditorUIPickerModalData = { selection: [] };
|
||||
|
||||
export const Overview: Story<UmbDataTypePickerFlowModalElement> = () => html`
|
||||
<umb-data-type-picker-flow-modal .data=${data as any}></umb-data-type-picker-flow-modal>
|
||||
`;
|
||||
@@ -188,10 +188,10 @@ export class UmbDataTypeRepository
|
||||
return this.#detailStore!.byId(id);
|
||||
}
|
||||
|
||||
async treeItemsByPropertyEditorUiAlias(propertyEditorUiAlias: string) {
|
||||
async byPropertyEditorUiAlias(propertyEditorUiAlias: string) {
|
||||
if (!propertyEditorUiAlias) throw new Error('propertyEditorUiAlias is missing');
|
||||
await this.#init;
|
||||
return this.#treeStore!.withPropertyEditorUiAlias(propertyEditorUiAlias);
|
||||
return this.#detailStore!.withPropertyEditorUiAlias(propertyEditorUiAlias);
|
||||
}
|
||||
|
||||
async create(dataType: CreateDataTypeRequestModel) {
|
||||
|
||||
@@ -52,4 +52,11 @@ export class UmbDataTypeStore extends UmbStoreBase<DataTypeResponseModel> {
|
||||
remove(uniques: Array<DataTypeResponseModel['id']>) {
|
||||
this._data.remove(uniques);
|
||||
}
|
||||
|
||||
withPropertyEditorUiAlias(propertyEditorUiAlias: string) {
|
||||
// TODO: Use a model for the data-type tree items: ^^Most likely it should be parsed to the UmbEntityTreeStore as a generic type.
|
||||
return this._data.getObservablePart((items) =>
|
||||
items.filter((item) => (item as any).propertyEditorUiAlias === propertyEditorUiAlias)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,15 +18,6 @@ export class UmbDataTypeTreeStore extends UmbEntityTreeStore {
|
||||
constructor(host: UmbControllerHostElement) {
|
||||
super(host, UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN.toString());
|
||||
}
|
||||
|
||||
withPropertyEditorUiAlias(propertyEditorUiAlias: string) {
|
||||
// TODO: Use a model for the data-type tree items: ^^Most likely it should be parsed to the UmbEntityTreeStore as a generic type.
|
||||
return this._data.getObservablePart((item) => {
|
||||
if ((item as any).propertyEditorUiAlias === propertyEditorUiAlias) {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const UMB_DATA_TYPE_TREE_STORE_CONTEXT_TOKEN = new UmbContextToken<UmbDataTypeTreeStore>('UmbDataTypeTreeStore');
|
||||
|
||||
Reference in New Issue
Block a user