Merge branch 'main' into feature/audit-log-and-info-workspace
This commit is contained in:
@@ -23,7 +23,7 @@ export * from './input-number-range/index.js';
|
||||
export * from './input-radio-button-list/index.js';
|
||||
export * from './input-section/index.js';
|
||||
export * from './input-slider/index.js';
|
||||
export * from './input-start-node/index.js';
|
||||
export * from './input-tree-picker-source/index.js';
|
||||
export * from './input-tiny-mce/index.js';
|
||||
export * from './input-toggle/index.js';
|
||||
export * from './input-upload-field/index.js';
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './input-start-node.element.js';
|
||||
@@ -0,0 +1 @@
|
||||
export * from './input-tree-picker-source.element.js';
|
||||
@@ -5,34 +5,34 @@ import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { UmbInputMediaElement } from '@umbraco-cms/backoffice/media';
|
||||
//import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
|
||||
export type ContentType = 'content' | 'member' | 'media';
|
||||
export type UmbTreePickerSource = {
|
||||
type?: UmbTreePickerSourceType;
|
||||
id?: string | null;
|
||||
dynamicRoot?: UmbTreePickerDynamicRoot | null;
|
||||
};
|
||||
|
||||
export type DynamicRootQueryStepType = {
|
||||
export type UmbTreePickerSourceType = 'content' | 'member' | 'media';
|
||||
|
||||
export type UmbTreePickerDynamicRoot = {
|
||||
originAlias: string;
|
||||
querySteps?: Array<UmbTreePickerDynamicRootQueryStep> | null;
|
||||
};
|
||||
|
||||
export type UmbTreePickerDynamicRootQueryStep = {
|
||||
alias: string;
|
||||
anyOfDocTypeKeys: Array<string>;
|
||||
};
|
||||
|
||||
export type DynamicRootType = {
|
||||
originAlias: string;
|
||||
querySteps?: Array<DynamicRootQueryStepType> | null;
|
||||
};
|
||||
|
||||
export type StartNode = {
|
||||
type?: ContentType;
|
||||
id?: string | null;
|
||||
dynamicRoot?: DynamicRootType | null;
|
||||
};
|
||||
|
||||
@customElement('umb-input-start-node')
|
||||
export class UmbInputStartNodeElement extends FormControlMixin(UmbLitElement) {
|
||||
@customElement('umb-input-tree-picker-source')
|
||||
export class UmbInputTreePickerSourceElement extends FormControlMixin(UmbLitElement) {
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _type: StartNode['type'] = 'content';
|
||||
private _type: UmbTreePickerSource['type'] = 'content';
|
||||
|
||||
@property()
|
||||
public set type(value: StartNode['type']) {
|
||||
public set type(value: UmbTreePickerSource['type']) {
|
||||
if (value === undefined) {
|
||||
value = this._type;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export class UmbInputStartNodeElement extends FormControlMixin(UmbLitElement) {
|
||||
|
||||
this.requestUpdate('type', oldValue);
|
||||
}
|
||||
public get type(): StartNode['type'] {
|
||||
public get type(): UmbTreePickerSource['type'] {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export class UmbInputStartNodeElement extends FormControlMixin(UmbLitElement) {
|
||||
nodeId?: string | null;
|
||||
|
||||
@property({ attribute: false })
|
||||
dynamicRoot?: DynamicRootType | null;
|
||||
dynamicRoot?: UmbTreePickerDynamicRoot | null;
|
||||
|
||||
@state()
|
||||
_options: Array<Option> = [
|
||||
@@ -67,7 +67,7 @@ export class UmbInputStartNodeElement extends FormControlMixin(UmbLitElement) {
|
||||
#onTypeChange(event: UUISelectEvent) {
|
||||
//console.log('onTypeChange');
|
||||
|
||||
this.type = event.target.value as StartNode['type'];
|
||||
this.type = event.target.value as UmbTreePickerSource['type'];
|
||||
|
||||
this.nodeId = '';
|
||||
|
||||
@@ -140,10 +140,10 @@ export class UmbInputStartNodeElement extends FormControlMixin(UmbLitElement) {
|
||||
];
|
||||
}
|
||||
|
||||
export default UmbInputStartNodeElement;
|
||||
export default UmbInputTreePickerSourceElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-input-start-node': UmbInputStartNodeElement;
|
||||
'umb-input-tree-picker-source': UmbInputTreePickerSourceElement;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UmbTreeElement } from '../../../tree/tree.element.js';
|
||||
import { UmbTreeElement, type UmbTreeSelectionConfiguration } from '@umbraco-cms/backoffice/tree';
|
||||
import { css, html, nothing, customElement, query, state, styleMap } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UUIBooleanInputEvent, UUIInputElement } from '@umbraco-cms/backoffice/external/uui';
|
||||
import {
|
||||
@@ -13,6 +13,13 @@ import { UMB_DOCUMENT_TREE_ALIAS } from '@umbraco-cms/backoffice/document';
|
||||
|
||||
@customElement('umb-link-picker-modal')
|
||||
export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPickerModalData, UmbLinkPickerModalValue> {
|
||||
@state()
|
||||
private _selectionConfiguration: UmbTreeSelectionConfiguration = {
|
||||
multiple: false,
|
||||
selectable: true,
|
||||
selection: [],
|
||||
};
|
||||
|
||||
@state()
|
||||
_selectedKey?: string;
|
||||
|
||||
@@ -51,6 +58,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
|
||||
this.observe(this.modalContext.value, (value) => {
|
||||
(this._link as any) = value.link;
|
||||
this._selectedKey = this._link?.udi ? getKeyFromUdi(this._link.udi) : undefined;
|
||||
this._selectionConfiguration.selection = this._selectedKey ? [this._selectedKey] : [];
|
||||
});
|
||||
}
|
||||
this._layout = this.data?.config;
|
||||
@@ -76,11 +84,13 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
|
||||
//TODO: Update icon, published, trashed
|
||||
e.stopPropagation();
|
||||
const element = e.target as UmbTreeElement;
|
||||
const selectedKey = element.selection[element.selection.length - 1];
|
||||
const selection = element.getSelection();
|
||||
const selectedKey = selection[selection.length - 1];
|
||||
|
||||
if (!selectedKey) {
|
||||
this.#partialUpdateLink({ udi: '', url: undefined });
|
||||
this._selectedKey = undefined;
|
||||
this._selectionConfiguration.selection = [];
|
||||
this.requestUpdate();
|
||||
return;
|
||||
}
|
||||
@@ -88,6 +98,7 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
|
||||
const udi = buildUdi(entityType, selectedKey);
|
||||
|
||||
this._selectedKey = selectedKey;
|
||||
this._selectionConfiguration.selection = [this._selectedKey];
|
||||
this.#partialUpdateLink({ udi: udi, url: udi });
|
||||
this.requestUpdate();
|
||||
}
|
||||
@@ -177,11 +188,9 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
|
||||
label=${this.localize.term('placeholders_search')}></uui-input>
|
||||
<umb-tree
|
||||
?hide-tree-root=${true}
|
||||
?multiple=${false}
|
||||
alias=${UMB_DOCUMENT_TREE_ALIAS}
|
||||
@selection-change=${(event: CustomEvent) => this.#handleSelectionChange(event, 'document')}
|
||||
.selection=${[this._selectedKey ?? '']}
|
||||
selectable></umb-tree>
|
||||
.selectionConfiguration=${this._selectionConfiguration}></umb-tree>
|
||||
</div>
|
||||
<hr />
|
||||
<uui-symbol-expand
|
||||
@@ -192,11 +201,9 @@ export class UmbLinkPickerModalElement extends UmbModalBaseElement<UmbLinkPicker
|
||||
<div style="${styleMap({ display: !this.mediaExpanded ? 'block' : 'none' })}">
|
||||
<umb-tree
|
||||
?hide-tree-root=${true}
|
||||
?multiple=${false}
|
||||
alias="Umb.Tree.Media"
|
||||
@selection-change=${(event: CustomEvent) => this.#handleSelectionChange(event, 'media')}
|
||||
.selection=${[this._selectedKey ?? '']}
|
||||
selectable></umb-tree>
|
||||
.selectionConfiguration=${this._selectionConfiguration}></umb-tree>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { type UmbTreeElement } from '../../../tree/tree.element.js';
|
||||
import { html, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbTreePickerModalData, UmbPickerModalValue, UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbTreeItemModelBase } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbTreeElement, UmbTreeItemModelBase, type UmbTreeSelectionConfiguration } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
@customElement('umb-tree-picker-modal')
|
||||
export class UmbTreePickerModalElement<TreeItemType extends UmbTreeItemModelBase> extends UmbModalBaseElement<
|
||||
@@ -11,10 +10,11 @@ export class UmbTreePickerModalElement<TreeItemType extends UmbTreeItemModelBase
|
||||
UmbPickerModalValue
|
||||
> {
|
||||
@state()
|
||||
_selection: Array<string | null> = [];
|
||||
|
||||
@state()
|
||||
_multiple = false;
|
||||
_selectionConfiguration: UmbTreeSelectionConfiguration = {
|
||||
multiple: false,
|
||||
selectable: true,
|
||||
selection: [],
|
||||
};
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
@@ -22,17 +22,17 @@ export class UmbTreePickerModalElement<TreeItemType extends UmbTreeItemModelBase
|
||||
// TODO: We should make a nicer way to observe the value..
|
||||
if (this.modalContext) {
|
||||
this.observe(this.modalContext.value, (value) => {
|
||||
this._selection = value?.selection ?? [];
|
||||
this._selectionConfiguration.selection = value?.selection ?? [];
|
||||
});
|
||||
}
|
||||
|
||||
this._multiple = this.data?.multiple ?? false;
|
||||
this._selectionConfiguration.multiple = this.data?.multiple ?? false;
|
||||
}
|
||||
|
||||
#onSelectionChange(e: CustomEvent) {
|
||||
e.stopPropagation();
|
||||
const element = e.target as UmbTreeElement;
|
||||
this.value = { selection: element.selection };
|
||||
this.value = { selection: element.getSelection() };
|
||||
this.dispatchEvent(new UmbSelectionChangeEvent());
|
||||
}
|
||||
|
||||
@@ -44,11 +44,9 @@ export class UmbTreePickerModalElement<TreeItemType extends UmbTreeItemModelBase
|
||||
?hide-tree-root=${this.data?.hideTreeRoot}
|
||||
alias=${ifDefined(this.data?.treeAlias)}
|
||||
@selection-change=${this.#onSelectionChange}
|
||||
.selection=${this._selection}
|
||||
selectable
|
||||
.selectionConfiguration=${this._selectionConfiguration}
|
||||
.filter=${this.data?.filter}
|
||||
.selectableFilter=${this.data?.pickableFilter}
|
||||
?multiple=${this._multiple}></umb-tree>
|
||||
.selectableFilter=${this.data?.pickableFilter}></umb-tree>
|
||||
</uui-box>
|
||||
<div slot="actions">
|
||||
<uui-button label=${this.localize.term('general_close')} @click=${this._rejectModal}></uui-button>
|
||||
|
||||
@@ -2,11 +2,11 @@ import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension
|
||||
|
||||
export const manifest: ManifestPropertyEditorUi = {
|
||||
type: 'propertyEditorUi',
|
||||
alias: 'Umb.PropertyEditorUi.TreePicker.StartNode',
|
||||
name: 'Tree Picker Start Node Property Editor UI',
|
||||
js: () => import('./property-editor-ui-tree-picker-start-node.element.js'),
|
||||
alias: 'Umb.PropertyEditorUi.TreePicker.SourcePicker',
|
||||
name: 'Tree Picker Source Picker Property Editor UI',
|
||||
js: () => import('./property-editor-ui-tree-picker-source-picker.element.js'),
|
||||
meta: {
|
||||
label: 'Tree Picker Start Node',
|
||||
label: 'Tree Picker Source Picker',
|
||||
icon: 'icon-page-add',
|
||||
group: 'pickers',
|
||||
propertyEditorSchemaAlias: '',
|
||||
@@ -1,4 +1,4 @@
|
||||
import { StartNode, UmbInputStartNodeElement } from '@umbraco-cms/backoffice/components';
|
||||
import { type UmbTreePickerSource, UmbInputTreePickerSourceElement } from '@umbraco-cms/backoffice/components';
|
||||
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
|
||||
@@ -6,18 +6,18 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
|
||||
/**
|
||||
* @element umb-property-editor-ui-tree-picker-start-node
|
||||
* @element umb-property-editor-ui-tree-picker-source-picker
|
||||
*/
|
||||
@customElement('umb-property-editor-ui-tree-picker-start-node')
|
||||
export class UmbPropertyEditorUITreePickerStartNodeElement extends UmbLitElement implements UmbPropertyEditorUiElement {
|
||||
@customElement('umb-property-editor-ui-tree-picker-source-picker')
|
||||
export class UmbPropertyEditorUITreePickerSourcePickerElement extends UmbLitElement implements UmbPropertyEditorUiElement {
|
||||
@property({ type: Object })
|
||||
value?: StartNode;
|
||||
value?: UmbTreePickerSource;
|
||||
|
||||
@property({ type: Object, attribute: false })
|
||||
public config?: UmbPropertyEditorConfigCollection;
|
||||
|
||||
#onChange(event: CustomEvent) {
|
||||
const target = event.target as UmbInputStartNodeElement;
|
||||
const target = event.target as UmbInputTreePickerSourceElement;
|
||||
|
||||
this.value = {
|
||||
type: target.type,
|
||||
@@ -29,19 +29,19 @@ export class UmbPropertyEditorUITreePickerStartNodeElement extends UmbLitElement
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<umb-input-start-node
|
||||
return html`<umb-input-tree-picker-source
|
||||
@change=${this.#onChange}
|
||||
.type=${this.value?.type}
|
||||
.nodeId=${this.value?.id}></umb-input-start-node>`;
|
||||
.nodeId=${this.value?.id}></umb-input-tree-picker-source>`;
|
||||
}
|
||||
|
||||
static styles = [UmbTextStyles];
|
||||
}
|
||||
|
||||
export default UmbPropertyEditorUITreePickerStartNodeElement;
|
||||
export default UmbPropertyEditorUITreePickerSourcePickerElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-property-editor-ui-tree-picker-start-node': UmbPropertyEditorUITreePickerStartNodeElement;
|
||||
'umb-property-editor-ui-tree-picker-source-picker': UmbPropertyEditorUITreePickerSourcePickerElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import type { UmbPropertyEditorUITreePickerSourcePickerElement } from './property-editor-ui-tree-picker-source-picker.element.js';
|
||||
import { html } from '@umbraco-cms/backoffice/external/lit';
|
||||
|
||||
import './property-editor-ui-tree-picker-source-picker.element.js';
|
||||
|
||||
export default {
|
||||
title: 'Property Editor UIs/Tree Picker Start Node',
|
||||
component: 'umb-property-editor-ui-tree-picker-source-picker',
|
||||
id: 'umb-property-editor-ui-tree-picker-source-pickere',
|
||||
} as Meta;
|
||||
|
||||
export const AAAOverview: Story<UmbPropertyEditorUITreePickerSourcePickerElement> = () =>
|
||||
html`<umb-property-editor-ui-tree-picker-source-picker></umb-property-editor-ui-tree-picker-source-picker>`;
|
||||
AAAOverview.storyName = 'Overview';
|
||||
@@ -1,18 +1,18 @@
|
||||
import { expect, fixture, html } from '@open-wc/testing';
|
||||
import { UmbPropertyEditorUITreePickerStartNodeElement } from './property-editor-ui-tree-picker-start-node.element.js';
|
||||
import { UmbPropertyEditorUITreePickerSourcePickerElement } from './property-editor-ui-tree-picker-source-picker.element.js';
|
||||
import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils';
|
||||
|
||||
describe('UmbPropertyEditorUITreePickerStartNodeElement', () => {
|
||||
let element: UmbPropertyEditorUITreePickerStartNodeElement;
|
||||
describe('UmbPropertyEditorUITreePickerSourcePickerElement', () => {
|
||||
let element: UmbPropertyEditorUITreePickerSourcePickerElement;
|
||||
|
||||
beforeEach(async () => {
|
||||
element = await fixture(html`
|
||||
<umb-property-editor-ui-tree-picker-start-node></umb-property-editor-ui-tree-picker-start-node>
|
||||
<umb-property-editor-ui-tree-picker-source-picker></umb-property-editor-ui-tree-picker-source-picker>
|
||||
`);
|
||||
});
|
||||
|
||||
it('is defined with its own instance', () => {
|
||||
expect(element).to.be.instanceOf(UmbPropertyEditorUITreePickerStartNodeElement);
|
||||
expect(element).to.be.instanceOf(UmbPropertyEditorUITreePickerSourcePickerElement);
|
||||
});
|
||||
|
||||
if ((window as any).__UMBRACO_TEST_RUN_A11Y_TEST) {
|
||||
@@ -0,0 +1,14 @@
|
||||
import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifest: ManifestPropertyEditorUi = {
|
||||
type: 'propertyEditorUi',
|
||||
alias: 'Umb.PropertyEditorUi.TreePicker.SourceTypePicker',
|
||||
name: 'Tree Picker Source Type Picker Property Editor UI',
|
||||
js: () => import('./property-editor-ui-tree-picker-source-type-picker.element.js'),
|
||||
meta: {
|
||||
label: 'Tree Picker Source Type Picker',
|
||||
icon: 'icon-page-add',
|
||||
group: 'pickers',
|
||||
propertyEditorSchemaAlias: '',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,121 @@
|
||||
import { UmbDocumentTypeInputElement } from '@umbraco-cms/backoffice/document-type';
|
||||
import { UmbMediaTypeInputElement } from '@umbraco-cms/backoffice/media-type';
|
||||
import { UmbMemberTypeInputElement } from '@umbraco-cms/backoffice/member-type';
|
||||
import type { UmbTreePickerSource } from '@umbraco-cms/backoffice/components';
|
||||
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
|
||||
|
||||
/**
|
||||
* @element umb-property-editor-ui-tree-picker-source-type-picker
|
||||
*/
|
||||
@customElement('umb-property-editor-ui-tree-picker-source-type-picker')
|
||||
export class UmbPropertyEditorUITreePickerSourceTypePickerElement extends UmbLitElement implements UmbPropertyEditorUiElement {
|
||||
#datasetContext?: typeof UMB_PROPERTY_DATASET_CONTEXT.TYPE;
|
||||
|
||||
@property({ type: Array })
|
||||
value?: string[];
|
||||
|
||||
@state()
|
||||
private sourceType: string = 'content';
|
||||
|
||||
#initialized: boolean = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (datasetContext) => {
|
||||
this.#datasetContext = datasetContext;
|
||||
this._observeProperty();
|
||||
});
|
||||
}
|
||||
|
||||
private async _observeProperty() {
|
||||
if (!this.#datasetContext) return;
|
||||
this.observe(
|
||||
await this.#datasetContext.propertyValueByAlias('startNode'),
|
||||
(value) => {
|
||||
const startNode = value as UmbTreePickerSource;
|
||||
if (startNode.type) {
|
||||
// If we had a sourceType before, we can see this as a change and not the initial value,
|
||||
// so let's reset the value, so we don't carry over content-types to the new source type.
|
||||
if (this.#initialized && this.sourceType !== startNode.type) {
|
||||
this.value = [];
|
||||
}
|
||||
|
||||
this.sourceType = startNode.type;
|
||||
|
||||
if (!this.#initialized) {
|
||||
this.#initialized = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
'observeValue',
|
||||
);
|
||||
}
|
||||
|
||||
#onChange(event: CustomEvent) {
|
||||
switch (this.sourceType) {
|
||||
case 'content':
|
||||
this.value = (<UmbDocumentTypeInputElement>event.target).selectedIds;
|
||||
break;
|
||||
case 'media':
|
||||
this.value = (<UmbMediaTypeInputElement>event.target).selectedIds;
|
||||
break;
|
||||
case 'member':
|
||||
this.value = (<UmbMemberTypeInputElement>event.target).selectedIds;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this.dispatchEvent(new CustomEvent('property-value-change'));
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.#renderType();
|
||||
}
|
||||
|
||||
#renderType() {
|
||||
switch (this.sourceType) {
|
||||
case 'content':
|
||||
return this.#renderTypeContent();
|
||||
case 'media':
|
||||
return this.#renderTypeMedia();
|
||||
case 'member':
|
||||
return this.#renderTypeMember();
|
||||
default:
|
||||
return 'No source type found';
|
||||
}
|
||||
}
|
||||
|
||||
#renderTypeContent() {
|
||||
return html`<umb-document-type-input
|
||||
@change=${this.#onChange}
|
||||
.selectedIds=${this.value || []}></umb-document-type-input>`;
|
||||
}
|
||||
|
||||
#renderTypeMedia() {
|
||||
return html`<umb-media-type-input
|
||||
@change=${this.#onChange}
|
||||
.selectedIds=${this.value || []}></umb-media-type-input>`;
|
||||
}
|
||||
|
||||
#renderTypeMember() {
|
||||
return html`<umb-input-member-type
|
||||
@change=${this.#onChange}
|
||||
.selectedIds=${this.value || []}></umb-input-member-type>`;
|
||||
}
|
||||
|
||||
static styles = [UmbTextStyles];
|
||||
}
|
||||
|
||||
export default UmbPropertyEditorUITreePickerSourceTypePickerElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-property-editor-ui-tree-picker-source-type-picker': UmbPropertyEditorUITreePickerSourceTypePickerElement;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import type { UmbPropertyEditorUITreePickerStartNodeElement } from './property-editor-ui-tree-picker-start-node.element.js';
|
||||
import { html } from '@umbraco-cms/backoffice/external/lit';
|
||||
|
||||
import './property-editor-ui-tree-picker-start-node.element.js';
|
||||
|
||||
export default {
|
||||
title: 'Property Editor UIs/Tree Picker Start Node',
|
||||
component: 'umb-property-editor-ui-tree-picker-start-node',
|
||||
id: 'umb-property-editor-ui-tree-picker-start-node',
|
||||
} as Meta;
|
||||
|
||||
export const AAAOverview: Story<UmbPropertyEditorUITreePickerStartNodeElement> = () =>
|
||||
html`<umb-property-editor-ui-tree-picker-start-node></umb-property-editor-ui-tree-picker-start-node>`;
|
||||
AAAOverview.storyName = 'Overview';
|
||||
@@ -1,4 +1,5 @@
|
||||
import { manifest as startNode } from './config/start-node/manifests.js';
|
||||
import { manifest as sourcePicker } from './config/source-picker/manifests.js';
|
||||
import { manifest as sourceTypePicker } from './config/source-type-picker/manifests.js';
|
||||
import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
const manifest: ManifestPropertyEditorUi = {
|
||||
@@ -17,13 +18,13 @@ const manifest: ManifestPropertyEditorUi = {
|
||||
alias: 'startNode',
|
||||
label: 'Node type',
|
||||
description: '',
|
||||
propertyEditorUiAlias: 'Umb.PropertyEditorUi.TreePicker.StartNode',
|
||||
propertyEditorUiAlias: sourcePicker.alias,
|
||||
},
|
||||
{
|
||||
alias: 'filter',
|
||||
label: 'Allow items of type',
|
||||
description: '',
|
||||
propertyEditorUiAlias: 'Umb.PropertyEditorUi.TreePicker',
|
||||
description: 'Select the applicable types',
|
||||
propertyEditorUiAlias: sourceTypePicker.alias,
|
||||
},
|
||||
{
|
||||
alias: 'showOpenButton',
|
||||
@@ -36,6 +37,6 @@ const manifest: ManifestPropertyEditorUi = {
|
||||
},
|
||||
};
|
||||
|
||||
const config: Array<ManifestPropertyEditorUi> = [startNode];
|
||||
const config: Array<ManifestPropertyEditorUi> = [sourcePicker, sourceTypePicker];
|
||||
|
||||
export const manifests = [manifest, ...config];
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extensi
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
|
||||
import type { UmbInputTreeElement } from '@umbraco-cms/backoffice/tree';
|
||||
import type { StartNode } from '@umbraco-cms/backoffice/components';
|
||||
import type { UmbTreePickerSource } from '@umbraco-cms/backoffice/components';
|
||||
|
||||
/**
|
||||
* @element umb-property-editor-ui-tree-picker
|
||||
@@ -16,7 +16,7 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen
|
||||
value = '';
|
||||
|
||||
@state()
|
||||
type?: StartNode['type'];
|
||||
type?: UmbTreePickerSource['type'];
|
||||
|
||||
@state()
|
||||
startNodeId?: string | null;
|
||||
@@ -38,7 +38,7 @@ export class UmbPropertyEditorUITreePickerElement extends UmbLitElement implemen
|
||||
|
||||
@property({ attribute: false })
|
||||
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
|
||||
const startNode: StartNode | undefined = config?.getValueByAlias('startNode');
|
||||
const startNode: UmbTreePickerSource | undefined = config?.getValueByAlias('startNode');
|
||||
if (startNode) {
|
||||
this.type = startNode.type;
|
||||
this.startNodeId = startNode.id;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
import { UmbInputDocumentElement } from '@umbraco-cms/backoffice/document';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import type { StartNode } from '@umbraco-cms/backoffice/components';
|
||||
import type { UmbTreePickerSource } from '@umbraco-cms/backoffice/components';
|
||||
|
||||
@customElement('umb-input-tree')
|
||||
export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) {
|
||||
@@ -11,16 +11,16 @@ export class UmbInputTreeElement extends FormControlMixin(UmbLitElement) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _type: StartNode['type'] = undefined;
|
||||
private _type: UmbTreePickerSource['type'] = undefined;
|
||||
@property()
|
||||
public set type(newType: StartNode['type']) {
|
||||
public set type(newType: UmbTreePickerSource['type']) {
|
||||
const oldType = this._type;
|
||||
if (newType?.toLowerCase() !== this._type) {
|
||||
this._type = newType?.toLowerCase() as StartNode['type'];
|
||||
this._type = newType?.toLowerCase() as UmbTreePickerSource['type'];
|
||||
this.requestUpdate('type', oldType);
|
||||
}
|
||||
}
|
||||
public get type(): StartNode['type'] {
|
||||
public get type(): UmbTreePickerSource['type'] {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,47 +7,42 @@ import { UmbObserverController } from '@umbraco-cms/backoffice/observable-api';
|
||||
import './tree-item-default/tree-item.element.js';
|
||||
import './tree-item-base/tree-item-base.element.js';
|
||||
|
||||
export type UmbTreeSelectionConfiguration = {
|
||||
multiple?: boolean;
|
||||
selectable?: boolean;
|
||||
selection?: Array<string | null>;
|
||||
};
|
||||
|
||||
@customElement('umb-tree')
|
||||
export class UmbTreeElement extends UmbLitElement {
|
||||
@property({ type: String, reflect: true })
|
||||
get alias() {
|
||||
return this.#treeContext.getTreeAlias();
|
||||
}
|
||||
set alias(newVal) {
|
||||
this.#treeContext.setTreeAlias(newVal);
|
||||
}
|
||||
|
||||
@property({ type: Boolean, reflect: true })
|
||||
get selectable() {
|
||||
return this.#treeContext.selection.getSelectable();
|
||||
}
|
||||
set selectable(newVal) {
|
||||
this.#treeContext.selection.setSelectable(newVal);
|
||||
get alias() {
|
||||
return this.#treeContext.getTreeAlias();
|
||||
}
|
||||
|
||||
@property({ type: Array })
|
||||
get selection() {
|
||||
return this.#treeContext.selection.getSelection();
|
||||
}
|
||||
set selection(newVal) {
|
||||
if (!Array.isArray(newVal)) return;
|
||||
this.#treeContext?.selection.setSelection(newVal);
|
||||
}
|
||||
private _selectionConfiguration: UmbTreeSelectionConfiguration = {
|
||||
multiple: false,
|
||||
selectable: true,
|
||||
selection: [],
|
||||
};
|
||||
|
||||
@property({ type: Boolean, reflect: true })
|
||||
get multiple() {
|
||||
return this.#treeContext.selection.getMultiple();
|
||||
@property({ type: Object })
|
||||
set selectionConfiguration(config: UmbTreeSelectionConfiguration) {
|
||||
this._selectionConfiguration = config;
|
||||
this.#treeContext.selection.setMultiple(config.multiple ?? false);
|
||||
this.#treeContext.selection.setSelectable(config.selectable ?? true);
|
||||
this.#treeContext.selection.setSelection(config.selection ?? []);
|
||||
}
|
||||
set multiple(newVal) {
|
||||
this.#treeContext.selection.setMultiple(newVal);
|
||||
get selectionConfiguration(): UmbTreeSelectionConfiguration {
|
||||
return this._selectionConfiguration;
|
||||
}
|
||||
|
||||
// TODO: what is the best name for this functionality?
|
||||
private _hideTreeRoot = false;
|
||||
@property({ type: Boolean, attribute: 'hide-tree-root' })
|
||||
get hideTreeRoot() {
|
||||
return this._hideTreeRoot;
|
||||
}
|
||||
set hideTreeRoot(newVal: boolean) {
|
||||
const oldVal = this._hideTreeRoot;
|
||||
this._hideTreeRoot = newVal;
|
||||
@@ -57,22 +52,25 @@ export class UmbTreeElement extends UmbLitElement {
|
||||
|
||||
this.requestUpdate('hideTreeRoot', oldVal);
|
||||
}
|
||||
get hideTreeRoot() {
|
||||
return this._hideTreeRoot;
|
||||
}
|
||||
|
||||
@property()
|
||||
get selectableFilter() {
|
||||
return this.#treeContext.selectableFilter;
|
||||
}
|
||||
set selectableFilter(newVal) {
|
||||
this.#treeContext.selectableFilter = newVal;
|
||||
}
|
||||
get selectableFilter() {
|
||||
return this.#treeContext.selectableFilter;
|
||||
}
|
||||
|
||||
@property()
|
||||
get filter() {
|
||||
return this.#treeContext.filter;
|
||||
}
|
||||
set filter(newVal) {
|
||||
this.#treeContext.filter = newVal;
|
||||
}
|
||||
get filter() {
|
||||
return this.#treeContext.filter;
|
||||
}
|
||||
|
||||
@state()
|
||||
private _items: UmbTreeItemModelBase[] = [];
|
||||
@@ -111,6 +109,10 @@ export class UmbTreeElement extends UmbLitElement {
|
||||
}
|
||||
}
|
||||
|
||||
getSelection() {
|
||||
return this.#treeContext.selection.getSelection();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` ${this.#renderTreeRoot()} ${this.#renderRootItems()}`;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
UmbModalBaseElement,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbId } from '@umbraco-cms/backoffice/id';
|
||||
import { UmbEntityTreeItemModel, UmbTreeElement } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbEntityTreeItemModel, UmbTreeElement, type UmbTreeSelectionConfiguration } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
interface DictionaryItemPreview {
|
||||
name: string;
|
||||
@@ -21,6 +21,13 @@ export class UmbImportDictionaryModalLayout extends UmbModalBaseElement<
|
||||
UmbImportDictionaryModalData,
|
||||
UmbImportDictionaryModalValue
|
||||
> {
|
||||
@state()
|
||||
private _selectionConfiguration: UmbTreeSelectionConfiguration = {
|
||||
multiple: false,
|
||||
selectable: true,
|
||||
selection: [],
|
||||
};
|
||||
|
||||
@state()
|
||||
private _parentId?: string;
|
||||
|
||||
@@ -93,6 +100,7 @@ export class UmbImportDictionaryModalLayout extends UmbModalBaseElement<
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._parentId = this.data?.unique ?? undefined;
|
||||
this._selectionConfiguration.selection = this._parentId ? [this._parentId] : [];
|
||||
}
|
||||
|
||||
#dictionaryPreviewBuilder(htmlString: string) {
|
||||
@@ -139,7 +147,7 @@ export class UmbImportDictionaryModalLayout extends UmbModalBaseElement<
|
||||
}
|
||||
|
||||
#onParentChange() {
|
||||
this._parentId = this._treeElement?.selection[0] ?? undefined;
|
||||
this._parentId = this._treeElement?.getSelection()[0] ?? undefined;
|
||||
}
|
||||
|
||||
async #onFileInput() {
|
||||
@@ -189,11 +197,9 @@ export class UmbImportDictionaryModalLayout extends UmbModalBaseElement<
|
||||
|
||||
<umb-tree
|
||||
?hide-tree-root=${true}
|
||||
?multiple=${false}
|
||||
alias=${UMB_DICTIONARY_TREE_ALIAS}
|
||||
@selection-change=${this.#onParentChange}
|
||||
.selection=${[this._parentId ?? '']}
|
||||
selectable></umb-tree>
|
||||
.selectionConfiguration=${this._selectionConfiguration}></umb-tree>
|
||||
</div>
|
||||
|
||||
${this.#renderNavigate()}
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
import './document-type-input/document-type-input.element.js';
|
||||
|
||||
export * from './document-type-input/document-type-input.element.js';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import './components/index.js';
|
||||
|
||||
export * from './repository/index.js';
|
||||
export * from './components/index.js';
|
||||
|
||||
export const UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE = 'document-type-root';
|
||||
export const UMB_DOCUMENT_TYPE_ENTITY_TYPE = 'document-type';
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
import './media-type-input/media-type-input.element.js';
|
||||
|
||||
export * from './media-type-input/media-type-input.element.js';
|
||||
|
||||
@@ -12,3 +12,5 @@ export {
|
||||
UMB_MEDIA_TYPE_ENTITY_TYPE,
|
||||
UMB_MEDIA_TYPE_FOLDER_ENTITY_TYPE,
|
||||
} from './entity.js';
|
||||
|
||||
export * from './components/index.js';
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
import './input-member-type/input-member-type.element.js';
|
||||
|
||||
export * from './input-member-type/input-member-type.element.js';
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
UmbPartialViewPickerModalValue,
|
||||
UmbModalBaseElement,
|
||||
} from '@umbraco-cms/backoffice/modal';
|
||||
import { UmbTreeElement } from '@umbraco-cms/backoffice/tree';
|
||||
import { UmbTreeElement, type UmbTreeSelectionConfiguration } from '@umbraco-cms/backoffice/tree';
|
||||
|
||||
@customElement('umb-partial-view-picker-modal')
|
||||
export default class UmbPartialViewPickerModalElement extends UmbModalBaseElement<
|
||||
@@ -13,26 +13,26 @@ export default class UmbPartialViewPickerModalElement extends UmbModalBaseElemen
|
||||
UmbPartialViewPickerModalValue
|
||||
> {
|
||||
@state()
|
||||
_selection: Array<string | null> = [];
|
||||
|
||||
@state()
|
||||
_multiple = false;
|
||||
_selectionConfiguration: UmbTreeSelectionConfiguration = {
|
||||
multiple: false,
|
||||
selectable: true,
|
||||
selection: [],
|
||||
};
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._selection = this.value?.selection ?? [];
|
||||
this._multiple = this.data?.multiple ?? true;
|
||||
this._selectionConfiguration.selection = this.value?.selection ?? [];
|
||||
this._selectionConfiguration.multiple = this.data?.multiple ?? true;
|
||||
}
|
||||
|
||||
private _handleSelectionChange(e: CustomEvent) {
|
||||
e.stopPropagation();
|
||||
const element = e.target as UmbTreeElement;
|
||||
this._selection = this._multiple ? element.selection : [element.selection[element.selection.length - 1]];
|
||||
this.value = { selection: element.getSelection() };
|
||||
this._submit();
|
||||
}
|
||||
|
||||
private _submit() {
|
||||
this.value = { selection: this._selection };
|
||||
this.modalContext?.submit();
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@ export default class UmbPartialViewPickerModalElement extends UmbModalBaseElemen
|
||||
<umb-tree
|
||||
alias="Umb.Tree.PartialViews"
|
||||
@selection-change=${this._handleSelectionChange}
|
||||
.selection=${this._selection}
|
||||
selectable></umb-tree>
|
||||
.selectionConfiguration=${this._selectionConfiguration}></umb-tree>
|
||||
</uui-box>
|
||||
</div>
|
||||
<div slot="actions">
|
||||
|
||||
Reference in New Issue
Block a user