From 95db9f6528c4f12719df5606c2a5cbe5eaf49531 Mon Sep 17 00:00:00 2001 From: Eric Tuvesson Date: Wed, 8 Jan 2025 21:58:37 +0100 Subject: [PATCH] chore: Add some TS types to WarningsModel (#86) --- .../src/editor/src/ViewerConnection.ts | 6 +- .../NodeTypeAdapters/RouterNavigateAdapter.ts | 4 +- .../src/editor/src/models/VariantModel.ts | 4 +- .../src/editor/src/models/warningsmodel.ts | 112 ++++++++++++------ 4 files changed, 82 insertions(+), 44 deletions(-) diff --git a/packages/noodl-editor/src/editor/src/ViewerConnection.ts b/packages/noodl-editor/src/editor/src/ViewerConnection.ts index aec9a0c..e4f88e3 100644 --- a/packages/noodl-editor/src/editor/src/ViewerConnection.ts +++ b/packages/noodl-editor/src/editor/src/ViewerConnection.ts @@ -6,7 +6,7 @@ import { EventDispatcher } from '../../shared/utils/EventDispatcher'; import ProjectModules from '../../shared/utils/projectmodules'; import { NodeLibrary } from './models/nodelibrary'; import { ProjectModel } from './models/projectmodel'; -import { WarningsModel } from './models/warningsmodel'; +import { WarningRef, WarningsModel } from './models/warningsmodel'; import DebugInspector from './utils/debuginspector'; import * as Exporter from './utils/exporter'; @@ -112,7 +112,7 @@ export class ViewerConnection extends Model { } else if (request.cmd === 'showwarning' && request.type === 'viewer') { const content = JSON.parse(request.content); if (ProjectModel.instance !== undefined) { - const ref = { + const ref: WarningRef = { component: ProjectModel.instance.getComponentWithName(content.componentName), node: ProjectModel.instance.findNodeWithId(content.nodeId), key: content.key, @@ -124,7 +124,7 @@ export class ViewerConnection extends Model { } } else if (request.cmd === 'clearwarnings' && request.type === 'viewer') { const content = JSON.parse(request.content); - const ref = { + const ref: WarningRef = { component: ProjectModel.instance.getComponentWithName(content.componentName), node: ProjectModel.instance.findNodeWithId(content.nodeId) }; diff --git a/packages/noodl-editor/src/editor/src/models/NodeTypeAdapters/RouterNavigateAdapter.ts b/packages/noodl-editor/src/editor/src/models/NodeTypeAdapters/RouterNavigateAdapter.ts index a0544ce..7c9509d 100644 --- a/packages/noodl-editor/src/editor/src/models/NodeTypeAdapters/RouterNavigateAdapter.ts +++ b/packages/noodl-editor/src/editor/src/models/NodeTypeAdapters/RouterNavigateAdapter.ts @@ -1,5 +1,5 @@ import { NodeGraphNode } from '@noodl-models/nodegraphmodel'; -import { WarningsModel } from '@noodl-models/warningsmodel'; +import { type Warning, WarningsModel } from '@noodl-models/warningsmodel'; import { ProjectModel } from '../projectmodel'; import NodeTypeAdapter from './NodeTypeAdapter'; @@ -103,7 +103,7 @@ export class RouterNavigateAdapter extends NodeTypeAdapter { const hasValidTarget = target && pageComponents.includes(target); - const warning = + const warning: Warning = hasValidTarget === false ? { message: "The target page doesn't belong to the target router", diff --git a/packages/noodl-editor/src/editor/src/models/VariantModel.ts b/packages/noodl-editor/src/editor/src/models/VariantModel.ts index a8c770a..50eb190 100644 --- a/packages/noodl-editor/src/editor/src/models/VariantModel.ts +++ b/packages/noodl-editor/src/editor/src/models/VariantModel.ts @@ -458,11 +458,11 @@ export class VariantModel extends Model { } ); } else if (c.type === 'defaultStateTransition') { - var state = + const state = this.getType().visualStates !== undefined ? this.getType().visualStates.find((s) => s.name === c.state) : undefined; - var stateName = state !== undefined ? state.label : c.state; + const stateName = state !== undefined ? state.label : c.state; WarningsModel.instance.setWarning( { key: 'variant-dst-conflict-' + this.name + '-' + this.getType().fullName + '-' + c.state }, diff --git a/packages/noodl-editor/src/editor/src/models/warningsmodel.ts b/packages/noodl-editor/src/editor/src/models/warningsmodel.ts index 12225c7..7f77afe 100644 --- a/packages/noodl-editor/src/editor/src/models/warningsmodel.ts +++ b/packages/noodl-editor/src/editor/src/models/warningsmodel.ts @@ -1,9 +1,42 @@ -import { ComponentModel } from '@noodl-models/componentmodel'; -import { ProjectModel } from '@noodl-models/projectmodel'; import { toArray } from 'underscore'; + +import type { ComponentModel } from '@noodl-models/componentmodel'; + import Model from '../../../shared/model'; +import type { NodeGraphNode } from './nodegraphmodel'; import { NodeLibrary } from './nodelibrary'; +export type WarningLabel = 'warning' | 'error'; + +export type Warning = + | { + type?: string; + level?: WarningLabel; + message: string; + showGlobally?: boolean; + } + | { + type: 'conflict' | 'conflict-source-code'; + level?: WarningLabel; + message: string; + showGlobally?: boolean; + conflictMetadata: { + parameter: string; + ours: string; + theirs: string; + }; + onDismiss: () => void; + onUseTheirs: () => void; + }; + +export type WarningRef = { + key?: string; + component?: ComponentModel; + connection?: TSFixme; + node?: NodeGraphNode; + isFromViewer?: boolean; +}; + /** * The first level of the warnings object is component name * Second is the connection / node identifier @@ -14,7 +47,7 @@ interface Warnings { [node_connection_id: string]: { [warningKey: string]: { ref: TSFixme; - warning: TSFixme; + warning: Warning; }; }; }; @@ -24,7 +57,7 @@ export class WarningsModel extends Model { public static instance = new WarningsModel(); private warnings: Warnings = {}; - private notifyChangedScheduled: boolean = false; + private notifyChangedScheduled = false; constructor() { super(); @@ -35,10 +68,12 @@ export class WarningsModel extends Model { }); } - public setWarning(ref, warning) { - var w = this.getWarningsForRef(ref, warning !== undefined); + public setWarning(ref: WarningRef, warning: Warning) { + const w = this.getWarningsForRef(ref, warning !== undefined); if (!warning) { - if (w) delete w[ref.key]; + if (w) { + delete w[ref.key]; + } } else { warning.level = warning.level || 'warning'; w[ref.key] = { ref: ref, warning: warning }; @@ -47,31 +82,34 @@ export class WarningsModel extends Model { this.scheduleNotifyChanged(); } - public clearWarningsForRef(ref) { - var w = this.getWarningsForRef(ref); + public clearWarningsForRef(ref: WarningRef) { + const w = this.getWarningsForRef(ref); if (!w) return; - for (var i in w) delete w[i]; + for (const i in w) { + delete w[i]; + } this.scheduleNotifyChanged(); } - public clearAllWarningsForComponent(component) { + public clearAllWarningsForComponent(component: ComponentModel) { const warnings = this.warnings[component.name]; - if (!warnings) return; - for (let i in warnings) delete warnings[i]; + for (const i in warnings) { + delete warnings[i]; + } this.scheduleNotifyChanged(); } - public clearWarningsForRefMatching(matchCb) { + public clearWarningsForRefMatching(matchFn: (ref: TSFixme) => boolean) { for (const cw of Object.values(this.warnings)) { for (const ws of Object.values(cw)) { for (const key in ws) { const w = ws[key]; - if (matchCb(w.ref)) { + if (matchFn(w.ref)) { delete ws[key]; } } @@ -87,15 +125,14 @@ export class WarningsModel extends Model { this.scheduleNotifyChanged(); } - public getWarnings(ref) { - var w = this.getWarningsForRef(ref); + public getWarnings(ref: WarningRef) { + const w = this.getWarningsForRef(ref); if (!w) return; - if (Object.keys(w).length === 0) return; // Create short message for hover - var messages = []; - for (var k in w) { + const messages = []; + for (const k in w) { if (w[k].warning) messages.push(w[k].warning.message); } @@ -106,13 +143,13 @@ export class WarningsModel extends Model { } public forEachWarningInComponent(c, callback, args) { - var cw = this.warnings[c ? c.name : '/']; + const cw = this.warnings[c ? c.name : '/']; if (!cw) return; - for (var ref in cw) { - var ws = cw[ref]; + for (const ref in cw) { + const ws = cw[ref]; - for (var w in ws) { + for (const w in ws) { if (!args || !args.levels || args.levels.indexOf(ws[w].warning.level) !== -1) { callback(ws[w]); } @@ -121,7 +158,7 @@ export class WarningsModel extends Model { } public getAllWarningsForComponent(c, args) { - var warnings = []; + const warnings = []; this.forEachWarningInComponent( c, function (warning) { @@ -152,15 +189,15 @@ export class WarningsModel extends Model { } public getTotalNumberOfWarnings(args) { - var total = 0; - for (var key in this.warnings) { + let total = 0; + for (const key in this.warnings) { total += this.getNumberOfWarningsForComponent({ name: key }, args); } return total; } public getTotalNumberOfWarningsMatching(matchCb) { - var total = 0; + let total = 0; this.forEachWarning((c, ref, key, warning) => { if (matchCb(key, ref, warning)) total++; }); @@ -168,16 +205,16 @@ export class WarningsModel extends Model { } public forEachWarning(callback: (c: string, ref, key, warning) => void) { - var w = this.warnings; + const w = this.warnings; for (const c in w) { // Loop over all components - var _w = w[c]; + const _w = w[c]; for (const ref in _w) { // Loop over all refs - var __w = _w[ref]; + const __w = _w[ref]; for (const key in __w) { // Loop over all keys - var warning = __w[key]; + const warning = __w[key]; callback(c, ref, key, warning); } @@ -195,12 +232,12 @@ export class WarningsModel extends Model { // node: nodeRef, // connection: connectionRef, // key: key of warning as string} - private getWarningsForRef(ref, create?) { - var componentName = ref.component ? ref.component.name : '/'; + private getWarningsForRef(ref: WarningRef, create?) { + const componentName = ref.component ? ref.component.name : '/'; if (!this.warnings[componentName]) this.warnings[componentName] = {}; - var cw = this.warnings[componentName]; + const cw = this.warnings[componentName]; - var key; + let key; if (ref.node) key = 'node/' + ref.node.id; else if (ref.connection) key = @@ -220,7 +257,8 @@ export class WarningsModel extends Model { /** Batch changed notifications so listeners don't get peppered */ private scheduleNotifyChanged() { - var _this = this; + // eslint-disable-next-line @typescript-eslint/no-this-alias + const _this = this; if (this.notifyChangedScheduled) return; this.notifyChangedScheduled = true;