workspaces
This commit is contained in:
@@ -61,7 +61,8 @@ export class UmbWorkspaceViewDocumentTypePermissionsElement extends UmbLitElemen
|
||||
Allow content of the specified types to be created underneath content of this type.
|
||||
</div>
|
||||
<div slot="editor">
|
||||
<umb-input-document-type-picker></umb-input-document-type-picker>
|
||||
<umb-input-document-type-picker
|
||||
.currentDocumentType="${this._documentType}"></umb-input-document-type-picker>
|
||||
</div>
|
||||
</umb-workspace-property-layout>
|
||||
<umb-workspace-property-layout alias="VaryByNature" label="Allow vary by culture">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { css, html } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, query, state } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { UmbWorkspaceDocumentTypeContext } from '../../document-type-workspace.context';
|
||||
import { UmbTemplateCardListElement } from '../../../../../shared/components/template-card/template-card-list.element';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import type { DocumentTypeModel } from '@umbraco-cms/backend-api';
|
||||
import '../../../../../shared/property-creator/property-creator.element.ts';
|
||||
@@ -37,9 +37,18 @@ export class UmbWorkspaceViewDocumentTypeTemplatesElement extends UmbLitElement
|
||||
`,
|
||||
];
|
||||
|
||||
@property()
|
||||
defaultTemplateKey?: string = '123';
|
||||
|
||||
@state()
|
||||
_documentType?: DocumentTypeModel;
|
||||
|
||||
@state()
|
||||
_templates = [
|
||||
{ key: '123', name: 'Blog Post Page' },
|
||||
{ key: '456', name: 'Blog Entry Page' },
|
||||
];
|
||||
|
||||
private _workspaceContext?: UmbWorkspaceDocumentTypeContext;
|
||||
|
||||
constructor() {
|
||||
@@ -60,17 +69,21 @@ export class UmbWorkspaceViewDocumentTypeTemplatesElement extends UmbLitElement
|
||||
});
|
||||
}
|
||||
|
||||
#changeDefaultTemplate(e: CustomEvent) {
|
||||
this.defaultTemplateKey = (e.target as UmbTemplateCardListElement).value as string;
|
||||
console.log('default template key', this.defaultTemplateKey);
|
||||
}
|
||||
|
||||
#removeTemplate(key: string) {
|
||||
console.log('remove template', key);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<uui-box headline="Templates">
|
||||
<umb-workspace-property-layout alias="Templates" label="Allowed Templates">
|
||||
<div slot="description">Choose which templates editors are allowed to use on content of this type</div>
|
||||
<div id="templates" slot="editor">
|
||||
<umb-template-card-list>
|
||||
<umb-template-card value="123"></umb-template-card>
|
||||
<umb-template-card value="456"></umb-template-card>
|
||||
</umb-template-card-list>
|
||||
|
||||
</div>
|
||||
<umb-input-template-picker umb-input-template-picker></umb-input-template-picker>
|
||||
</div>
|
||||
</umb-workspace-property-layout>
|
||||
</uui-box>`;
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
import { css, html } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import type { UmbTreeElement } from '../../../../shared/components/tree/tree.element';
|
||||
import { UmbDocumentTypePickerModalData, UmbDocumentTypePickerModalResult } from '.';
|
||||
import { UmbModalBaseElement } from '@umbraco-cms/modal';
|
||||
|
||||
// TODO: make use of UmbPickerLayoutBase
|
||||
@customElement('umb-document-type-picker-modal')
|
||||
export class UmbDocumentTypePickerModalElement extends UmbModalBaseElement<
|
||||
UmbDocumentTypePickerModalData,
|
||||
UmbDocumentTypePickerModalResult
|
||||
> {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
h3 {
|
||||
margin-left: var(--uui-size-space-5);
|
||||
margin-right: var(--uui-size-space-5);
|
||||
}
|
||||
|
||||
uui-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--uui-color-divider);
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
#content-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--uui-size-space-3);
|
||||
}
|
||||
|
||||
.content-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.content-item.selected {
|
||||
background-color: var(--uui-color-selected);
|
||||
color: var(--uui-color-selected-contrast);
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@state()
|
||||
_selection: Array<string> = [];
|
||||
|
||||
@state()
|
||||
_multiple = true;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._selection = this.data?.selection ?? [];
|
||||
this._multiple = this.data?.multiple ?? true;
|
||||
}
|
||||
|
||||
private _handleSelectionChange(e: CustomEvent) {
|
||||
e.stopPropagation();
|
||||
const element = e.target as UmbTreeElement;
|
||||
//TODO: Should multiple property be implemented here or be passed down into umb-tree?
|
||||
this._selection = this._multiple ? element.selection : [element.selection[element.selection.length - 1]];
|
||||
}
|
||||
|
||||
private _submit() {
|
||||
this.modalHandler?.submit({ selection: this._selection });
|
||||
}
|
||||
|
||||
private _close() {
|
||||
this.modalHandler?.reject();
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<umb-workspace-layout headline="Select Content">
|
||||
<uui-box>
|
||||
<uui-input></uui-input>
|
||||
<hr />
|
||||
<umb-tree
|
||||
alias="Umb.Tree.DocumentTypes"
|
||||
@selected=${this._handleSelectionChange}
|
||||
.selection=${this._selection}
|
||||
selectable></umb-tree>
|
||||
</uui-box>
|
||||
<div slot="actions">
|
||||
<uui-button label="Close" @click=${this._close}></uui-button>
|
||||
<uui-button label="Submit" look="primary" color="positive" @click=${this._submit}></uui-button>
|
||||
</div>
|
||||
</umb-workspace-layout>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbDocumentTypePickerModalElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-document-type-picker-modal': UmbDocumentTypePickerModalElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import '../../../../shared/components/body-layout/body-layout.element';
|
||||
import './document-type-picker-modal.element';
|
||||
|
||||
import { Meta, Story } from '@storybook/web-components';
|
||||
import { html } from 'lit';
|
||||
|
||||
import type { UmbDocumentTypePickerModalElement } from './document-type-picker-modal.element';
|
||||
import type { UmbDocumentTypePickerModalData } from './index';
|
||||
|
||||
export default {
|
||||
title: 'API/Modals/Layouts/Content Picker',
|
||||
component: 'umb-document-picker-modal',
|
||||
id: 'umb-document-picker-modal',
|
||||
} as Meta;
|
||||
|
||||
const data: UmbDocumentTypePickerModalData = {
|
||||
multiple: true,
|
||||
selection: [],
|
||||
};
|
||||
|
||||
export const Overview: Story<UmbDocumentTypePickerModalElement> = () => html`
|
||||
<!-- TODO: figure out if generics are allowed for properties:
|
||||
https://github.com/runem/lit-analyzer/issues/149
|
||||
https://github.com/runem/lit-analyzer/issues/163 -->
|
||||
<umb-document-picker-modal .data=${data as any}></umb-document-picker-modal>
|
||||
`;
|
||||
@@ -0,0 +1,18 @@
|
||||
import { UmbModalToken } from '@umbraco-cms/modal';
|
||||
|
||||
export interface UmbDocumentTypePickerModalData {
|
||||
multiple?: boolean;
|
||||
selection?: Array<string>;
|
||||
}
|
||||
|
||||
export interface UmbDocumentTypePickerModalResult {
|
||||
selection: Array<string>;
|
||||
}
|
||||
|
||||
export const UMB_DOCUMENT_TYPE_PICKER_MODAL_TOKEN = new UmbModalToken<
|
||||
UmbDocumentTypePickerModalData,
|
||||
UmbDocumentTypePickerModalResult
|
||||
>('Umb.Modal.DocumentTypePicker', {
|
||||
type: 'sidebar',
|
||||
size: 'small',
|
||||
});
|
||||
@@ -7,6 +7,12 @@ const modals: Array<ManifestModal> = [
|
||||
name: 'Document Picker Modal',
|
||||
loader: () => import('./document-picker/document-picker-modal.element'),
|
||||
},
|
||||
{
|
||||
type: 'modal',
|
||||
alias: 'Umb.Modal.DocumentTypePicker',
|
||||
name: 'Document Type Picker Modal',
|
||||
loader: () => import('./document-type-picker/document-type-picker-modal.element'),
|
||||
},
|
||||
];
|
||||
|
||||
export const manifests = [...modals];
|
||||
|
||||
@@ -28,6 +28,7 @@ import './input-media-picker/input-media-picker.element';
|
||||
import './input-multi-url-picker/input-multi-url-picker.element';
|
||||
import './input-slider/input-slider.element';
|
||||
import './input-toggle/input-toggle.element';
|
||||
import './input-template-picker/input-template-picker.element';
|
||||
import './property-type-based-property/property-type-based-property.element';
|
||||
import './ref-property-editor-ui/ref-property-editor-ui.element';
|
||||
import './section/section-main/section-main.element';
|
||||
@@ -47,7 +48,7 @@ import './workspace/workspace-layout/workspace-layout.element';
|
||||
|
||||
import './workspace/workspace-footer-layout/workspace-footer-layout.element';
|
||||
|
||||
import './template-cards/template-card.element';
|
||||
import './template-cards/template-card-list.element';
|
||||
import './template-card/template-card.element';
|
||||
import './template-card/template-card-list.element';
|
||||
|
||||
export const manifests = [...debugManifests];
|
||||
|
||||
@@ -3,13 +3,15 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
||||
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
|
||||
import { UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN } from '../../../documents/documents/repository/document.tree.store';
|
||||
import { UmbDocumentTypeTreeStore } from '../../../documents/document-types/repository/document-type.tree.store';
|
||||
import {
|
||||
UmbDocumentTypeTreeStore,
|
||||
UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN,
|
||||
} from '../../../documents/document-types/repository/document-type.tree.store';
|
||||
import { UMB_CONFIRM_MODAL_TOKEN } from '../../modals/confirm';
|
||||
import { UMB_DOCUMENT_PICKER_MODAL_TOKEN } from '../../../documents/documents/modals/document-picker';
|
||||
import { UMB_DOCUMENT_TYPE_PICKER_MODAL_TOKEN } from '../../../documents/documents/modals/document-type-picker';
|
||||
import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import type { DocumentTypeTreeItemModel, FolderTreeItemModel } from '@umbraco-cms/backend-api';
|
||||
import type { DocumentTypeModel, DocumentTypeTreeItemModel, FolderTreeItemModel } from '@umbraco-cms/backend-api';
|
||||
import type { UmbObserverController } from '@umbraco-cms/observable-api';
|
||||
|
||||
@customElement('umb-input-document-type-picker')
|
||||
@@ -20,43 +22,16 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl
|
||||
#add-button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#current-node {
|
||||
background-color: var(--uui-color-surface-alt);
|
||||
}
|
||||
|
||||
#wrapper-nodes {
|
||||
margin-left: var(--uui-size-space-6);
|
||||
}
|
||||
`,
|
||||
];
|
||||
/**
|
||||
* This is a minimum amount of selected items in this input.
|
||||
* @type {number}
|
||||
* @attr
|
||||
* @default undefined
|
||||
*/
|
||||
@property({ type: Number })
|
||||
min?: number;
|
||||
|
||||
/**
|
||||
* Min validation message.
|
||||
* @type {boolean}
|
||||
* @attr
|
||||
* @default
|
||||
*/
|
||||
@property({ type: String, attribute: 'min-message' })
|
||||
minMessage = 'This field need more items';
|
||||
|
||||
/**
|
||||
* This is a maximum amount of selected items in this input.
|
||||
* @type {number}
|
||||
* @attr
|
||||
* @default undefined
|
||||
*/
|
||||
@property({ type: Number })
|
||||
max?: number;
|
||||
|
||||
/**
|
||||
* Max validation message.
|
||||
* @type {boolean}
|
||||
* @attr
|
||||
* @default
|
||||
*/
|
||||
@property({ type: String, attribute: 'min-message' })
|
||||
maxMessage = 'This field exceeds the allowed amount of items';
|
||||
|
||||
// TODO: do we need both selectedKeys and value? If we just use value we follow the same pattern as native form controls.
|
||||
private _selectedKeys: Array<string> = [];
|
||||
@@ -76,29 +51,20 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl
|
||||
}
|
||||
}
|
||||
|
||||
@property()
|
||||
currentDocumentType?: DocumentTypeModel;
|
||||
|
||||
@state()
|
||||
private _items?: Array<DocumentTypeTreeItemModel>;
|
||||
|
||||
private _modalContext?: UmbModalContext;
|
||||
private _documentStore?: UmbDocumentTypeTreeStore;
|
||||
private _documentTypeStore?: UmbDocumentTypeTreeStore;
|
||||
private _pickedItemsObserver?: UmbObserverController<FolderTreeItemModel>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.addValidator(
|
||||
'rangeUnderflow',
|
||||
() => this.minMessage,
|
||||
() => !!this.min && this._selectedKeys.length < this.min
|
||||
);
|
||||
this.addValidator(
|
||||
'rangeOverflow',
|
||||
() => this.maxMessage,
|
||||
() => !!this.max && this._selectedKeys.length > this.max
|
||||
);
|
||||
|
||||
this.consumeContext(UMB_DOCUMENT_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this._documentStore = instance;
|
||||
this.consumeContext(UMB_DOCUMENT_TYPE_TREE_STORE_CONTEXT_TOKEN, (instance) => {
|
||||
this._documentTypeStore = instance;
|
||||
this._observePickedDocuments();
|
||||
});
|
||||
this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
|
||||
@@ -113,18 +79,18 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl
|
||||
private _observePickedDocuments() {
|
||||
this._pickedItemsObserver?.destroy();
|
||||
|
||||
if (!this._documentStore) return;
|
||||
if (!this._documentTypeStore) return;
|
||||
|
||||
// TODO: consider changing this to the list data endpoint when it is available
|
||||
this._pickedItemsObserver = this.observe(this._documentStore.items(this._selectedKeys), (items) => {
|
||||
this._pickedItemsObserver = this.observe(this._documentTypeStore.items(this._selectedKeys), (items) => {
|
||||
this._items = items;
|
||||
});
|
||||
}
|
||||
|
||||
private _openPicker() {
|
||||
// We send a shallow copy(good enough as its just an array of keys) of our this._selectedKeys, as we don't want the modal to manipulate our data:
|
||||
const modalHandler = this._modalContext?.open(UMB_DOCUMENT_PICKER_MODAL_TOKEN, {
|
||||
multiple: this.max === 1 ? false : true,
|
||||
const modalHandler = this._modalContext?.open(UMB_DOCUMENT_TYPE_PICKER_MODAL_TOKEN, {
|
||||
multiple: true,
|
||||
selection: [...this._selectedKeys],
|
||||
});
|
||||
|
||||
@@ -153,8 +119,13 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl
|
||||
|
||||
render() {
|
||||
return html`
|
||||
${this._items?.map((item) => this._renderItem(item))}
|
||||
<uui-button id="add-button" look="placeholder" @click=${this._openPicker} label="open">Add</uui-button>
|
||||
<uui-ref-node id="current-node" .name="${this.currentDocumentType?.name ?? ''} (current)">
|
||||
<uui-icon slot="icon" .name="${this.currentDocumentType?.icon ?? 'umb:document'}"></uui-icon>
|
||||
</uui-ref-node>
|
||||
<div id="wrapper-nodes">
|
||||
<uui-ref-list> ${this._items?.map((item) => this._renderItem(item))} </uui-ref-list>
|
||||
<uui-button id="add-button" look="placeholder" @click=${this._openPicker} label="open">Add</uui-button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -164,6 +135,7 @@ export class UmbInputDocumentTypePickerElement extends FormControlMixin(UmbLitEl
|
||||
|
||||
return html`
|
||||
<uui-ref-node name=${ifDefined(item.name === null ? undefined : item.name)} detail=${ifDefined(item.key)}>
|
||||
<uui-icon slot="icon" name="${ifDefined(item.icon)}"></uui-icon>
|
||||
${tempItem.isTrashed ? html` <uui-tag size="s" slot="tag" color="danger">Trashed</uui-tag> ` : nothing}
|
||||
<uui-action-bar slot="actions">
|
||||
<uui-button @click=${() => this._removeItem(item)} label="Remove document ${item.name}">Remove</uui-button>
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
import { css, html } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property, queryAll, state } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
|
||||
import { UMB_CONFIRM_MODAL_TOKEN } from '../../modals/confirm';
|
||||
import { UmbTemplateCardElement } from '../template-card/template-card.element';
|
||||
import { UmbModalContext, UMB_MODAL_CONTEXT_TOKEN } from '@umbraco-cms/modal';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import { TemplateModel, TemplateResource } from '@umbraco-cms/backend-api';
|
||||
import { tryExecuteAndNotify } from '@umbraco-cms/resources';
|
||||
|
||||
type DocTypTemplateModel = TemplateModel & { default: boolean };
|
||||
|
||||
@customElement('umb-input-template-picker')
|
||||
export class UmbInputTemplatePickerElement extends FormControlMixin(UmbLitElement) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
#add-button {
|
||||
width: 100%;
|
||||
}
|
||||
:host {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
gap: var(--uui-size-space-4);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
:host > * {
|
||||
max-width: 180px;
|
||||
min-width: 180px;
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fadeIn 1s;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`,
|
||||
];
|
||||
/**
|
||||
* This is a minimum amount of selected items in this input.
|
||||
* @type {number}
|
||||
* @attr
|
||||
* @default undefined
|
||||
*/
|
||||
@property({ type: Number })
|
||||
min?: number;
|
||||
|
||||
/**
|
||||
* Min validation message.
|
||||
* @type {boolean}
|
||||
* @attr
|
||||
* @default
|
||||
*/
|
||||
@property({ type: String, attribute: 'min-message' })
|
||||
minMessage = 'This field need more items';
|
||||
|
||||
/**
|
||||
* This is a maximum amount of selected items in this input.
|
||||
* @type {number}
|
||||
* @attr
|
||||
* @default undefined
|
||||
*/
|
||||
@property({ type: Number })
|
||||
max?: number;
|
||||
|
||||
/**
|
||||
* Max validation message.
|
||||
* @type {boolean}
|
||||
* @attr
|
||||
* @default
|
||||
*/
|
||||
@property({ type: String, attribute: 'min-message' })
|
||||
maxMessage = 'This field exceeds the allowed amount of items';
|
||||
|
||||
private _templates: Array<DocTypTemplateModel> = [];
|
||||
public get templates(): Array<DocTypTemplateModel> {
|
||||
return this._templates;
|
||||
}
|
||||
public set templates(newTemplates: Array<DocTypTemplateModel>) {
|
||||
const keys = newTemplates.map((template) => template.key);
|
||||
super.value = keys.join(',');
|
||||
this._templates = newTemplates;
|
||||
}
|
||||
|
||||
@state()
|
||||
private _items: Array<any> = [
|
||||
{ key: '2bf464b6-3aca-4388-b043-4eb439cc2643', name: 'Doc 1', default: false },
|
||||
{ key: '9a84c0b3-03b4-4dd4-84ac-706740ac0f71', name: 'Test', default: true },
|
||||
];
|
||||
|
||||
private _modalContext?: UmbModalContext;
|
||||
//private _documentStore?: UmbDocumentTreeStore;
|
||||
//private _pickedItemsObserver?: UmbObserverController<FolderTreeItemModel>;
|
||||
|
||||
@queryAll('.template-card')
|
||||
private _templateCardElements?: NodeListOf<Element>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.addValidator(
|
||||
'rangeUnderflow',
|
||||
() => this.minMessage,
|
||||
() => !!this.min && this._templates.length < this.min
|
||||
);
|
||||
this.addValidator(
|
||||
'rangeOverflow',
|
||||
() => this.maxMessage,
|
||||
() => !!this.max && this._templates.length > this.max
|
||||
);
|
||||
|
||||
this.consumeContext(UMB_MODAL_CONTEXT_TOKEN, (instance) => {
|
||||
this._modalContext = instance;
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._items = this._items.sort((a, b) => b.default - a.default);
|
||||
this.#setup();
|
||||
}
|
||||
|
||||
async #setup() {
|
||||
const templates = await tryExecuteAndNotify(this, TemplateResource.getTreeTemplateRoot({ skip: 0, take: 9999 }));
|
||||
console.log(templates);
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
#openTemplatePickerModal() {
|
||||
console.log('template picker modal');
|
||||
}
|
||||
|
||||
#changeSelected() {
|
||||
console.log('selected');
|
||||
}
|
||||
|
||||
/** Clicking the template card buttons */
|
||||
|
||||
#changeDefault(e: CustomEvent) {
|
||||
const key = (e.target as UmbTemplateCardElement).value;
|
||||
|
||||
const oldDefault = this._items.find((x) => x.default === true);
|
||||
const newDefault = this._items.find((x) => x.key === key);
|
||||
|
||||
const items = this._items.map((item) => {
|
||||
if (item.default === true) return { ...newDefault, default: true };
|
||||
if (item.key === key) return { ...oldDefault, default: false };
|
||||
return item;
|
||||
});
|
||||
|
||||
this._items = items;
|
||||
}
|
||||
|
||||
#openTemplate(e: CustomEvent) {
|
||||
const key = (e.target as UmbTemplateCardElement).value;
|
||||
console.log('open', key);
|
||||
}
|
||||
|
||||
#removeTemplate(key: string) {
|
||||
console.log('remove', key);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
${repeat(
|
||||
this._items,
|
||||
(template) => template.default,
|
||||
(template, index) => html`<div class="fade-in">
|
||||
<umb-template-card
|
||||
class="template-card"
|
||||
name="${template.name}"
|
||||
key="${template.key}"
|
||||
@default-change="${this.#changeDefault}"
|
||||
@open="${this.#openTemplate}"
|
||||
?default="${template.default}">
|
||||
<uui-button
|
||||
slot="actions"
|
||||
label="Remove document ${template.name}"
|
||||
@click="${() => this.#removeTemplate(template.key)}"
|
||||
compact>
|
||||
<uui-icon name="umb:trash"> </uui-icon>
|
||||
</uui-button>
|
||||
</umb-template-card>
|
||||
</div>`
|
||||
)}
|
||||
<uui-button id="add-button" look="placeholder" label="open">Add</uui-button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbInputTemplatePickerElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-input-template-picker': UmbInputTemplatePickerElement;
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,7 @@ export class UmbTemplateCardListElement extends FormControlMixin(UmbLitElement)
|
||||
el.selected = false;
|
||||
}
|
||||
});
|
||||
this.value = newValue;
|
||||
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
||||
}
|
||||
|
||||
@@ -41,13 +41,16 @@ export class UmbTemplateCardElement extends FormControlMixin(UmbLitElement) {
|
||||
border-radius: var(--uui-border-radius);
|
||||
border: 1px solid var(--uui-color-divider-emphasis);
|
||||
background-color: var(--uui-color-background);
|
||||
padding: var(--uui-size-space-4);
|
||||
padding: var(--uui-size-4);
|
||||
}
|
||||
|
||||
:host([selected]) #card {
|
||||
:host([default]) #card {
|
||||
border: 1px solid var(--uui-color-selected);
|
||||
outline: 1px solid var(--uui-color-selected);
|
||||
}
|
||||
#card:has(uui-button:hover) {
|
||||
border: 1px solid var(--uui-color-selected);
|
||||
}
|
||||
|
||||
#bottom {
|
||||
margin-top: auto;
|
||||
@@ -117,7 +120,7 @@ export class UmbTemplateCardElement extends FormControlMixin(UmbLitElement) {
|
||||
name = '';
|
||||
|
||||
@property({ type: Boolean, reflect: true })
|
||||
selected = false;
|
||||
default = false;
|
||||
|
||||
_key = '';
|
||||
@property({ type: String })
|
||||
@@ -137,7 +140,7 @@ export class UmbTemplateCardElement extends FormControlMixin(UmbLitElement) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
//this.selected = true;
|
||||
this.dispatchEvent(new CustomEvent('selected', { bubbles: true, composed: true }));
|
||||
this.dispatchEvent(new CustomEvent('default-change', { bubbles: true, composed: true }));
|
||||
}
|
||||
#openTemplate(e: KeyboardEvent) {
|
||||
e.preventDefault();
|
||||
@@ -152,8 +155,8 @@ export class UmbTemplateCardElement extends FormControlMixin(UmbLitElement) {
|
||||
<uui-icon class="logo" name="umb:layout"></uui-icon>
|
||||
<strong>${this.name.length ? this.name : 'Untitled template'}</strong>
|
||||
</button>
|
||||
<uui-button id="bottom" label="Default template" ?disabled="${this.selected}" @click="${this.#setSelection}">
|
||||
${this.selected ? '(Default template)' : 'Set default'}
|
||||
<uui-button id="bottom" label="Default template" ?disabled="${this.default}" @click="${this.#setSelection}">
|
||||
${this.default ? '(Default template)' : 'Set default'}
|
||||
</uui-button>
|
||||
</div>`;
|
||||
}
|
||||
Reference in New Issue
Block a user