mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 23:45:59 +00:00
Merge branch 'master' into redis
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "4.7.3-beta.1",
|
"version": "4.7.3-beta.4",
|
||||||
"name": "dbgate-all",
|
"name": "dbgate-all",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*",
|
"packages/*",
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
"start:api": "yarn workspace dbgate-api start",
|
"start:api": "yarn workspace dbgate-api start",
|
||||||
"start:app": "cd app && yarn start",
|
"start:app": "cd app && yarn start",
|
||||||
"start:api:portal": "yarn workspace dbgate-api start:portal",
|
"start:api:portal": "yarn workspace dbgate-api start:portal",
|
||||||
"start:api:covid": "yarn workspace dbgate-api start:covid",
|
"start:api:singledb": "yarn workspace dbgate-api start:singledb",
|
||||||
"start:web": "yarn workspace dbgate-web dev",
|
"start:web": "yarn workspace dbgate-web dev",
|
||||||
"start:sqltree": "yarn workspace dbgate-sqltree start",
|
"start:sqltree": "yarn workspace dbgate-sqltree start",
|
||||||
"start:tools": "yarn workspace dbgate-tools start",
|
"start:tools": "yarn workspace dbgate-tools start",
|
||||||
|
|||||||
@@ -53,8 +53,8 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "env-cmd node src/index.js",
|
"start": "env-cmd node src/index.js",
|
||||||
"start:portal": "env-cmd -f .env-portal node src/index.js",
|
"start:portal": "env-cmd -f env/portal/.env node src/index.js",
|
||||||
"start:singledb": "env-cmd -f .env-singledb node src/index.js",
|
"start:singledb": "env-cmd -f env/singledb/.env node src/index.js",
|
||||||
"start:filedb": "env-cmd node src/index.js /home/jena/test/chinook/Chinook.db",
|
"start:filedb": "env-cmd node src/index.js /home/jena/test/chinook/Chinook.db",
|
||||||
"start:singleconn": "env-cmd node src/index.js --server localhost --user root --port 3307 --engine mysql@dbgate-plugin-mysql --password test",
|
"start:singleconn": "env-cmd node src/index.js --server localhost --user root --port 3307 --engine mysql@dbgate-plugin-mysql --password test",
|
||||||
"ts": "tsc",
|
"ts": "tsc",
|
||||||
|
|||||||
@@ -265,4 +265,16 @@ module.exports = {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createConfigFile_meta: true,
|
||||||
|
async createConfigFile({ appFolder, fileName, content }) {
|
||||||
|
const file = path.join(appdir(), appFolder, fileName);
|
||||||
|
if (!(await fs.exists(file))) {
|
||||||
|
await fs.writeFile(file, JSON.stringify(content, undefined, 2));
|
||||||
|
socket.emitChanged(`app-files-changed-${appFolder}`);
|
||||||
|
socket.emitChanged('used-apps-changed');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ module.exports = {
|
|||||||
const app = folder.substring('app:'.length);
|
const app = folder.substring('app:'.length);
|
||||||
await fs.writeFile(path.join(appdir(), app, file), serialize(format, data));
|
await fs.writeFile(path.join(appdir(), app, file), serialize(format, data));
|
||||||
socket.emitChanged(`app-files-changed-${app}`);
|
socket.emitChanged(`app-files-changed-${app}`);
|
||||||
|
socket.emitChanged('used-apps-changed');
|
||||||
apps.emitChangedDbApp(folder);
|
apps.emitChangedDbApp(folder);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -89,6 +89,12 @@ module.exports = {
|
|||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
})
|
})
|
||||||
.then(x => JSON.parse(x));
|
.then(x => JSON.parse(x));
|
||||||
|
if (!manifest.keywords) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!manifest.keywords.includes('dbgateplugin')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const readmeFile = path.join(isPackaged ? packagedPluginsDir() : pluginsdir(), packageName, 'README.md');
|
const readmeFile = path.join(isPackaged ? packagedPluginsDir() : pluginsdir(), packageName, 'README.md');
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (await fs.exists(readmeFile)) {
|
if (await fs.exists(readmeFile)) {
|
||||||
|
|||||||
@@ -95,7 +95,12 @@ function start() {
|
|||||||
|
|
||||||
if (platformInfo.isNpmDist) {
|
if (platformInfo.isNpmDist) {
|
||||||
app.use(getExpressPath('/'), express.static(path.join(__dirname, '../../dbgate-web/public')));
|
app.use(getExpressPath('/'), express.static(path.join(__dirname, '../../dbgate-web/public')));
|
||||||
getPort({ port: 5000 }).then(port => {
|
getPort({
|
||||||
|
port: parseInt(
|
||||||
|
// @ts-ignore
|
||||||
|
process.env.PORT || 3000
|
||||||
|
),
|
||||||
|
}).then(port => {
|
||||||
server.listen(port, () => {
|
server.listen(port, () => {
|
||||||
console.log(`DbGate API listening on port ${port}`);
|
console.log(`DbGate API listening on port ${port}`);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,18 +1,47 @@
|
|||||||
const EnsureStreamHeaderStream = require('../utility/EnsureStreamHeaderStream');
|
const EnsureStreamHeaderStream = require('../utility/EnsureStreamHeaderStream');
|
||||||
|
const Stream = require('stream');
|
||||||
|
const ColumnMapTransformStream = require('../utility/ColumnMapTransformStream');
|
||||||
|
|
||||||
|
function copyStream(input, output, options) {
|
||||||
|
const { columns } = options || {};
|
||||||
|
|
||||||
|
const transforms = [];
|
||||||
|
if (columns) {
|
||||||
|
transforms.push(new ColumnMapTransformStream(columns));
|
||||||
|
}
|
||||||
|
if (output.requireFixedStructure) {
|
||||||
|
transforms.push(new EnsureStreamHeaderStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// Stream.pipeline(input, ...transforms, output, err => {
|
||||||
|
// if (err) {
|
||||||
|
// reject(err);
|
||||||
|
// } else {
|
||||||
|
// resolve();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
function copyStream(input, output) {
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const finisher = output['finisher'] || output;
|
const finisher = output['finisher'] || output;
|
||||||
finisher.on('finish', resolve);
|
finisher.on('finish', resolve);
|
||||||
finisher.on('error', reject);
|
finisher.on('error', reject);
|
||||||
|
|
||||||
if (output.requireFixedStructure) {
|
let lastStream = input;
|
||||||
const ensureHeader = new EnsureStreamHeaderStream();
|
for (const tran of transforms) {
|
||||||
input.pipe(ensureHeader);
|
lastStream.pipe(tran);
|
||||||
ensureHeader.pipe(output);
|
lastStream = tran;
|
||||||
} else {
|
|
||||||
input.pipe(output);
|
|
||||||
}
|
}
|
||||||
|
lastStream.pipe(output);
|
||||||
|
|
||||||
|
// if (output.requireFixedStructure) {
|
||||||
|
// const ensureHeader = new EnsureStreamHeaderStream();
|
||||||
|
// input.pipe(ensureHeader);
|
||||||
|
// ensureHeader.pipe(output);
|
||||||
|
// } else {
|
||||||
|
// input.pipe(output);
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
packages/api/src/utility/ColumnMapTransformStream.js
Normal file
21
packages/api/src/utility/ColumnMapTransformStream.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const stream = require('stream');
|
||||||
|
const { transformRowUsingColumnMap } = require('dbgate-tools');
|
||||||
|
|
||||||
|
class ColumnMapTransformStream extends stream.Transform {
|
||||||
|
constructor(columns) {
|
||||||
|
super({ objectMode: true });
|
||||||
|
this.columns = columns;
|
||||||
|
}
|
||||||
|
_transform(chunk, encoding, done) {
|
||||||
|
if (chunk.__isStreamHeader) {
|
||||||
|
// skip stream header
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push(transformRowUsingColumnMap(chunk, this.columns));
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ColumnMapTransformStream;
|
||||||
@@ -3,7 +3,7 @@ const fs = require('fs-extra');
|
|||||||
async function saveFreeTableData(file, data) {
|
async function saveFreeTableData(file, data) {
|
||||||
const { structure, rows } = data;
|
const { structure, rows } = data;
|
||||||
const fileStream = fs.createWriteStream(file);
|
const fileStream = fs.createWriteStream(file);
|
||||||
await fileStream.write(JSON.stringify(structure) + '\n');
|
await fileStream.write(JSON.stringify({ __isStreamHeader: true, ...structure }) + '\n');
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
await fileStream.write(JSON.stringify(row) + '\n');
|
await fileStream.write(JSON.stringify(row) + '\n');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,11 +166,12 @@ export abstract class GridDisplay {
|
|||||||
hideAllColumns() {
|
hideAllColumns() {
|
||||||
this.setConfig(cfg => ({
|
this.setConfig(cfg => ({
|
||||||
...cfg,
|
...cfg,
|
||||||
hiddenColumns: this.columns.map(x => x.uniqueName),
|
hiddenColumns: this.columns.filter(x => x.uniquePath.length == 1).map(x => x.uniqueName),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
get hiddenColumnIndexes() {
|
get hiddenColumnIndexes() {
|
||||||
|
// console.log('GridDisplay.hiddenColumn', this.config.hiddenColumns);
|
||||||
return (this.config.hiddenColumns || []).map(x => _.findIndex(this.allColumns, y => y.uniqueName == x));
|
return (this.config.hiddenColumns || []).map(x => _.findIndex(this.allColumns, y => y.uniqueName == x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,6 +570,20 @@ export abstract class GridDisplay {
|
|||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getExportColumnMap() {
|
||||||
|
const changesDefined = this.config.hiddenColumns?.length > 0 || this.config.addedColumns?.length > 0;
|
||||||
|
if (this.isDynamicStructure && !changesDefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return this.getColumns(null)
|
||||||
|
.filter(col => col.isChecked)
|
||||||
|
.map(col => ({
|
||||||
|
dst: col.headerText,
|
||||||
|
src: col.uniqueName,
|
||||||
|
ignore: !changesDefined,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
resizeColumn(uniqueName: string, computedSize: number, diff: number) {
|
resizeColumn(uniqueName: string, computedSize: number, diff: number) {
|
||||||
this.setConfig(cfg => {
|
this.setConfig(cfg => {
|
||||||
const columnWidths = {
|
const columnWidths = {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ npm install -g dbgate
|
|||||||
|
|
||||||
After installing, you can run dbgate with command:
|
After installing, you can run dbgate with command:
|
||||||
```sh
|
```sh
|
||||||
dbgate
|
dbgate-serve
|
||||||
```
|
```
|
||||||
|
|
||||||
Then open http://localhost:5000 in your browser
|
Then open http://localhost:5000 in your browser
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
global.dbgateApiModulePath = path.dirname(path.dirname(require.resolve('dbgate-api')));
|
global.dbgateApiModulePath = path.dirname(path.dirname(require.resolve('dbgate-api')));
|
||||||
global.dbgateApiPackagedPluginsPath = path.dirname(global.dbgateApiModulePath);
|
global.dbgateApiPackagedPluginsPath = path.dirname(global.dbgateApiModulePath);
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"author": "Jan Prochazka",
|
"author": "Jan Prochazka",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"dbgate": "./bin/dbgate.js"
|
"dbgate-serve": "./bin/dbgate-serve.js"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"sql",
|
"sql",
|
||||||
@@ -19,12 +19,14 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dbgate-api": "^4.1.1",
|
"dbgate-api": "^4.1.1",
|
||||||
"dbgate-web": "^4.1.1",
|
|
||||||
"dbgate-plugin-csv": "^4.1.1",
|
"dbgate-plugin-csv": "^4.1.1",
|
||||||
"dbgate-plugin-excel": "^4.1.1",
|
"dbgate-plugin-excel": "^4.1.1",
|
||||||
"dbgate-plugin-mongo": "^4.1.1",
|
"dbgate-plugin-mongo": "^4.1.1",
|
||||||
"dbgate-plugin-mysql": "^4.1.1",
|
|
||||||
"dbgate-plugin-mssql": "^4.1.1",
|
"dbgate-plugin-mssql": "^4.1.1",
|
||||||
"dbgate-plugin-postgres": "^4.1.1"
|
"dbgate-plugin-mysql": "^4.1.1",
|
||||||
|
"dbgate-plugin-postgres": "^4.1.1",
|
||||||
|
"dbgate-plugin-xml": "^4.1.1",
|
||||||
|
"dbgate-web": "^4.1.1",
|
||||||
|
"dotenv": "^16.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import { TableInfo } from 'dbgate-types';
|
import { TableInfo } from 'dbgate-types';
|
||||||
import _cloneDeep from 'lodash/cloneDeep';
|
import _cloneDeep from 'lodash/cloneDeep';
|
||||||
|
import _fromPairs from 'lodash/fromPairs';
|
||||||
|
import _get from 'lodash/get';
|
||||||
|
|
||||||
export function prepareTableForImport(table: TableInfo): TableInfo {
|
export function prepareTableForImport(table: TableInfo): TableInfo {
|
||||||
const res = _cloneDeep(table);
|
const res = _cloneDeep(table);
|
||||||
@@ -10,3 +12,12 @@ export function prepareTableForImport(table: TableInfo): TableInfo {
|
|||||||
if (res.primaryKey) res.primaryKey.constraintName = null;
|
if (res.primaryKey) res.primaryKey.constraintName = null;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TransformColumnDefinition {
|
||||||
|
src: string;
|
||||||
|
dst: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function transformRowUsingColumnMap(row, columns: TransformColumnDefinition[]) {
|
||||||
|
return _fromPairs(columns.map(col => [col.dst, _get(row, col.src)]));
|
||||||
|
}
|
||||||
|
|||||||
@@ -174,6 +174,7 @@
|
|||||||
initialValues.sourceDatabaseName = database;
|
initialValues.sourceDatabaseName = database;
|
||||||
initialValues.sourceSql = getExportQuery();
|
initialValues.sourceSql = getExportQuery();
|
||||||
initialValues.sourceList = [pureName];
|
initialValues.sourceList = [pureName];
|
||||||
|
initialValues[`columns_${pureName}`] = display.getExportColumnMap();
|
||||||
showModal(ImportExportModal, { initialValues });
|
showModal(ImportExportModal, { initialValues });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +209,8 @@
|
|||||||
sql: getExportQuery(),
|
sql: getExportQuery(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fmt
|
fmt,
|
||||||
|
display.getExportColumnMap()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -175,10 +175,12 @@
|
|||||||
if (domFocusField) domFocusField.focus();
|
if (domFocusField) domFocusField.focus();
|
||||||
}}
|
}}
|
||||||
on:setvisibility={e => {
|
on:setvisibility={e => {
|
||||||
for (const name of selectedColumns) {
|
if (selectedColumns.includes(column.uniqueName)) {
|
||||||
const column = items.find(x => x.uniqueName == name);
|
for (const name of selectedColumns) {
|
||||||
if (column) {
|
const column = items.find(x => x.uniqueName == name);
|
||||||
display.setColumnVisibility(column.uniquePath, e.detail);
|
if (column) {
|
||||||
|
display.setColumnVisibility(column.uniquePath, e.detail);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -800,6 +800,7 @@
|
|||||||
// $: console.log('containerHeight', containerHeight);
|
// $: console.log('containerHeight', containerHeight);
|
||||||
|
|
||||||
// $: console.log('COLUMNS', columns);
|
// $: console.log('COLUMNS', columns);
|
||||||
|
// $: console.log('columnSizes.realCount', columnSizes.realCount);
|
||||||
// $: console.log('realColumnUniqueNames', realColumnUniqueNames);
|
// $: console.log('realColumnUniqueNames', realColumnUniqueNames);
|
||||||
// $: console.log('columnSizes.realCount', columnSizes.realCount);
|
// $: console.log('columnSizes.realCount', columnSizes.realCount);
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
import RowsArrayGrider from './RowsArrayGrider';
|
import RowsArrayGrider from './RowsArrayGrider';
|
||||||
|
|
||||||
export let jslid;
|
export let jslid;
|
||||||
|
export let display;
|
||||||
|
|
||||||
export const activator = createActivator('JslDataGridCore', false);
|
export const activator = createActivator('JslDataGridCore', false);
|
||||||
|
|
||||||
@@ -93,10 +94,12 @@
|
|||||||
initialValues.sourceStorageType = 'archive';
|
initialValues.sourceStorageType = 'archive';
|
||||||
initialValues.sourceArchiveFolder = archiveMatch[1];
|
initialValues.sourceArchiveFolder = archiveMatch[1];
|
||||||
initialValues.sourceList = [archiveMatch[2]];
|
initialValues.sourceList = [archiveMatch[2]];
|
||||||
|
initialValues[`columns_${archiveMatch[2]}`] = display.getExportColumnMap();
|
||||||
} else {
|
} else {
|
||||||
initialValues.sourceStorageType = 'jsldata';
|
initialValues.sourceStorageType = 'jsldata';
|
||||||
initialValues.sourceJslId = jslid;
|
initialValues.sourceJslId = jslid;
|
||||||
initialValues.sourceList = ['query-data'];
|
initialValues.sourceList = ['query-data'];
|
||||||
|
initialValues[`columns_query-data`] = display.getExportColumnMap();
|
||||||
}
|
}
|
||||||
showModal(ImportExportModal, { initialValues });
|
showModal(ImportExportModal, { initialValues });
|
||||||
}
|
}
|
||||||
@@ -113,7 +116,8 @@
|
|||||||
fileName: archiveMatch[2],
|
fileName: archiveMatch[2],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fmt
|
fmt,
|
||||||
|
display.getExportColumnMap()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
exportQuickExportFile(
|
exportQuickExportFile(
|
||||||
@@ -124,7 +128,8 @@
|
|||||||
jslid,
|
jslid,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fmt
|
fmt,
|
||||||
|
display.getExportColumnMap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -99,9 +99,12 @@ export class SeriesSizes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.modelIndexes = _.range(0, this.count);
|
this.modelIndexes = _.range(0, this.count);
|
||||||
|
// console.log('SeriesSize:build:this.modelIndexes-before', this.modelIndexes);
|
||||||
|
// console.log('SeriesSize:build:this.hiddenAndFrozenModelIndexes', this.hiddenAndFrozenModelIndexes);
|
||||||
if (this.hiddenAndFrozenModelIndexes) {
|
if (this.hiddenAndFrozenModelIndexes) {
|
||||||
this.modelIndexes = this.modelIndexes.filter(col => !this.hiddenAndFrozenModelIndexes.includes(col));
|
this.modelIndexes = this.modelIndexes.filter(col => !this.hiddenAndFrozenModelIndexes.includes(col));
|
||||||
}
|
}
|
||||||
|
// console.log('SeriesSize:build:this.modelIndexes-result', this.modelIndexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getScrollIndexOnPosition(position: number): number {
|
public getScrollIndexOnPosition(position: number): number {
|
||||||
|
|||||||
@@ -135,6 +135,7 @@
|
|||||||
initialValues.sourceDatabaseName = database;
|
initialValues.sourceDatabaseName = database;
|
||||||
initialValues.sourceSql = display.getExportQuery();
|
initialValues.sourceSql = display.getExportQuery();
|
||||||
initialValues.sourceList = display.baseTableOrSimilar ? [display.baseTableOrSimilar.pureName] : [];
|
initialValues.sourceList = display.baseTableOrSimilar ? [display.baseTableOrSimilar.pureName] : [];
|
||||||
|
initialValues[`columns_${pureName}`] = display.getExportColumnMap();
|
||||||
showModal(ImportExportModal, { initialValues });
|
showModal(ImportExportModal, { initialValues });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +194,8 @@
|
|||||||
sql: display.getExportQuery(),
|
sql: display.getExportQuery(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fmt
|
fmt,
|
||||||
|
display.getExportColumnMap()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
registerQuickExportHandler(quickExportHandler);
|
registerQuickExportHandler(quickExportHandler);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export function countColumnSizes(grider: Grider, columns, containerWidth, displa
|
|||||||
//return this.context.measureText(txt).width;
|
//return this.context.measureText(txt).width;
|
||||||
|
|
||||||
// console.log('countColumnSizes', loadedRows.length, containerWidth);
|
// console.log('countColumnSizes', loadedRows.length, containerWidth);
|
||||||
|
// console.log('countColumnSizes:columns', columns);
|
||||||
|
|
||||||
columnSizes.maxSize = (containerWidth * 2) / 3;
|
columnSizes.maxSize = (containerWidth * 2) / 3;
|
||||||
columnSizes.count = columns.length;
|
columnSizes.count = columns.length;
|
||||||
@@ -114,10 +115,12 @@ export function countVisibleRealColumns(columnSizes, firstVisibleColumnScrollInd
|
|||||||
) {
|
) {
|
||||||
visibleRealColumnIndexes.push(colIndex + columnSizes.frozenCount);
|
visibleRealColumnIndexes.push(colIndex + columnSizes.frozenCount);
|
||||||
}
|
}
|
||||||
|
// console.log('countVisibleRealColumns:visibleRealColumnIndexes', visibleRealColumnIndexes);
|
||||||
|
|
||||||
// real columns
|
// real columns
|
||||||
for (let colIndex of visibleRealColumnIndexes) {
|
for (let colIndex of visibleRealColumnIndexes) {
|
||||||
let modelColumnIndex = columnSizes.realToModel(colIndex);
|
let modelColumnIndex = columnSizes.realToModel(colIndex);
|
||||||
|
// console.log('countVisibleRealColumns:modelColumnIndex', modelColumnIndex);
|
||||||
modelIndexes[colIndex] = modelColumnIndex;
|
modelIndexes[colIndex] = modelColumnIndex;
|
||||||
|
|
||||||
let col = columns[modelColumnIndex];
|
let col = columns[modelColumnIndex];
|
||||||
@@ -129,6 +132,7 @@ export function countVisibleRealColumns(columnSizes, firstVisibleColumnScrollInd
|
|||||||
width,
|
width,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// console.log('countVisibleRealColumns:realColumns', realColumns);
|
||||||
return realColumns;
|
return realColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
export let selectedIndex = 0;
|
export let selectedIndex = 0;
|
||||||
export let clickable = false;
|
export let clickable = false;
|
||||||
export let disableFocusOutline = false;
|
export let disableFocusOutline = false;
|
||||||
|
export let emptyMessage = null;
|
||||||
|
|
||||||
export let domTable = undefined;
|
export let domTable = undefined;
|
||||||
|
|
||||||
@@ -99,6 +100,11 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
|
{#if emptyMessage && rows.length == 0}
|
||||||
|
<tr>
|
||||||
|
<td colspan={columnList.length}>{emptyMessage}</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
import { createGridCache, FreeTableGridDisplay } from 'dbgate-datalib';
|
import { createGridCache, FreeTableGridDisplay } from 'dbgate-datalib';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import uuidv1 from 'uuid/v1';
|
import uuidv1 from 'uuid/v1';
|
||||||
|
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||||
import registerCommand from '../commands/registerCommand';
|
import registerCommand from '../commands/registerCommand';
|
||||||
|
|
||||||
import DataGridCore from '../datagrid/DataGridCore.svelte';
|
import DataGridCore from '../datagrid/DataGridCore.svelte';
|
||||||
@@ -24,6 +25,8 @@
|
|||||||
import { apiCall } from '../utility/api';
|
import { apiCall } from '../utility/api';
|
||||||
import { registerMenu } from '../utility/contextMenu';
|
import { registerMenu } from '../utility/contextMenu';
|
||||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||||
|
import createQuickExportMenu from '../utility/createQuickExportMenu';
|
||||||
|
import { exportQuickExportFile } from '../utility/exportFileTools';
|
||||||
import FreeTableGrider from './FreeTableGrider';
|
import FreeTableGrider from './FreeTableGrider';
|
||||||
import MacroPreviewGrider from './MacroPreviewGrider';
|
import MacroPreviewGrider from './MacroPreviewGrider';
|
||||||
|
|
||||||
@@ -51,10 +54,31 @@
|
|||||||
initialValues.sourceStorageType = 'jsldata';
|
initialValues.sourceStorageType = 'jsldata';
|
||||||
initialValues.sourceJslId = jslid;
|
initialValues.sourceJslId = jslid;
|
||||||
initialValues.sourceList = ['editor-data'];
|
initialValues.sourceList = ['editor-data'];
|
||||||
|
initialValues[`columns_editor-data`] = display.getExportColumnMap();
|
||||||
showModal(ImportExportModal, { initialValues: initialValues });
|
showModal(ImportExportModal, { initialValues: initialValues });
|
||||||
}
|
}
|
||||||
|
|
||||||
registerMenu({ command: 'freeTableGrid.export', tag: 'export' });
|
const quickExportHandler = fmt => async () => {
|
||||||
|
const jslid = uuidv1();
|
||||||
|
await apiCall('jsldata/save-free-table', { jslid, data: modelState.value });
|
||||||
|
exportQuickExportFile(
|
||||||
|
'editor-data',
|
||||||
|
{
|
||||||
|
functionName: 'jslDataReader',
|
||||||
|
props: {
|
||||||
|
jslid,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fmt,
|
||||||
|
display.getExportColumnMap()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
registerQuickExportHandler(quickExportHandler);
|
||||||
|
|
||||||
|
registerMenu(() => ({
|
||||||
|
...createQuickExportMenu(quickExportHandler, { command: 'freeTableGrid.export' }),
|
||||||
|
tag: 'export',
|
||||||
|
}));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DataGridCore {...$$props} {grider} {display} frameSelection={!!macroPreview} bind:selectedCellsPublished />
|
<DataGridCore {...$$props} {grider} {display} frameSelection={!!macroPreview} bind:selectedCellsPublished />
|
||||||
|
|||||||
@@ -42,11 +42,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
import Link from '../elements/Link.svelte';
|
||||||
import TableControl from '../elements/TableControl.svelte';
|
import TableControl from '../elements/TableControl.svelte';
|
||||||
import CheckboxField from '../forms/CheckboxField.svelte';
|
import CheckboxField from '../forms/CheckboxField.svelte';
|
||||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||||
import TextField from '../forms/TextField.svelte';
|
import TextField from '../forms/TextField.svelte';
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
|
import ColumnMapModal from '../modals/ColumnMapModal.svelte';
|
||||||
|
import { showModal } from '../modals/modalTools';
|
||||||
import { findFileFormat } from '../plugins/fileformats';
|
import { findFileFormat } from '../plugins/fileformats';
|
||||||
import { extensions } from '../stores';
|
import { extensions } from '../stores';
|
||||||
import getAsArray from '../utility/getAsArray';
|
import getAsArray from '../utility/getAsArray';
|
||||||
@@ -189,6 +192,11 @@
|
|||||||
header: 'Preview',
|
header: 'Preview',
|
||||||
slot: 0,
|
slot: 0,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldName: 'columns',
|
||||||
|
header: 'Columns',
|
||||||
|
slot: 2,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="0" let:row>
|
<svelte:fragment slot="0" let:row>
|
||||||
@@ -214,6 +222,18 @@
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="2" let:row>
|
||||||
|
{@const columnCount = ($values[`columns_${row}`] || []).filter(x => !x.skip).length}
|
||||||
|
<Link
|
||||||
|
onClick={() => {
|
||||||
|
showModal(ColumnMapModal, {
|
||||||
|
value: $values[`columns_${row}`],
|
||||||
|
onConfirm: value => setFieldValue(`columns_${row}`, value),
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>{columnCount > 0 ? `(${columnCount} columns)` : '(copy from source)'}
|
||||||
|
</Link>
|
||||||
|
</svelte:fragment>
|
||||||
</TableControl>
|
</TableControl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,12 +25,20 @@ export default class ScriptWriter {
|
|||||||
this.packageNames.push(...extractShellApiPlugins(functionName, props));
|
this.packageNames.push(...extractShellApiPlugins(functionName, props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assignValue(variableName, jsonValue) {
|
||||||
|
this.put(`const ${variableName} = ${JSON.stringify(jsonValue)};`);
|
||||||
|
}
|
||||||
|
|
||||||
requirePackage(packageName) {
|
requirePackage(packageName) {
|
||||||
this.packageNames.push(packageName);
|
this.packageNames.push(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyStream(sourceVar, targetVar) {
|
copyStream(sourceVar, targetVar, colmapVar = null) {
|
||||||
this.put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar});`);
|
if (colmapVar) {
|
||||||
|
this.put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar}, {columns: ${colmapVar}});`);
|
||||||
|
} else {
|
||||||
|
this.put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar});`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
comment(s) {
|
comment(s) {
|
||||||
|
|||||||
@@ -160,6 +160,21 @@ function getTargetExpr(extensions, sourceName, values, targetConnection, targetD
|
|||||||
throw new Error(`Unknown target storage type: ${targetStorageType}`);
|
throw new Error(`Unknown target storage type: ${targetStorageType}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeExportColumnMap(colmap) {
|
||||||
|
if (!colmap) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!colmap.find(x => !x.ignore)) {
|
||||||
|
// all values are ignored, ignore column map
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
colmap = colmap.filter(x => !x.skip);
|
||||||
|
if (colmap.length > 0) {
|
||||||
|
return colmap.map(x => _.omit(x, ['ignore']));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export default async function createImpExpScript(extensions, values, addEditorInfo = true) {
|
export default async function createImpExpScript(extensions, values, addEditorInfo = true) {
|
||||||
const script = new ScriptWriter(values.startVariableIndex || 0);
|
const script = new ScriptWriter(values.startVariableIndex || 0);
|
||||||
|
|
||||||
@@ -186,7 +201,15 @@ export default async function createImpExpScript(extensions, values, addEditorIn
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
script.assign(targetVar, ...getTargetExpr(extensions, sourceName, values, targetConnection, targetDriver));
|
script.assign(targetVar, ...getTargetExpr(extensions, sourceName, values, targetConnection, targetDriver));
|
||||||
|
|
||||||
script.copyStream(sourceVar, targetVar);
|
const colmap = normalizeExportColumnMap(values[`columns_${sourceName}`] );
|
||||||
|
|
||||||
|
let colmapVar = null;
|
||||||
|
if (colmap) {
|
||||||
|
colmapVar = script.allocVariable();
|
||||||
|
script.assignValue(colmapVar, colmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
script.copyStream(sourceVar, targetVar, colmapVar);
|
||||||
script.put();
|
script.put();
|
||||||
}
|
}
|
||||||
if (addEditorInfo) {
|
if (addEditorInfo) {
|
||||||
|
|||||||
91
packages/web/src/modals/ColumnMapModal.svelte
Normal file
91
packages/web/src/modals/ColumnMapModal.svelte
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||||
|
import Link from '../elements/Link.svelte';
|
||||||
|
import TableControl from '../elements/TableControl.svelte';
|
||||||
|
import CheckboxField from '../forms/CheckboxField.svelte';
|
||||||
|
|
||||||
|
import FormProvider from '../forms/FormProvider.svelte';
|
||||||
|
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||||
|
import TextField from '../forms/TextField.svelte';
|
||||||
|
import ModalBase from './ModalBase.svelte';
|
||||||
|
import { closeCurrentModal } from './modalTools';
|
||||||
|
|
||||||
|
export let header = 'Configure columns';
|
||||||
|
export let onConfirm;
|
||||||
|
export let value = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FormProvider>
|
||||||
|
<ModalBase {...$$restProps}>
|
||||||
|
<div slot="header">{header}</div>
|
||||||
|
|
||||||
|
<div class="m-3">
|
||||||
|
When no columns are defined in this mapping, source row is copied to target without any modifications
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<TableControl
|
||||||
|
columns={[
|
||||||
|
{ fieldName: 'use', header: 'Use', slot: 4 },
|
||||||
|
{ fieldName: 'src', header: 'Source column', slot: 1 },
|
||||||
|
{ fieldName: 'dst', header: 'Target column', slot: 2 },
|
||||||
|
{ fieldName: 'actions', header: '', slot: 3 },
|
||||||
|
]}
|
||||||
|
rows={value || []}
|
||||||
|
emptyMessage="No transform defined"
|
||||||
|
>
|
||||||
|
<svelte:fragment slot="4" let:row let:index>
|
||||||
|
<CheckboxField
|
||||||
|
checked={!row['skip']}
|
||||||
|
on:change={e =>
|
||||||
|
(value = (value || []).map((x, i) => (i == index ? { ...x, skip: !e.target.checked, ignore: false } : x)))}
|
||||||
|
/>
|
||||||
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="1" let:row let:index>
|
||||||
|
<TextField
|
||||||
|
value={row['src']}
|
||||||
|
on:change={e =>
|
||||||
|
(value = (value || []).map((x, i) => (i == index ? { ...x, src: e.target.value, ignore: false } : x)))}
|
||||||
|
/>
|
||||||
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="2" let:row let:index>
|
||||||
|
<TextField
|
||||||
|
value={row['dst']}
|
||||||
|
on:change={e =>
|
||||||
|
(value = (value || []).map((x, i) => (i == index ? { ...x, dst: e.target.value, ignore: false } : x)))}
|
||||||
|
/>
|
||||||
|
</svelte:fragment>
|
||||||
|
<svelte:fragment slot="3" let:index>
|
||||||
|
<Link
|
||||||
|
onClick={() => {
|
||||||
|
value = value.filter((x, i) => i != index);
|
||||||
|
}}>Remove</Link
|
||||||
|
>
|
||||||
|
</svelte:fragment>
|
||||||
|
</TableControl>
|
||||||
|
|
||||||
|
<svelte:fragment slot="footer">
|
||||||
|
<FormSubmit
|
||||||
|
value="OK"
|
||||||
|
on:click={() => {
|
||||||
|
closeCurrentModal();
|
||||||
|
onConfirm(!value || value.length == 0 ? null : value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||||
|
<FormStyledButton
|
||||||
|
type="button"
|
||||||
|
value="Add column"
|
||||||
|
on:click={() => {
|
||||||
|
value = [...(value || []), {}];
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormStyledButton
|
||||||
|
type="button"
|
||||||
|
value="Reset"
|
||||||
|
on:click={() => {
|
||||||
|
value = [];
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</svelte:fragment>
|
||||||
|
</ModalBase>
|
||||||
|
</FormProvider>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
|
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
|
||||||
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
|
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
|
||||||
import ToolStripExportButton from '../buttons/ToolStripExportButton.svelte';
|
import ToolStripExportButton, { createQuickExportHandlerRef } from '../buttons/ToolStripExportButton.svelte';
|
||||||
import registerCommand from '../commands/registerCommand';
|
import registerCommand from '../commands/registerCommand';
|
||||||
import DataGrid from '../datagrid/DataGrid.svelte';
|
import DataGrid from '../datagrid/DataGrid.svelte';
|
||||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||||
@@ -137,6 +137,8 @@ import ToolStripExportButton from '../buttons/ToolStripExportButton.svelte';
|
|||||||
|
|
||||||
// display is overridden in FreeTableGridCore, this is because of column manager
|
// display is overridden in FreeTableGridCore, this is because of column manager
|
||||||
$: display = new FreeTableGridDisplay($modelState.value, $config, config.update, null, null);
|
$: display = new FreeTableGridDisplay($modelState.value, $config, config.update, null, null);
|
||||||
|
|
||||||
|
const quickExportHandlerRef = createQuickExportHandlerRef();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isLoading}
|
{#if isLoading}
|
||||||
@@ -161,7 +163,7 @@ import ToolStripExportButton from '../buttons/ToolStripExportButton.svelte';
|
|||||||
/>
|
/>
|
||||||
<svelte:fragment slot="toolstrip">
|
<svelte:fragment slot="toolstrip">
|
||||||
<ToolStripCommandButton command="freeTable.save" />
|
<ToolStripCommandButton command="freeTable.save" />
|
||||||
<ToolStripExportButton command="freeTableGrid.export" />
|
<ToolStripExportButton command="freeTableGrid.export" {quickExportHandlerRef} />
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</ToolStripContainer>
|
</ToolStripContainer>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
import useEditorData from '../query/useEditorData';
|
import useEditorData from '../query/useEditorData';
|
||||||
import invalidateCommands from '../commands/invalidateCommands';
|
import invalidateCommands from '../commands/invalidateCommands';
|
||||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||||
|
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
|
||||||
|
import ToolStripSaveButton from '../buttons/ToolStripSaveButton.svelte';
|
||||||
|
|
||||||
export let tabid;
|
export let tabid;
|
||||||
|
|
||||||
@@ -70,14 +72,20 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<AceEditor
|
<ToolStripContainer>
|
||||||
value={$editorState.value || ''}
|
<AceEditor
|
||||||
menu={createMenu()}
|
value={$editorState.value || ''}
|
||||||
on:input={e => setEditorData(e.detail)}
|
menu={createMenu()}
|
||||||
on:focus={() => {
|
on:input={e => setEditorData(e.detail)}
|
||||||
activator.activate();
|
on:focus={() => {
|
||||||
invalidateCommands();
|
activator.activate();
|
||||||
}}
|
invalidateCommands();
|
||||||
bind:this={domEditor}
|
}}
|
||||||
mode="json"
|
bind:this={domEditor}
|
||||||
/>
|
mode="json"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<svelte:fragment slot="toolstrip">
|
||||||
|
<ToolStripSaveButton idPrefix="json" />
|
||||||
|
</svelte:fragment>
|
||||||
|
</ToolStripContainer>
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ import getElectron from './getElectron';
|
|||||||
import { showSnackbar, showSnackbarInfo, showSnackbarError, closeSnackbar } from '../utility/snackbar';
|
import { showSnackbar, showSnackbarInfo, showSnackbarError, closeSnackbar } from '../utility/snackbar';
|
||||||
import resolveApi from './resolveApi';
|
import resolveApi from './resolveApi';
|
||||||
import { apiCall, apiOff, apiOn } from './api';
|
import { apiCall, apiOff, apiOn } from './api';
|
||||||
|
import { normalizeExportColumnMap } from '../impexp/createImpExpScript';
|
||||||
|
|
||||||
export async function exportQuickExportFile(dataName, reader, format) {
|
export async function exportQuickExportFile(dataName, reader, format, columnMap = null) {
|
||||||
const electron = getElectron();
|
const electron = getElectron();
|
||||||
|
|
||||||
let filePath;
|
let filePath;
|
||||||
@@ -31,7 +32,14 @@ export async function exportQuickExportFile(dataName, reader, format) {
|
|||||||
const writer = format.createWriter(filePath, dataName);
|
const writer = format.createWriter(filePath, dataName);
|
||||||
script.assign(targetVar, writer.functionName, writer.props);
|
script.assign(targetVar, writer.functionName, writer.props);
|
||||||
|
|
||||||
script.copyStream(sourceVar, targetVar);
|
const colmap = normalizeExportColumnMap(columnMap);
|
||||||
|
let colmapVar = null;
|
||||||
|
if (colmap) {
|
||||||
|
colmapVar = script.allocVariable();
|
||||||
|
script.assignValue(colmapVar, colmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
script.copyStream(sourceVar, targetVar, colmapVar);
|
||||||
script.put();
|
script.put();
|
||||||
|
|
||||||
const resp = await apiCall('runners/start', { script: script.getScript() });
|
const resp = await apiCall('runners/start', { script: script.getScript() });
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
import { useAppFiles, useArchiveFolders } from '../utility/metadataLoaders';
|
import { useAppFiles, useArchiveFolders } from '../utility/metadataLoaders';
|
||||||
import openNewTab from '../utility/openNewTab';
|
import openNewTab from '../utility/openNewTab';
|
||||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||||
|
import { showSnackbarError } from '../utility/snackbar';
|
||||||
|
|
||||||
let filter = '';
|
let filter = '';
|
||||||
|
|
||||||
@@ -66,12 +67,27 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleNewConfigFile(fileName, content) {
|
||||||
|
if (!(await apiCall('apps/create-config-file', { fileName, content, appFolder: $currentApplication }))) {
|
||||||
|
showSnackbarError('File not created, probably already exists');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createAddMenu() {
|
function createAddMenu() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
text: 'New SQL command',
|
text: 'New SQL command',
|
||||||
onClick: () => handleNewSqlFile('command.sql', 'Create new SQL command', COMMAND_TEMPLATE),
|
onClick: () => handleNewSqlFile('command.sql', 'Create new SQL command', COMMAND_TEMPLATE),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'New virtual references file',
|
||||||
|
onClick: () => handleNewConfigFile('virtual-references.config.json', []),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'New disctionary descriptions file',
|
||||||
|
onClick: () => handleNewConfigFile('dictionary-descriptions.config.json', []),
|
||||||
|
},
|
||||||
|
|
||||||
// { text: 'New query view', onClick: () => handleNewSqlFile('query.sql', 'Create new SQL query', QUERY_TEMPLATE) },
|
// { text: 'New query view', onClick: () => handleNewSqlFile('query.sql', 'Create new SQL query', QUERY_TEMPLATE) },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -387,15 +387,17 @@
|
|||||||
draggingDbGroupTarget = null;
|
draggingDbGroupTarget = null;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FontIcon icon={getDbIcon(tabGroup.tabDbKey)} padRight />
|
<div class="db-name-inner">
|
||||||
{tabGroup.tabDbName}
|
<FontIcon icon={getDbIcon(tabGroup.tabDbKey)} />
|
||||||
|
{tabGroup.tabDbName}
|
||||||
|
</div>
|
||||||
|
|
||||||
<span
|
<div
|
||||||
class="close-button-right tabCloseButton"
|
class="close-button-right tabCloseButton"
|
||||||
on:click={e => closeMultipleTabs(tab => tabGroup.tabs.find(x => x.tabid == tab.tabid))}
|
on:click={e => closeMultipleTabs(tab => tabGroup.tabs.find(x => x.tabid == tab.tabid))}
|
||||||
>
|
>
|
||||||
<FontIcon icon="icon close" />
|
<FontIcon icon="icon close" />
|
||||||
</span>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="db-group">
|
<div class="db-group">
|
||||||
{#each tabGroup.tabs as tab}
|
{#each tabGroup.tabs as tab}
|
||||||
@@ -505,7 +507,10 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.db-name-inner {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
/* .db-name:hover {
|
/* .db-name:hover {
|
||||||
background-color: var(--theme-bg-3);
|
background-color: var(--theme-bg-3);
|
||||||
@@ -541,7 +546,6 @@
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
color: var(--theme-font-3);
|
color: var(--theme-font-3);
|
||||||
float: right;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-button:hover {
|
.close-button:hover {
|
||||||
|
|||||||
10
yarn.lock
10
yarn.lock
@@ -3199,6 +3199,11 @@ dbgate-plugin-tools@^1.0.4, dbgate-plugin-tools@^1.0.7:
|
|||||||
pacote "^11.1.13"
|
pacote "^11.1.13"
|
||||||
rimraf "^3.0.2"
|
rimraf "^3.0.2"
|
||||||
|
|
||||||
|
dbgate-plugin-xml@^4.1.1:
|
||||||
|
version "4.7.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/dbgate-plugin-xml/-/dbgate-plugin-xml-4.7.2.tgz#4a1817a7fc3b1ac5191e45dc7b1016b2f97c3158"
|
||||||
|
integrity sha512-LA52/Wg+blaRp/H+v4ypT+l6kbi4sYsTD/JdPaTbfwErMXhGZew9wtDolvbDjKZZ/zfRig0TDXj9fhLILw2cGw==
|
||||||
|
|
||||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
@@ -3488,6 +3493,11 @@ dot-prop@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-obj "^1.0.0"
|
is-obj "^1.0.0"
|
||||||
|
|
||||||
|
dotenv@^16.0.0:
|
||||||
|
version "16.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.0.tgz#c619001253be89ebb638d027b609c75c26e47411"
|
||||||
|
integrity sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==
|
||||||
|
|
||||||
duplexer2@~0.0.2:
|
duplexer2@~0.0.2:
|
||||||
version "0.0.2"
|
version "0.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"
|
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"
|
||||||
|
|||||||
Reference in New Issue
Block a user