Skip to content
Snippets Groups Projects
Commit 38c8f591 authored by Matthias Konitzny's avatar Matthias Konitzny :fire:
Browse files

Added more flexibility to history handling.

parent f161b127
No related branches found
No related tags found
No related merge requests found
......@@ -95,7 +95,7 @@ export class Node
}
public setType(typeId: number) {
const newType = this.graph.nameToObjectGroup.get(typeId); // TODO
const newType = this.graph.nameToObjectGroup.get(String(typeId)); // TODO
// Exists?
if (newType === undefined) {
......
import { SerializableItem } from "./serializableitem";
interface SavePoint<DataType> {
id: number;
description: string;
data: DataType;
}
export class History<HistoryDataType> {
public maxCheckpoints: number;
public currentCheckpoint: number;
private current: number;
private data: SerializableItem<unknown, HistoryDataType>;
private checkpoints: SavePoint<HistoryDataType>[];
public checkpoints: SavePoint<HistoryDataType>[];
private next: number;
constructor(
data: SerializableItem<unknown, HistoryDataType>,
......@@ -20,49 +22,63 @@ export class History<HistoryDataType> {
this.data = data;
this.maxCheckpoints = maxCheckpoints;
this.checkpoints = [];
this.currentCheckpoint = -1;
this.checkpoint(initialMessage);
this.current = 0;
this.next = 0;
this.createCheckpoint(initialMessage);
}
checkpoint(description: string) {
public createCheckpoint(description: string) {
const checkpointData = this.data.toHistorySerializableObject();
const checkpoint = {
id: ++this.next,
description: description,
data: JSON.parse(JSON.stringify(checkpointData)), // deepcopy
};
// Remove potential history which is not relevant anymore (maybe caused by undo ops)
this.currentCheckpoint++;
this.checkpoints.length = this.currentCheckpoint;
this.checkpoints.length = ++this.current;
this.checkpoints.push(checkpoint);
}
public get currentCheckpoint() {
return this.checkpoints[this.current];
}
public historyDescription(): Array<string> {
return this.checkpoints.map((savepoint) => savepoint.description);
}
public resetToCheckpoint(id: number): SavePoint<HistoryDataType> {
const index = this.checkpoints.findIndex(
(checkpoint) => checkpoint.id == id
);
if (index > 0) {
this.current = index;
return this.checkpoints[index];
}
}
public undo(): SavePoint<HistoryDataType> {
if (this.hasUndoCheckpoints()) {
return this.checkpoints[this.currentCheckpoint--];
} else {
return this.checkpoints[0];
this.current--;
}
return this.checkpoints[this.current];
}
public redo(): SavePoint<HistoryDataType> {
if (this.hasRedoCheckpoints()) {
return this.checkpoints[this.currentCheckpoint++];
} else {
return this.checkpoints[this.checkpoints.length - 1];
this.current++;
}
return this.checkpoints[this.current];
}
public hasUndoCheckpoints(): boolean {
return this.currentCheckpoint > 0;
return this.current > 0;
}
public hasRedoCheckpoints(): boolean {
return this.currentCheckpoint < this.checkpoints.length;
return this.current < this.checkpoints.length;
}
}
import React, { ChangeEvent } from "react";
import { saveGraphJson } from "../../common/datasets";
import ManagedData from "../structures/manageddata";
import "./historynavigator.css";
import { History } from "../../common/history";
type propTypes = {
historyObject: ManagedData;
history: History<any>;
spaceId: string;
onChange: { (): void };
};
......@@ -23,23 +23,26 @@ export class HistoryNavigator extends React.Component<propTypes> {
* Undo a step in the history object.
*/
handleUndo() {
this.props.historyObject.undo();
this.props.history.undo();
}
/**
* Redo a step in the hisory object.
*/
handleRedo() {
this.props.historyObject.redo();
this.props.history.redo();
}
/**
* Saves current data of history object.
*/
handleSave() {
saveGraphJson(this.props.spaceId, this.props.historyObject.serialize());
saveGraphJson(
this.props.spaceId,
this.props.history.currentCheckpoint.data
);
// TODO: Save successful?
this.props.historyObject.markChangesAsSaved();
// this.props.historyObject.markChangesAsSaved(); TODO: Reimplement
alert(
"Saved! (Though not for sure, currently not checking for success of failure)"
);
......@@ -49,7 +52,7 @@ export class HistoryNavigator extends React.Component<propTypes> {
* Loads selected savepoint into history object.
*/
handleSelectSavepoint(e: ChangeEvent<HTMLSelectElement>) {
if (!this.props.historyObject.goToSavePoint(Number(e.target.value))) {
if (!this.props.history.resetToCheckpoint(Number(e.target.value))) {
alert("Something went wrong, could not load savepoint.");
} else {
this.props.onChange();
......@@ -64,14 +67,13 @@ export class HistoryNavigator extends React.Component<propTypes> {
<select
onChange={this.handleSelectSavepoint}
value={
this.props.historyObject &&
this.props.historyObject.currentSavePoint
? this.props.historyObject.currentSavePoint.id
this.props.history
? this.props.history.currentCheckpoint.id
: 0
}
>
{this.props.historyObject
? this.props.historyObject.history.map((savepoint) => {
{this.props.history
? this.props.history.checkpoints.map((savepoint) => {
return (
<option
key={savepoint.id}
......@@ -85,11 +87,11 @@ export class HistoryNavigator extends React.Component<propTypes> {
</select>
<button
onClick={this.handleSave}
disabled={
this.props.historyObject
? !this.props.historyObject.hasUnsavedChanges()
: true
}
// disabled={ TODO: Reimplement
// this.props.history
// ? !this.props.history.hasUnsavedChanges()
// : true
// }
>
Save
</button>
......
......@@ -660,7 +660,7 @@ export class Editor extends React.PureComponent<propTypes, stateTypes> {
<div id="sidepanel">
<HistoryNavigator
spaceId="space"
historyObject={this.state.graph}
history={this.state.graph}
onChange={this.onGraphDataChange}
/>
<hr />
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment