implement sorting

This commit is contained in:
Julia Gru
2023-08-28 15:35:11 +02:00
parent 7b94bcc47f
commit 17f6838cdb
2 changed files with 51 additions and 10 deletions

View File

@@ -6,9 +6,11 @@ import { UmbArrayState, UmbBooleanState, UmbObjectState, createObservablePart }
import { loadCodeEditor } from '@umbraco-cms/backoffice/code-editor';
import { RichTextRuleModel, UpdateStylesheetRequestModel } from '@umbraco-cms/backoffice/backend-api';
export type RichTextRuleModelSortable = RichTextRuleModel & { sortOrder?: number };
export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext<UmbStylesheetRepository, StylesheetDetails> {
#data = new UmbObjectState<StylesheetDetails | undefined>(undefined);
#rules = new UmbArrayState<RichTextRuleModel>([]);
#rules = new UmbArrayState<RichTextRuleModelSortable>([]);
data = this.#data.asObservable();
rules = this.#rules.asObservable();
name = createObservablePart(this.#data, (data) => data?.name);
@@ -20,6 +22,7 @@ export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext<UmbStyles
constructor(host: UmbControllerHostElement) {
super(host, 'Umb.Workspace.StyleSheet', new UmbStylesheetRepository(host));
this.#rules.sortBy((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
this.#loadCodeEditor();
}
@@ -49,7 +52,7 @@ export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext<UmbStyles
}
setRules(rules: RichTextRuleModel[]) {
this.#rules.next(rules);
this.#rules.next(rules.map((r, i) => ({ ...r, sortOrder: i })));
this.sendRulesGetContent();
}
@@ -73,7 +76,7 @@ export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext<UmbStyles
}
if (rules.data) {
this.#rules.next(rules.data.rules ?? []);
this.#rules.next(rules.data.rules?.map((r, i) => ({ ...r, sortOrder: i })) ?? []);
}
}
@@ -88,9 +91,8 @@ export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext<UmbStyles
}
async sendContentGetRules() {
if (!this.getData()?.content) return;
if (!this.getData()?.content) return Promise.reject('There is no content to extract rules from...');
const requestBody = {
content: this.getData()?.content,
};
@@ -99,6 +101,17 @@ export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext<UmbStyles
this.setRules(data?.rules ?? []);
}
findNewSortOrder(rule: RichTextRuleModel, newIndex: number) {
const rules = [...this.getRules()].sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
const oldIndex = rules.findIndex((r) => r.name === rule.name);
if (oldIndex === -1) return false;
rules.splice(oldIndex, 1);
rules.splice(newIndex, 0, rule);
this.setRules(rules.map((r, i) => ({ ...r, sortOrder: i })));
return true;
}
public async save() {
const stylesheet = this.getData();
@@ -130,8 +143,8 @@ export class UmbStylesheetWorkspaceContext extends UmbWorkspaceContext<UmbStyles
path: parentKey ?? '',
content: '',
};
this.setIsNew(true);
this.#data.next(newStylesheet);
this.setIsNew(true);
}
public destroy(): void {

View File

@@ -16,6 +16,8 @@ import {
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';
export const UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR_MODAL = new UmbModalToken<
StylesheetRichTextEditorStyleModalData,
@@ -24,6 +26,20 @@ export const UMB_MODAL_TEMPLATING_STYLESHEET_RTF_STYLE_SIDEBAR_MODAL = new UmbMo
type: 'sidebar',
size: 'medium',
});
const SORTER_CONFIG: UmbSorterConfig<RichTextRuleModel> = {
compareElementToModel: (element: HTMLElement, model: RichTextRuleModel) => {
return element.getAttribute('data-umb-rule-name') === model.name;
},
querySelectModelToElement: (container: HTMLElement, modelEntry: RichTextRuleModel) => {
return container.querySelector('data-umb-rule-name[' + modelEntry.name + ']');
},
identifier: 'stylesheet-rules-sorter',
itemSelector: '[data-umb-rule-name]',
disabledItemSelector: '[inherited]',
containerSelector: '#rules-container',
};
@customElement('umb-stylesheet-workspace-view-rich-text-editor')
export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitElement {
@state()
@@ -46,6 +62,19 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme
#currentlyEditing: RichTextRuleModel | null = null;
#sorter = new UmbSorterController(this, {
...SORTER_CONFIG,
performItemInsert: ({ item, newIndex }) => {
//return true;
return this.#context?.findNewSortOrder(item, newIndex) ?? false;
},
performItemRemove: (args) => {
console.log(args, 'remove');
return true;
},
});
constructor() {
super();
@@ -71,6 +100,7 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme
this.observe(this.#context.rules, (rules) => {
this._rules = rules;
this.#sorter.setModel(this._rules);
});
});
@@ -79,8 +109,6 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme
});
}
#openModal = (rule: RichTextRuleModel | null = null) => {
if (!this._modalContext) throw new Error('Modal context not found');
this.#currentlyEditing = rule;
@@ -109,7 +137,7 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme
}
renderRule(rule: RichTextRuleModel) {
return html`<div class="rule">
return html`<div class="rule" data-umb-rule-name="${ifDefined(rule.name)}">
<div class="rule-name"><uui-icon name="umb:navigation"></uui-icon>${rule.name}</div>
<div class="rule-actions">
<uui-button label="Edit" look="secondary" @click=${() => this.#openModal(rule)}>Edit</uui-button
@@ -124,7 +152,7 @@ export class UmbStylesheetWorkspaceViewRichTextEditorElement extends UmbLitEleme
<div id="box-row">
<p id="description">Define the styles that should be available in the rich text editor for this stylesheet.</p>
<div id="rules">
${this._rules?.map((rule) => this.renderRule(rule))}
<div id="rules-container">${repeat(this._rules, (rule) => rule.name, this.renderRule)}</div>
<uui-button label="Add rule" look="primary" @click=${() => this.#openModal(null)}>Add</uui-button>
</div>
</div>