From 58159f4b97a80ae8d8b4bfb1369da2effe08a04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 8 Nov 2023 16:22:15 +1300 Subject: [PATCH] setup header and footer --- .../media-type-workspace-editor.element.ts | 172 ++++++++++++++++-- 1 file changed, 154 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts index d944f86789..c1845d45a9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/media-type-workspace-editor.element.ts @@ -1,55 +1,191 @@ -import { UMB_MEDIA_TYPE_WORKSPACE_CONTEXT } from './media-type-workspace.context.js'; +import { UmbMediaTypeWorkspaceContext } from './media-type-workspace.context.js'; import { UUIInputElement, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; -import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, customElement, state, ifDefined } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { + UMB_ICON_PICKER_MODAL, + UMB_MODAL_MANAGER_CONTEXT_TOKEN, + UmbModalManagerContext, +} from '@umbraco-cms/backoffice/modal'; +import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; +import { generateAlias } from '@umbraco-cms/backoffice/utils'; @customElement('umb-media-type-workspace-editor') export class UmbMediaTypeWorkspaceEditorElement extends UmbLitElement { @state() - private _mediaTypeName?: string | null = ''; - #workspaceContext?: typeof UMB_MEDIA_TYPE_WORKSPACE_CONTEXT.TYPE; + private _name?: string; + + @state() + private _alias?: string; + + @state() + private _aliasLocked = true; + + @state() + private _icon?: string; + + @state() + private _iconColorAlias?: string; + // TODO: Color should be using an alias, and look up in some dictionary/key/value) of project-colors. + + #workspaceContext?: UmbMediaTypeWorkspaceContext; + + private _modalContext?: UmbModalManagerContext; constructor() { super(); - this.consumeContext(UMB_MEDIA_TYPE_WORKSPACE_CONTEXT, (instance) => { - this.#workspaceContext = instance; - this.#observeName(); + this.consumeContext(UMB_WORKSPACE_CONTEXT, (instance) => { + this.#workspaceContext = instance as UmbMediaTypeWorkspaceContext; + this.#observeMediaType(); + }); + + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this._modalContext = instance; }); } - #observeName() { + #observeMediaType() { if (!this.#workspaceContext) return; - this.observe(this.#workspaceContext.name, (name) => { - this._mediaTypeName = name; - }); + this.observe(this.#workspaceContext.name, (name) => (this._name = name), '_observeName'); + this.observe(this.#workspaceContext.alias, (alias) => (this._alias = alias), '_observeAlias'); + this.observe(this.#workspaceContext.icon, (icon) => (this._icon = icon), '_observeIcon'); + + this.observe( + this.#workspaceContext.isNew, + (isNew) => { + if (isNew) { + // TODO: Would be good with a more general way to bring focus to the name input. + (this.shadowRoot?.querySelector('#name') as HTMLElement)?.focus(); + } + this.removeControllerByAlias('_observeIsNew'); + }, + '_observeIsNew', + ); } - // TODO. find a way where we don't have to do this for all Workspaces. - #handleInput(event: UUIInputEvent) { + // TODO. find a way where we don't have to do this for all workspaces. + #onNameChange(event: UUIInputEvent) { if (event instanceof UUIInputEvent) { const target = event.composedPath()[0] as UUIInputElement; if (typeof target?.value === 'string') { - this.#workspaceContext?.setName(target.value); + const oldName = this._name; + const oldAlias = this._alias; + const newName = event.target.value.toString(); + if (this._aliasLocked) { + const expectedOldAlias = generateAlias(oldName ?? ''); + // Only update the alias if the alias matches a generated alias of the old name (otherwise the alias is considered one written by the user.) + if (expectedOldAlias === oldAlias) { + this.#workspaceContext?.updateProperty('alias', generateAlias(newName)); + } + } + this.#workspaceContext?.updateProperty('name', target.value); } } } + // TODO. find a way where we don't have to do this for all workspaces. + #onAliasChange(event: UUIInputEvent) { + if (event instanceof UUIInputEvent) { + const target = event.composedPath()[0] as UUIInputElement; + + if (typeof target?.value === 'string') { + this.#workspaceContext?.updateProperty('alias', target.value); + } + } + event.stopPropagation(); + } + + #onToggleAliasLock() { + this._aliasLocked = !this._aliasLocked; + } + + private async _handleIconClick() { + const modalContext = this._modalContext?.open(UMB_ICON_PICKER_MODAL, { + icon: this._icon, + color: this._iconColorAlias, + }); + + modalContext?.onSubmit().then((saved) => { + if (saved.icon) this.#workspaceContext?.updateProperty('icon', saved.icon); + // TODO: save color ALIAS as well + }); + } + render() { return html` - + + +
+ + + Keyboard Shortcuts + + ALT + + + shift + + + k + + +
`; } static styles = [ css` + :host { + display: block; + width: 100%; + height: 100%; + } + #header { display: flex; - gap: var(--uui-size-space-4); - width: 100%; + flex: 1 1 auto; } - uui-input { + + #name { width: 100%; + flex: 1 1 auto; + align-items: center; + } + + #alias-lock { + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + } + #alias-lock uui-icon { + margin-bottom: 2px; + } + + #icon { + font-size: calc(var(--uui-size-layout-3) / 2); + margin-right: var(--uui-size-space-2); + margin-left: calc(var(--uui-size-space-4) * -1); } `, ];