diff --git a/src/html/component/functions-editor/editor-tile/editor-tile.ts b/src/html/component/functions-editor/editor-tile/editor-tile.ts index cd97f29..102ba49 100644 --- a/src/html/component/functions-editor/editor-tile/editor-tile.ts +++ b/src/html/component/functions-editor/editor-tile/editor-tile.ts @@ -1,4 +1,4 @@ -import { css, LitElement, type PropertyValues, unsafeCSS } from 'lit' +import { css, LitElement, unsafeCSS } from 'lit' import { property, query, state } from 'lit/decorators.js' import style_less from './editor-tile.less?inline' import { Essentiality, type IFunctionData, type IRegulationData, Monotonicity } from '../../../util/data-interfaces' @@ -52,10 +52,6 @@ export abstract class EditorTile extends LitElement { this.aceEditor.renderer.attachToShadowRoot() } - protected updated (_changedProperties: PropertyValues): void { - super.updated(_changedProperties) - } - protected updateEditor (name: string, func: string): void { if (this.nameField !== undefined) { this.nameField.value = name diff --git a/src/html/component/functions-editor/editor-tile/function-tile.ts b/src/html/component/functions-editor/editor-tile/function-tile.ts index e0f524a..ce6cfe5 100644 --- a/src/html/component/functions-editor/editor-tile/function-tile.ts +++ b/src/html/component/functions-editor/editor-tile/function-tile.ts @@ -9,6 +9,7 @@ import ace, { type Ace } from 'ace-builds' import langTools from 'ace-builds/src-noconflict/ext-language_tools' import 'ace-builds/esm-resolver' import { EditorTile } from './editor-tile' +import { functionDebounceTimer } from '../../../util/config' library.add(faTrash, faMagnifyingGlass) @@ -38,6 +39,7 @@ export class FunctionTile extends EditorTile { }))) } }) + this.aceEditor.setOption('placeholder', '$f_' + this.functions[this.index].id + '(...)') } protected firstUpdated (_changedProperties: PropertyValues): void { @@ -54,8 +56,7 @@ export class FunctionTile extends EditorTile { bubbles: true, composed: true })) - }, - 300 + }, functionDebounceTimer ) functionUpdated = debounce(() => { @@ -67,8 +68,7 @@ export class FunctionTile extends EditorTile { bubbles: true, composed: true })) - }, - 300 + }, functionDebounceTimer ) async removeVariable (): Promise { diff --git a/src/html/component/functions-editor/editor-tile/variable-tile.ts b/src/html/component/functions-editor/editor-tile/variable-tile.ts index 9e2a649..bf012fa 100644 --- a/src/html/component/functions-editor/editor-tile/variable-tile.ts +++ b/src/html/component/functions-editor/editor-tile/variable-tile.ts @@ -9,6 +9,7 @@ import ace, { type Ace } from 'ace-builds' import langTools from 'ace-builds/src-noconflict/ext-language_tools' import 'ace-builds/esm-resolver' import { EditorTile } from './editor-tile' +import { functionDebounceTimer } from '../../../util/config' library.add(faTrash, faMagnifyingGlass) @customElement('variable-tile') @@ -40,6 +41,7 @@ export class VariableTile extends EditorTile { 'constant.language': this.variables.map(v => v.id).join('|'), 'support.function.dom': this.functions.map(f => f.id).join('|') }) + this.aceEditor.setOption('placeholder', '$f_' + this.variables[this.index].id + '(...)') } private getVariables (): IVariableData[] { @@ -55,8 +57,7 @@ export class VariableTile extends EditorTile { bubbles: true, composed: true })) - }, - 300 + }, functionDebounceTimer ) functionUpdated = debounce(() => { @@ -68,8 +69,7 @@ export class VariableTile extends EditorTile { bubbles: true, composed: true })) - }, - 300 + }, functionDebounceTimer ) toggleEssentiality (regulation: IRegulationData): void { diff --git a/src/html/component/root-component/root-component.ts b/src/html/component/root-component/root-component.ts index 789dd6d..1a131a2 100644 --- a/src/html/component/root-component/root-component.ts +++ b/src/html/component/root-component/root-component.ts @@ -112,19 +112,18 @@ export default class RootComponent extends LitElement { this.data = this.data.copy({ functions }) } - private saveData (variables: IVariableData[], regulations: IRegulationData[], layout: ILayoutData): void { - // save variable/regulation/layout data, leave functions as is - - // sort nodes to keep alphabetical order in lists + private saveVariables (variables: IVariableData[]): void { variables.sort((a, b) => (a.id > b.id ? 1 : -1)) + this.data = this.data.copy({ variables }) + } + + private saveRegulations (regulations: IRegulationData[]): void { regulations.sort((a, b) => (a.source + a.target > b.source + b.target ? 1 : -1)) + this.data = this.data.copy({ regulations }) + } - this.data = ContentData.create({ - variables, - regulations, - layout, - functions: this.data.functions - }) + private saveLayout (layout: ILayoutData): void { + this.data = this.data.copy({ layout }) } renameVariable (event: Event): void { @@ -140,7 +139,7 @@ export default class RootComponent extends LitElement { id: data.id, name: data.name } - this.saveData(variables, this.data.regulations, this.data.layout) + this.saveVariables(variables) } private addVariable (event: Event): void { @@ -160,7 +159,7 @@ export default class RootComponent extends LitElement { name: data.name, function: '' }) - this.saveData(variables, this.data.regulations, this.data.layout) + this.saveVariables(variables) } private addRegulation (event: Event): void { @@ -177,7 +176,7 @@ export default class RootComponent extends LitElement { essential: data.essential, monotonicity: data.sign }) - this.saveData(this.data.variables, regulations, this.data.layout) + this.saveRegulations(regulations) } private async removeVariable (event: Event): Promise { @@ -187,16 +186,14 @@ export default class RootComponent extends LitElement { } #onVariableRemoved (data: VariableData): void { - this.saveData( - this.data.variables.filter((variable) => variable.id !== data.id), - this.data.regulations, - this.data.layout + this.saveVariables( + this.data.variables.filter((variable) => variable.id !== data.id) ) } private adjustRegEditor (): void { const visible = this.visibleTabs() - if (window.outerWidth <= 800 || visible.includes(this.tabs[0])) return + if (window.outerWidth <= 800 || !visible.includes(this.tabs[0])) return window.dispatchEvent(new CustomEvent('adjust-graph', { detail: { tabCount: visible.length @@ -224,11 +221,12 @@ export default class RootComponent extends LitElement { #onNodePositionChanged (data: LayoutNodeData): void { // TODO: add support for layouts - this.data.layout.set(data.variable, { + const layout = new Map(this.data.layout) + layout.set(data.variable, { x: data.px, y: data.py }) - this.saveData(this.data.variables, this.data.regulations, this.data.layout) + this.saveLayout(layout) } private setVariableId (event: Event): void { @@ -256,7 +254,7 @@ export default class RootComponent extends LitElement { regulations[index].target = data.new_id } }) - this.saveData(variables, this.data.regulations, this.data.layout) + this.saveVariables(variables) // TODO: this refresh is a temporary solution to get potentially modified update function expressions aeonState.model.refreshVariables() @@ -275,7 +273,7 @@ export default class RootComponent extends LitElement { ...regulations[index], essential: data.essential } - this.saveData(this.data.variables, regulations, this.data.layout) + this.saveRegulations(regulations) } private toggleRegulationMonotonicity (event: Event): void { @@ -291,7 +289,7 @@ export default class RootComponent extends LitElement { ...regulations[index], monotonicity: data.sign } - this.saveData(this.data.variables, regulations, this.data.layout) + this.saveRegulations(regulations) } private setVariableFunction (event: Event): void { @@ -307,7 +305,7 @@ export default class RootComponent extends LitElement { ...variables[variableIndex], function: data.update_fn } - this.saveData(variables, this.data.regulations, this.data.layout) + this.saveVariables(variables) } private async removeRegulation (event: Event): Promise { @@ -317,18 +315,14 @@ export default class RootComponent extends LitElement { } #onRegulationRemoved (data: RegulationData): void { - this.saveData( - this.data.variables, - this.data.regulations.filter((regulation) => regulation.source !== data.regulator || regulation.target !== data.target), - this.data.layout + this.saveRegulations( + this.data.regulations.filter((regulation) => regulation.source !== data.regulator || regulation.target !== data.target) ) } #onVariablesRefreshed (variables: VariableData[]): void { - this.saveData( - variables.map(v => { return { ...v, function: v.update_fn } }), - this.data.regulations, - this.data.layout + this.saveVariables( + variables.map(v => { return { ...v, function: v.update_fn } }) ) } @@ -337,7 +331,7 @@ export default class RootComponent extends LitElement { layoutNodes.forEach(layoutNode => { layout.set(layoutNode.variable, { x: layoutNode.px, y: layoutNode.py }) }) - this.saveData(this.data.variables, this.data.regulations, layout) + this.saveLayout(layout) } #onRegulationsRefreshed (regulations: RegulationData[]): void { @@ -350,7 +344,7 @@ export default class RootComponent extends LitElement { monotonicity: data.sign } }) - this.saveData(this.data.variables, regs, this.data.layout) + this.saveRegulations(regs) } async loadDummy (): Promise { diff --git a/src/html/component/undo-redo/undo-redo.less b/src/html/component/undo-redo/undo-redo.less index 024302d..d34232c 100644 --- a/src/html/component/undo-redo/undo-redo.less +++ b/src/html/component/undo-redo/undo-redo.less @@ -18,12 +18,19 @@ .uk-button { background: rgb(34, 34, 34); } - - } @media (prefers-color-scheme: light) { .uk-button { background: rgb(222, 222, 222); } + + .uk-button:hover { + background: rgb(200, 200, 200); + } + + + .fa-arrow-left, .fa-arrow-right { + color: black; + } } diff --git a/src/html/component/undo-redo/undo-redo.ts b/src/html/component/undo-redo/undo-redo.ts index 9ba68ca..3754d46 100644 --- a/src/html/component/undo-redo/undo-redo.ts +++ b/src/html/component/undo-redo/undo-redo.ts @@ -29,9 +29,9 @@ export default class UndoRedo extends LitElement { render (): TemplateResult { return html`
- -
` diff --git a/src/html/util/config.ts b/src/html/util/config.ts index 583102e..4e9b5ed 100644 --- a/src/html/util/config.ts +++ b/src/html/util/config.ts @@ -36,3 +36,5 @@ export const tabList: TabData[] = [ icon: 'a' }) ] + +export const functionDebounceTimer = 1000