feat: implemented the rest of the warning registry
ref: N25B-450
This commit is contained in:
@@ -1,25 +1,43 @@
|
|||||||
|
/* contains all logic for the VisProgEditor warning system
|
||||||
|
*
|
||||||
|
* Missing but desirable features:
|
||||||
|
* - Global Warnings, e.g. not node specific
|
||||||
|
* - could be done by creating a global scope entry with GLOBAL as nodeId
|
||||||
|
* - Warning filtering:
|
||||||
|
* - if there is no completely connected chain of startNode-[PhaseNodes]-EndNode
|
||||||
|
* then hide any startNode, phaseNode, or endNode specific warnings
|
||||||
|
* */
|
||||||
|
|
||||||
// --| Type definitions |--
|
// --| Type definitions |--
|
||||||
|
|
||||||
import type {FlowState} from "./VisProgTypes.tsx";
|
import type {FlowState} from "./VisProgTypes.tsx";
|
||||||
|
|
||||||
|
|
||||||
|
export type WarningId = NodeId | "GLOBAL_WARNINGS";
|
||||||
export type NodeId = string;
|
export type NodeId = string;
|
||||||
|
|
||||||
|
|
||||||
export type WarningType =
|
export type WarningType =
|
||||||
| 'MISSING_INPUT'
|
| 'MISSING_INPUT'
|
||||||
| 'MISSING_OUTPUT'
|
| 'MISSING_OUTPUT'
|
||||||
|
| 'PLAN_IS_UNDEFINED'
|
||||||
| string
|
| string
|
||||||
export type WarningSeverity =
|
|
||||||
| 'INFO' // Acceptable, but probably not desirable
|
|
||||||
| 'WARNING' // Prevents running program, should be fixed before running program is allowed
|
|
||||||
|
|
||||||
|
export type WarningSeverity =
|
||||||
|
| 'INFO' // Acceptable, but important to be aware of
|
||||||
|
| 'WARNING' // Acceptable, but probably undesirable behavior
|
||||||
|
| 'ERROR' // Prevents running program, should be fixed before running program is allowed
|
||||||
|
|
||||||
|
export type WarningScope = {
|
||||||
|
id: string;
|
||||||
|
handleId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type EditorWarning = {
|
export type EditorWarning = {
|
||||||
nodeId: NodeId;
|
scope: WarningScope;
|
||||||
type: WarningType;
|
type: WarningType;
|
||||||
severity: WarningSeverity;
|
severity: WarningSeverity;
|
||||||
description: string;
|
description: string;
|
||||||
handleId?: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,8 +46,9 @@ export type EditorWarning = {
|
|||||||
*/
|
*/
|
||||||
export type WarningKey = { type: WarningType, handleId: string | null }; // for warnings that can occur on a per-handle basis
|
export type WarningKey = { type: WarningType, handleId: string | null }; // for warnings that can occur on a per-handle basis
|
||||||
|
|
||||||
export type WarningRegistry = Map<NodeId, Map<WarningKey, EditorWarning>>;
|
|
||||||
export type SeverityIndex = Map<WarningSeverity, Set<{ nodeId: NodeId, warningKey: WarningKey}>>;
|
export type WarningRegistry = Map<WarningId , Map<WarningKey, EditorWarning>>;
|
||||||
|
export type SeverityIndex = Map<WarningSeverity, Set<{ id: WarningId, warningKey: WarningKey}>>;
|
||||||
|
|
||||||
type ZustandSet = (partial: Partial<FlowState> | ((state: FlowState) => Partial<FlowState>)) => void;
|
type ZustandSet = (partial: Partial<FlowState> | ((state: FlowState) => Partial<FlowState>)) => void;
|
||||||
type ZustandGet = () => FlowState;
|
type ZustandGet = () => FlowState;
|
||||||
@@ -58,35 +77,37 @@ export type EditorWarningRegistry = {
|
|||||||
* unregisters a warning from the warningRegistry and the SeverityIndex
|
* unregisters a warning from the warningRegistry and the SeverityIndex
|
||||||
* @param {EditorWarning} warning
|
* @param {EditorWarning} warning
|
||||||
*/
|
*/
|
||||||
unregisterWarning: (nodeId: NodeId, warningKey: WarningKey) => void
|
unregisterWarning: (id: WarningId, warningKey: WarningKey) => void
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* unregisters warnings from the warningRegistry and the SeverityIndex
|
* unregisters warnings from the warningRegistry and the SeverityIndex
|
||||||
* @param {EditorWarning} warning
|
* @param {EditorWarning} warning
|
||||||
*/
|
*/
|
||||||
unregisterWarningsForNode: (nodeId: string) => void;
|
unregisterWarningsForId: (id: WarningId) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --| implemented logic |--
|
// --| implemented logic |--
|
||||||
|
|
||||||
|
export const globalWarningKey = (type: WarningType) : WarningKey => { return {type: type, handleId: null}};
|
||||||
|
export const globalWarning = "GLOBAL_WARNINGS";
|
||||||
|
|
||||||
|
|
||||||
export function editorWarningRegistry(get: ZustandGet, set: ZustandSet) : EditorWarningRegistry { return {
|
export function editorWarningRegistry(get: ZustandGet, set: ZustandSet) : EditorWarningRegistry { return {
|
||||||
editorWarningRegistry: new Map<NodeId, Map<WarningKey, EditorWarning>>(),
|
editorWarningRegistry: new Map<NodeId, Map<WarningKey, EditorWarning>>(),
|
||||||
severityIndex: new Map([
|
severityIndex: new Map([
|
||||||
['INFO', new Set<{ nodeId: NodeId, warningKey: WarningKey}>()],
|
['INFO', new Set<{ id: WarningId, warningKey: WarningKey}>()],
|
||||||
['WARNING', new Set<{ nodeId: NodeId, warningKey: WarningKey}>()]
|
['WARNING', new Set<{ id: WarningId, warningKey: WarningKey}>()]
|
||||||
]),
|
]),
|
||||||
|
|
||||||
getWarningsBySeverity: (warningSeverity) => {
|
getWarningsBySeverity: (warningSeverity) => {
|
||||||
const wRegistry = get().editorWarningRegistry;
|
const wRegistry = get().editorWarningRegistry;
|
||||||
const sIndex = get().severityIndex;
|
const sIndex = get().severityIndex;
|
||||||
|
|
||||||
const warningKeys = sIndex.get(warningSeverity);
|
const warningKeys = sIndex.get(warningSeverity);
|
||||||
|
|
||||||
const warnings: EditorWarning[] = [];
|
const warnings: EditorWarning[] = [];
|
||||||
|
|
||||||
warningKeys?.forEach(
|
warningKeys?.forEach(
|
||||||
({nodeId, warningKey}) => {
|
({id, warningKey}) => {
|
||||||
const warning = wRegistry.get(nodeId)?.get(warningKey);
|
const warning = wRegistry.get(id)?.get(warningKey);
|
||||||
|
|
||||||
if (warning) {
|
if (warning) {
|
||||||
warnings.push(warning);
|
warnings.push(warning);
|
||||||
@@ -97,24 +118,29 @@ export function editorWarningRegistry(get: ZustandGet, set: ZustandSet) : Editor
|
|||||||
return warnings;
|
return warnings;
|
||||||
},
|
},
|
||||||
|
|
||||||
isProgramValid: () => { return true},
|
isProgramValid: () => {
|
||||||
|
const sIndex = get().severityIndex;
|
||||||
|
return sIndex.get("ERROR")!.size === 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
getWarnings: () => Array.from(get().editorWarningRegistry.values())
|
||||||
|
.flatMap(innerMap => Array.from(innerMap.values())),
|
||||||
|
|
||||||
getWarnings: () => { return []},
|
|
||||||
|
|
||||||
registerWarning: (warning) => {
|
registerWarning: (warning) => {
|
||||||
const { nodeId, type, severity, handleId } = warning;
|
const { scope: {id, handleId}, type, severity } = warning;
|
||||||
const warningKey = handleId ? { type, handleId } : { type, handleId: null};
|
const warningKey = handleId ? { type, handleId } : { type, handleId: null};
|
||||||
const wRegistry = get().editorWarningRegistry;
|
const wRegistry = get().editorWarningRegistry;
|
||||||
const sIndex = get().severityIndex;
|
const sIndex = get().severityIndex;
|
||||||
|
|
||||||
// add to registry
|
// add to warning registry
|
||||||
if (!wRegistry.has(nodeId)) {
|
if (!wRegistry.has(id)) {
|
||||||
wRegistry.set(nodeId, new Map());
|
wRegistry.set(id, new Map());
|
||||||
}
|
}
|
||||||
wRegistry.get(nodeId)!.set(warningKey, warning);
|
wRegistry.get(id)!.set(warningKey, warning);
|
||||||
|
|
||||||
// add to severityIndex
|
// add to severityIndex
|
||||||
sIndex.get(severity)!.add({nodeId,warningKey});
|
sIndex.get(severity)!.add({id,warningKey});
|
||||||
|
|
||||||
set({
|
set({
|
||||||
editorWarningRegistry: wRegistry,
|
editorWarningRegistry: wRegistry,
|
||||||
@@ -122,18 +148,18 @@ export function editorWarningRegistry(get: ZustandGet, set: ZustandSet) : Editor
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
unregisterWarning: (nodeId, warningKey) => {
|
unregisterWarning: (id, warningKey) => {
|
||||||
|
|
||||||
const wRegistry = get().editorWarningRegistry;
|
const wRegistry = get().editorWarningRegistry;
|
||||||
const sIndex = get().severityIndex;
|
const sIndex = get().severityIndex;
|
||||||
|
|
||||||
const warning = wRegistry.get(nodeId)!.get(warningKey);
|
const warning = wRegistry.get(id)!.get(warningKey);
|
||||||
// remove from registry
|
// remove from warning registry
|
||||||
wRegistry.get(nodeId)!.delete(warningKey);
|
wRegistry.get(id)!.delete(warningKey);
|
||||||
|
|
||||||
|
|
||||||
// remove from severityIndex
|
// remove from severityIndex
|
||||||
sIndex.get(warning!.severity)!.delete({nodeId,warningKey});
|
sIndex.get(warning!.severity)!.delete({id,warningKey});
|
||||||
|
|
||||||
set({
|
set({
|
||||||
editorWarningRegistry: wRegistry,
|
editorWarningRegistry: wRegistry,
|
||||||
@@ -141,21 +167,21 @@ export function editorWarningRegistry(get: ZustandGet, set: ZustandSet) : Editor
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
unregisterWarningsForNode: (nodeId) => {
|
unregisterWarningsForId: (id) => {
|
||||||
const wRegistry = get().editorWarningRegistry;
|
const wRegistry = get().editorWarningRegistry;
|
||||||
const sIndex = get().severityIndex;
|
const sIndex = get().severityIndex;
|
||||||
|
|
||||||
const nodeWarnings = wRegistry.get(nodeId);
|
const nodeWarnings = wRegistry.get(id);
|
||||||
|
|
||||||
// remove from severity index
|
// remove from severity index
|
||||||
if (nodeWarnings) {
|
if (nodeWarnings) {
|
||||||
nodeWarnings.forEach((warning, warningKey) => {
|
nodeWarnings.forEach((warning, warningKey) => {
|
||||||
sIndex.get(warning.severity)?.delete({nodeId, warningKey});
|
sIndex.get(warning.severity)?.delete({id, warningKey});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove from registry
|
// remove from warning registry
|
||||||
wRegistry.delete(nodeId);
|
wRegistry.delete(id);
|
||||||
|
|
||||||
set({
|
set({
|
||||||
editorWarningRegistry: wRegistry,
|
editorWarningRegistry: wRegistry,
|
||||||
|
|||||||
Reference in New Issue
Block a user