show objects by schemas

This commit is contained in:
SPRINX0\prochazka 2024-09-18 13:50:02 +02:00
parent c429424fda
commit 592d7987ab
5 changed files with 133 additions and 5 deletions

View File

@ -877,7 +877,7 @@
{...$$restProps}
module={$$props.module}
{data}
title={data.schemaName ? `${data.schemaName}.${data.pureName}` : data.pureName}
title={data.schemaName && !passProps?.hideSchemaName ? `${data.schemaName}.${data.pureName}` : data.pureName}
icon={databaseObjectIcons[data.objectTypeField]}
menu={createMenu}
showPinnedInsteadOfUnpin={passProps?.showPinnedInsteadOfUnpin}

View File

@ -11,6 +11,7 @@
export let isMulti = false;
export let notSelected = null;
export let defaultValue = '';
export let selectClass = '';
let listOpen = false;
let isFocused = false;
@ -23,6 +24,7 @@
{#if isNative}
<select
value={options.find(x => x.value == value) ? value : defaultValue}
class={selectClass}
{...$$restProps}
on:change={e => {
dispatch('change', e.target['value']);
@ -46,7 +48,7 @@
items={options}
value={isMulti
? _.compact(value?.map(item => options.find(x => x.value == item)) ?? [])
: options.find(x => x.value == value) ?? null}
: (options.find(x => x.value == value) ?? null)}
on:select={e => {
if (isMulti) {
dispatch(

View File

@ -36,6 +36,7 @@
'icon minus-box': 'mdi mdi-minus-box-outline',
'icon plus-box': 'mdi mdi-plus-box-outline',
'icon plus-thick': 'mdi mdi-plus-thick',
'icon minus-thick': 'mdi mdi-minus-thick',
'icon invisible-box': 'mdi mdi-minus-box-outline icon-invisible',
'icon cloud-upload': 'mdi mdi-cloud-upload',
'icon import': 'mdi mdi-application-import',

View File

@ -0,0 +1,101 @@
<script lang="ts">
import InlineButton from '../buttons/InlineButton.svelte';
import SelectField from '../forms/SelectField.svelte';
import _ from 'lodash';
import FontIcon from '../icons/FontIcon.svelte';
import { DatabaseInfo } from 'dbgate-types';
export let dbinfo: DatabaseInfo;
export let selectedSchema;
export let objectList;
export let onApplySelectedSchema;
let appliedSchema;
$: {
if (selectedSchema != null) {
appliedSchema = selectedSchema;
} else {
const usedSchemas = Object.keys(countBySchema);
if (usedSchemas.length == 1) {
appliedSchema = usedSchemas[0];
} else {
appliedSchema = null;
}
}
}
$: onApplySelectedSchema(appliedSchema);
function computeCountBySchema(list) {
const res = {};
for (const item of list) {
if (!item.schemaName) continue;
if (!res[item.schemaName]) res[item.schemaName] = 0;
res[item.schemaName] += 1;
}
return res;
}
$: schemaList = _.uniq(_.compact(dbinfo?.schemas?.map(x => x.schemaName) ?? []));
$: countBySchema = computeCountBySchema(objectList ?? []);
function handleAddNewSchema() {
// runCommand('add-schema', { conid: dbinfo.conid, database: dbinfo.database });
}
</script>
{#if schemaList.length > 0}
<div class="wrapper">
<div class="mr-1">Schema:</div>
<SelectField
isNative
options={[
{ label: `All schemas (${objectList?.length ?? 0})`, value: '' },
...schemaList.filter(x => countBySchema[x]).map(x => ({ label: `${x} (${countBySchema[x] ?? 0})`, value: x })),
...schemaList.filter(x => !countBySchema[x]).map(x => ({ label: `${x} (${countBySchema[x] ?? 0})`, value: x })),
]}
value={selectedSchema ?? appliedSchema ?? ''}
on:change={e => {
selectedSchema = e.detail;
}}
selectClass="schema-select"
/>
{#if selectedSchema != null}
<InlineButton
on:click={() => {
selectedSchema = null;
}}
title="Reset to default"
>
<FontIcon icon="icon close" />
</InlineButton>
{/if}
<InlineButton on:click={handleAddNewSchema} title="Add new schema" square>
<FontIcon icon="icon plus-thick" />
</InlineButton>
<InlineButton on:click={handleAddNewSchema} title="Delete schema" square>
<FontIcon icon="icon minus-thick" />
</InlineButton>
</div>
{/if}
<style>
.wrapper {
display: flex;
border-bottom: 1px solid var(--theme-border);
margin-bottom: 5px;
align-items: center;
margin-top: -5px;
}
:global(.schema-select) {
flex: 1;
min-width: 10px;
min-height: 22px;
width: 10px;
border: none;
}
</style>

View File

@ -35,11 +35,14 @@
import runCommand from '../commands/runCommand';
import { apiCall } from '../utility/api';
import { filterAppsForDatabase } from '../utility/appTools';
import SchemaSelector from './SchemaSelector.svelte';
export let conid;
export let database;
let filter = '';
let selectedSchema = null;
let appliedSelectedSchema = null;
$: objects = useDatabaseInfo({ conid, database });
$: status = useDatabaseStatus({ conid, database });
@ -99,6 +102,12 @@
);
return res;
}
$: flatFilteredList = objectList.filter(data => {
const matcher = databaseObjectAppObject.createMatcher(data);
if (matcher && !matcher(filter)) return false;
return true;
});
</script>
{#if $status && $status.name == 'error'}
@ -130,16 +139,27 @@
<SearchInput placeholder="Search in tables, objects, # prefix in columns" bind:value={filter} />
<CloseSearchButton bind:filter />
<DropDownButton icon="icon plus-thick" menu={createAddMenu} />
<InlineButton on:click={handleRefreshDatabase} title="Refresh database connection and object list">
<InlineButton on:click={handleRefreshDatabase} title="Refresh database connection and object list" square>
<FontIcon icon="icon refresh" />
</InlineButton>
</SearchBoxWrapper>
<SchemaSelector
dbinfo={$objects}
bind:selectedSchema
objectList={flatFilteredList}
onApplySelectedSchema={x => {
appliedSelectedSchema = x;
}}
/>
<WidgetsInnerContainer>
{#if ($status && ($status.name == 'pending' || $status.name == 'checkStructure' || $status.name == 'loadStructure') && $objects) || !$objects}
<LoadingInfo message={$status?.feedback?.analysingMessage || 'Loading database structure'} />
{:else}
<AppObjectList
list={objectList.map(x => ({ ...x, conid, database }))}
list={objectList
.filter(x => (appliedSelectedSchema ? x.schemaName == appliedSelectedSchema : true))
.map(x => ({ ...x, conid, database }))}
module={databaseObjectAppObject}
groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField, driver)}
subItemsComponent={SubColumnParamList}
@ -147,7 +167,11 @@
data.objectTypeField == 'tables' || data.objectTypeField == 'views' || data.objectTypeField == 'matviews'}
expandIconFunc={chevronExpandIcon}
{filter}
passProps={{ showPinnedInsteadOfUnpin: true, connection: $connection }}
passProps={{
showPinnedInsteadOfUnpin: true,
connection: $connection,
hideSchemaName: !!appliedSelectedSchema,
}}
/>
{/if}
</WidgetsInnerContainer>