From dfffa799dca49e86c53206df9ec7c2ef498ddba1 Mon Sep 17 00:00:00 2001 From: Mohammad Azmi Date: Mon, 13 Nov 2023 14:45:14 +0700 Subject: [PATCH] replace native dialog with vue modal --- apps/studio/src/App.vue | 5 +- apps/studio/src/assets/styles/app/modals.scss | 17 +++++ .../common/modals/ConfirmationModal.vue | 71 +++++++++++++++++++ .../components/sidebar/core/FavoriteList.vue | 2 +- .../src/components/tableinfo/TableSchema.vue | 3 +- apps/studio/src/plugins/BeekeeperPlugin.ts | 14 ++++ apps/studio/src/shims-plugins.d.ts | 4 +- bin/check-for-native-dialog.sh | 14 ++++ 8 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 apps/studio/src/components/common/modals/ConfirmationModal.vue create mode 100644 bin/check-for-native-dialog.sh diff --git a/apps/studio/src/App.vue b/apps/studio/src/App.vue index b67ba151f..26c340098 100644 --- a/apps/studio/src/App.vue +++ b/apps/studio/src/App.vue @@ -24,6 +24,7 @@ multiple /> + @@ -40,13 +41,13 @@ import DataManager from './components/data/DataManager.vue' import querystring from 'query-string' import NotificationManager from './components/NotificationManager.vue' import UpgradeRequiredModal from './components/common/UpgradeRequiredModal.vue' - +import ConfirmationModal from '@/components/common/modals/ConfirmationModal.vue' export default Vue.extend({ name: 'App', components: { CoreInterface, ConnectionInterface, Titlebar, AutoUpdater, NotificationManager, - StateManager, DataManager, UpgradeRequiredModal + StateManager, DataManager, UpgradeRequiredModal, ConfirmationModal }, data() { return { diff --git a/apps/studio/src/assets/styles/app/modals.scss b/apps/studio/src/assets/styles/app/modals.scss index 07c7d1f59..ab9325764 100644 --- a/apps/studio/src/assets/styles/app/modals.scss +++ b/apps/studio/src/assets/styles/app/modals.scss @@ -37,4 +37,21 @@ } } + &.confirmation-modal { + .v--modal { + width: auto !important; + min-height: 0px; + } + .dialog-content { + padding: 1.5rem 1.5rem 2rem; + } + .dialog-c-title { + padding-bottom: 1.25rem; + } + .vue-dialog-buttons { + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-bottom: 1.5rem; + } + } } diff --git a/apps/studio/src/components/common/modals/ConfirmationModal.vue b/apps/studio/src/components/common/modals/ConfirmationModal.vue new file mode 100644 index 000000000..b570150f0 --- /dev/null +++ b/apps/studio/src/components/common/modals/ConfirmationModal.vue @@ -0,0 +1,71 @@ + + + diff --git a/apps/studio/src/components/sidebar/core/FavoriteList.vue b/apps/studio/src/components/sidebar/core/FavoriteList.vue index e1c0c2606..6a0f0236e 100644 --- a/apps/studio/src/components/sidebar/core/FavoriteList.vue +++ b/apps/studio/src/components/sidebar/core/FavoriteList.vue @@ -196,7 +196,7 @@ import QueryRenameForm from '@/components/common/form/QueryRenameForm.vue' this.$root.$emit('favoriteClick', item) }, async remove(favorite) { - if (window.confirm("Really delete?")) { + if (await this.$confirm("Really delete?")) { await this.$store.dispatch('data/queries/remove', favorite) } }, diff --git a/apps/studio/src/components/tableinfo/TableSchema.vue b/apps/studio/src/components/tableinfo/TableSchema.vue index 8cd4ef0ea..5634ba8ce 100644 --- a/apps/studio/src/components/tableinfo/TableSchema.vue +++ b/apps/studio/src/components/tableinfo/TableSchema.vue @@ -327,7 +327,8 @@ export default Vue.extend({ }, async refreshColumns() { if(this.hasEdits) { - if (!window.confirm("Are you sure? You will lose unsaved changes")) { + const confirmed = await this.$confirm("Are you sure? You will lose unsaved changes") + if (!confirmed) { return } } diff --git a/apps/studio/src/plugins/BeekeeperPlugin.ts b/apps/studio/src/plugins/BeekeeperPlugin.ts index 579304456..f2e9bf91c 100644 --- a/apps/studio/src/plugins/BeekeeperPlugin.ts +++ b/apps/studio/src/plugins/BeekeeperPlugin.ts @@ -3,6 +3,7 @@ import Vue from 'vue' import ContextMenu from '@/components/common/ContextMenu.vue' import { IConnection } from "@/common/interfaces/IConnection" import path from 'path' +import { uuidv4 } from "@/lib/uuid" export interface ContextOption { name: string, @@ -106,5 +107,18 @@ export default { install(Vue) { Vue.prototype.$app = BeekeeperPlugin Vue.prototype.$bks = BeekeeperPlugin + + Vue.prototype.$confirmModalId = uuidv4() + Vue.prototype.$confirm = function(title: string, message?: string): Promise { + return new Promise((resolve) => { + this.$modal.show(Vue.prototype.$confirmModalId, { + title, + message, + onCancel: () => resolve(false), + onConfirm: () => resolve(true), + }) + }) + } + } } diff --git a/apps/studio/src/shims-plugins.d.ts b/apps/studio/src/shims-plugins.d.ts index c69a6a723..95b9c7194 100644 --- a/apps/studio/src/shims-plugins.d.ts +++ b/apps/studio/src/shims-plugins.d.ts @@ -21,10 +21,12 @@ declare module 'vue/types/vue' { warning(text: string, opts?: any): Noty info(text: string, opts?: any): Noty } + $confirm: Promise + $confirmModalId: string // TODO: figure out how to add these automatically from AppEvent.ts registerHandlers(bindings: RootBinding[]): void unregisterHandlers(bindings: RootBinding[]): void trigger(event: AppEvent, options: T): void } -} \ No newline at end of file +} diff --git a/bin/check-for-native-dialog.sh b/bin/check-for-native-dialog.sh new file mode 100644 index 000000000..5cd9c295e --- /dev/null +++ b/bin/check-for-native-dialog.sh @@ -0,0 +1,14 @@ +#! /bin/bash + +git grep -a "window\.confirm" apps/studio/src +STATUS=$? + +if [[ $STATUS -eq 0 ]] +then + echo "Found native dialogs. Please avoid using the native dialogs." + exit 1; + +else + echo "OK. No native dialogs found." + exit 0 +fi