new collection modal refactor

This commit is contained in:
Jan Prochazka
2024-08-22 09:43:33 +02:00
parent 869e837ee5
commit 77b42e6a04
11 changed files with 67 additions and 25 deletions

View File

@@ -2,7 +2,7 @@ import stream from 'stream';
import { QueryResult } from './query';
import { SqlDialect } from './dialect';
import { SqlDumper } from './dumper';
import { DatabaseInfo, NamedObjectInfo, TableInfo, ViewInfo, ProcedureInfo, FunctionInfo, TriggerInfo } from './dbinfo';
import { DatabaseInfo, NamedObjectInfo, TableInfo, ViewInfo, ProcedureInfo, FunctionInfo, TriggerInfo, CollectionInfo } from './dbinfo';
import { FilterBehaviour } from './filter-type';
export interface StreamOptions {
@@ -115,6 +115,8 @@ export interface EngineDriver extends FilterBehaviourProvider {
profilerChartAggregateFunction?: string;
profilerChartMeasures?: { label: string; field: string }[];
isElectronOnly?: boolean;
collectionSingularLabel?: string;
collectionPluralLabel?: string;
supportedCreateDatabase?: boolean;
showConnectionField?: (
field: string,
@@ -163,7 +165,7 @@ export interface EngineDriver extends FilterBehaviourProvider {
getAuthTypes(): EngineAuthType[];
readCollection(pool: any, options: ReadCollectionOptions): Promise<any>;
updateCollection(pool: any, changeSet: any): Promise<any>;
getCollectionUpdateScript(changeSet: any): string;
getCollectionUpdateScript(changeSet: any, collectionInfo: CollectionInfo): string;
createDatabase(pool: any, name: string): Promise;
dropDatabase(pool: any, name: string): Promise;
getQuerySplitterOptions(usage: 'stream' | 'script' | 'editor'): any;

View File

@@ -91,16 +91,14 @@
};
const handleNewCollection = () => {
showModal(InputTextModal, {
value: '',
label: 'New collection/container name',
header: 'Create collection/container',
onConfirm: async newCollection => {
showModal(NewCollectionModal, {
driver,
onConfirm: async values => {
runOperationOnDatabase(
{ conid: connection._id, database: name },
{
type: 'createCollection',
collection: newCollection,
collection: values,
}
);
@@ -294,7 +292,10 @@
return [
{ onClick: handleNewQuery, text: 'New query', isNewQuery: true },
driver?.databaseEngineTypes?.includes('sql') && { onClick: handleNewTable, text: 'New table' },
driver?.databaseEngineTypes?.includes('document') && { onClick: handleNewCollection, text: 'New collection/container' },
driver?.databaseEngineTypes?.includes('document') && {
onClick: handleNewCollection,
text: `New ${driver?.collectionSingularLabel ?? 'collection/container'}`,
},
driver?.databaseEngineTypes?.includes('sql') && { onClick: handleQueryDesigner, text: 'Design query' },
driver?.databaseEngineTypes?.includes('sql') && {
onClick: handleNewPerspective,
@@ -386,6 +387,7 @@
import ExportDatabaseDumpModal from '../modals/ExportDatabaseDumpModal.svelte';
import ConfirmModal from '../modals/ConfirmModal.svelte';
import { closeMultipleTabs } from '../tabpanel/TabsPanel.svelte';
import NewCollectionModal from '../modals/NewCollectionModal.svelte';
export let data;
export let passProps;

View File

@@ -525,8 +525,8 @@
copyTextToClipboard(data.pureName);
} else if (menu.isRenameCollection) {
showModal(InputTextModal, {
label: 'New collection/container name',
header: 'Rename collection/container',
label: `New collection/container name`,
header: `Rename collection/container`,
value: data.pureName,
onConfirm: async newName => {
const dbid = _.pick(data, ['conid', 'database']);

View File

@@ -40,6 +40,7 @@ import { doLogout, internalRedirectTo } from '../clientAuth';
import { disconnectServerConnection } from '../appobj/ConnectionAppObject.svelte';
import UploadErrorModal from '../modals/UploadErrorModal.svelte';
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
import NewCollectionModal from '../modals/NewCollectionModal.svelte';
// function themeCommand(theme: ThemeDefinition) {
// return {
@@ -287,20 +288,19 @@ registerCommand({
const $currentDatabase = get(currentDatabase);
const connection = _.get($currentDatabase, 'connection') || {};
const database = _.get($currentDatabase, 'name');
const driver = findEngineDriver(get(currentDatabase)?.connection, getExtensions());
const dbid = { conid: connection._id, database };
showModal(InputTextModal, {
value: '',
label: 'New collection/container name',
header: 'Create collection/container',
onConfirm: async newCollection => {
showModal(NewCollectionModal, {
driver,
onConfirm: async values => {
// await apiCall('database-connections/run-script', { ...dbid, sql: `db.createCollection('${newCollection}')` });
const resp = await apiCall('database-connections/run-operation', {
...dbid,
operation: {
type: 'createCollection',
collection: newCollection,
collection: values,
},
});

View File

@@ -0,0 +1,32 @@
<script lang="ts">
import FormStyledButton from '../buttons/FormStyledButton.svelte';
import FormProvider from '../forms/FormProvider.svelte';
import FormSubmit from '../forms/FormSubmit.svelte';
import FormTextField from '../forms/FormTextField.svelte';
import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools';
export let onConfirm;
export let driver;
const handleSubmit = async values => {
closeCurrentModal();
onConfirm(values);
};
</script>
<FormProvider initialValues={{ name: '' }}>
<ModalBase {...$$restProps}>
<svelte:fragment slot="header">
Create {driver?.collectionSingularLabel ?? 'collection/container'}
</svelte:fragment>
<FormTextField label={`New ${driver?.collectionSingularLabel ?? 'collection/container'} name`} name="name" focused />
<svelte:fragment slot="footer">
<FormSubmit value="OK" on:click={e => handleSubmit(e.detail)} />
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
</svelte:fragment>
</ModalBase>
</FormProvider>

View File

@@ -139,7 +139,7 @@
export function save() {
const json = $changeSetStore?.value;
const driver = findEngineDriver($connection, $extensions);
const script = driver.getCollectionUpdateScript ? driver.getCollectionUpdateScript(json) : null;
const script = driver.getCollectionUpdateScript ? driver.getCollectionUpdateScript(json, $collectionInfo) : null;
if (script) {
if (getBoolSettingsValue('skipConfirm.collectionDataSave', false)) {
handleConfirmChange(json);

View File

@@ -38,9 +38,9 @@ export function setSelectedTab(tabid) {
openedTabs.update(tabs => setSelectedTabFunc(tabs, tabid));
}
export function getObjectTypeFieldLabel(objectTypeField) {
export function getObjectTypeFieldLabel(objectTypeField, driver?) {
if (objectTypeField == 'matviews') return 'Materialized Views';
if (objectTypeField == 'collections') return 'Collections/Containers';
if (objectTypeField == 'collections') return _.startCase(driver?.collectionPluralLabel) ?? 'Collections/Containers';
return _.startCase(objectTypeField);
}

View File

@@ -47,7 +47,9 @@
</WidgetColumnBarItem>
<WidgetColumnBarItem
title={driver?.databaseEngineTypes?.includes('document') ? 'Collections/containers' : 'Tables, views, functions'}
title={driver?.databaseEngineTypes?.includes('document')
? driver?.collectionPluralLabel ?? 'Collections/containers'
: 'Tables, views, functions'}
name="dbObjects"
storageName="dbObjectsWidget"
skip={!(

View File

@@ -120,7 +120,9 @@
{/if}
{#if driver?.databaseEngineTypes?.includes('document')}
<div class="m-1" />
<InlineButton on:click={() => runCommand('new.collection')}>New collection/container</InlineButton>
<InlineButton on:click={() => runCommand('new.collection')}
>New {driver?.collectionSingularLabel ?? 'collection/container'}</InlineButton
>
{/if}
</WidgetsInnerContainer>
{:else}
@@ -139,7 +141,7 @@
<AppObjectList
list={objectList.map(x => ({ ...x, conid, database }))}
module={databaseObjectAppObject}
groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField)}
groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField, driver)}
subItemsComponent={SubColumnParamList}
isExpandable={data =>
data.objectTypeField == 'tables' || data.objectTypeField == 'views' || data.objectTypeField == 'matviews'}

View File

@@ -109,7 +109,7 @@ const driver = {
const { type } = operation;
switch (type) {
case 'createCollection':
await this.script(pool, `db.createCollection('${operation.collection}')`);
await this.script(pool, `db.createCollection('${operation.collection.name}')`);
case 'dropOperation':
await this.script(pool, `db.dropCollection('${operation.collection}')`);
default:

View File

@@ -44,6 +44,8 @@ const driver = {
{ label: 'Max duration', field: 'maxDuration' },
],
databaseUrlPlaceholder: 'e.g. mongodb://username:password@mongodb.mydomain.net/dbname',
collectionSingularLabel: 'collection',
collectionPluralLabel: 'collections',
getQuerySplitterOptions: () => mongoSplitterOptions,
@@ -65,7 +67,7 @@ const driver = {
},
],
getCollectionUpdateScript(changeSet) {
getCollectionUpdateScript(changeSet, collectionInfo) {
let res = '';
for (const insert of changeSet.inserts) {
res += `db.${insert.pureName}.insertOne(${jsonStringifyWithObjectId({