perf(UI): loading animation on tables and table context menu improvements

This commit is contained in:
Fabio Di Stasio 2021-08-03 15:43:13 +02:00
parent 5d271be062
commit 372049ae64
6 changed files with 122 additions and 44 deletions

View File

@ -117,7 +117,7 @@ export default {
},
getStatusBadge (uid) {
if (this.getWorkspace(uid)) {
const status = this.getWorkspace(uid).connection_status;
const status = this.getWorkspace(uid).connectionStatus;
switch (status) {
case 'connected':

View File

@ -1,11 +1,11 @@
<template>
<div v-show="isSelected" class="workspace column columns col-gapless">
<WorkspaceExploreBar
v-if="workspace.connection_status === 'connected'"
v-if="workspace.connectionStatus === 'connected'"
:connection="connection"
:is-selected="isSelected"
/>
<div v-if="workspace.connection_status === 'connected'" class="workspace-tabs column columns col-gapless">
<div v-if="workspace.connectionStatus === 'connected'" class="workspace-tabs column columns col-gapless">
<Draggable
ref="tabWrap"
v-model="draggableTabs"
@ -183,12 +183,6 @@
</a>
</li>
</Draggable>
<!--<WorkspacePropsTabScheduler
v-show="selectedTab === 'prop' && workspace.breadcrumbs.scheduler"
:is-selected="selectedTab === 'prop'"
:connection="connection"
:scheduler="workspace.breadcrumbs.scheduler"
/> -->
<WorkspaceEmptyState v-if="!workspace.tabs.length" @new-tab="addQueryTab" />
<template v-for="tab of workspace.tabs">
<WorkspaceQueryTab
@ -358,7 +352,7 @@ export default {
return false;
},
selectedTab () {
return this.workspace.selected_tab;
return this.workspace.selectedTab;
},
queryTabs () {
return this.workspace.tabs.filter(tab => tab.type === 'query');

View File

@ -8,7 +8,7 @@
>
<div class="workspace-explorebar-header">
<span class="workspace-explorebar-title">{{ connectionName }}</span>
<span v-if="workspace.connection_status === 'connected'" class="workspace-explorebar-tools">
<span v-if="workspace.connectionStatus === 'connected'" class="workspace-explorebar-tools">
<i
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
:title="$t('message.createNewSchema')"
@ -28,7 +28,7 @@
</span>
</div>
<div class="workspace-explorebar-search">
<div v-if="workspace.connection_status === 'connected'" class="has-icon-right">
<div v-if="workspace.connectionStatus === 'connected'" class="has-icon-right">
<input
v-model="searchTerm"
class="form-input input-sm"
@ -113,7 +113,7 @@
@reload="refresh"
/>
<TableContext
v-if="isTableContext"
v-show="isTableContext"
:selected-schema="selectedSchema"
:selected-table="selectedTable"
:context-event="tableContextEvent"

View File

@ -24,7 +24,12 @@
@contextmenu.prevent="showTableContext($event, table)"
>
<a class="table-name">
<i class="table-icon mdi mdi-18px mr-1" :class="table.type === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
<div v-if="checkLoadingStatus(table.name, 'table')" class="icon loading mr-1" />
<i
v-else
class="table-icon mdi mdi-18px mr-1"
:class="table.type === 'view' ? 'mdi-table-eye' : 'mdi-table'"
/>
<span v-html="highlightWord(table.name)" />
</a>
<div
@ -251,11 +256,14 @@ export default {
filteredSchedulers () {
return this.database.schedulers.filter(scheduler => scheduler.name.search(this.searchTerm) >= 0);
},
workspace () {
return this.getWorkspace(this.connection.uid);
},
breadcrumbs () {
return this.getWorkspace(this.connection.uid).breadcrumbs;
return this.workspace.breadcrumbs;
},
customizations () {
return this.getWorkspace(this.connection.uid).customizations;
return this.workspace.customizations;
},
loadedSchemas () {
return this.getLoadedSchemas(this.connection.uid);
@ -365,6 +373,12 @@ export default {
}
else
return string;
},
checkLoadingStatus (name, type) {
return this.workspace.loadingElements.some(el =>
el.name === name &&
el.type === type &&
el.schema === this.database.name);
}
}
};

View File

@ -4,14 +4,14 @@
@close-context="closeContext"
>
<div
v-if="selectedTable.type === 'table' && workspace.customizations.tableSettings"
v-if="selectedTable.type === 'table' && customizations.tableSettings"
class="context-element"
@click="openTableSettingTab"
>
<span class="d-flex"><i class="mdi mdi-18px mdi-tune-vertical-variant text-light pr-1" /> {{ $t('word.settings') }}</span>
</div>
<div
v-if="selectedTable.type === 'view' && workspace.customizations.viewSettings"
v-if="selectedTable.type === 'view' && customizations.viewSettings"
class="context-element"
@click="openViewSettingTab"
>
@ -102,6 +102,9 @@ export default {
}),
workspace () {
return this.getWorkspace(this.selectedWorkspace);
},
customizations () {
return this.workspace ? this.workspace.customizations : {};
}
},
methods: {
@ -109,6 +112,8 @@ export default {
addNotification: 'notifications/addNotification',
newTab: 'workspaces/newTab',
removeTabs: 'workspaces/removeTabs',
addLoadingElement: 'workspaces/addLoadingElement',
removeLoadingElement: 'workspaces/removeLoadingElement',
changeBreadcrumbs: 'workspaces/changeBreadcrumbs'
}),
showCreateTableModal () {
@ -162,6 +167,14 @@ export default {
this.closeContext();
},
async duplicateTable () {
this.closeContext();
this.addLoadingElement({
name: this.selectedTable.name,
schema: this.selectedSchema,
type: 'table'
});
try {
const { status, response } = await Tables.duplicateTable({
uid: this.selectedWorkspace,
@ -169,18 +182,30 @@ export default {
schema: this.selectedSchema
});
if (status === 'success') {
this.closeContext();
if (status === 'success')
this.$emit('reload');
}
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
this.removeLoadingElement({
name: this.selectedTable.name,
schema: this.selectedSchema,
type: 'table'
});
},
async emptyTable () {
this.closeContext();
this.addLoadingElement({
name: this.selectedTable.name,
schema: this.selectedSchema,
type: 'table'
});
try {
const { status, response } = await Tables.truncateTable({
uid: this.selectedWorkspace,
@ -188,18 +213,30 @@ export default {
schema: this.selectedSchema
});
if (status === 'success') {
this.closeContext();
if (status === 'success')
this.$emit('reload');
}
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
this.removeLoadingElement({
name: this.selectedTable.name,
schema: this.selectedSchema,
type: 'table'
});
},
async deleteTable () {
this.closeContext();
this.addLoadingElement({
name: this.selectedTable.name,
schema: this.selectedSchema,
type: 'table'
});
try {
let res;
@ -228,7 +265,6 @@ export default {
schema: this.selectedSchema
});
this.closeContext();
this.$emit('reload');
}
else
@ -237,6 +273,12 @@ export default {
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
this.removeLoadingElement({
name: this.selectedTable.name,
schema: this.selectedSchema,
type: 'table'
});
}
}
};

View File

@ -35,14 +35,14 @@ export default {
},
getConnected: state => {
return state.workspaces
.filter(workspace => workspace.connection_status === 'connected')
.filter(workspace => workspace.connectionStatus === 'connected')
.map(workspace => workspace.uid);
},
getLoadedSchemas: state => uid => {
return state.workspaces.find(workspace => workspace.uid === uid).loaded_schemas;
return state.workspaces.find(workspace => workspace.uid === uid).loadedSchemas;
},
getSearchTerm: state => uid => {
return state.workspaces.find(workspace => workspace.uid === uid).search_term;
return state.workspaces.find(workspace => workspace.uid === uid).searchTerm;
}
},
mutations: {
@ -72,9 +72,9 @@ export default {
indexTypes,
customizations,
structure,
connection_status: 'connected',
connectionStatus: 'connected',
tabs: cachedTabs,
selected_tab: cachedTabs.length ? cachedTabs[0].uid : null,
selectedTab: cachedTabs.length ? cachedTabs[0].uid : null,
version
}
: workspace);
@ -85,8 +85,8 @@ export default {
...workspace,
structure: {},
breadcrumbs: {},
loaded_schemas: new Set(),
connection_status: 'connecting'
loadedSchemas: new Set(),
connectionStatus: 'connecting'
}
: workspace);
},
@ -96,8 +96,8 @@ export default {
...workspace,
structure: {},
breadcrumbs: {},
loaded_schemas: new Set(),
connection_status: 'failed'
loadedSchemas: new Set(),
connectionStatus: 'failed'
}
: workspace);
},
@ -107,8 +107,8 @@ export default {
...workspace,
structure: {},
breadcrumbs: {},
loaded_schemas: new Set(),
connection_status: 'disconnected'
loadedSchemas: new Set(),
connectionStatus: 'disconnected'
}
: workspace);
},
@ -180,7 +180,7 @@ export default {
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid
? {
...workspace,
search_term: term
searchTerm: term
}
: workspace);
},
@ -292,7 +292,7 @@ export default {
persistentStore.set(uid, state.workspaces.find(workspace => workspace.uid === uid).tabs);
},
SELECT_TAB (state, { uid, tab }) {
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, selected_tab: tab } : workspace);
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, selectedTab: tab } : workspace);
},
UPDATE_TABS (state, { uid, tabs }) {
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid ? { ...workspace, tabs } : workspace);
@ -356,7 +356,28 @@ export default {
ADD_LOADED_SCHEMA (state, payload) {
state.workspaces = state.workspaces.map(workspace => {
if (workspace.uid === payload.uid)
workspace.loaded_schemas.add(payload.schema);
workspace.loadedSchemas.add(payload.schema);
return workspace;
});
},
ADD_LOADING_ELEMENT (state, payload) {
state.workspaces = state.workspaces.map(workspace => {
if (workspace.uid === payload.uid)
workspace.loadingElements.push(payload.element);
return workspace;
});
},
REMOVE_LOADING_ELEMENT (state, payload) {
state.workspaces = state.workspaces.map(workspace => {
if (workspace.uid === payload.uid) {
const loadingElements = workspace.loadingElements.filter(el =>
el.schema !== payload.element.schema &&
el.name !== payload.element.name &&
el.type !== payload.element.type
);
workspace = { ...workspace, loadingElements };
}
return workspace;
});
}
@ -513,16 +534,17 @@ export default {
addWorkspace ({ commit }, uid) {
const workspace = {
uid,
connection_status: 'disconnected',
selected_tab: 0,
search_term: '',
connectionStatus: 'disconnected',
selectedTab: 0,
searchTerm: '',
tabs: [],
structure: {},
variables: [],
collations: [],
users: [],
breadcrumbs: {},
loaded_schemas: new Set()
loadingElements: [],
loadedSchemas: new Set()
};
commit('ADD_WORKSPACE', workspace);
@ -545,6 +567,12 @@ export default {
addLoadedSchema ({ commit, getters }, schema) {
commit('ADD_LOADED_SCHEMA', { uid: getters.getSelected, schema });
},
addLoadingElement ({ commit, getters }, element) {
commit('ADD_LOADING_ELEMENT', { uid: getters.getSelected, element });
},
removeLoadingElement ({ commit, getters }, element) {
commit('REMOVE_LOADING_ELEMENT', { uid: getters.getSelected, element });
},
setSearchTerm ({ commit, getters }, term) {
commit('SET_SEARCH_TERM', { uid: getters.getSelected, term });
},
@ -697,7 +725,7 @@ export default {
checkSelectedTabExists ({ state, commit }, uid) {
const workspace = state.workspaces.find(workspace => workspace.uid === uid);
const isSelectedExistent = workspace
? workspace.tabs.some(tab => tab.uid === workspace.selected_tab)
? workspace.tabs.some(tab => tab.uid === workspace.selectedTab)
: false;
if (!isSelectedExistent && workspace.tabs.length)