diff --git a/CHANGELOG.md b/CHANGELOG.md
index 980f438d3..2c2387412 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# ChangeLog
+### 4.2.6
+ - Fixed MongoDB import
+ - Configurable thousands separator #136
+ - Using case insensitive text search in postgres
+
### 4.2.5
- FIXED: Fixed crash when using large model on some installations
- FIXED: Postgre SQL CREATE function
diff --git a/README.md b/README.md
index a818c4565..22a4ff147 100644
--- a/README.md
+++ b/README.md
@@ -64,7 +64,7 @@ There are many database managers now, so why DbGate?
* Backend - NodeJs, ExpressJs, socket.io, database connection drivers
* JavaScript + TypeScript
* App - electron
-* Platform independed - will run as web application in single docker container on server, or as application using Electron platform on Linux, Windows and Mac
+* Platform independent - will run as web application in single docker container on server, or as application using Electron platform on Linux, Windows and Mac
## Plugins
Plugins are standard NPM packages published on [npmjs.com](https://www.npmjs.com).
diff --git a/package.json b/package.json
index 7dc596f42..4658893ca 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"private": true,
- "version": "4.2.6-beta.2",
+ "version": "4.2.7",
"name": "dbgate-all",
"workspaces": [
"packages/*",
diff --git a/packages/datalib/src/GridDisplay.ts b/packages/datalib/src/GridDisplay.ts
index 9b5678a82..714da9384 100644
--- a/packages/datalib/src/GridDisplay.ts
+++ b/packages/datalib/src/GridDisplay.ts
@@ -75,6 +75,7 @@ export abstract class GridDisplay {
}
changeSetKeyFields: string[] = null;
sortable = false;
+ groupable = false;
filterable = false;
editable = false;
isLoadedCorrectly = true;
diff --git a/packages/datalib/src/TableGridDisplay.ts b/packages/datalib/src/TableGridDisplay.ts
index 46bc64d5a..044f5aa65 100644
--- a/packages/datalib/src/TableGridDisplay.ts
+++ b/packages/datalib/src/TableGridDisplay.ts
@@ -35,6 +35,7 @@ export class TableGridDisplay extends GridDisplay {
this.columns = this.getDisplayColumns(this.table, []);
this.filterable = true;
this.sortable = true;
+ this.groupable = true;
this.editable = true;
this.supportsReload = true;
this.baseTable = this.table;
diff --git a/packages/datalib/src/ViewGridDisplay.ts b/packages/datalib/src/ViewGridDisplay.ts
index bc785426b..f8d24e756 100644
--- a/packages/datalib/src/ViewGridDisplay.ts
+++ b/packages/datalib/src/ViewGridDisplay.ts
@@ -17,6 +17,7 @@ export class ViewGridDisplay extends GridDisplay {
this.columns = this.getDisplayColumns(view);
this.filterable = true;
this.sortable = true;
+ this.groupable = true;
this.editable = false;
this.supportsReload = true;
}
diff --git a/packages/web/src/appobj/AppObjectCore.svelte b/packages/web/src/appobj/AppObjectCore.svelte
index facb0e1d9..7370635ae 100644
--- a/packages/web/src/appobj/AppObjectCore.svelte
+++ b/packages/web/src/appobj/AppObjectCore.svelte
@@ -38,6 +38,14 @@
}
}
+ function handleMouseUp(e) {
+ if (e.button == 1) {
+ dispatch('middleclick');
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ }
+
function setChecked(value) {
if (!value && isChecked) {
checkedObjectsStore.update(x => x.filter(y => module.extractKey(data) != module.extractKey(y)));
@@ -53,6 +61,7 @@
class:isBold
draggable={true}
on:click={handleClick}
+ on:mouseup={handleMouseUp}
use:contextMenu={disableContextMenu ? null : menu}
on:dragstart={e => {
e.dataTransfer.setData('app_object_drag_data', JSON.stringify(data));
diff --git a/packages/web/src/appobj/ConnectionAppObject.svelte b/packages/web/src/appobj/ConnectionAppObject.svelte
index 1d4f07612..829a8c85e 100644
--- a/packages/web/src/appobj/ConnectionAppObject.svelte
+++ b/packages/web/src/appobj/ConnectionAppObject.svelte
@@ -123,7 +123,7 @@
text: 'Connect',
onClick: handleConnect,
},
- { onClick: handleNewQuery, text: 'New query' },
+ { onClick: handleNewQuery, text: 'New query', isNewQuery: true },
$openedConnections.includes(data._id) &&
data.status && {
text: 'Refresh',
@@ -190,4 +190,9 @@
on:click={handleConnect}
on:click
on:expand
+ on:middleclick={() => {
+ _.flattenDeep(getContextMenu())
+ .find(x => x.isNewQuery)
+ .onClick();
+ }}
/>
diff --git a/packages/web/src/appobj/DatabaseAppObject.svelte b/packages/web/src/appobj/DatabaseAppObject.svelte
index 53a7f97a6..f275c5987 100644
--- a/packages/web/src/appobj/DatabaseAppObject.svelte
+++ b/packages/web/src/appobj/DatabaseAppObject.svelte
@@ -54,7 +54,7 @@
};
return [
- { onClick: handleNewQuery, text: 'New query' },
+ { onClick: handleNewQuery, text: 'New query', isNewQuery: true },
{ onClick: handleImport, text: 'Import' },
{ onClick: handleExport, text: 'Export' },
{ onClick: handleSqlGenerator, text: 'SQL Generator' },
@@ -68,7 +68,7 @@
handleClick()}
+ on:middleclick={() => handleClick(true)}
on:expand
/>
diff --git a/packages/web/src/datagrid/ColumnHeaderControl.svelte b/packages/web/src/datagrid/ColumnHeaderControl.svelte
index e6f0a2a1d..715925ef6 100644
--- a/packages/web/src/datagrid/ColumnHeaderControl.svelte
+++ b/packages/web/src/datagrid/ColumnHeaderControl.svelte
@@ -6,6 +6,7 @@
import ColumnLabel from '../elements/ColumnLabel.svelte';
import { isTypeDateTime } from 'dbgate-tools';
import { openDatabaseObjectDetail } from '../appobj/DatabaseObjectAppObject.svelte';
+ import { copyTextToClipboard } from '../utility/clipboard';
export let column;
export let conid = undefined;
@@ -27,19 +28,20 @@
function getMenu() {
return [
- { onClick: () => setSort('ASC'), text: 'Sort ascending' },
- { onClick: () => setSort('DESC'), text: 'Sort descending' },
+ setSort && { onClick: () => setSort('ASC'), text: 'Sort ascending' },
+ setSort && { onClick: () => setSort('DESC'), text: 'Sort descending' },
+ { onClick: () => copyTextToClipboard(column.columnName), text: 'Copy column name' },
column.foreignKey && [{ divider: true }, { onClick: openReferencedTable, text: column.foreignKey.refTableName }],
- { divider: true },
- { onClick: () => setGrouping('GROUP'), text: 'Group by' },
- { onClick: () => setGrouping('MAX'), text: 'MAX' },
- { onClick: () => setGrouping('MIN'), text: 'MIN' },
- { onClick: () => setGrouping('SUM'), text: 'SUM' },
- { onClick: () => setGrouping('AVG'), text: 'AVG' },
- { onClick: () => setGrouping('COUNT'), text: 'COUNT' },
- { onClick: () => setGrouping('COUNT DISTINCT'), text: 'COUNT DISTINCT' },
+ setGrouping && { divider: true },
+ setGrouping && { onClick: () => setGrouping('GROUP'), text: 'Group by' },
+ setGrouping && { onClick: () => setGrouping('MAX'), text: 'MAX' },
+ setGrouping && { onClick: () => setGrouping('MIN'), text: 'MIN' },
+ setGrouping && { onClick: () => setGrouping('SUM'), text: 'SUM' },
+ setGrouping && { onClick: () => setGrouping('AVG'), text: 'AVG' },
+ setGrouping && { onClick: () => setGrouping('COUNT'), text: 'COUNT' },
+ setGrouping && { onClick: () => setGrouping('COUNT DISTINCT'), text: 'COUNT DISTINCT' },
isTypeDateTime(column.dataType) && [
{ divider: true },
diff --git a/packages/web/src/datagrid/DataGridCell.svelte b/packages/web/src/datagrid/DataGridCell.svelte
index 454dfa4ef..ee7bf99af 100644
--- a/packages/web/src/datagrid/DataGridCell.svelte
+++ b/packages/web/src/datagrid/DataGridCell.svelte
@@ -12,7 +12,8 @@
return value;
}
- const dateTimeRegex = /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d\d\d)?Z?$/;
+ // const dateTimeRegex = /^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d\d\d)?Z?$/;
+ const dateTimeRegex = /^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|()|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))$/;
function formatNumber(value) {
if (value >= 10000 || value <= -10000) {
@@ -25,12 +26,15 @@
return value.toString();
}
+
+ function formatDateTime(testedString) {
+ const m = testedString.match(dateTimeRegex);
+ return `${m[1]}-${m[2]}-${m[3]} ${m[4]}:${m[5]}:${m[6]}`;
+ }