Merge pull request #1268 from dbgate/feature/sort-sql

Feature/sort sql
This commit is contained in:
Jan Prochazka
2025-11-24 09:04:06 +01:00
committed by GitHub
3 changed files with 113 additions and 20 deletions

View File

@@ -86,14 +86,26 @@
submenuKey += 1;
return;
}
if (item.switchStore && item.switchValue) {
item.switchStore.update(x => ({
...x,
[item.switchValue]: !x[item.switchValue],
}));
if (item.switchStore) {
if (item.switchValue) {
item.switchStore.update(x => ({
...x,
[item.switchValue]: !x[item.switchValue],
}));
}
if (item.switchOption && item.switchOptionValue) {
item.switchStore.update(x => ({
...x,
[item.switchOption]: item.switchOptionValue,
}));
}
switchIndex++;
return;
if (!item.closeOnSwitchClick) {
return;
}
}
dispatchClose();
if (onCloseParent) onCloseParent();
if (item.onClick) item.onClick();
@@ -163,6 +175,16 @@
{/if}
{/key}
{/if}
{#if item.switchOption && item.switchStoreGetter}
{@const optionValue = item.switchStoreGetter()[item.switchOption]}
{#key switchIndex}
{#if optionValue === item.switchOptionValue || (item.switchOptionIsDefault && !optionValue)}
<FontIcon icon="icon check" padRight />
{:else}
<FontIcon icon="icon invisible-box" padRight />
{/if}
{/key}
{/if}
{item.text || item.label}
</span>
{#if item.keyText}

View File

@@ -200,6 +200,7 @@ export const DEFAULT_OBJECT_SEARCH_SETTINGS = {
sqlObjectText: false,
tableEngine: false,
tablesWithRows: false,
sortBy: undefined as string
};
export const DEFAULT_CONNECTION_SEARCH_SETTINGS = {

View File

@@ -79,12 +79,30 @@
// $: console.log('OBJECTS', $objects);
$: sortArgs =
$databaseObjectAppObjectSearchSettings.sortBy == 'rowCount'
? [
['rowCount', 'sizeBytes', 'schemaName', 'pureName'],
['desc', 'desc', 'asc', 'asc'],
]
: $databaseObjectAppObjectSearchSettings.sortBy == 'sizeBytes'
? [
['sizeBytes', 'rowCount', 'schemaName', 'pureName'],
['desc', 'desc', 'asc', 'asc'],
]
: [
['schemaName', 'pureName'],
['asc', 'asc'],
];
$: objectList = _.flatten([
...['tables', 'collections', 'views', 'matviews', 'procedures', 'functions', 'triggers', 'schedulerEvents'].map(
objectTypeField =>
_.sortBy(
_.orderBy(
(($objects || {})[objectTypeField] || []).map(obj => ({ ...obj, objectTypeField })),
['schemaName', 'pureName']
sortArgs[0],
// @ts-ignore
sortArgs[1]
)
),
...appsForDb.map(app =>
@@ -133,19 +151,62 @@
const res = [];
res.push({ label: _t('sqlObject.searchBy', { defaultMessage: 'Search by:' }), isBold: true, disabled: true });
if (driver?.databaseEngineTypes?.includes('document')) {
res.push({ label: _t('sqlObject.collectionName', { defaultMessage: 'Collection name' }), switchValue: 'pureName' });
res.push({
label: _t('sqlObject.collectionName', { defaultMessage: 'Collection name' }),
switchValue: 'pureName',
});
}
if (driver?.databaseEngineTypes?.includes('sql')) {
res.push({ label: _t('sqlObject.tableViewProcedureName', { defaultMessage: 'Table/view/procedure name' }), switchValue: 'pureName' });
res.push({
label: _t('sqlObject.tableViewProcedureName', { defaultMessage: 'Table/view/procedure name' }),
switchValue: 'pureName',
});
res.push({ label: _t('sqlObject.schemaName', { defaultMessage: 'Schema' }), switchValue: 'schemaName' });
res.push({ label: _t('sqlObject.columnName', { defaultMessage: 'Column name' }), switchValue: 'columnName' });
res.push({ label: _t('sqlObject.columnDataType', { defaultMessage: 'Column data type' }), switchValue: 'columnDataType' });
res.push({ label: _t('sqlObject.tableComment', { defaultMessage: 'Table comment' }), switchValue: 'tableComment' });
res.push({ label: _t('sqlObject.columnComment', { defaultMessage: 'Column comment' }), switchValue: 'columnComment' });
res.push({ label: _t('sqlObject.viewProcedureTriggerText', { defaultMessage: 'View/procedure/trigger text' }), switchValue: 'sqlObjectText' });
res.push({
label: _t('sqlObject.columnDataType', { defaultMessage: 'Column data type' }),
switchValue: 'columnDataType',
});
res.push({
label: _t('sqlObject.tableComment', { defaultMessage: 'Table comment' }),
switchValue: 'tableComment',
});
res.push({
label: _t('sqlObject.columnComment', { defaultMessage: 'Column comment' }),
switchValue: 'columnComment',
});
res.push({
label: _t('sqlObject.viewProcedureTriggerText', { defaultMessage: 'View/procedure/trigger text' }),
switchValue: 'sqlObjectText',
});
res.push({ label: _t('sqlObject.tableEngine', { defaultMessage: 'Table engine' }), switchValue: 'tableEngine' });
res.push({ label: _t('sqlObject.tablesWithRows', { defaultMessage: 'Only tables with rows' }), switchValue: 'tablesWithRows' });
res.push({
label: _t('sqlObject.tablesWithRows', { defaultMessage: 'Only tables with rows' }),
switchValue: 'tablesWithRows',
});
}
res.push({ label: _t('sqlObject.sortBy', { defaultMessage: 'Sort by:' }), isBold: true, disabled: true });
res.push({
label: _t('sqlObject.name', { defaultMessage: 'Name' }),
switchOption: 'sortBy',
switchOptionValue: 'name',
switchOptionIsDefault: true,
closeOnSwitchClick: true,
});
res.push({
label: _t('sqlObject.rowCount', { defaultMessage: 'Row count' }),
switchOption: 'sortBy',
switchOptionValue: 'rowCount',
closeOnSwitchClick: true,
});
res.push({
label: _t('sqlObject.sizeBytes', { defaultMessage: 'Size (bytes)' }),
switchOption: 'sortBy',
switchOptionValue: 'sizeBytes',
closeOnSwitchClick: true,
});
return res.map(item => ({
...item,
switchStore: databaseObjectAppObjectSearchSettings,
@@ -193,19 +254,25 @@
<WidgetsInnerContainer hideContent={differentFocusedDb}>
<ErrorInfo
message={_t('sqlObject.databaseEmpty', { defaultMessage: 'Database {database} is empty or structure is not loaded, press Refresh button to reload structure', values: { database } })}
message={_t('sqlObject.databaseEmpty', {
defaultMessage:
'Database {database} is empty or structure is not loaded, press Refresh button to reload structure',
values: { database },
})}
icon="img alert"
/>
<div class="m-1" />
<InlineButton on:click={handleRefreshDatabase}>{_t('common.refresh', { defaultMessage: 'Refresh' })}</InlineButton>
{#if driver?.databaseEngineTypes?.includes('sql')}
<div class="m-1" />
<InlineButton on:click={() => runCommand('new.table')}>{_t('database.newTable', { defaultMessage: 'New table' })}</InlineButton>
<InlineButton on:click={() => runCommand('new.table')}
>{_t('database.newTable', { defaultMessage: 'New table' })}</InlineButton
>
{/if}
{#if driver?.databaseEngineTypes?.includes('document')}
<div class="m-1" />
<InlineButton on:click={() => runCommand('new.collection')}
>{_t('sqlObject.newCollection', { defaultMessage: 'New collection/container'})}</InlineButton
>{_t('sqlObject.newCollection', { defaultMessage: 'New collection/container' })}</InlineButton
>
{/if}
</WidgetsInnerContainer>
@@ -233,7 +300,7 @@
{/if}
<InlineButton
on:click={handleRefreshDatabase}
title={_t('sqlObjectList.refreshDatabase', { defaultMessage: "Refresh database connection and object list" })}
title={_t('sqlObjectList.refreshDatabase', { defaultMessage: 'Refresh database connection and object list' })}
square
data-testid="SqlObjectList_refreshButton"
>
@@ -260,7 +327,10 @@
data-testid="SqlObjectList_container"
>
{#if ($status && ($status.name == 'pending' || $status.name == 'checkStructure' || $status.name == 'loadStructure') && $objects) || !$objects}
<LoadingInfo message={$status?.feedback?.analysingMessage || _t('sqlObject.loadingStructure', { defaultMessage: 'Loading database structure' })} />
<LoadingInfo
message={$status?.feedback?.analysingMessage ||
_t('sqlObject.loadingStructure', { defaultMessage: 'Loading database structure' })}
/>
{:else}
<AppObjectListHandler
bind:this={domListHandler}