focusable databases WIP

This commit is contained in:
SPRINX0\prochazka
2024-11-25 13:46:16 +01:00
parent 398d9f15df
commit a37b74f693
6 changed files with 111 additions and 29 deletions

View File

@@ -446,6 +446,7 @@ await dbgateApi.dropAllDbObjects(${JSON.stringify(
currentArchive,
currentDatabase,
extensions,
focusedConnectionOrDatabase,
getCurrentDatabase,
getExtensions,
getOpenedTabs,
@@ -512,7 +513,13 @@ await dbgateApi.dropAllDbObjects(${JSON.stringify(
passProps?.connectionColorFactory({ conid: data?.connection?._id, database: data.name }, null, null, false)}
isBold={$currentDatabase?.connection?._id == data?.connection?._id &&
extractDbNameFromComposite($currentDatabase?.name) == data.name}
on:click={() => switchCurrentDatabase(data)}
on:dblclick={() => {
switchCurrentDatabase(data);
passProps?.onFocusSqlObjectList?.();
}}
on:click={() => {
$focusedConnectionOrDatabase = { conid: data.connection?._id, database: data.name };
}}
on:dragstart
on:dragenter
on:dragend
@@ -532,4 +539,6 @@ await dbgateApi.dropAllDbObjects(${JSON.stringify(
list.filter(x => x?.name != data?.name || x?.connection?._id != data?.connection?._id)
)
: null}
isChoosed={data.connection?._id == $focusedConnectionOrDatabase?.conid &&
data.name == $focusedConnectionOrDatabase?.database}
/>

View File

@@ -15,13 +15,11 @@
$: databases = useDatabaseList({ conid: isExpandedOnlyBySearch ? null : data._id });
$: dbList = isExpandedOnlyBySearch ? getLocalStorage(`database_list_${data._id}`) || [] : $databases || [];
$: connectionLabel = getConnectionLabel(data);
</script>
<AppObjectList
list={_.sortBy(
dbList.filter(x => filterName(filter, x.name, connectionLabel)),
dbList.filter(x => filterName(filter, x.name, data.displayName, data.server)),
x => x.sortOrder ?? x.name
).map(db => ({ ...db, connection: data }))}
module={databaseAppObject}

View File

@@ -15,9 +15,11 @@
let domDiv = null;
function handleKeyDown(ev) {
const listInstance = _.isFunction(list) ? list() : list;
function selectByDiff(diff) {
const selected = getSelectedObject();
const index = _.findIndex(list, x => selectedObjectMatcher(x, selected));
const index = _.findIndex(listInstance, x => selectedObjectMatcher(x, selected));
if (index == 0 && diff < 0) {
onFocusFilterBox?.();
@@ -26,16 +28,16 @@
if (index >= 0) {
let newIndex = index + diff;
if (newIndex >= list.length) {
newIndex = list.length - 1;
if (newIndex >= listInstance.length) {
newIndex = listInstance.length - 1;
}
if (newIndex < 0) {
newIndex = 0;
}
if (list[newIndex]) {
selectedObjectStore.set(list[newIndex]);
handleObjectClick?.(list[newIndex], { tabPreviewMode: true });
if (listInstance[newIndex]) {
selectedObjectStore.set(listInstance[newIndex]);
handleObjectClick?.(listInstance[newIndex], { tabPreviewMode: true });
}
if (newIndex == 0) {
@@ -64,25 +66,27 @@
ev.preventDefault();
}
if (ev.keyCode == keycodes.home) {
if (list[0]) {
selectedObjectStore.set(list[0]);
handleObjectClick?.(list[0], { tabPreviewMode: true });
if (listInstance[0]) {
selectedObjectStore.set(listInstance[0]);
handleObjectClick?.(listInstance[0], { tabPreviewMode: true });
onScrollTop?.();
}
}
if (ev.keyCode == keycodes.end) {
if (list[list.length - 1]) {
selectedObjectStore.set(list[list.length - 1]);
handleObjectClick?.(list[list.length - 1], { tabPreviewMode: true });
if (listInstance[listInstance.length - 1]) {
selectedObjectStore.set(listInstance[listInstance.length - 1]);
handleObjectClick?.(listInstance[listInstance.length - 1], { tabPreviewMode: true });
}
}
}
export function focusFirst() {
const listInstance = _.isFunction(list) ? list() : list;
domDiv?.focus();
if (list[0]) {
selectedObjectStore.set(list[0]);
handleObjectClick?.(list[0], { tabPreviewMode: true });
if (listInstance[0]) {
selectedObjectStore.set(listInstance[0]);
handleObjectClick?.(listInstance[0], { tabPreviewMode: true });
onScrollTop?.();
}
}

View File

@@ -1,4 +1,10 @@
<script lang="ts">
connectionAppObject.
connectionAppObject.
connectionAppObject.
import _ from 'lodash';
import InlineButton from '../buttons/InlineButton.svelte';
import SearchInput from '../elements/SearchInput.svelte';
@@ -20,7 +26,7 @@
getFocusedConnectionOrDatabase,
} from '../stores';
import runCommand from '../commands/runCommand';
import { getConnectionLabel } from 'dbgate-tools';
import { filterName, getConnectionLabel } from 'dbgate-tools';
import { useConnectionColorFactory } from '../utility/useConnectionColor';
import FontIcon from '../icons/FontIcon.svelte';
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
@@ -32,10 +38,16 @@
import InputTextModal from '../modals/InputTextModal.svelte';
import ConfirmModal from '../modals/ConfirmModal.svelte';
import AppObjectListHandler from './AppObjectListHandler.svelte';
import { getLocalStorage } from '../utility/storageCache';
import { switchCurrentDatabase } from '../utility/common';
import openNewTab from '../utility/openNewTab';
import {openConnection} from '../appobj/ConnectionAppObject.svelte';
const connections = useConnectionList();
const serverStatus = useServerStatus();
export let passProps: any = {};
let filter = '';
let domListHandler;
let domContainer = null;
@@ -66,10 +78,42 @@
connection => (getConnectionLabel(connection) || '').toUpperCase()
);
$: focusFlatList = [
...connectionsWithParent.map(x => ({ conid: x._id })),
...connectionsWithoutParent.map(x => ({ conid: x._id })),
];
function getFocusFlatList() {
const expanded = $expandedConnections;
const opened = $openedConnections;
const res = [];
for (const con of [...connectionsWithParent, ...connectionsWithoutParent]) {
const databases = getLocalStorage(`database_list_${con._id}`) || [];
if (!filterName(filter, con.displayName, con.server, ...databases.map(x => x.name))) {
continue;
}
res.push({
connection: con,
conid: con._id,
});
if ((expanded.includes(con._id) && opened.includes(con._id)) || filter) {
for (const db of _.sortBy(databases, x => x.sortOrder ?? x.name)) {
if (!filterName(filter, con.displayName, con.server, db.name)) {
continue;
}
res.push({
conid: con._id,
database: db.name,
dbobj: {
connection: con,
name: db.name,
},
});
}
}
}
return res;
}
const handleRefreshConnections = () => {
for (const conid of $openedConnections) {
@@ -161,7 +205,7 @@
>
<AppObjectListHandler
bind:this={domListHandler}
list={focusFlatList}
list={getFocusFlatList}
selectedObjectStore={focusedConnectionOrDatabase}
getSelectedObject={getFocusedConnectionOrDatabase}
selectedObjectMatcher={(o1, o2) => o1.conid == o2.conid && o1.database == o2.database}
@@ -171,6 +215,28 @@
onFocusFilterBox={() => {
domFilter?.focus();
}}
handleObjectClick={(data, options) => {
if (data.database) {
if (options.focusTab) {
switchCurrentDatabase(data.dbobj);
passProps?.onFocusSqlObjectList?.();
}
} else {
if (options.focusTab) {
openConnection(data.connection);
} else {
openNewTab({
title: getConnectionLabel(data.connection),
icon: 'img connection',
tabComponent: 'ConnectionTab',
tabPreviewMode: options.tabPreviewMode,
props: {
conid: data.conid,
},
});
}
}
}}
>
<AppObjectList
list={connectionsWithParent}
@@ -179,7 +245,7 @@
expandOnClick
isExpandable={data => $openedConnections.includes(data._id) && !data.singleDatabase}
{filter}
passProps={{ connectionColorFactory: $connectionColorFactory, showPinnedInsteadOfUnpin: true }}
passProps={{ ...passProps, connectionColorFactory: $connectionColorFactory, showPinnedInsteadOfUnpin: true }}
getIsExpanded={data => $expandedConnections.includes(data._id) && !data.singleDatabase}
setIsExpanded={(data, value) => {
expandedConnections.update(old => (value ? [...old, data._id] : old.filter(x => x != data._id)));

View File

@@ -16,6 +16,7 @@
import _ from 'lodash';
export let hidden = false;
let domSqlObjectList = null;
$: conid = $currentDatabase?.connection?._id;
$: connection = useConnectionInfo({ conid });
@@ -32,7 +33,7 @@
</WidgetColumnBarItem>
{:else if !$config?.singleDbConnection}
<WidgetColumnBarItem title="Connections" name="connections" height="35%" storageName="connectionsWidget">
<ConnectionList />
<ConnectionList passProps={{ onFocusSqlObjectList: () => domSqlObjectList.focus() }} />
</WidgetColumnBarItem>
{/if}
<WidgetColumnBarItem
@@ -48,7 +49,7 @@
<WidgetColumnBarItem
title={driver?.databaseEngineTypes?.includes('document')
? driver?.collectionPluralLabel ?? 'Collections/containers'
? (driver?.collectionPluralLabel ?? 'Collections/containers')
: 'Tables, views, functions'}
name="dbObjects"
storageName="dbObjectsWidget"
@@ -58,7 +59,7 @@
(driver?.databaseEngineTypes?.includes('sql') || driver?.databaseEngineTypes?.includes('document'))
)}
>
<SqlObjectList {conid} {database} />
<SqlObjectList {conid} {database} bind:this={domSqlObjectList} />
</WidgetColumnBarItem>
<WidgetColumnBarItem

View File

@@ -125,6 +125,10 @@
if (matcher && !matcher(filter)) return false;
return true;
});
export function focus() {
domListHandler?.focusFirst();
}
</script>
{#if $status && $status.name == 'error'}