feat: unsaved changes reminder

This commit is contained in:
Fabio Di Stasio 2020-12-04 11:19:16 +01:00
parent a4122b4eaa
commit 33d1fa2290
7 changed files with 117 additions and 9 deletions

View File

@ -17,6 +17,7 @@
<TheNotificationsBoard />
<ModalNewConnection v-if="isNewConnModal" />
<ModalSettings v-if="isSettingModal" />
<ModalDiscardChanges v-if="isUnsavedDiscardModal" />
</div>
</div>
</template>
@ -35,7 +36,8 @@ export default {
TheAppWelcome: () => import(/* webpackChunkName: "TheAppWelcome" */'@/components/TheAppWelcome'),
Workspace: () => import(/* webpackChunkName: "Workspace" */'@/components/Workspace'),
ModalNewConnection: () => import(/* webpackChunkName: "ModalNewConnection" */'@/components/ModalNewConnection'),
ModalSettings: () => import(/* webpackChunkName: "ModalSettings" */'@/components/ModalSettings')
ModalSettings: () => import(/* webpackChunkName: "ModalSettings" */'@/components/ModalSettings'),
ModalDiscardChanges: () => import(/* webpackChunkName: "ModalDiscardChanges" */'@/components/ModalDiscardChanges')
},
data () {
return {};
@ -46,7 +48,8 @@ export default {
isNewConnModal: 'application/isNewModal',
isEditModal: 'application/isEditModal',
isSettingModal: 'application/isSettingModal',
connections: 'connections/getConnections'
connections: 'connections/getConnections',
isUnsavedDiscardModal: 'workspaces/isUnsavedDiscardModal'
})
},
mounted () {

View File

@ -0,0 +1,57 @@
<template>
<ConfirmModal
:confirm-text="$t('word.discard')"
:cancel-text="$t('word.stay')"
@confirm="discardUnsavedChanges"
@hide="closeUnsavedChangesModal"
>
<template slot="header">
<div class="d-flex">
<i class="mdi mdi-24px mdi-content-save-alert mr-1" /> {{ $t('message.unsavedChanges') }}
</div>
</template>
<div slot="body">
<div>
{{ $t('message.discardUnsavedChanges') }}
</div>
</div>
</ConfirmModal>
</template>
<script>
import { mapActions } from 'vuex';
import ConfirmModal from '@/components/BaseConfirmModal';
export default {
name: 'ModalDiscardChanges',
components: {
ConfirmModal
},
created () {
window.addEventListener('keydown', this.onKey);
},
beforeDestroy () {
window.removeEventListener('keydown', this.onKey);
},
methods: {
...mapActions({
discardUnsavedChanges: 'workspaces/discardUnsavedChanges',
closeUnsavedChangesModal: 'workspaces/closeUnsavedChangesModal'
}),
closeModal () {
this.$emit('close');
},
onKey (e) {
e.stopPropagation();
if (e.key === 'Escape')
this.closeModal();
}
}
};
</script>
<style scoped>
.modal-container {
max-width: 360px;
}
</style>

View File

@ -67,6 +67,7 @@
</ul>
<WorkspacePropsTab
v-show="selectedTab === 'prop'"
:is-selected="selectedTab === 'prop'"
:connection="connection"
:table="workspace.breadcrumbs.table"
/>

View File

@ -18,7 +18,7 @@
:key="table.name"
class="menu-item"
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.table === table.name}"
@click="changeBreadcrumbs({schema: database.name, table: table.name})"
@click="setBreadcrumbs({schema: database.name, table: table.name})"
@contextmenu.prevent="showTableContext($event, table.name)"
>
<a class="table-name">
@ -76,6 +76,10 @@ export default {
piePercentage (val) {
const perc = val / this.maxSize * 100;
return { background: `conic-gradient(lime ${perc}%, white 0)` };
},
setBreadcrumbs (payload) {
if (this.breadcrumbs.schema === payload.schema && this.breadcrumbs.table === payload.table) return;
this.changeBreadcrumbs(payload);
}
}
};

