([]);
@@ -141,6 +150,30 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
}
});
+ function rollBackTo(action: UndoRedoAction) {
+ const undoSet = new Set(undoActionStack.value);
+
+ if (!undoSet.has(action)) {
+ throw new ActionOutOfBoundsError(action, "undo");
+ }
+
+ while (nextRedoAction.value !== action) {
+ undo();
+ }
+ }
+
+ function rollForwardTo(action: UndoRedoAction) {
+ const redoSet = new Set(redoActionStack.value);
+
+ if (!redoSet.has(action)) {
+ throw new ActionOutOfBoundsError(action, "redo");
+ }
+
+ while (nextUndoAction.value !== action) {
+ redo();
+ }
+ }
+
return {
undoActionStack,
redoActionStack,
@@ -162,6 +195,8 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
hasUndo,
hasRedo,
$reset,
+ rollBackTo,
+ rollForwardTo,
};
});
diff --git a/client/src/stores/undoRedoStore/undoRedoAction.ts b/client/src/stores/undoRedoStore/undoRedoAction.ts
index 63a54f5e4ff4..88a42a5a0971 100644
--- a/client/src/stores/undoRedoStore/undoRedoAction.ts
+++ b/client/src/stores/undoRedoStore/undoRedoAction.ts
@@ -1,5 +1,12 @@
+let idCounter = 0;
+
export class UndoRedoAction {
protected internalName?: string;
+ public id: number;
+
+ constructor() {
+ this.id = idCounter++;
+ }
get name(): string | undefined {
return this.internalName;
From bf3b7353958d8fd3c34f88d272b5ba8edf884f15 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 6 May 2024 17:23:49 +0200
Subject: [PATCH 02/17] allow clicking actions to change current state
---
.../src/components/UndoRedo/UndoRedoStack.vue | 26 ++++++++++++-------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/client/src/components/UndoRedo/UndoRedoStack.vue b/client/src/components/UndoRedo/UndoRedoStack.vue
index 5a4c15480e03..8166433ba945 100644
--- a/client/src/components/UndoRedo/UndoRedoStack.vue
+++ b/client/src/components/UndoRedo/UndoRedoStack.vue
@@ -1,17 +1,12 @@
+
diff --git a/client/src/stores/undoRedoStore/index.ts b/client/src/stores/undoRedoStore/index.ts
index 2c7fc7773f76..ea5ea277c3d4 100644
--- a/client/src/stores/undoRedoStore/index.ts
+++ b/client/src/stores/undoRedoStore/index.ts
@@ -151,6 +151,7 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
});
function rollBackTo(action: UndoRedoAction) {
+ flushLazyAction();
const undoSet = new Set(undoActionStack.value);
if (!undoSet.has(action)) {
@@ -163,6 +164,7 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
}
function rollForwardTo(action: UndoRedoAction) {
+ flushLazyAction();
const redoSet = new Set(redoActionStack.value);
if (!redoSet.has(action)) {
From 98696a5bffa546ba82437198f6bd707f0efe6a53 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Mon, 15 Jul 2024 11:36:10 +0200
Subject: [PATCH 04/17] move changes button to top bar
---
client/src/components/Workflow/Editor/Index.vue | 13 +++++++++----
client/src/components/Workflow/Editor/Options.vue | 13 +------------
2 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/client/src/components/Workflow/Editor/Index.vue b/client/src/components/Workflow/Editor/Index.vue
index b336174caf0a..74cdc9382529 100644
--- a/client/src/components/Workflow/Editor/Index.vue
+++ b/client/src/components/Workflow/Editor/Index.vue
@@ -59,6 +59,12 @@
@click="undoRedoStore.redo()">
+
+
+
+ @onUpgrade="onUpgrade" />
@@ -182,7 +187,7 @@
@@ -59,7 +74,16 @@ watch(
diff --git a/client/src/composables/math.ts b/client/src/composables/math.ts
new file mode 100644
index 000000000000..7703c203f1fe
--- /dev/null
+++ b/client/src/composables/math.ts
@@ -0,0 +1,49 @@
+/**
+ * There are similar functions to those in this module in vue-use, but they only work one-way.
+ * Unlike vue-use, these composables return refs which can be set.
+ */
+
+import { type MaybeRefOrGetter, toValue } from "@vueuse/core";
+import { computed, type Ref } from "vue";
+
+/**
+ * Wraps a number ref, restricting it's values to a given range
+ *
+ * @param ref ref containing a number to wrap
+ * @param min lowest possible value of range
+ * @param max highest possible value of range
+ * @returns clamped ref
+ */
+export function useClamp(ref: Ref, min: MaybeRefOrGetter, max: MaybeRefOrGetter): Ref {
+ const clamp = (value: number) => {
+ return Math.min(Math.max(value, toValue(min)), toValue(max));
+ };
+
+ const clampedRef = computed({
+ get: () => clamp(ref.value),
+ set: (value) => (ref.value = clamp(value)),
+ });
+
+ return clampedRef;
+}
+
+/**
+ * Wraps a number ref, restricting it's values to align to a given step size
+ *
+ * @param ref ref containing a number to wrap
+ * @param stepSize size of steps to restrict value to
+ * @returns wrapped red
+ */
+export function useStep(ref: Ref, stepSize: MaybeRefOrGetter = 1): Ref {
+ const step = (value: number) => {
+ const stepSizeValue = toValue(stepSize);
+ return Math.round(value / stepSizeValue) * stepSizeValue;
+ };
+
+ const steppedRef = computed({
+ get: () => step(ref.value),
+ set: (value) => (ref.value = step(value)),
+ });
+
+ return steppedRef;
+}
diff --git a/client/src/stores/undoRedoStore/index.ts b/client/src/stores/undoRedoStore/index.ts
index e0bcb3577266..e1f4c9bf65cb 100644
--- a/client/src/stores/undoRedoStore/index.ts
+++ b/client/src/stores/undoRedoStore/index.ts
@@ -1,5 +1,6 @@
import { computed, ref } from "vue";
+import { useClamp, useStep } from "@/composables/math";
import { useUserLocalStorage } from "@/composables/userLocalStorage";
import { defineScopedStore } from "@/stores/scopedStore";
@@ -22,9 +23,13 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
const undoActionStack = ref([]);
const redoActionStack = ref([]);
- const maxUndoActions = useUserLocalStorage(`undoRedoStore-maxUndoActions`, 100);
+ const minUndoActions = ref(10);
+ const maxUndoActions = ref(10000);
- /** names of actions which were deleted due to maxUndoActions being exceeded */
+ const savedUndoActionsValue = useUserLocalStorage(`undoRedoStore-savedUndoActions`, 100);
+ const savedUndoActions = useClamp(useStep(savedUndoActionsValue), minUndoActions, maxUndoActions);
+
+ /** names of actions which were deleted due to savedUndoActions being exceeded */
const deletedActions = ref([]);
function $reset() {
@@ -59,7 +64,7 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
clearRedoStack();
undoActionStack.value.push(action);
- while (undoActionStack.value.length > maxUndoActions.value && undoActionStack.value.length > 0) {
+ while (undoActionStack.value.length > savedUndoActions.value && undoActionStack.value.length > 0) {
const action = undoActionStack.value.shift();
deletedActions.value.push(action?.name ?? "unnamed action");
action?.destroy();
@@ -186,7 +191,9 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
return {
undoActionStack,
redoActionStack,
+ minUndoActions,
maxUndoActions,
+ savedUndoActions,
deletedActions,
undo,
redo,
From 15b353e660b8d1fc1cc6352e1003412ea7750a98 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Fri, 2 Aug 2024 13:15:05 +0200
Subject: [PATCH 16/17] make best practice panel hide changes
---
client/src/components/Workflow/Editor/Index.vue | 1 +
client/src/composables/math.ts | 2 +-
client/src/stores/undoRedoStore/index.ts | 2 ++
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/client/src/components/Workflow/Editor/Index.vue b/client/src/components/Workflow/Editor/Index.vue
index c0ef58b0406a..1258bbca0a0a 100644
--- a/client/src/components/Workflow/Editor/Index.vue
+++ b/client/src/components/Workflow/Editor/Index.vue
@@ -798,6 +798,7 @@ export default {
this.ensureParametersSet();
this.stateStore.activeNodeId = null;
this.showInPanel = "lint";
+ this.showChanges = false;
},
onUpgrade() {
this.onAttemptRefactor([{ action_type: "upgrade_all_steps" }]);
diff --git a/client/src/composables/math.ts b/client/src/composables/math.ts
index 7703c203f1fe..421a9ca24aa5 100644
--- a/client/src/composables/math.ts
+++ b/client/src/composables/math.ts
@@ -31,7 +31,7 @@ export function useClamp(ref: Ref, min: MaybeRefOrGetter, max: M
* Wraps a number ref, restricting it's values to align to a given step size
*
* @param ref ref containing a number to wrap
- * @param stepSize size of steps to restrict value to
+ * @param [stepSize = 1] size of steps to restrict value to. defaults to 1
* @returns wrapped red
*/
export function useStep(ref: Ref, stepSize: MaybeRefOrGetter = 1): Ref {
diff --git a/client/src/stores/undoRedoStore/index.ts b/client/src/stores/undoRedoStore/index.ts
index e1f4c9bf65cb..f83dd6f6d103 100644
--- a/client/src/stores/undoRedoStore/index.ts
+++ b/client/src/stores/undoRedoStore/index.ts
@@ -36,6 +36,8 @@ export const useUndoRedoStore = defineScopedStore("undoRedoStore", () => {
undoActionStack.value.forEach((action) => action.destroy());
undoActionStack.value = [];
deletedActions.value = [];
+ minUndoActions.value = 10;
+ maxUndoActions.value = 10000;
clearRedoStack();
}
From bb43a51ef5661c0e10381116e76e3b7bb17c3291 Mon Sep 17 00:00:00 2001
From: Laila Los <44241786+ElectronicBlueberry@users.noreply.github.com>
Date: Fri, 2 Aug 2024 14:32:55 +0200
Subject: [PATCH 17/17] add info
---
client/src/components/UndoRedo/UndoRedoStack.vue | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/client/src/components/UndoRedo/UndoRedoStack.vue b/client/src/components/UndoRedo/UndoRedoStack.vue
index 33d7e4f13cde..e0b89b1cbe73 100644
--- a/client/src/components/UndoRedo/UndoRedoStack.vue
+++ b/client/src/components/UndoRedo/UndoRedoStack.vue
@@ -72,6 +72,8 @@ function updateSavedUndoActions() {
start of session
+ click an action to undo/redo multiple changes
+