make workspace display code editor

This commit is contained in:
Julia Gru
2023-07-18 12:25:15 +02:00
parent 25e485eb01
commit 32d21488ef
2 changed files with 133 additions and 29 deletions

View File

@@ -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<string>();
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`<umb-code-editor
language="razor"
id="content"
.code=${this._content ?? ''}
@input=${this.#onCodeEditorInput}></umb-code-editor>`;
}
render() {
// TODO: add correct UI elements
return html`<umb-body-layout alias="Umb.Workspace.Template">
<uui-input slot="header" .value=${this._name} @input=${this.#onNameInput}></uui-input>
return html`<umb-workspace-editor alias="Umb.Workspace.Template">
<uui-input
placeholder="Enter name..."
slot="header"
.value=${this._name}
@input=${this.#onNameInput}
label="template name"></uui-input>
<uui-box>
<uui-button color="danger" look="primary" slot="header" @click=${this.#insertCode}
>Insert "My hovercraft is full of eels"</uui-button
>
<umb-code-editor
language="razor"
id="content"
.code=${this._content ?? ''}
@input=${this.#onCodeEditorInput}></umb-code-editor>
<div slot="header" id="code-editor-menu-container">
<div>
<umb-templating-insert-menu @insert=${this.#insertSnippet}></umb-templating-insert-menu>
<uui-button
look="secondary"
id="query-builder-button"
label="Query builder"
@click=${this.#openQueryBuilder}>
<uui-icon name="umb:wand"></uui-icon>Query builder
</uui-button>
</div>
</div>
${this._ready
? this.#renderCodeEditor()
: html`<div id="loader-container">
<uui-loader></uui-loader>
</div>`}
</uui-box>
</umb-body-layout>`;
</umb-workspace-editor>`;
}
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);
}
`,
];
}

View File

@@ -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<TemplateResponseModel | undefined>(undefined);
#data = new UmbDeepState<PartialViewDetails | undefined>(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() {