Merge branch 'feature/connection-keyboard-browse'

This commit is contained in:
SPRINX0\prochazka
2024-11-26 09:11:23 +01:00
13 changed files with 357 additions and 82 deletions

View File

@@ -50,7 +50,7 @@
<svelte:component
this={module.default}
{data}
on:click={handleExpand}
on:dblclick={handleExpand}
on:expand={handleExpandButton}
expandIcon={getExpandIcon(!isExpandedBySearch && expandable, subItemsComponent, isExpanded, expandIconFunc)}
{checkedObjectsStore}

View File

@@ -12,6 +12,16 @@
return filterName(filter, ...databases.map(x => x.name));
};
export function openConnection(connection) {
if (connection.singleDatabase) {
if (getOpenedSingleDatabaseConnections().includes(connection._id)) {
return;
}
} else {
if (getOpenedConnections().includes(connection._id)) {
return;
}
}
const config = getCurrentConfig();
if (connection.singleDatabase) {
switchCurrentDatabase({ connection, name: connection.defaultDatabase });
@@ -83,10 +93,12 @@
currentDatabase,
expandedConnections,
extensions,
focusedConnectionOrDatabase,
getCurrentConfig,
getCurrentDatabase,
getCurrentSettings,
getOpenedConnections,
getOpenedSingleDatabaseConnections,
getOpenedTabs,
openedConnections,
openedSingleDatabaseConnections,
@@ -135,7 +147,7 @@
});
};
const handleClick = async () => {
const handleDoubleClick = async () => {
const config = getCurrentConfig();
if (config.runAsPortal) {
await tick();
@@ -158,6 +170,19 @@
}
};
const handleClick = async e => {
focusedConnectionOrDatabase.set({ conid: data?._id });
openNewTab({
title: getConnectionLabel(data),
icon: 'img connection',
tabComponent: 'ConnectionTab',
tabPreviewMode: true,
props: {
conid: data._id,
},
});
};
const handleSqlRestore = () => {
showModal(ImportDatabaseDumpModal, {
connection: data,
@@ -329,7 +354,7 @@
colorMark={passProps?.connectionColorFactory && passProps?.connectionColorFactory({ conid: data._id })}
menu={getContextMenu}
on:click={handleClick}
on:click
on:dblclick
on:expand
on:dblclick={handleConnect}
on:middleclick={() => {
@@ -337,4 +362,5 @@
.find(x => x.isNewQuery)
.onClick();
}}
isChoosed={data._id == $focusedConnectionOrDatabase?.conid && !$focusedConnectionOrDatabase?.database}
/>

View File

@@ -446,6 +446,7 @@ await dbgateApi.dropAllDbObjects(${JSON.stringify(
currentArchive,
currentDatabase,
extensions,
focusedConnectionOrDatabase,
getCurrentDatabase,
getExtensions,
getOpenedTabs,
@@ -512,7 +513,14 @@ 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={() => {
// switchCurrentDatabase(data);
$focusedConnectionOrDatabase = { conid: data.connection?._id, database: data.name, connection: data.connection };
}}
on:dragstart
on:dragenter
on:dragend
@@ -532,4 +540,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

@@ -7,6 +7,7 @@
export let disabled = false;
export let value;
export let title = null;
export let skipWidth = false;
function handleClick() {
if (!disabled) dispatch('click');
@@ -19,19 +20,22 @@
}
</script>
<input {type} {value} {title} class:disabled {...$$restProps} on:click={handleClick} bind:this={domButton} />
<input {type} {value} {title} class:disabled {...$$restProps} on:click={handleClick} bind:this={domButton} class:skipWidth />
<style>
input {
border: 1px solid var(--theme-bg-button-inv-2);
padding: 5px;
margin: 2px;
width: 100px;
background-color: var(--theme-bg-button-inv);
color: var(--theme-font-inv-1);
border-radius: 2px;
}
input:not(.skipWidth) {
width: 100px;
}
input:hover:not(.disabled) {
background-color: var(--theme-bg-button-inv-2);
}

View File

@@ -23,8 +23,12 @@
const debouncedSet = _.debounce(x => (value = x), 500);
export function focus() {
export function focus(text) {
domInput.focus();
if (text) {
domInput.value = text;
value = text;
}
}
</script>

View File

@@ -158,6 +158,7 @@ export const appliedCurrentSchema = writable<string>(null);
export const loadingSchemaLists = writable({}); // dict [`${conid}::${database}`]: true
export const selectedDatabaseObjectAppObject = writable(null);
export const focusedConnectionOrDatabase = writable<{ conid: string; database?: string; connection: any }>(null);
export const currentThemeDefinition = derived([currentTheme, extensions], ([$currentTheme, $extensions]) =>
$extensions.themes.find(x => x.themeClassName == $currentTheme)
@@ -339,3 +340,15 @@ openedModals.subscribe(value => {
openedModalsValue = value;
});
export const getOpenedModals = () => openedModalsValue;
let focusedConnectionOrDatabaseValue = null;
focusedConnectionOrDatabase.subscribe(value => {
focusedConnectionOrDatabaseValue = value;
});
export const getFocusedConnectionOrDatabase = () => focusedConnectionOrDatabaseValue;
let openedSingleDatabaseConnectionsValue = [];
openedSingleDatabaseConnections.subscribe(value => {
openedSingleDatabaseConnectionsValue = value;
});
export const getOpenedSingleDatabaseConnections = () => openedSingleDatabaseConnectionsValue;

View File

@@ -1,6 +1,7 @@
import _ from 'lodash';
import {
currentDatabase,
focusedConnectionOrDatabase,
getActiveTab,
getCurrentDatabase,
getLockedDatabaseMode,
@@ -78,6 +79,16 @@ export async function handleAfterTabClick() {
}
currentDatabase.subscribe(currentDb => {
if (currentDb) {
focusedConnectionOrDatabase.set({
conid: currentDb.connection?._id,
database: currentDb.name,
connection: currentDb.connection,
});
} else {
focusedConnectionOrDatabase.set(null);
}
if (!getLockedDatabaseMode()) return;
if (!currentDb && !getAppLoaded()) return;
openedTabs.update(tabs => {

View File

@@ -1,23 +1,28 @@
<script lang="ts">
import keycodes from '../utility/keycodes';
import _ from 'lodash';
import { sleep } from '../utility/common';
export let list;
export let selectedObjectStore;
export let getSelectedObject;
export let selectedObjectMatcher;
export let module;
export let handleObjectClick;
export let onScrollTop = null;
export let onFocusFilterBox = null;
export let getDefaultFocusedItem = null;
let isListFocused = false;
let domDiv = null;
export let hideContent = false;
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 +31,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]);
module.handleObjectClick(list[newIndex], { tabPreviewMode: true });
if (listInstance[newIndex]) {
selectedObjectStore.set(listInstance[newIndex]);
handleObjectClick?.(listInstance[newIndex], { tabPreviewMode: true });
}
if (newIndex == 0) {
@@ -52,7 +57,7 @@
ev.preventDefault();
}
if (ev.keyCode == keycodes.enter) {
module.handleObjectClick(getSelectedObject(), { tabPreviewMode: false, focusTab: true });
handleObjectClick?.(getSelectedObject(), { tabPreviewMode: false, focusTab: true });
ev.preventDefault();
}
if (ev.keyCode == keycodes.pageDown) {
@@ -64,28 +69,66 @@
ev.preventDefault();
}
if (ev.keyCode == keycodes.home) {
if (list[0]) {
selectedObjectStore.set(list[0]);
module.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]);
module.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 });
}
}
if (
!ev.ctrlKey &&
!ev.altKey &&
!ev.metaKey &&
((ev.keyCode >= keycodes.a && ev.keyCode <= keycodes.z) ||
(ev.keyCode >= keycodes.n0 && ev.keyCode <= keycodes.n9) ||
(ev.keyCode >= keycodes.numPad0 && ev.keyCode <= keycodes.numPad9) ||
ev.keyCode == keycodes.dash)
) {
const text = ev.key;
onFocusFilterBox?.(text);
ev.preventDefault();
}
}
export function focusFirst() {
const listInstance = _.isFunction(list) ? list() : list;
domDiv?.focus();
if (list[0]) {
selectedObjectStore.set(list[0]);
module.handleObjectClick(list[0], { tabPreviewMode: true });
if (listInstance[0]) {
selectedObjectStore.set(listInstance[0]);
handleObjectClick?.(listInstance[0], { tabPreviewMode: true });
onScrollTop?.();
}
}
async function handleFocus() {
isListFocused = true;
// await tick();
await sleep(100);
// console.log('ON FOCUS AFTER SLEEP');
const listInstance = _.isFunction(list) ? list() : list;
const selected = getSelectedObject();
const index = _.findIndex(listInstance, x => selectedObjectMatcher(x, selected));
if (index < 0) {
const focused = getDefaultFocusedItem?.();
if (focused) {
const index2 = _.findIndex(listInstance, x => selectedObjectMatcher(x, focused));
if (index2 >= 0) {
selectedObjectStore.set(focused);
handleObjectClick?.(focused, { tabPreviewMode: true });
return;
}
}
focusFirst();
}
}
</script>
<div
@@ -93,13 +136,12 @@
on:keydown={handleKeyDown}
class="wrapper"
class:app-object-list-focused={isListFocused}
on:focus={() => {
isListFocused = true;
}}
on:focus={handleFocus}
on:blur={() => {
isListFocused = false;
}}
bind:this={domDiv}
class:hideContent
>
<slot />
</div>
@@ -108,4 +150,8 @@
.wrapper:focus {
outline: none;
}
.hideContent {
visibility: hidden;
}
</style>

View File

@@ -16,9 +16,12 @@
openedTabs,
emptyConnectionGroupNames,
collapsedConnectionGroupNames,
focusedConnectionOrDatabase,
getFocusedConnectionOrDatabase,
currentDatabase,
} 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';
@@ -29,11 +32,21 @@
import { showModal } from '../modals/modalTools';
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;
let domFilter = null;
$: connectionsWithStatus =
$connections && $serverStatus
@@ -47,12 +60,52 @@
x => !x.unsaved || $openedConnections.includes(x._id) || $openedSingleDatabaseConnections.includes(x._id)
);
$: connectionsWithParent = connectionsWithStatusFiltered
? connectionsWithStatusFiltered?.filter(x => x.parent !== undefined && x.parent !== null && x.parent.length !== 0)
: [];
$: connectionsWithoutParent = connectionsWithStatusFiltered
? connectionsWithStatusFiltered?.filter(x => x.parent === undefined || x.parent === null || x.parent.length === 0)
: [];
$: connectionsWithParent = _.sortBy(
connectionsWithStatusFiltered
? connectionsWithStatusFiltered?.filter(x => x.parent !== undefined && x.parent !== null && x.parent.length !== 0)
: [],
connection => (getConnectionLabel(connection) || '').toUpperCase()
);
$: connectionsWithoutParent = _.sortBy(
connectionsWithStatusFiltered
? connectionsWithStatusFiltered?.filter(x => x.parent === undefined || x.parent === null || x.parent.length === 0)
: [],
connection => (getConnectionLabel(connection) || '').toUpperCase()
);
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,
connection: con,
});
}
}
}
return res;
}
const handleRefreshConnections = () => {
for (const conid of $openedConnections) {
@@ -112,7 +165,14 @@
</script>
<SearchBoxWrapper>
<SearchInput placeholder="Search connection or database" bind:value={filter} />
<SearchInput
placeholder="Search connection or database"
bind:value={filter}
bind:this={domFilter}
onFocusFilteredList={() => {
domListHandler?.focusFirst();
}}
/>
<CloseSearchButton bind:filter />
{#if $commandsCustomized['new.connection']?.enabled}
<InlineButton on:click={() => runCommand('new.connection')} title="Add new connection">
@@ -127,6 +187,7 @@
</InlineButton>
</SearchBoxWrapper>
<WidgetsInnerContainer
bind:this={domContainer}
on:drop={e => {
var data = e.dataTransfer.getData('app_object_drag_data');
if (data) {
@@ -134,43 +195,88 @@
}
}}
>
<AppObjectList
list={_.sortBy(connectionsWithParent, connection => (getConnectionLabel(connection) || '').toUpperCase())}
module={connectionAppObject}
subItemsComponent={SubDatabaseList}
expandOnClick
isExpandable={data => $openedConnections.includes(data._id) && !data.singleDatabase}
{filter}
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)));
<AppObjectListHandler
bind:this={domListHandler}
list={getFocusFlatList}
selectedObjectStore={focusedConnectionOrDatabase}
getSelectedObject={getFocusedConnectionOrDatabase}
selectedObjectMatcher={(o1, o2) => o1?.conid == o2?.conid && o1?.database == o2?.database}
getDefaultFocusedItem={() =>
$currentDatabase
? {
conid: $currentDatabase?.connection?._id,
database: $currentDatabase?.name,
connection: $currentDatabase?.connection,
}
: null}
onScrollTop={() => {
domContainer?.scrollTop();
}}
groupIconFunc={chevronExpandIcon}
groupFunc={data => data.parent}
expandIconFunc={plusExpandIcon}
onDropOnGroup={handleDropOnGroup}
emptyGroupNames={$emptyConnectionGroupNames}
sortGroups
groupContextMenu={createGroupContextMenu}
collapsedGroupNames={collapsedConnectionGroupNames}
/>
{#if (connectionsWithParent?.length > 0 && connectionsWithoutParent?.length > 0) || ($emptyConnectionGroupNames.length > 0 && connectionsWithoutParent?.length > 0)}
<div class="br" />
{/if}
<AppObjectList
list={_.sortBy(connectionsWithoutParent, connection => (getConnectionLabel(connection) || '').toUpperCase())}
module={connectionAppObject}
subItemsComponent={SubDatabaseList}
expandOnClick
isExpandable={data => $openedConnections.includes(data._id) && !data.singleDatabase}
{filter}
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)));
onFocusFilterBox={text => {
domFilter?.focus(text);
}}
/>
handleObjectClick={(data, options) => {
if (data.database) {
if (options.focusTab) {
switchCurrentDatabase({ connection: data.connection, name: data.database });
// console.log('FOCUSING DB', passProps);
// 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}
module={connectionAppObject}
subItemsComponent={SubDatabaseList}
expandOnClick
isExpandable={data => $openedConnections.includes(data._id) && !data.singleDatabase}
{filter}
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)));
}}
groupIconFunc={chevronExpandIcon}
groupFunc={data => data.parent}
expandIconFunc={plusExpandIcon}
onDropOnGroup={handleDropOnGroup}
emptyGroupNames={$emptyConnectionGroupNames}
sortGroups
groupContextMenu={createGroupContextMenu}
collapsedGroupNames={collapsedConnectionGroupNames}
/>
{#if (connectionsWithParent?.length > 0 && connectionsWithoutParent?.length > 0) || ($emptyConnectionGroupNames.length > 0 && connectionsWithoutParent?.length > 0)}
<div class="br" />
{/if}
<AppObjectList
list={connectionsWithoutParent}
module={connectionAppObject}
subItemsComponent={SubDatabaseList}
expandOnClick
isExpandable={data => $openedConnections.includes(data._id) && !data.singleDatabase}
{filter}
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)));
}}
/>
</AppObjectListHandler>
{#if $connections && !$connections.find(x => !x.unsaved) && $openedConnections.length == 0 && $commandsCustomized['new.connection']?.enabled && !$openedTabs.find(x => !x.closedTime && x.tabComponent == 'ConnectionTab' && !x.props?.conid)}
<LargeButton icon="icon new-connection" on:click={() => runCommand('new.connection')} fillHorizontal
>Add new connection</LargeButton

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

@@ -31,7 +31,7 @@
import { chevronExpandIcon } from '../icons/expandIcons';
import ErrorInfo from '../elements/ErrorInfo.svelte';
import LoadingInfo from '../elements/LoadingInfo.svelte';
import { getObjectTypeFieldLabel } from '../utility/common';
import { getObjectTypeFieldLabel, switchCurrentDatabase } from '../utility/common';
import DropDownButton from '../buttons/DropDownButton.svelte';
import FontIcon from '../icons/FontIcon.svelte';
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
@@ -39,6 +39,7 @@
import {
currentDatabase,
extensions,
focusedConnectionOrDatabase,
getSelectedDatabaseObjectAppObject,
selectedDatabaseObjectAppObject,
} from '../stores';
@@ -50,6 +51,8 @@
import { appliedCurrentSchema } from '../stores';
import AppObjectListHandler from './AppObjectListHandler.svelte';
import { matchDatabaseObjectAppObject } from '../appobj/appObjectTools';
import FormStyledButton from '../buttons/FormStyledButton.svelte';
import clickOutside from '../utility/clickOutside';
export let conid;
export let database;
@@ -125,6 +128,15 @@
if (matcher && !matcher(filter)) return false;
return true;
});
export function focus() {
domListHandler?.focusFirst();
}
$: differentFocusedDb =
$focusedConnectionOrDatabase &&
$focusedConnectionOrDatabase?.database &&
($focusedConnectionOrDatabase.conid != conid || $focusedConnectionOrDatabase?.database != database);
</script>
{#if $status && $status.name == 'error'}
@@ -185,7 +197,36 @@
negativeMarginTop
/>
<WidgetsInnerContainer bind:this={domContainer}>
{#if differentFocusedDb}
<div class="no-focused-info">
<div class="m-1">Current database:</div>
<div class="m-1 ml-3 mb-3">
<b>{database}</b>
</div>
<FormStyledButton
value={`Switch to ${$focusedConnectionOrDatabase?.database}`}
skipWidth
on:click={() =>
switchCurrentDatabase({
connection: $focusedConnectionOrDatabase?.connection,
name: $focusedConnectionOrDatabase?.database,
})}
/>
<FormStyledButton
value={`Show ${database}`}
skipWidth
on:click={() => {
$focusedConnectionOrDatabase = {
conid,
database,
connection: $connection,
};
}}
/>
</div>
{/if}
<WidgetsInnerContainer bind:this={domContainer} hideContent={differentFocusedDb}>
{#if ($status && ($status.name == 'pending' || $status.name == 'checkStructure' || $status.name == 'loadStructure') && $objects) || !$objects}
<LoadingInfo message={$status?.feedback?.analysingMessage || 'Loading database structure'} />
{:else}
@@ -195,12 +236,12 @@
selectedObjectStore={selectedDatabaseObjectAppObject}
getSelectedObject={getSelectedDatabaseObjectAppObject}
selectedObjectMatcher={matchDatabaseObjectAppObject}
module={databaseObjectAppObject}
handleObjectClick={(data, options) => databaseObjectAppObject.handleObjectClick(data, options)}
onScrollTop={() => {
domContainer?.scrollTop();
}}
onFocusFilterBox={() => {
domFilter?.focus();
onFocusFilterBox={text => {
domFilter?.focus(text);
}}
>
<AppObjectList
@@ -224,3 +265,12 @@
{/if}
</WidgetsInnerContainer>
{/if}
<style>
.no-focused-info {
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
}
</style>

View File

@@ -1,12 +1,14 @@
<script lang="ts">
let domDiv;
export let hideContent = false;
export function scrollTop() {
domDiv.scrollTop = 0;
}
</script>
<div on:drop bind:this={domDiv}><slot /></div>
<div on:drop bind:this={domDiv} class:hideContent><slot /></div>
<style>
div {
@@ -15,4 +17,8 @@
overflow-y: auto;
width: var(--dim-left-panel-width);
}
.hideContent {
visibility: hidden;
}
</style>