From 32d21488efdc5ca58b89c23131bda03e60d980fe Mon Sep 17 00:00:00 2001 From: Julia Gru <56249914+julczka@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:25:15 +0200 Subject: [PATCH] make workspace display code editor --- .../partial-views-workspace-edit.element.ts | 139 ++++++++++++++---- .../partial-views-workspace.context.ts | 23 ++- 2 files changed, 133 insertions(+), 29 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace-edit.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace-edit.element.ts index bea83b8754..2e84f6960d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace-edit.element.ts @@ -3,6 +3,11 @@ import type { UmbCodeEditorElement } from '@umbraco-cms/backoffice/code-editor'; import { UUITextStyles, UUIInputElement } from '@umbraco-cms/backoffice/external/uui'; import { css, html, customElement, query, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_MODAL_MANAGER_CONTEXT_TOKEN, UmbModalManagerContext } from '@umbraco-cms/backoffice/modal'; +import { UmbTemplatingInsertMenuElement } from '../../components/index.js'; +import { UMB_TEMPLATE_QUERY_BUILDER_MODAL } from '../../templates/modals/modal-tokens.js'; +import { getQuerySnippet } from '../../utils.js'; +import { Subject, debounceTime } from '@umbraco-cms/backoffice/external/rxjs'; @customElement('umb-partial-views-workspace-edit') export class UmbPartialViewsWorkspaceEditElement extends UmbLitElement { @@ -12,16 +17,28 @@ export class UmbPartialViewsWorkspaceEditElement extends UmbLitElement { @state() private _content?: string | null = ''; + @state() + private _ready?: boolean = false; + @query('umb-code-editor') private _codeEditor?: UmbCodeEditorElement; #partialViewsWorkspaceContext?: UmbPartialViewsWorkspaceContext; + private _modalContext?: UmbModalManagerContext; + #isNew = false; + private inputQuery$ = new Subject(); + constructor() { super(); - this.consumeContext('umbWorkspaceContext', (workspaceContext: UmbPartialViewsWorkspaceContext) => { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this._modalContext = instance; + }); + + //tODO: should this be called something else here? + this.consumeContext('UmbEntityWorkspaceContext', (workspaceContext: UmbPartialViewsWorkspaceContext) => { this.#partialViewsWorkspaceContext = workspaceContext; this.observe(this.#partialViewsWorkspaceContext.name, (name) => { this._name = name; @@ -31,49 +48,82 @@ export class UmbPartialViewsWorkspaceEditElement extends UmbLitElement { this._content = content; }); - // this.observe(this.#partialViewsWorkspaceContext.isNew, (isNew) => { - // this.#isNew = !!isNew; - // }); + this.observe(this.#partialViewsWorkspaceContext.isNew, (isNew) => { + this.#isNew = !!isNew; + }); + + this.observe(this.#partialViewsWorkspaceContext.isCodeEditorReady, (isReady) => { + this._ready = isReady; + }); + + this.inputQuery$.pipe(debounceTime(250)).subscribe((nameInputValue: string) => { + this.#partialViewsWorkspaceContext?.setName(nameInputValue); + }); }); } - // TODO: temp code for testing create and save #onNameInput(event: Event) { const target = event.target as UUIInputElement; const value = target.value as string; - this.#partialViewsWorkspaceContext?.setName(value); + this.inputQuery$.next(value); } - //TODO - debounce that #onCodeEditorInput(event: Event) { const target = event.target as UmbCodeEditorElement; const value = target.code as string; this.#partialViewsWorkspaceContext?.setContent(value); } - #insertCode(event: Event) { - const target = event.target as UUIInputElement; + #insertSnippet(event: Event) { + const target = event.target as UmbTemplatingInsertMenuElement; const value = target.value as string; + this._codeEditor?.insert(value); + } - this._codeEditor?.insert(`My hovercraft is full of eels`); + #openQueryBuilder() { + const queryBuilderModal = this._modalContext?.open(UMB_TEMPLATE_QUERY_BUILDER_MODAL); + + queryBuilderModal?.onSubmit().then((queryBuilderModalResult) => { + if (queryBuilderModalResult.value) this._codeEditor?.insert(getQuerySnippet(queryBuilderModalResult.value)); + }); + } + + #renderCodeEditor() { + return html``; } render() { - // TODO: add correct UI elements - return html` - + return html` + - Insert "My hovercraft is full of eels" - - +
+
+ + + Query builder + +
+
+ ${this._ready + ? this.#renderCodeEditor() + : html`
+ +
`}
-
`; + `; } static styles = [ @@ -85,19 +135,58 @@ export class UmbPartialViewsWorkspaceEditElement extends UmbLitElement { height: 100%; } + #loader-container { + display: grid; + place-items: center; + min-height: calc(100dvh - 360px); + } + umb-code-editor { - --editor-height: calc(100vh - 300px); + --editor-height: calc(100dvh - 300px); } uui-box { - margin: 1em; + min-height: calc(100dvh - 300px); + margin: var(--uui-size-layout-1); --uui-box-default-padding: 0; + /* remove header border bottom as code editor looks better in this box */ + --uui-color-divider-standalone: transparent; } uui-input { width: 100%; margin: 1em; } + + #code-editor-menu-container uui-icon:not([name='umb:delete']) { + margin-right: var(--uui-size-space-3); + } + + #insert-menu { + margin: 0; + padding: 0; + margin-top: var(--uui-size-space-3); + background-color: var(--uui-color-surface); + box-shadow: var(--uui-shadow-depth-3); + min-width: calc(100% + var(--uui-size-8, 24px)); + } + + #insert-menu > li, + ul { + padding: 0; + width: 100%; + list-style: none; + } + + .insert-menu-item { + width: 100%; + } + + #code-editor-menu-container { + display: flex; + justify-content: space-between; + gap: var(--uui-size-space-3); + } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace.context.ts index 20547409e6..6f0ad7cc15 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/workspace/partial-views-workspace.context.ts @@ -1,12 +1,13 @@ import { UmbPartialViewsRepository } from '../repository/partial-views.repository.js'; -import { createObservablePart, UmbDeepState } from '@umbraco-cms/backoffice/observable-api'; -import { TemplateResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { PartialViewDetails } from '../config.js'; +import { createObservablePart, UmbBooleanState, UmbDeepState } from '@umbraco-cms/backoffice/observable-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; import { UmbWorkspaceContext } from '@umbraco-cms/backoffice/workspace'; +import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor'; export class UmbPartialViewsWorkspaceContext extends UmbWorkspaceContext< UmbPartialViewsRepository, - TemplateResponseModel + PartialViewDetails > { getEntityId(): string | undefined { throw new Error('Method not implemented.'); @@ -20,13 +21,27 @@ export class UmbPartialViewsWorkspaceContext extends UmbWorkspaceContext< destroy(): void { throw new Error('Method not implemented.'); } - #data = new UmbDeepState(undefined); + #data = new UmbDeepState(undefined); data = this.#data.asObservable(); name = createObservablePart(this.#data, (data) => data?.name); content = createObservablePart(this.#data, (data) => data?.content); + path = createObservablePart(this.#data, (data) => data?.path); + + #isCodeEditorReady = new UmbBooleanState(false); + isCodeEditorReady = this.#isCodeEditorReady.asObservable(); constructor(host: UmbControllerHostElement) { super(host, new UmbPartialViewsRepository(host)); + this.#loadCodeEditor(); + } + + async #loadCodeEditor() { + try { + await loadCodeEditor(); + this.#isCodeEditorReady.next(true); + } catch (error) { + console.error(error); + } } getData() {