initial version

This commit is contained in:
Niels Lyngsø
2023-06-01 14:22:45 +02:00
parent 46bf87f2ca
commit da27b970c0
7 changed files with 72 additions and 79 deletions

View File

@@ -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,

View File

@@ -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}

View File

@@ -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);

View File

@@ -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>
`;

View File

@@ -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) {

View File

@@ -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)
);
}
}

View File

@@ -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');