Skip to content

Commit 476d341

Browse files
authored
feat(entities-plugins): add leave confirmation for flow editor (#2612)
1 parent 38b6181 commit 476d341

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed
Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
import { createGlobalState, useLocalStorage } from '@vueuse/core'
1+
import { toValue } from 'vue'
2+
import { onBeforeRouteLeave } from 'vue-router'
3+
import {
4+
createGlobalState,
5+
useEventListener,
6+
useLocalStorage,
7+
} from '@vueuse/core'
8+
import { createI18n } from '@kong-ui-public/i18n'
9+
import english from '../../../locales/en.json'
210
export { provideEditorStore, useEditorStore } from './flow-editor/store/store'
311

12+
import type { MaybeRefOrGetter } from 'vue'
413
import type { EditorMode } from './types'
514

15+
const { t } = createI18n<typeof english>('en-us', english)
16+
617
export const usePreferences = createGlobalState(() => {
718
const editorMode = useLocalStorage<EditorMode>('datakit-editor-mode', 'flow')
819
const sidePanelExpanded = useLocalStorage<boolean>(
@@ -11,3 +22,30 @@ export const usePreferences = createGlobalState(() => {
1122
)
1223
return { editorMode, sidePanelExpanded }
1324
})
25+
26+
interface LeaveConfirmationOptions {
27+
enabled: MaybeRefOrGetter<boolean> // whether the confirmation step is enabled
28+
confirm?: () => boolean | Promise<boolean> // custom confirm function
29+
}
30+
31+
export function useLeaveConfirmation({
32+
enabled,
33+
confirm,
34+
}: LeaveConfirmationOptions) {
35+
// Soft navigation guard
36+
onBeforeRouteLeave(() => {
37+
if (!toValue(enabled)) return true
38+
39+
return confirm
40+
? confirm()
41+
: window.confirm(t('plugins.free-form.datakit.flow_editor.leave_confirm'))
42+
})
43+
44+
// Hard navigation guard
45+
const onBeforeUnload = (e: BeforeUnloadEvent) => {
46+
if (!toValue(enabled)) return
47+
e.preventDefault()
48+
}
49+
50+
useEventListener('beforeunload', onBeforeUnload)
51+
}

packages/entities/entities-plugins/src/components/free-form/Datakit/flow-editor/FlowEditor.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { watch } from 'vue'
3030
3131
import english from '../../../../locales/en.json'
3232
import { useFormShared } from '../../shared/composables'
33-
import { provideEditorStore } from '../composables'
33+
import { provideEditorStore, useLeaveConfirmation } from '../composables'
3434
import FlowPanels from './FlowPanels.vue'
3535
import EditorModal from './modal/EditorModal.vue'
3636
@@ -77,6 +77,8 @@ watch(modalOpen, () => {
7777
// `fitView` when model is toggled.
7878
setPendingFitView(true)
7979
}, { flush: 'post' }) // Safely schedule fitView after <FlowPanels /> receives the latest `inactive` prop
80+
81+
useLeaveConfirmation({ enabled: modalOpen })
8082
</script>
8183

8284
<style lang="scss" scoped>

packages/entities/entities-plugins/src/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,7 @@
895895
},
896896
"proceed": "Yes, update"
897897
},
898+
"leave_confirm": "Leave current page? Changes you made may not be saved.",
898899
"phase_mask_help": "You can't add call nodes in the response phase."
899900
},
900901
"code_editor": {

0 commit comments

Comments
 (0)