View File

@ -137,7 +137,7 @@ export default {
},
tableOptions () {
const db = this.workspace.structure.find(db => db.name === this.schema);
return db ? db.tables.find(table => table.name === this.table) : {};
return db && this.table ? db.tables.find(table => table.name === this.table) : {};
},
defaultEngine () {
return this.getDatabaseVariable(this.connection.uid, 'default_storage_engine').value || '';
@ -167,12 +167,17 @@ export default {
this.getFieldsData();
this.lastTable = this.table;
}
},
isChanged (val) {
if (this.isSelected && this.lastTable === this.table && this.table !== null)
this.setUnsavedChanges(val);
}
},
methods: {
...mapActions({
addNotification: 'notifications/addNotification',
refreshStructure: 'workspaces/refreshStructure'
refreshStructure: 'workspaces/refreshStructure',
setUnsavedChanges: 'workspaces/setUnsavedChanges'
}),
async getFieldsData () {
if (!this.table) return;

View File

@ -59,7 +59,9 @@ module.exports = {
field: 'Field | Fields',
approximately: 'Approximately',
total: 'Total',
table: 'Table'
table: 'Table',
discard: 'Discard',
stay: 'Stay'
},
message: {
appWelcome: 'Welcome to Antares SQL Client!',
@ -111,7 +113,9 @@ module.exports = {
createNewTable: 'Create new table',
emptyTable: 'Empty table',
deleteTable: 'Delete table',
emptyCorfirm: 'Do you confirm to empty'
emptyCorfirm: 'Do you confirm to empty',
unsavedChanges: 'Unsaved changes',
discardUnsavedChanges: 'You have some unsaved changes. By leaving this tab these changes will be discarded.'
},
// Date and Time
short: {

View File

@ -11,7 +11,9 @@ export default {
state: {
workspaces: [],
selected_workspace: null,
has_unsaved_changes: false
has_unsaved_changes: false,
is_unsaved_discard_modal: false,
pending_breadcrumbs: {}
},
getters: {
getSelected: state => {
@ -36,6 +38,9 @@ export default {
return state.workspaces
.filter(workspace => workspace.connected)
.map(workspace => workspace.uid);
},
isUnsavedDiscardModal: state => {
return state.is_unsaved_discard_modal;
}
},
mutations: {
@ -176,6 +181,15 @@ export default {
else
return workspace;
});
},
SET_UNSAVED_CHANGES (state, val) {
state.has_unsaved_changes = !!val;
},
SET_UNSAVED_DISCARD_MODAL (state, val) {
state.is_unsaved_discard_modal = !!val;
},
SET_PENDING_BREADCRUMBS (state, payload) {
state.pending_breadcrumbs = payload;
}
},
actions: {
@ -294,8 +308,16 @@ export default {
if (getters.getWorkspace(uid).tabs.length < 3)
dispatch('newTab', uid);
dispatch('setUnsavedChanges', false);
},
changeBreadcrumbs ({ commit, getters }, payload) {
changeBreadcrumbs ({ state, commit, getters }, payload) {
if (state.has_unsaved_changes) {
commit('SET_UNSAVED_DISCARD_MODAL', true);
commit('SET_PENDING_BREADCRUMBS', payload);
return;
}
const breadcrumbsObj = {
schema: null,
table: null,
@ -329,6 +351,18 @@ export default {
},
setTabKeyUsage ({ commit }, payload) {
commit('SET_TAB_KEY_USAGE', payload);
},
setUnsavedChanges ({ commit }, val) {
commit('SET_UNSAVED_CHANGES', val);
},
discardUnsavedChanges ({ state, commit, dispatch }) {
dispatch('setUnsavedChanges', false);
dispatch('changeBreadcrumbs', state.pending_breadcrumbs);
commit('SET_UNSAVED_DISCARD_MODAL', false);
commit('SET_PENDING_BREADCRUMBS', {});
},
closeUnsavedChangesModal ({ commit }) {
commit('SET_UNSAVED_DISCARD_MODAL', false);
}
}
};