From 456f0a25612e0578856c4e891e83c27d0986875c Mon Sep 17 00:00:00 2001 From: Julia Gru <56249914+julczka@users.noreply.github.com> Date: Tue, 29 Aug 2023 12:43:46 +0200 Subject: [PATCH] add rule element --- .../stylesheets/workspace/manifests.ts | 3 +- .../workspace/stylesheet-workspace.context.ts | 11 +- ...pace-view-rich-text-editor-rule.element.ts | 87 ++++++++++++++ ...rich-text-editor-style-sidebar.element.ts} | 3 +- ...workspace-view-rich-text-editor.element.ts | 112 ++++-------------- 5 files changed, 122 insertions(+), 94 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-rule.element.ts rename src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/{stylesheet-workspace-view-rich-text-editor-style-sidebar.ts => stylesheet-workspace-view-rich-text-editor-style-sidebar.element.ts} (97%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/manifests.ts index 3c6dde658c..6f6bfff160 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/manifests.ts @@ -82,7 +82,8 @@ const modals: Array = [ type: 'modal', alias: UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR, name: 'Rich text editor style modal', - loader: () => import('./views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.js'), + loader: () => + import('./views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.element.js'), }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts index 4556460fee..fac1510f4b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/stylesheet-workspace.context.ts @@ -10,7 +10,7 @@ export type RichTextRuleModelSortable = RichTextRuleModel & { sortOrder?: number export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext { #data = new UmbObjectState(undefined); - #rules = new UmbArrayState([]); + #rules = new UmbArrayState([], (rule) => rule.name); data = this.#data.asObservable(); rules = this.#rules.asObservable(); name = createObservablePart(this.#data, (data) => data?.name); @@ -51,8 +51,13 @@ export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext ({ ...r, sortOrder: i }))); + updateRule(unique: string, rule: RichTextRuleModelSortable) { + this.#rules.updateOne(unique, rule); + } + + setRules(rules: RichTextRuleModelSortable[]) { + const newRules = rules.map((r, i) => ({ ...r, sortOrder: i })); + this.#rules.next(newRules); this.sendRulesGetContent(); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-rule.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-rule.element.ts new file mode 100644 index 0000000000..71cd598dbf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-rule.element.ts @@ -0,0 +1,87 @@ +import { UmbStylesheetWorkspaceContext } from '../../stylesheet-workspace.context.js'; +import { UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR_MODAL } from './stylesheet-workspace-view-rich-text-editor.element.js'; +import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; +import { css, html, customElement, property } from '@umbraco-cms/backoffice/external/lit'; +import { RichTextRuleModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; +import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; +import { UMB_MODAL_MANAGER_CONTEXT_TOKEN, UmbModalManagerContext } from '@umbraco-cms/backoffice/modal'; + +@customElement('umb-stylesheet-rich-text-editor-rule') +export default class UmbStylesheetRichTextEditorRuleElement extends UmbLitElement { + @property({ type: Object, attribute: false }) + private rule: RichTextRuleModel | null = null; + + #context?: UmbStylesheetWorkspaceContext; + private _modalContext?: UmbModalManagerContext; + + constructor() { + super(); + + this.consumeContext(UMB_WORKSPACE_CONTEXT, (workspaceContext) => { + this.#context = workspaceContext as UmbStylesheetWorkspaceContext; + }); + + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT_TOKEN, (instance) => { + this._modalContext = instance; + }); + } + + openModal = () => { + if (!this._modalContext) throw new Error('Modal context not found'); + const modal = this._modalContext.open(UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR_MODAL, { + rule: this.rule, + }); + modal?.onSubmit().then((result) => { + if (result.rule && this.rule?.name) { + this.#context?.updateRule(this.rule?.name, result.rule); + } + }); + }; + + removeRule = () => { + //TODO: SPORTER BREAKS THAT - rules are removed from the data but not from the DOM + if (!this.#context) throw new Error('Context not found'); + this.#context.setRules(this.#context.getRules().filter((r) => r.name !== this.rule?.name)); + }; + + render() { + return html` +
${this.rule?.name}
+
+ EditRemove +
+ `; + } + + static styles = [ + UUITextStyles, + css` + :host { + display: flex; + width: 100%; + justify-content: space-between; + padding: var(--uui-size-2); + align-items: center; + border-radius: var(--uui-border-radius); + background-color: var(--uui-color-surface-alt); + margin-bottom: var(--uui-size-space-4); + } + + .rule-name { + display: flex; + align-items: center; + gap: var(--uui-size-2); + padding-left: var(--uui-size-2); + font-weight: bold; + } + `, + ]; +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-stylesheet-rich-text-editor-rule': UmbStylesheetRichTextEditorRuleElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.element.ts similarity index 97% rename from src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.ts rename to src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.element.ts index ff2db7e201..147952cf48 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor-style-sidebar.element.ts @@ -2,9 +2,10 @@ import { UUITextStyles } from '@umbraco-cms/backoffice/external/uui'; import { css, html, customElement, ifDefined, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/internal/modal'; import { RichTextRuleModel } from '@umbraco-cms/backoffice/backend-api'; +import { RichTextRuleModelSortable } from '../../stylesheet-workspace.context.js'; export interface StylesheetRichTextEditorStyleModalData { - rule: RichTextRuleModel | null; + rule: RichTextRuleModelSortable | null; } export type StylesheetRichTextEditorStyleModalResult = NonNullable>; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor.element.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor.element.ts index 40b5d7e6c0..a84967deb4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/workspace/views/rich-text-editor/stylesheet-workspace-view-rich-text-editor.element.ts @@ -1,24 +1,21 @@ import { UUITextStyles } from '@umbraco-ui/uui-css'; import { css, html } from 'lit'; import { customElement, state } from 'lit/decorators.js'; -import { UmbStylesheetWorkspaceContext } from '../../stylesheet-workspace.context.js'; +import { RichTextRuleModelSortable, UmbStylesheetWorkspaceContext } from '../../stylesheet-workspace.context.js'; import { UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR } from '../../manifests.js'; import { StylesheetRichTextEditorStyleModalData, StylesheetRichTextEditorStyleModalResult, -} from './stylesheet-workspace-view-rich-text-editor-style-sidebar.js'; +} from './stylesheet-workspace-view-rich-text-editor-style-sidebar.element.js'; import { UmbLitElement } from '@umbraco-cms/internal/lit-element'; import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace'; -import { - UMB_MODAL_MANAGER_CONTEXT_TOKEN, - UmbModalContext, - UmbModalManagerContext, - UmbModalToken, -} from '@umbraco-cms/backoffice/modal'; +import { UMB_MODAL_MANAGER_CONTEXT_TOKEN, UmbModalManagerContext, UmbModalToken } from '@umbraco-cms/backoffice/modal'; import { RichTextRuleModel } from '@umbraco-cms/backoffice/backend-api'; import { UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter'; import { ifDefined, repeat } from '@umbraco-cms/backoffice/external/lit'; +import './stylesheet-workspace-view-rich-text-editor-rule.element.js'; + export const UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR_MODAL = new UmbModalToken< StylesheetRichTextEditorStyleModalData, StylesheetRichTextEditorStyleModalResult @@ -35,33 +32,18 @@ const SORTER_CONFIG: UmbSorterConfig = { return container.querySelector('data-umb-rule-name[' + modelEntry.name + ']'); }, identifier: 'stylesheet-rules-sorter', - itemSelector: '[data-umb-rule-name]', - disabledItemSelector: '[inherited]', + itemSelector: 'umb-stylesheet-rich-text-editor-rule', containerSelector: '#rules-container', }; @customElement('umb-stylesheet-workspace-view-rich-text-editor') export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitElement { @state() - private _content: string = ''; - - @state() - private _path: string = ''; - - @state() - private _ready: boolean = false; - - @state() - _rules: RichTextRuleModel[] = []; + _rules: RichTextRuleModelSortable[] = []; #context?: UmbStylesheetWorkspaceContext; private _modalContext?: UmbModalManagerContext; - #isNew = false; - #modal?: UmbModalContext; - - #currentlyEditing: RichTextRuleModel | null = null; - #sorter = new UmbSorterController(this, { ...SORTER_CONFIG, performItemInsert: ({ item, newIndex }) => { @@ -70,7 +52,6 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme return this.#context?.findNewSortOrder(item, newIndex) ?? false; }, performItemRemove: (args) => { - console.log(args, 'remove'); return true; }, }); @@ -82,22 +63,6 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme this.#context = workspaceContext as UmbStylesheetWorkspaceContext; this.#context.sendContentGetRules(); - this.observe(this.#context.content, (content) => { - this._content = content ?? ''; - }); - - this.observe(this.#context.path, (path) => { - this._path = path ?? ''; - }); - - this.observe(this.#context.isNew, (isNew) => { - this.#isNew = !!isNew; - }); - - this.observe(this.#context.isCodeEditorReady, (isReady) => { - this._ready = isReady; - }); - this.observe(this.#context.rules, (rules) => { this._rules = rules; this.#sorter.setModel(this._rules); @@ -109,51 +74,39 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme }); } - #openModal = (rule: RichTextRuleModel | null = null) => { + openModal = (rule: RichTextRuleModelSortable | null = null) => { if (!this._modalContext) throw new Error('Modal context not found'); - this.#currentlyEditing = rule; const modal = this._modalContext.open(UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR_MODAL, { rule, }); modal?.onSubmit().then((result) => { - if (this.#currentlyEditing && result.rule) { - this.#replaceRule(result.rule); - this.#currentlyEditing = null; - return; - } if (result.rule) { - this.#context?.setRules([...this._rules, result.rule]); - this.#currentlyEditing = null; + this.#context?.setRules([...this._rules, { ...result.rule, sortOrder: this._rules.length }]); } }); }; - #removeRule = (rule: RichTextRuleModel) => { - this.#context?.setRules(this._rules?.filter((r) => r !== rule)); + removeRule = (rule: RichTextRuleModelSortable) => { + const rules = this._rules?.filter((r) => r.name !== rule.name); + this.#context?.setRules(rules); }; - #replaceRule(rule: RichTextRuleModel) { - this.#context?.setRules(this._rules?.map((r) => (r === this.#currentlyEditing ? rule : r))); - } - - renderRule(rule: RichTextRuleModel) { - return html`
-
${rule.name}
-
- this.#openModal(rule)}>Edit this.#removeRule(rule)} - >Remove -
-
`; - } render() { return html`

Define the styles that should be available in the rich text editor for this stylesheet.

-
${repeat(this._rules, (rule) => rule.name, this.renderRule)}
- this.#openModal(null)}>Add +
+ ${repeat( + this._rules, + (rule) => rule?.name ?? '' + rule?.sortOrder ?? '', + (rule) => + html``, + )} +
+ this.openModal(null)}>Add
`; @@ -182,25 +135,6 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme max-width: 600px; } - .rule-name { - display: flex; - align-items: center; - gap: var(--uui-size-2); - padding-left: var(--uui-size-2); - font-weight: bold; - } - - .rule { - display: flex; - width: 100%; - justify-content: space-between; - padding: var(--uui-size-2); - align-items: center; - border-radius: var(--uui-border-radius); - background-color: var(--uui-color-surface-alt); - margin-bottom: var(--uui-size-space-4); - } - uui-box { margin: var(--uui-size-layout-1); }