add reversibility on category level

This commit is contained in:
undergroundwires
2020-09-01 21:18:16 +01:00
parent d235dee955
commit f51e8859ee
23 changed files with 717 additions and 162 deletions

View File

@@ -0,0 +1,30 @@
import { IReverter } from './IReverter';
import { getCategoryId } from '../../../ScriptNodeParser';
import { SelectedScript } from '@/application/State/Selection/SelectedScript';
import { IApplication } from '@/domain/IApplication';
import { ScriptReverter } from './ScriptReverter';
import { IUserSelection } from '@/application/State/Selection/IUserSelection';
export class CategoryReverter implements IReverter {
private readonly categoryId: number;
private readonly scriptReverters: ReadonlyArray<ScriptReverter>;
constructor(nodeId: string, app: IApplication) {
this.categoryId = getCategoryId(nodeId);
this.scriptReverters = getAllSubScriptReverters(this.categoryId, app);
}
public getState(selectedScripts: ReadonlyArray<SelectedScript>): boolean {
return this.scriptReverters.every((script) => script.getState(selectedScripts));
}
public selectWithRevertState(newState: boolean, selection: IUserSelection): void {
selection.addOrUpdateAllInCategory(this.categoryId, newState);
}
}
function getAllSubScriptReverters(categoryId: number, app: IApplication) {
const category = app.findCategory(categoryId);
if (!category) {
throw new Error(`Category with id "${categoryId}" does not exist`);
}
const scripts = category.getAllScriptsRecursively();
return scripts.map((script) => new ScriptReverter(script.id));
}

View File

@@ -0,0 +1,7 @@
import { SelectedScript } from '@/application/State/Selection/SelectedScript';
import { IUserSelection } from '@/application/State/IApplicationState';
export interface IReverter {
getState(selectedScripts: ReadonlyArray<SelectedScript>): boolean;
selectWithRevertState(newState: boolean, selection: IUserSelection): void;
}

View File

@@ -0,0 +1,16 @@
import { INode, NodeType } from '../INode';
import { IReverter } from './IReverter';
import { ScriptReverter } from './ScriptReverter';
import { IApplication } from '@/domain/IApplication';
import { CategoryReverter } from './CategoryReverter';
export function getReverter(node: INode, app: IApplication): IReverter {
switch (node.type) {
case NodeType.Category:
return new CategoryReverter(node.id, app);
case NodeType.Script:
return new ScriptReverter(node.id);
default:
throw new Error('Unknown script type');
}
}

View File

@@ -0,0 +1,21 @@
import { IReverter } from './IReverter';
import { getScriptId } from '../../../ScriptNodeParser';
import { SelectedScript } from '@/application/State/Selection/SelectedScript';
import { IUserSelection } from '@/application/State/IApplicationState';
export class ScriptReverter implements IReverter {
private readonly scriptId: string;
constructor(nodeId: string) {
this.scriptId = getScriptId(nodeId);
}
public getState(selectedScripts: ReadonlyArray<SelectedScript>): boolean {
const selectedScript = selectedScripts.find((selected) => selected.id === this.scriptId);
if (!selectedScript) {
return false;
}
return selectedScript.revert;
}
public selectWithRevertState(newState: boolean, selection: IUserSelection): void {
selection.addOrUpdateSelectedScript(this.scriptId, newState);
}
}