mirror of
https://github.com/Fabio286/antares.git
synced 2025-02-16 19:50:37 +01:00
feat(PostgreSQL): ability to switch the database, closes #432
This commit is contained in:
parent
9d00f58998
commit
89815bf5e7
14939
package-lock.json
generated
14939
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
src/main/ipc-handlers/database.ts
Normal file
14
src/main/ipc-handlers/database.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import * as antares from 'common/interfaces/antares';
|
||||||
|
import { ipcMain } from 'electron';
|
||||||
|
|
||||||
|
export default (connections: {[key: string]: antares.Client}) => {
|
||||||
|
ipcMain.handle('get-databases', async (event, uid) => {
|
||||||
|
try {
|
||||||
|
const result = await connections[uid].getDatabases();
|
||||||
|
return { status: 'success', response: result };
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
return { status: 'error', response: err.toString() };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
@ -9,6 +9,7 @@ import functions from './functions';
|
|||||||
import schedulers from './schedulers';
|
import schedulers from './schedulers';
|
||||||
import updates from './updates';
|
import updates from './updates';
|
||||||
import application from './application';
|
import application from './application';
|
||||||
|
import database from './database';
|
||||||
import schema from './schema';
|
import schema from './schema';
|
||||||
import users from './users';
|
import users from './users';
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ export default () => {
|
|||||||
routines(connections);
|
routines(connections);
|
||||||
functions(connections);
|
functions(connections);
|
||||||
schedulers(connections);
|
schedulers(connections);
|
||||||
|
database(connections);
|
||||||
schema(connections);
|
schema(connections);
|
||||||
users(connections);
|
users(connections);
|
||||||
updates();
|
updates();
|
||||||
|
@ -162,6 +162,10 @@ export abstract class AntaresCore {
|
|||||||
throw new Error('Method "getDbConfig" not implemented');
|
throw new Error('Method "getDbConfig" not implemented');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getDatabases () {
|
||||||
|
throw new Error('Method "getDatabases" not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
createSchema (...args: any) {
|
createSchema (...args: any) {
|
||||||
throw new Error('Method "createSchema" not implemented');
|
throw new Error('Method "createSchema" not implemented');
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
host: this._params.host,
|
host: this._params.host,
|
||||||
port: this._params.port,
|
port: this._params.port,
|
||||||
user: this._params.user,
|
user: this._params.user,
|
||||||
database: undefined as string | undefined,
|
database: 'postgres' as string,
|
||||||
password: this._params.password,
|
password: this._params.password,
|
||||||
ssl: null as mysql.SslOptions
|
ssl: null as mysql.SslOptions
|
||||||
};
|
};
|
||||||
@ -262,6 +262,18 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getDatabases () {
|
||||||
|
const { rows } = await this.raw('SELECT datname FROM pg_database WHERE datistemplate = false');
|
||||||
|
if (rows) {
|
||||||
|
return rows.reduce((acc, cur) => {
|
||||||
|
acc.push(cur.datname);
|
||||||
|
return acc;
|
||||||
|
}, [] as string[]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
async getStructure (schemas: Set<string>) {
|
async getStructure (schemas: Set<string>) {
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
interface ShowTableResult {
|
interface ShowTableResult {
|
||||||
|
@ -124,8 +124,8 @@ else {
|
|||||||
if (isWindows)
|
if (isWindows)
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
|
|
||||||
if (isDevelopment)
|
// if (isDevelopment)
|
||||||
mainWindow.webContents.openDevTools();
|
// mainWindow.webContents.openDevTools();
|
||||||
|
|
||||||
process.on('uncaughtException', error => {
|
process.on('uncaughtException', error => {
|
||||||
mainWindow.webContents.send('unhandled-exception', error);
|
mainWindow.webContents.send('unhandled-exception', error);
|
||||||
|
@ -380,7 +380,7 @@ emit('folder-sort');// To apply changes on component key change
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
line-height: 1;
|
line-height: 1.02;
|
||||||
transition: bottom .2s;
|
transition: bottom .2s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -444,7 +444,7 @@ emit('folder-sort');// To apply changes on component key change
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
line-height: 1;
|
line-height: 1.02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,11 @@ const workspace = computed(() => getWorkspace(props.connection.uid));
|
|||||||
|
|
||||||
const draggableTabs = computed<WorkspaceTab[]>({
|
const draggableTabs = computed<WorkspaceTab[]>({
|
||||||
get () {
|
get () {
|
||||||
return workspace.value.tabs;
|
if (workspace.value.customizations.database)
|
||||||
|
return workspace.value.tabs.filter(tab => tab.type === 'query' || tab.database === workspace.value.database);
|
||||||
|
|
||||||
|
else
|
||||||
|
return workspace.value.tabs;
|
||||||
},
|
},
|
||||||
set (val) {
|
set (val) {
|
||||||
updateTabs({ uid: props.connection.uid, tabs: val });
|
updateTabs({ uid: props.connection.uid, tabs: val });
|
||||||
|
@ -120,6 +120,7 @@
|
|||||||
v-model="connection.database"
|
v-model="connection.database"
|
||||||
class="form-input"
|
class="form-input"
|
||||||
type="text"
|
type="text"
|
||||||
|
:placeholder="clientCustomizations.defaultDatabase"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -122,6 +122,7 @@
|
|||||||
v-model="localConnection.database"
|
v-model="localConnection.database"
|
||||||
class="form-input"
|
class="form-input"
|
||||||
type="text"
|
type="text"
|
||||||
|
:placeholder="clientCustomizations.defaultDatabase"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,7 +10,18 @@
|
|||||||
@keydown="explorebarSearch"
|
@keydown="explorebarSearch"
|
||||||
>
|
>
|
||||||
<div class="workspace-explorebar-header">
|
<div class="workspace-explorebar-header">
|
||||||
<span class="workspace-explorebar-title">{{ connectionName }}</span>
|
<div
|
||||||
|
v-if="customizations.database"
|
||||||
|
class="workspace-explorebar-database-switch"
|
||||||
|
:title="t('message.switchDatabase')"
|
||||||
|
>
|
||||||
|
<BaseSelect
|
||||||
|
v-model="selectedDatabase"
|
||||||
|
:options="databases"
|
||||||
|
class="form-select select-sm text-bold my-0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span v-else class="workspace-explorebar-title">{{ connectionName }}</span>
|
||||||
<span v-if="workspace.connectionStatus === 'connected'" class="workspace-explorebar-tools">
|
<span v-if="workspace.connectionStatus === 'connected'" class="workspace-explorebar-tools">
|
||||||
<i
|
<i
|
||||||
v-if="customizations.schemas"
|
v-if="customizations.schemas"
|
||||||
@ -124,10 +135,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Component, computed, onMounted, Ref, ref, watch } from 'vue';
|
import { Component, computed, onMounted, Prop, Ref, ref, watch } from 'vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
import { useConnectionsStore } from '@/stores/connections';
|
import { useConnectionsStore } from '@/stores/connections';
|
||||||
|
import { ConnectionParams } from 'common/interfaces/antares';
|
||||||
import { useNotificationsStore } from '@/stores/notifications';
|
import { useNotificationsStore } from '@/stores/notifications';
|
||||||
import { useSettingsStore } from '@/stores/settings';
|
import { useSettingsStore } from '@/stores/settings';
|
||||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||||
@ -141,12 +153,14 @@ import TableContext from '@/components/WorkspaceExploreBarTableContext.vue';
|
|||||||
import MiscContext from '@/components/WorkspaceExploreBarMiscContext.vue';
|
import MiscContext from '@/components/WorkspaceExploreBarMiscContext.vue';
|
||||||
import MiscFolderContext from '@/components/WorkspaceExploreBarMiscFolderContext.vue';
|
import MiscFolderContext from '@/components/WorkspaceExploreBarMiscFolderContext.vue';
|
||||||
import ModalNewSchema from '@/components/ModalNewSchema.vue';
|
import ModalNewSchema from '@/components/ModalNewSchema.vue';
|
||||||
|
import BaseSelect from '@/components/BaseSelect.vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import Databases from '@/ipc-api/Databases';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
connection: Object,
|
connection: Object as Prop<ConnectionParams>,
|
||||||
isSelected: Boolean
|
isSelected: Boolean
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -160,11 +174,13 @@ const { explorebarSize } = storeToRefs(settingsStore);
|
|||||||
const { changeExplorebarSize } = settingsStore;
|
const { changeExplorebarSize } = settingsStore;
|
||||||
const {
|
const {
|
||||||
getWorkspace,
|
getWorkspace,
|
||||||
|
switchConnection,
|
||||||
removeConnected: disconnectWorkspace,
|
removeConnected: disconnectWorkspace,
|
||||||
refreshStructure,
|
refreshStructure,
|
||||||
newTab,
|
newTab,
|
||||||
removeTabs,
|
removeTabs,
|
||||||
setSearchTerm,
|
setSearchTerm,
|
||||||
|
setDatabase,
|
||||||
addLoadingElement,
|
addLoadingElement,
|
||||||
removeLoadingElement
|
removeLoadingElement
|
||||||
} = workspacesStore;
|
} = workspacesStore;
|
||||||
@ -172,6 +188,7 @@ const {
|
|||||||
const searchInput: Ref<HTMLInputElement> = ref(null);
|
const searchInput: Ref<HTMLInputElement> = ref(null);
|
||||||
const explorebar: Ref<HTMLInputElement> = ref(null);
|
const explorebar: Ref<HTMLInputElement> = ref(null);
|
||||||
const resizer: Ref<HTMLInputElement> = ref(null);
|
const resizer: Ref<HTMLInputElement> = ref(null);
|
||||||
|
const databases: Ref<string[]> = ref([]);
|
||||||
const schema: Ref<Component & { selectSchema: (name: string) => void; $refs: {schemaAccordion: HTMLDetailsElement} }[]> = ref(null);
|
const schema: Ref<Component & { selectSchema: (name: string) => void; $refs: {schemaAccordion: HTMLDetailsElement} }[]> = ref(null);
|
||||||
const isRefreshing = ref(false);
|
const isRefreshing = ref(false);
|
||||||
const isNewDBModal = ref(false);
|
const isNewDBModal = ref(false);
|
||||||
@ -185,6 +202,7 @@ const isMiscFolderContext = ref(false);
|
|||||||
const databaseContextEvent = ref(null);
|
const databaseContextEvent = ref(null);
|
||||||
const tableContextEvent = ref(null);
|
const tableContextEvent = ref(null);
|
||||||
const miscContextEvent = ref(null);
|
const miscContextEvent = ref(null);
|
||||||
|
const selectedDatabase = ref(props.connection.database);
|
||||||
const selectedSchema = ref('');
|
const selectedSchema = ref('');
|
||||||
const selectedTable = ref(null);
|
const selectedTable = ref(null);
|
||||||
const selectedMisc = ref(null);
|
const selectedMisc = ref(null);
|
||||||
@ -230,9 +248,14 @@ watch(searchTerm, () => {
|
|||||||
}, 200);
|
}, 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(selectedDatabase, (val, oldVal) => {
|
||||||
|
if (oldVal)
|
||||||
|
switchConnection({ ...props.connection, database: selectedDatabase.value });
|
||||||
|
});
|
||||||
|
|
||||||
localWidth.value = explorebarSize.value;
|
localWidth.value = explorebarSize.value;
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
resizer.value.addEventListener('mousedown', (e: MouseEvent) => {
|
resizer.value.addEventListener('mousedown', (e: MouseEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@ -240,10 +263,28 @@ onMounted(() => {
|
|||||||
window.addEventListener('mouseup', stopResize);
|
window.addEventListener('mouseup', stopResize);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (workspace.value.structure.length === 1) { // Auto-open if juust one schema
|
if (workspace.value.structure.length === 1) { // Auto-open if just one schema
|
||||||
schema.value[0].selectSchema(workspace.value.structure[0].name);
|
schema.value[0].selectSchema(workspace.value.structure[0].name);
|
||||||
schema.value[0].$refs.schemaAccordion.open = true;
|
schema.value[0].$refs.schemaAccordion.open = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (customizations.value.database) {
|
||||||
|
try {
|
||||||
|
const { status, response } = await Databases.getDatabases(props.connection.uid);
|
||||||
|
if (status === 'success') {
|
||||||
|
databases.value = response;
|
||||||
|
if (selectedDatabase.value === '') {
|
||||||
|
selectedDatabase.value = response[0];
|
||||||
|
setDatabase(selectedDatabase.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
addNotification({ status: 'error', message: response });
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
addNotification({ status: 'error', message: err.stack });
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
@ -254,8 +295,11 @@ const refresh = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const explorebarSearch = () => {
|
const explorebarSearch = (event: KeyboardEvent) => {
|
||||||
searchInput.value.focus();
|
const isLetter = (event.key >= 'a' && event.key <= 'z');
|
||||||
|
const isNumber = (event.key >= '0' && event.key <= '9');
|
||||||
|
if (isLetter || isNumber)
|
||||||
|
searchInput.value.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
const resize = (e: MouseEvent) => {
|
const resize = (e: MouseEvent) => {
|
||||||
@ -497,13 +541,31 @@ const toggleSearchMethod = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.workspace-explorebar-database-switch {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
z-index: 20;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-left: -4px;
|
||||||
|
margin-top: -3px;
|
||||||
|
margin-bottom: -0.5rem;
|
||||||
|
height: 24px;
|
||||||
|
|
||||||
|
.form-select.select-sm {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
height: 1.2rem;
|
||||||
|
line-height: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.workspace-explorebar-search {
|
.workspace-explorebar-search {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
font-size: 0.6rem;
|
font-size: 0.6rem;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
margin: 5px 0;
|
margin: 0 0 5px 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
.has-icon-right {
|
.has-icon-right {
|
||||||
@ -533,7 +595,7 @@ const toggleSearchMethod = () => {
|
|||||||
|
|
||||||
.workspace-explorebar-body {
|
.workspace-explorebar-body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc((100vh - 68px) - #{$excluding-size});
|
height: calc((100vh - 63px) - #{$excluding-size});
|
||||||
overflow: overlay;
|
overflow: overlay;
|
||||||
padding: 0 0.1rem;
|
padding: 0 0.1rem;
|
||||||
}
|
}
|
||||||
|
@ -291,6 +291,11 @@ watch(selectedSchema, () => {
|
|||||||
changeBreadcrumbs({ schema: selectedSchema.value, query: `Query #${props.tab.index}` });
|
changeBreadcrumbs({ schema: selectedSchema.value, query: `Query #${props.tab.index}` });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(databaseSchemas, () => {
|
||||||
|
if (!databaseSchemas.value.includes(selectedSchema.value))
|
||||||
|
selectedSchema.value = null;
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
const runQuery = async (query: string) => {
|
const runQuery = async (query: string) => {
|
||||||
if (!query || isQuering.value) return;
|
if (!query || isQuering.value) return;
|
||||||
isQuering.value = true;
|
isQuering.value = true;
|
||||||
@ -496,9 +501,6 @@ defineExpose({ resizeResults });
|
|||||||
query.value = props.tab.content as string;
|
query.value = props.tab.content as string;
|
||||||
selectedSchema.value = props.tab.schema || breadcrumbsSchema.value;
|
selectedSchema.value = props.tab.schema || breadcrumbsSchema.value;
|
||||||
|
|
||||||
if (!databaseSchemas.value.includes(selectedSchema.value))
|
|
||||||
selectedSchema.value = null;
|
|
||||||
|
|
||||||
window.addEventListener('resize', onWindowResize);
|
window.addEventListener('resize', onWindowResize);
|
||||||
|
|
||||||
const reloadListener = () => {
|
const reloadListener = () => {
|
||||||
|
@ -348,7 +348,8 @@ export const enUS = {
|
|||||||
closeAllTabs: 'Close all tabs',
|
closeAllTabs: 'Close all tabs',
|
||||||
closeOtherTabs: 'Close other tabs',
|
closeOtherTabs: 'Close other tabs',
|
||||||
closeTabsToLeft: 'Close tabs to the left',
|
closeTabsToLeft: 'Close tabs to the left',
|
||||||
closeTabsToRight: 'Close tabs to the right'
|
closeTabsToRight: 'Close tabs to the right',
|
||||||
|
switchDatabase: 'Switch the database'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Address',
|
address: 'Address',
|
||||||
|
9
src/renderer/ipc-api/Databases.ts
Normal file
9
src/renderer/ipc-api/Databases.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { ipcRenderer } from 'electron';
|
||||||
|
import { unproxify } from '../libs/unproxify';
|
||||||
|
import { IpcResponse } from 'common/interfaces/antares';
|
||||||
|
|
||||||
|
export default class {
|
||||||
|
static getDatabases (params: string): Promise<IpcResponse> {
|
||||||
|
return ipcRenderer.invoke('get-databases', unproxify(params));
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ export interface WorkspaceTab {
|
|||||||
index?: number;
|
index?: number;
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
type?: string;
|
type?: string;
|
||||||
|
database?: string;
|
||||||
schema?: string;
|
schema?: string;
|
||||||
elementName?: string;
|
elementName?: string;
|
||||||
elementNewName?: string;
|
elementNewName?: string;
|
||||||
@ -65,6 +66,7 @@ export interface Breadcrumb {
|
|||||||
export interface Workspace {
|
export interface Workspace {
|
||||||
uid: string;
|
uid: string;
|
||||||
client?: ClientCode;
|
client?: ClientCode;
|
||||||
|
database?: string;
|
||||||
connectionStatus: string;
|
connectionStatus: string;
|
||||||
selectedTab: string | number;
|
selectedTab: string | number;
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
@ -145,14 +147,15 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
else
|
else
|
||||||
this.selectedWorkspace = uid;
|
this.selectedWorkspace = uid;
|
||||||
},
|
},
|
||||||
async connectWorkspace (connection: ConnectionParams & { pgConnString?: string }) {
|
async connectWorkspace (connection: ConnectionParams & { pgConnString?: string }, mode?: string) {
|
||||||
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === connection.uid
|
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === connection.uid
|
||||||
? {
|
? {
|
||||||
...workspace,
|
...workspace,
|
||||||
structure: {},
|
structure: [],
|
||||||
breadcrumbs: {},
|
breadcrumbs: {},
|
||||||
loadedSchemas: new Set(),
|
loadedSchemas: new Set(),
|
||||||
connectionStatus: 'connecting'
|
database: connection.database,
|
||||||
|
connectionStatus: mode === 'switch' ? 'connected' : 'connecting'
|
||||||
}
|
}
|
||||||
: workspace);
|
: workspace);
|
||||||
|
|
||||||
@ -168,7 +171,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === connection.uid
|
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === connection.uid
|
||||||
? {
|
? {
|
||||||
...workspace,
|
...workspace,
|
||||||
structure: {},
|
structure: [],
|
||||||
breadcrumbs: {},
|
breadcrumbs: {},
|
||||||
loadedSchemas: new Set(),
|
loadedSchemas: new Set(),
|
||||||
connectionStatus: 'failed'
|
connectionStatus: 'failed'
|
||||||
@ -228,6 +231,12 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectedTab = cachedTabs.length
|
||||||
|
? connection.database
|
||||||
|
? cachedTabs.filter(tab => tab.type === 'query' || tab.database === connection.database)[0].uid
|
||||||
|
: cachedTabs[0].uid
|
||||||
|
: null;
|
||||||
|
|
||||||
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === connection.uid
|
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === connection.uid
|
||||||
? {
|
? {
|
||||||
...workspace,
|
...workspace,
|
||||||
@ -238,7 +247,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
structure: response,
|
structure: response,
|
||||||
connectionStatus: 'connected',
|
connectionStatus: 'connected',
|
||||||
tabs: cachedTabs,
|
tabs: cachedTabs,
|
||||||
selectedTab: cachedTabs.length ? cachedTabs[0].uid : null,
|
selectedTab,
|
||||||
version
|
version
|
||||||
}
|
}
|
||||||
: workspace);
|
: workspace);
|
||||||
@ -385,7 +394,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === uid
|
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === uid
|
||||||
? {
|
? {
|
||||||
...workspace,
|
...workspace,
|
||||||
structure: {},
|
structure: [],
|
||||||
breadcrumbs: {},
|
breadcrumbs: {},
|
||||||
loadedSchemas: new Set(),
|
loadedSchemas: new Set(),
|
||||||
connectionStatus: 'disconnected'
|
connectionStatus: 'disconnected'
|
||||||
@ -394,6 +403,10 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
|
|
||||||
this.selectTab({ uid, tab: 0 });
|
this.selectTab({ uid, tab: 0 });
|
||||||
},
|
},
|
||||||
|
async switchConnection (connection: ConnectionParams & { pgConnString?: string }) {
|
||||||
|
await Connection.disconnect(connection.uid);
|
||||||
|
return this.connectWorkspace(connection, 'switch');
|
||||||
|
},
|
||||||
addWorkspace (uid: string) {
|
addWorkspace (uid: string) {
|
||||||
const workspace: Workspace = {
|
const workspace: Workspace = {
|
||||||
uid,
|
uid,
|
||||||
@ -468,7 +481,15 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
}
|
}
|
||||||
: workspace);
|
: workspace);
|
||||||
},
|
},
|
||||||
_addTab ({ uid, tab, content, type, autorun, schema, elementName, elementType }: WorkspaceTab) {
|
setDatabase (databaseName: string) {
|
||||||
|
this.workspaces = (this.workspaces as Workspace[]).map(workspace => workspace.uid === this.getSelected
|
||||||
|
? {
|
||||||
|
...workspace,
|
||||||
|
database: databaseName
|
||||||
|
}
|
||||||
|
: workspace);
|
||||||
|
},
|
||||||
|
_addTab ({ uid, tab, content, type, autorun, schema, database, elementName, elementType }: WorkspaceTab) {
|
||||||
if (type === 'query')
|
if (type === 'query')
|
||||||
tabIndex[uid] = tabIndex[uid] ? ++tabIndex[uid] : 1;
|
tabIndex[uid] = tabIndex[uid] ? ++tabIndex[uid] : 1;
|
||||||
|
|
||||||
@ -477,6 +498,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
index: type === 'query' ? tabIndex[uid] : null,
|
index: type === 'query' ? tabIndex[uid] : null,
|
||||||
selected: false,
|
selected: false,
|
||||||
type,
|
type,
|
||||||
|
database,
|
||||||
schema,
|
schema,
|
||||||
elementName,
|
elementName,
|
||||||
elementType,
|
elementType,
|
||||||
@ -534,6 +556,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
content,
|
content,
|
||||||
type,
|
type,
|
||||||
autorun,
|
autorun,
|
||||||
|
database: workspaceTabs.database,
|
||||||
schema,
|
schema,
|
||||||
elementName,
|
elementName,
|
||||||
elementType
|
elementType
|
||||||
@ -572,7 +595,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tabUid = uidGen('T');
|
tabUid = uidGen('T');
|
||||||
this._addTab({ uid, tab: tabUid, content, type, autorun, schema, elementName, elementType });
|
this._addTab({ uid, tab: tabUid, content, type, autorun, database: workspaceTabs.database, schema, elementName, elementType });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this._replaceTab({ uid, tab: tab.uid, type, schema, elementName, elementType });
|
this._replaceTab({ uid, tab: tab.uid, type, schema, elementName, elementType });
|
||||||
@ -582,7 +605,7 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tabUid = uidGen('T');
|
tabUid = uidGen('T');
|
||||||
this._addTab({ uid, tab: tabUid, content, type, autorun, schema, elementName, elementType });
|
this._addTab({ uid, tab: tabUid, content, type, autorun, database: workspaceTabs.database, schema, elementName, elementType });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -603,18 +626,18 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
: false;
|
: false;
|
||||||
|
|
||||||
if (existentTab) {
|
if (existentTab) {
|
||||||
this._replaceTab({ uid, tab: existentTab.uid, type, schema, elementName, elementType });
|
this._replaceTab({ uid, tab: existentTab.uid, type, database: workspaceTabs.database, schema, elementName, elementType });
|
||||||
tabUid = existentTab.uid;
|
tabUid = existentTab.uid;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tabUid = uidGen('T');
|
tabUid = uidGen('T');
|
||||||
this._addTab({ uid, tab: tabUid, content, type, autorun, schema, elementName, elementType });
|
this._addTab({ uid, tab: tabUid, content, type, autorun, database: workspaceTabs.database, schema, elementName, elementType });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tabUid = uidGen('T');
|
tabUid = uidGen('T');
|
||||||
this._addTab({ uid, tab: tabUid, content, type, autorun, schema, elementName, elementType });
|
this._addTab({ uid, tab: tabUid, content, type, autorun, database: workspaceTabs.database, schema, elementName, elementType });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,8 +649,14 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
|||||||
? workspace.tabs.some(tab => tab.uid === workspace.selectedTab)
|
? workspace.tabs.some(tab => tab.uid === workspace.selectedTab)
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
if (!isSelectedExistent && workspace.tabs.length)
|
if (!isSelectedExistent && workspace.tabs.length) {
|
||||||
this.selectTab({ uid, tab: workspace.tabs[workspace.tabs.length - 1].uid });
|
if (workspace.customizations.database) {
|
||||||
|
const databaseTabs = workspace.tabs.filter(tab => tab.type === 'query' || tab.database === workspace.database);
|
||||||
|
this.selectTab({ uid, tab: databaseTabs[databaseTabs.length - 1].uid });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.selectTab({ uid, tab: workspace.tabs[workspace.tabs.length - 1].uid });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateTabContent ({ uid, tab, type, schema, content }: WorkspaceTab) {
|
updateTabContent ({ uid, tab, type, schema, content }: WorkspaceTab) {
|
||||||
this._replaceTab({ uid, tab, type, schema, content });
|
this._replaceTab({ uid, tab, type, schema, content });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user