From b650f5309dff6bca25dfa26ae0a105460e1e638d Mon Sep 17 00:00:00 2001 From: "Elias W. BA" Date: Wed, 23 Aug 2023 07:41:47 +0000 Subject: [PATCH 1/2] Write a JS hook using the browser beforeunload event to detect untracked changes --- assets/js/app.js | 3 ++- assets/js/hooks/index.ts | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/assets/js/app.js b/assets/js/app.js index 33a4f7657d..cba3989669 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -25,7 +25,7 @@ import { Socket } from 'phoenix'; import { LiveSocket } from 'phoenix_live_view'; import topbar from '../vendor/topbar'; -import { AssocListChange, Copy, Flash, SubmitViaCtrlS, Tooltip } from './hooks'; +import { AssocListChange, Copy, Flash, SubmitViaCtrlS, Tooltip, UnsavedChanges } from './hooks'; import JobEditor from './job-editor'; import JobEditorResizer from './job-editor-resizer/mount'; import TabSelector from './tab-selector'; @@ -41,6 +41,7 @@ let Hooks = { AssocListChange, Copy, SubmitViaCtrlS, + UnsavedChanges, }; // Sets the checkbox to indeterminate state if the element has the diff --git a/assets/js/hooks/index.ts b/assets/js/hooks/index.ts index 47b6300462..37baa9ab16 100644 --- a/assets/js/hooks/index.ts +++ b/assets/js/hooks/index.ts @@ -79,3 +79,20 @@ export const Copy = { }); }, } as PhoenixHook<{}, { to: string }>; + +export const UnsavedChanges = { + mounted() { + this.handleEvent('changes_detected', () => { + window.addEventListener('beforeunload', this.preventNav); + }); + + this.handleEvent('changes_saved', () => { + window.removeEventListener('beforeunload', this.preventNav); + }); + }, + + preventNav(e) { + e.preventDefault(); + e.returnValue = 'You have unsaved changes! Are you sure you want to leave?'; + }, +}; From 18b9ec1560e9e2a260078a3c5c771c6456860b43 Mon Sep 17 00:00:00 2001 From: "Elias W. BA" Date: Wed, 23 Aug 2023 07:50:08 +0000 Subject: [PATCH 2/2] Use hook to track unsaved changes when validate is called and saved changes when save is successful --- lib/lightning_web/live/workflow_live/edit.ex | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/lightning_web/live/workflow_live/edit.ex b/lib/lightning_web/live/workflow_live/edit.ex index 452159dbcf..6e624b0c98 100644 --- a/lib/lightning_web/live/workflow_live/edit.ex +++ b/lib/lightning_web/live/workflow_live/edit.ex @@ -62,7 +62,11 @@ defmodule LightningWeb.WorkflowLive.Edit do -
+
params}, socket) do + send(self(), :changes_detected) {:noreply, handle_new_params(socket, params)} end @@ -450,6 +455,8 @@ defmodule LightningWeb.WorkflowLive.Edit do Lightning.Repo.insert_or_update(socket.assigns.changeset) |> case do {:ok, workflow} -> + send(self(), :changes_saved) + socket |> assign_workflow(workflow) |> push_patch(to: build_next_path(socket, workflow), replace: true) @@ -501,6 +508,14 @@ defmodule LightningWeb.WorkflowLive.Edit do {:noreply, socket |> assign(follow_run_id: attempt_run.run_id)} end + def handle_info(:changes_detected, socket) do + {:noreply, push_event(socket, "changes_detected", %{})} + end + + def handle_info(:changes_saved, socket) do + {:noreply, push_event(socket, "changes_saved", %{})} + end + defp has_child_edges?(workflow_changeset, job_id) do workflow_changeset |> Ecto.Changeset.get_assoc(:edges, :struct)