1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-06-05 21:59:22 +02:00

Compare commits

...

39 Commits

Author SHA1 Message Date
4a83ae7e75 Update README.md 2020-07-24 14:05:14 +02:00
60132c94a1 Results table improvements 2020-07-24 13:26:56 +02:00
fdf5bef5ad Delete rows 2020-07-23 19:10:14 +02:00
67f55fbeb9 Merge pull request #17 from EStarium/dependabot/npm_and_yarn/mssql-6.2.1
Bump mssql from 6.2.0 to 6.2.1
2020-07-23 08:55:58 +02:00
dependabot[bot]
fd5a8548c7 Bump mssql from 6.2.0 to 6.2.1
Bumps [mssql](https://github.com/tediousjs/node-mssql) from 6.2.0 to 6.2.1.
- [Release notes](https://github.com/tediousjs/node-mssql/releases)
- [Changelog](https://github.com/tediousjs/node-mssql/blob/master/CHANGELOG.txt)
- [Commits](https://github.com/tediousjs/node-mssql/compare/v6.2.0...v6.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-23 05:45:56 +00:00
425ecf838d Row multi select 2020-07-22 18:30:52 +02:00
1a8a49eceb Merge pull request #15 from EStarium/dependabot/npm_and_yarn/codemirror-5.56.0
Bump codemirror from 5.55.0 to 5.56.0
2020-07-21 10:52:21 +02:00
dependabot[bot]
e9fffcc37e Bump codemirror from 5.55.0 to 5.56.0
Bumps [codemirror](https://github.com/codemirror/CodeMirror) from 5.55.0 to 5.56.0.
- [Release notes](https://github.com/codemirror/CodeMirror/releases)
- [Changelog](https://github.com/codemirror/CodeMirror/blob/master/CHANGELOG.md)
- [Commits](https://github.com/codemirror/CodeMirror/compare/5.55.0...5.56.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-21 05:56:20 +00:00
bba7c4af6f Merge pull request #14 from EStarium/dependabot/npm_and_yarn/electron-devtools-installer-3.1.1
Bump electron-devtools-installer from 3.1.0 to 3.1.1
2020-07-17 08:52:56 +02:00
dependabot[bot]
376d74c7dc Bump electron-devtools-installer from 3.1.0 to 3.1.1
Bumps [electron-devtools-installer](https://github.com/MarshallOfSound/electron-devtools-installer) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/MarshallOfSound/electron-devtools-installer/releases)
- [Changelog](https://github.com/MarshallOfSound/electron-devtools-installer/blob/master/.releaserc.json)
- [Commits](https://github.com/MarshallOfSound/electron-devtools-installer/compare/v3.1.0...v3.1.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-17 05:20:01 +00:00
307a32aff6 Starting implementation context on query Table 2020-07-10 19:51:36 +02:00
d1aaad276b Merge pull request #13 from EStarium/dependabot/npm_and_yarn/pg-8.3.0
Bump pg from 8.2.2 to 8.3.0
2020-07-10 08:57:31 +02:00
dependabot[bot]
b23b4f18b9 Bump pg from 8.2.2 to 8.3.0
Bumps [pg](https://github.com/brianc/node-postgres) from 8.2.2 to 8.3.0.
- [Release notes](https://github.com/brianc/node-postgres/releases)
- [Changelog](https://github.com/brianc/node-postgres/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianc/node-postgres/compare/pg@8.2.2...pg@8.3.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-10 05:36:39 +00:00
334cfa9047 Merge pull request #12 from EStarium/dependabot/npm_and_yarn/lodash-4.17.19
Bump lodash from 4.17.15 to 4.17.19
2020-07-09 08:40:12 +02:00
dependabot[bot]
2f6d16c730 Bump lodash from 4.17.15 to 4.17.19
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-09 05:34:34 +00:00
b8e09e7003 Merge pull request #10 from EStarium/dependabot/npm_and_yarn/pg-8.2.2
Bump pg from 8.2.1 to 8.2.2
2020-07-08 09:02:13 +02:00
9caf424331 Merge pull request #11 from EStarium/dependabot/npm_and_yarn/sass-loader-9.0.2
Bump sass-loader from 9.0.1 to 9.0.2
2020-07-08 09:01:59 +02:00
dependabot[bot]
9e5e545478 Bump sass-loader from 9.0.1 to 9.0.2
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 9.0.1 to 9.0.2.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v9.0.1...v9.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-08 05:22:00 +00:00
dependabot[bot]
c9ab731bb4 Bump pg from 8.2.1 to 8.2.2
Bumps [pg](https://github.com/brianc/node-postgres) from 8.2.1 to 8.2.2.
- [Release notes](https://github.com/brianc/node-postgres/releases)
- [Changelog](https://github.com/brianc/node-postgres/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianc/node-postgres/compare/pg@8.2.1...pg@8.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-08 05:18:40 +00:00
57832c43aa Merge pull request #8 from EStarium/dependabot/npm_and_yarn/vuedraggable-2.24.0
Bump vuedraggable from 2.23.2 to 2.24.0
2020-07-07 08:53:49 +02:00
dependabot[bot]
184363369b Bump vuedraggable from 2.23.2 to 2.24.0
Bumps [vuedraggable](https://github.com/SortableJS/Vue.Draggable) from 2.23.2 to 2.24.0.
- [Release notes](https://github.com/SortableJS/Vue.Draggable/releases)
- [Commits](https://github.com/SortableJS/Vue.Draggable/compare/v2.23.2...v2.24.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-07 05:38:42 +00:00
b221dd12ff Merge pull request #7 from EStarium/dependabot/npm_and_yarn/sass-loader-9.0.1
Bump sass-loader from 9.0.0 to 9.0.1
2020-07-06 08:56:30 +02:00
dependabot[bot]
1324464aa3 Bump sass-loader from 9.0.0 to 9.0.1
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 9.0.0 to 9.0.1.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v9.0.0...v9.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-06 05:40:58 +00:00
187b4f50f9 Datetime fields precision 2020-07-05 16:06:56 +02:00
262a476f50 Merge pull request #6 from EStarium/dependabot/npm_and_yarn/sass-loader-9.0.0
Bump sass-loader from 8.0.2 to 9.0.0
2020-07-03 08:51:07 +02:00
dependabot[bot]
f00c2600e5 Bump sass-loader from 8.0.2 to 9.0.0
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 8.0.2 to 9.0.0.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v8.0.2...v9.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-03 06:17:52 +00:00
75a7db9c05 Merge branch 'master' of https://github.com/EStarium/antares 2020-07-02 19:17:28 +02:00
50cd852d01 Editable datetime fields 2020-07-02 19:17:25 +02:00
bb8cfa533b Merge pull request #5 from EStarium/dependabot/npm_and_yarn/spectre.css-0.5.9
Bump spectre.css from 0.5.8 to 0.5.9
2020-07-02 08:59:48 +02:00
dependabot[bot]
1ddc8b5dca Bump spectre.css from 0.5.8 to 0.5.9
Bumps [spectre.css](https://github.com/picturepan2/spectre) from 0.5.8 to 0.5.9.
- [Release notes](https://github.com/picturepan2/spectre/releases)
- [Changelog](https://github.com/picturepan2/spectre/blob/master/CHANGELOG.md)
- [Commits](https://github.com/picturepan2/spectre/compare/v0.5.8...v0.5.9)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-02 06:13:17 +00:00
8a4c628128 Minor fix 2020-06-30 18:20:07 +02:00
0076f146fa Merge branch 'master' of https://github.com/EStarium/antares 2020-06-30 18:15:01 +02:00
098d12f462 Update packages 2020-06-30 18:14:57 +02:00
b619285d94 Merge pull request #3 from EStarium/dependabot/npm_and_yarn/vuex-3.5.1
Bump vuex from 3.4.0 to 3.5.1
2020-06-30 09:02:46 +02:00
dependabot[bot]
a5fed1bb64 Bump vuex from 3.4.0 to 3.5.1
Bumps [vuex](https://github.com/vuejs/vuex) from 3.4.0 to 3.5.1.
- [Release notes](https://github.com/vuejs/vuex/releases)
- [Changelog](https://github.com/vuejs/vuex/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vuex/compare/v3.4.0...v3.5.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-06-30 06:13:53 +00:00
55ec03bd8e Merge pull request #2 from EStarium/dependabot/npm_and_yarn/electron-9.0.5
Bump electron from 8.3.4 to 9.0.5
2020-06-29 09:09:19 +02:00
dependabot[bot]
d1977fbd75 Bump electron from 8.3.4 to 9.0.5
Bumps [electron](https://github.com/electron/electron) from 8.3.4 to 9.0.5.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/master/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v8.3.4...v9.0.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-06-29 07:07:31 +00:00
3c20c0733c Update dependabot.yml 2020-06-29 09:05:39 +02:00
1d4a353d5c Create dependabot.yml 2020-06-29 09:04:39 +02:00
25 changed files with 734 additions and 392 deletions

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"

View File

@@ -2,6 +2,28 @@
<img width="800" src="https://raw.githubusercontent.com/Fabio286/antares/master/docs/screen-alpha.png">
</p>
# Antares
# Antares SQL Client
🚧 Work in progress! 🚧
Antares is an SQL client based on Electron.js and Vue.js that aims to become a useful tool, especially for developers.
My target is to support as many databases as possible, and all major operating systems, including the ARM versions.
At the moment this application is in a development state, it lacks many features, and is'nt ready as a main SQL client. However i'm actively working on it, hoping to provide all all minimum features as soon as possible.
If you are curious to try this early state of Antares you can download and install the [latest release](https://github.com/EStarium/antares/releases), and stay tuned for updates. At moment is only available for Windows.
## Currently supported
### Databases
- [x] MySQL/MariaDB
- [ ] PostrgreSQL
- [ ] MSSQL
- [ ] SQLite
- [ ] OracleDB
- [ ] More...
### Operating Systems
- [x] Windows
- [ ] Linux
- [ ] MacOS

167
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "antares",
"version": "0.0.1-alpha",
"version": "0.0.2-alpha",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1146,6 +1146,12 @@
"integrity": "sha512-q95SP4FdkmF0CwO0F2q0H6ZgudsApaY/yCtAQNRn1gduef5fGpyEphzy0YCq/N0UFvDSnLg5V8jFK/YGXlDiCw==",
"dev": true
},
"@types/json-schema": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
"dev": true
},
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -1164,9 +1170,9 @@
"integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg=="
},
"@types/readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-oAbOdOKhx5nu1+pBPiwEHh6gqA3ojgwwNwNIjNd67TqwEjvVePqe21mnYc6RrnGZ8aVPFBe6sci3cU2pKKwuug==",
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.9.tgz",
"integrity": "sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw==",
"requires": {
"@types/node": "*",
"safe-buffer": "*"
@@ -3020,17 +3026,6 @@
}
}
},
"clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
"integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
"dev": true,
"requires": {
"is-plain-object": "^2.0.4",
"kind-of": "^6.0.2",
"shallow-clone": "^3.0.0"
}
},
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
@@ -3047,9 +3042,9 @@
"dev": true
},
"codemirror": {
"version": "5.55.0",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.55.0.tgz",
"integrity": "sha512-TumikSANlwiGkdF/Blnu/rqovZ0Y3Jh8yy9TqrPbSM0xxSucq3RgnpVDQ+mD9q6JERJEIT2FMuF/fBGfkhIR/g=="
"version": "5.56.0",
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.56.0.tgz",
"integrity": "sha512-MfKVmYgifXjQpLSgpETuih7A7WTTIsxvKfSLGseTY5+qt0E1UD1wblZGM6WLenORo8sgmf+3X+WTe2WF7mufyw=="
},
"collection-visit": {
"version": "1.0.0",
@@ -4034,9 +4029,9 @@
}
},
"electron": {
"version": "8.3.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-8.3.4.tgz",
"integrity": "sha512-aSYXBV0PxYHmXhjGFpR0x38zbO7UTDex2JrT5tcqJpUZTY+sKdfo9PA1TpiyrHNjA5+Q8UseRUsydRedOTeZQA==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-8.4.0.tgz",
"integrity": "sha512-SpgyccM5rjDJSGcpQjiviUBT44fZlSyhcjy8RpKSnAad+co4xY1vYj6T25U1CfSk0PH/dhvcp63P2sdXHCwq/Q==",
"dev": true,
"requires": {
"@electron/get": "^1.0.1",
@@ -4116,14 +4111,14 @@
}
},
"electron-devtools-installer": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.1.0.tgz",
"integrity": "sha512-qZd1Aoya8YOK6QauNX92V5qyKGtb4lbs238bP+qtMBkXts24xJ/1PtOVBPvdg5w3Ts9L5o6I9sDErKuzHeJFDA==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.1.1.tgz",
"integrity": "sha512-g2D4J6APbpsiIcnLkFMyKZ6bOpEJ0Ltcc2m66F7oKUymyGAt628OWeU9nRZoh1cNmUs/a6Cls2UfOmsZtE496Q==",
"dev": true,
"requires": {
"rimraf": "^3.0.2",
"semver": "^7.2.1",
"unzip-crx": "^0.2.0"
"unzip-crx-3": "^0.2.0"
},
"dependencies": {
"rimraf": {
@@ -7818,6 +7813,12 @@
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
"dev": true
},
"klona": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/klona/-/klona-1.1.2.tgz",
"integrity": "sha512-xf88rTeHiXk+XE2Vhi6yj8Wm3gMZrygGdKjJqN8HkV+PwF/t50/LdAKHoHpPcxFAlmQszTZ1CugrK25S7qDRLA==",
"dev": true
},
"latest-version": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
@@ -7939,9 +7940,9 @@
}
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
"version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
},
"lodash.isequal": {
"version": "4.5.0",
@@ -8500,9 +8501,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"mssql": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/mssql/-/mssql-6.2.0.tgz",
"integrity": "sha512-C1WcvpiyGGoNyA+rNae/87V4O47S1P75zqmITutxzamocccY8BsZA+cljXJvpnYbbGlmMB5eoSaVUSqR9NyLCg==",
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/mssql/-/mssql-6.2.1.tgz",
"integrity": "sha512-erINJ9EUPvPuWXifZfhum0CVEVrdvnFYlpgU6WKkQW69W4W7DWqJS2FHdedHnuJWlJ8x1WW1NcD8GFfF15O2aA==",
"requires": {
"debug": "^4",
"tarn": "^1.1.5",
@@ -9419,25 +9420,20 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"pg": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.2.1.tgz",
"integrity": "sha512-DKzffhpkWRr9jx7vKxA+ur79KG+SKw+PdjMb1IRhMiKI9zqYUGczwFprqy+5Veh/DCcFs1Y6V8lRLN5I1DlleQ==",
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.3.0.tgz",
"integrity": "sha512-jQPKWHWxbI09s/Z9aUvoTbvGgoj98AU7FDCcQ7kdejupn/TcNpx56v2gaOTzXkzOajmOEJEdi9eTh9cA2RVAjQ==",
"requires": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.2.3",
"pg-connection-string": "^2.3.0",
"pg-pool": "^3.2.1",
"pg-protocol": "^1.2.4",
"pg-protocol": "^1.2.5",
"pg-types": "^2.1.0",
"pgpass": "1.x",
"semver": "4.3.2"
},
"dependencies": {
"pg-connection-string": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.2.3.tgz",
"integrity": "sha512-I/KCSQGmOrZx6sMHXkOs2MjddrYcqpza3Dtsy0AjIgBr/bZiPJRK9WhABXN1Uy1UDazRbi9gZEzO2sAhL5EqiQ=="
},
"semver": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
@@ -9445,6 +9441,11 @@
}
}
},
"pg-connection-string": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.3.0.tgz",
"integrity": "sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w=="
},
"pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
@@ -9456,9 +9457,9 @@
"integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA=="
},
"pg-protocol": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.4.tgz",
"integrity": "sha512-/8L/G+vW/VhWjTGXpGh8XVkXOFx1ZDY+Yuz//Ab8CfjInzFkreI+fDG3WjCeSra7fIZwAFxzbGptNbm8xSXenw=="
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.5.tgz",
"integrity": "sha512-1uYCckkuTfzz/FCefvavRywkowa6M5FohNMF5OjKrqo9PSR8gYc8poVmwwYQaBxhmQdBjhtP514eXy9/Us2xKg=="
},
"pg-types": {
"version": "2.2.0",
@@ -10811,23 +10812,39 @@
}
},
"sass-loader": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
"integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==",
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-9.0.2.tgz",
"integrity": "sha512-nphcum3jNI442njnrZ5wJgSNX5lfEOHOKHCLf+PrTIaleploKqAMUuT9CVKjf+lyi6c2MCGPHh1vb9nGsjnZJA==",
"dev": true,
"requires": {
"clone-deep": "^4.0.1",
"loader-utils": "^1.2.3",
"klona": "^1.1.1",
"loader-utils": "^2.0.0",
"neo-async": "^2.6.1",
"schema-utils": "^2.6.1",
"semver": "^6.3.0"
"schema-utils": "^2.7.0",
"semver": "^7.3.2"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
"loader-utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"schema-utils": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.4",
"ajv": "^6.12.2",
"ajv-keywords": "^3.4.1"
}
}
}
},
@@ -11140,15 +11157,6 @@
"safe-buffer": "^5.0.1"
}
},
"shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
"integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
"dev": true,
"requires": {
"kind-of": "^6.0.2"
}
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -11521,9 +11529,9 @@
}
},
"spectre.css": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/spectre.css/-/spectre.css-0.5.8.tgz",
"integrity": "sha512-3N4WocWY+Dl6b3e5v3nsZYyp+VSDcBfGDzyyHw/H78ie9BoAhHkxmrhLxo9y8RadxYzVrPjfPdlev3hXEUzR2w=="
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/spectre.css/-/spectre.css-0.5.9.tgz",
"integrity": "sha512-9jUqwZmCnvflrxFGcK+ize43TvjwDjqMwZPVubEtSIHzvinH0TBUESm1LcOJx3Ur7bdPaeOHQIjOqBl1Y5kLFw=="
},
"split": {
"version": "1.0.1",
@@ -12460,10 +12468,10 @@
}
}
},
"unzip-crx": {
"unzip-crx-3": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/unzip-crx/-/unzip-crx-0.2.0.tgz",
"integrity": "sha1-TAuqi9rHViVnVL7KeEPBPXuFjBg=",
"resolved": "https://registry.npmjs.org/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz",
"integrity": "sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==",
"dev": true,
"requires": {
"jszip": "^3.1.0",
@@ -12793,18 +12801,23 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
"vue-the-mask": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz",
"integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ=="
},
"vuedraggable": {
"version": "2.23.2",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.23.2.tgz",
"integrity": "sha512-PgHCjUpxEAEZJq36ys49HfQmXglattf/7ofOzUrW2/rRdG7tu6fK84ir14t1jYv4kdXewTEa2ieKEAhhEMdwkQ==",
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.0.tgz",
"integrity": "sha512-IlslPpc+iZ2zPNSJbydFZIDrE+don5u+Nc/bjT2YaF+Azidc+wxxJKfKT0NwE68AKk0syb0YbZneAcnynqREZQ==",
"requires": {
"sortablejs": "^1.10.1"
}
},
"vuex": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.4.0.tgz",
"integrity": "sha512-ajtqwEW/QhnrBZQsZxCLHThZZaa+Db45c92Asf46ZDXu6uHXgbfVuBaJ4gzD2r4UX0oMJHstFwd2r2HM4l8umg=="
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
"integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw=="
},
"vuex-persist": {
"version": "2.2.0",

View File

@@ -10,7 +10,7 @@
"compile": "electron-webpack",
"dist": "cross-env NODE_ENV=production npm run compile && electron-builder",
"dist:dir": "cross-env NODE_ENV=production npm run dist --dir -c.compression=store -c.mac.identity=null",
"publish": "cross-env NODE_ENV=production npm run dist -p always"
"publish": "electron-builder -p always"
},
"author": "Fabio Di Stasio <fabio286@gmail.com>",
"build": {
@@ -29,29 +29,30 @@
}
},
"dependencies": {
"codemirror": "^5.55.0",
"codemirror": "^5.56.0",
"electron-log": "^4.2.2",
"electron-updater": "^4.3.1",
"lodash": "^4.17.15",
"lodash": "^4.17.19",
"material-design-icons": "^3.0.1",
"moment": "^2.27.0",
"mssql": "^6.2.0",
"mssql": "^6.2.1",
"mysql": "^2.18.1",
"pg": "^8.2.1",
"pg": "^8.3.0",
"source-map-support": "^0.5.16",
"spectre.css": "^0.5.8",
"spectre.css": "^0.5.9",
"vue-click-outside": "^1.1.0",
"vue-i18n": "^8.18.2",
"vuedraggable": "^2.23.2",
"vuex": "^3.4.0",
"vue-the-mask": "^0.11.1",
"vuedraggable": "^2.24.0",
"vuex": "^3.5.1",
"vuex-persist": "^2.2.0"
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"cross-env": "^7.0.2",
"electron": "^8.3.4",
"electron": "^8.4.0",
"electron-builder": "^22.7.0",
"electron-devtools-installer": "^3.1.0",
"electron-devtools-installer": "^3.1.1",
"electron-webpack": "^2.8.2",
"electron-webpack-vue": "^2.4.0",
"eslint": "^6.8.0",
@@ -62,7 +63,7 @@
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.2.2",
"node-sass": "^4.14.1",
"sass-loader": "^8.0.2",
"sass-loader": "^9.0.2",
"vue": "^2.6.11",
"webpack": "^4.43.0"
}

View File

@@ -1,11 +1,11 @@
import connection from './connection';
import structure from './structure';
import tables from './tables';
import updates from './updates';
const connections = {};
export default () => {
connection(connections);
structure(connections);
tables(connections);
updates();
};

View File

@@ -1,13 +1,13 @@
import { ipcMain } from 'electron';
import InformationSchema from '../models/InformationSchema';
import Generic from '../models/Generic';
import Tables from '../models/Tables';
// TODO: remap objects based on client
export default (connections) => {
ipcMain.handle('getTableColumns', async (event, { uid, schema, table }) => {
try {
const result = await InformationSchema.getTableColumns(connections[uid], schema, table);
const result = await InformationSchema.getTableColumns(connections[uid], schema, table);// TODO: uniform column properties
return { status: 'success', response: result };
}
catch (err) {
@@ -17,7 +17,7 @@ export default (connections) => {
ipcMain.handle('getTableData', async (event, { uid, schema, table }) => {
try {
const result = await Generic.getTableData(connections[uid], schema, table);
const result = await Tables.getTableData(connections[uid], schema, table);
return { status: 'success', response: result };
}
catch (err) {
@@ -27,7 +27,17 @@ export default (connections) => {
ipcMain.handle('updateTableCell', async (event, params) => {
try {
const result = await Generic.updateTableCell(connections[params.uid], params);
const result = await Tables.updateTableCell(connections[params.uid], params);
return { status: 'success', response: result };
}
catch (err) {
return { status: 'error', response: err.toString() };
}
});
ipcMain.handle('deleteTableRows', async (event, params) => {
try {
const result = await Tables.deleteTableRows(connections[params.uid], params);
return { status: 'success', response: result };
}
catch (err) {

View File

@@ -32,7 +32,7 @@ export class AntaresConnector {
join: [],
update: [],
insert: [],
delete: []
delete: false
};
this._query = Object.assign({}, this._queryDefaults);
}
@@ -107,6 +107,12 @@ export class AntaresConnector {
return this;
}
delete (table) {
this._query.delete = true;
this.from(table);
return this;
}
where (...args) {
this._query.where = [...this._query.where, ...args];
return this;
@@ -145,6 +151,11 @@ export class AntaresConnector {
return this.raw(sql);
}
/**
* @param {String | Array} args field = value
* @returns
* @memberof AntaresConnector
*/
update (...args) {
this._query.update = [...this._query.update, ...args];
return this;
@@ -176,7 +187,7 @@ export class AntaresConnector {
// FROM
let fromRaw = '';
if (!this._query.update.length)
if (!this._query.update.length && !!this._query.from)
fromRaw = 'FROM';
switch (this._client) {
@@ -217,7 +228,7 @@ export class AntaresConnector {
break;
}
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}`;
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}`;
}
/**

View File

@@ -11,22 +11,4 @@ export default class {
}
return connection.raw(query);
}
static async getTableData (connection, schema, table) {
return connection
.select('*')
.schema(schema)
.from(table)
.limit(1000)
.run();
}
static async updateTableCell (connection, params) { // TODO: Handle different field types
return connection
.update({ [params.field]: `= "${params.content}"` })
.schema(params.schema)
.from(params.table)
.where({ [params.primary]: `= ${params.id}` })
.run();
}
}

28
src/main/models/Tables.js Normal file
View File

@@ -0,0 +1,28 @@
'use strict';
export default class {
static async getTableData (connection, schema, table) {
return connection
.select('*')
.schema(schema)
.from(table)
.limit(1000)
.run();
}
static async updateTableCell (connection, params) { // TODO: Handle different field types
return connection
.update({ [params.field]: `= "${params.content}"` })
.schema(params.schema)
.from(params.table)
.where({ [params.primary]: `= ${params.id}` })
.run();
}
static async deleteTableRows (connection, params) {
return connection
.schema(params.schema)
.delete(params.table)
.where({ [params.primary]: `IN (${params.rows.join(',')})` })
.run();
}
}

View File

@@ -41,6 +41,8 @@ export default {
.context{
display: flex;
position: absolute;
color: $body-font-color;
font-size: 16px;
z-index: 400;
justify-content: center;
align-items: center;

View File

@@ -152,9 +152,14 @@ export default {
border-left: none;
border-bottom-width: 2px;
border-color: $bg-color-light;
padding: .1rem .4rem;
padding: 0;
font-weight: 700;
font-size: .7rem;
> div {
padding: .1rem .4rem;
min-width: -webkit-fill-available;
}
}
.td{

View File

@@ -35,6 +35,7 @@
:results="results"
:fields="resultsFields"
@updateField="updateField"
@deleteSelected="deleteSelected"
/>
</div>
</div>
@@ -42,10 +43,11 @@
<script>
import Connection from '@/ipc-api/Connection';
import Structure from '@/ipc-api/Structure';
import Tables from '@/ipc-api/Tables';
import QueryEditor from '@/components/QueryEditor';
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
import { mapGetters, mapActions } from 'vuex';
import tableTabs from '@/mixins/tableTabs';
export default {
name: 'WorkspaceQueryTab',
@@ -53,6 +55,7 @@ export default {
QueryEditor,
WorkspaceQueryTable
},
mixins: [tableTabs],
props: {
connection: Object
},
@@ -77,7 +80,8 @@ export default {
return {
name: field.COLUMN_NAME,
key: field.COLUMN_KEY.toLowerCase(),
type: field.DATA_TYPE
type: field.DATA_TYPE,
precision: field.DATETIME_PRECISION
};
}).filter(field => {
if (this.results.fields) {
@@ -128,7 +132,7 @@ export default {
table: this.table
};
const { status, response } = await Structure.getTableColumns(params);
const { status, response } = await Tables.getTableColumns(params);
if (status === 'success')
this.fields = response.rows;
else
@@ -139,25 +143,6 @@ export default {
}
this.isQuering = false;
},
async updateField (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.workspace.breadcrumbs.table,
...payload
};
try {
const { status, response } = await Structure.updateTableCell(params);
if (status === 'success')
this.$refs.queryTable.applyUpdate(payload);
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
}
}
};

View File

@@ -1,65 +1,83 @@
<template>
<BaseVirtualScroll
v-if="results.rows"
ref="resultTable"
:items="localResults"
:item-height="25"
class="vscroll"
:style="{'height': resultsSize+'px'}"
>
<template slot-scope="{ items }">
<div class="table table-hover">
<div class="thead">
<div class="tr">
<div
v-for="field in fields"
:key="field.name"
class="th"
>
<div class="table-column-title">
<i
v-if="field.key"
class="material-icons column-key c-help"
:class="`key-${field.key}`"
:title="keyName(field.key)"
>vpn_key</i>
<span>{{ field.name }}</span>
<div>
<TableContext
v-if="isContext"
:context-event="contextEvent"
:selected-rows="selectedRows"
@deleteSelected="deleteSelected"
@closeContext="isContext = false"
/>
<BaseVirtualScroll
v-if="results.rows"
ref="resultTable"
:items="sortedResults"
:item-height="25"
class="vscroll"
:style="{'height': resultsSize+'px'}"
>
<template slot-scope="{ items }">
<div class="table table-hover">
<div class="thead">
<div class="tr">
<div
v-for="field in fields"
:key="field.name"
class="th c-hand"
>
<div ref="columnResize" class="column-resizable">
<div class="table-column-title" @click="sort(field.name)">
<i
v-if="field.key"
class="material-icons column-key c-help"
:class="`key-${field.key}`"
:title="keyName(field.key)"
>vpn_key</i>
<span>{{ field.name }}</span>
<i v-if="currentSort === field.name" class="material-icons sort-icon">{{ currentSortDir === 'asc' ? 'arrow_upward':'arrow_downward' }}</i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tbody">
<div
v-for="row in items"
:key="row._id"
class="tr"
>
<WorkspaceQueryTableCell
v-for="(col, cKey) in row"
:key="cKey"
:content="col"
:field="cKey"
:type="fieldType(cKey)"
@updateField="updateField($event, row[primaryField.name])"
/>
<div class="tbody">
<div
v-for="row in items"
:key="row._id"
class="tr"
:class="{'selected': selectedRows.includes(row._id)}"
@click="selectRow($event, row._id)"
>
<WorkspaceQueryTableCell
v-for="(col, cKey) in row"
:key="cKey"
:content="col"
:field="cKey"
:precision="fieldPrecision(cKey)"
:type="fieldType(cKey)"
@updateField="updateField($event, row[primaryField.name])"
@contextmenu="contextMenu($event, {id: row._id, field: cKey})"
/>
</div>
</div>
</div>
</div>
</template>
</BaseVirtualScroll>
</template>
</BaseVirtualScroll>
</div>
</template>
<script>
import { uidGen } from 'common/libs/utilities';
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
import WorkspaceQueryTableCell from '@/components/WorkspaceQueryTableCell';
import TableContext from '@/components/WorkspaceQueryTableContext';
import { mapActions } from 'vuex';
export default {
name: 'WorkspaceQueryTable',
components: {
BaseVirtualScroll,
WorkspaceQueryTableCell
WorkspaceQueryTableCell,
TableContext
},
props: {
results: Object,
@@ -68,16 +86,38 @@ export default {
data () {
return {
resultsSize: 1000,
localResults: []
localResults: [],
isContext: false,
contextEvent: null,
selectedCell: null,
selectedRows: [],
currentSort: '',
currentSortDir: 'asc'
};
},
computed: {
primaryField () {
return this.fields.filter(field => field.key === 'pri')[0] || false;
},
sortedResults () {
if (this.currentSort) {
return [...this.localResults].sort((a, b) => {
let modifier = 1;
const valA = typeof a[this.currentSort] === 'string' ? a[this.currentSort].toLowerCase() : a[this.currentSort];
const valB = typeof b[this.currentSort] === 'string' ? b[this.currentSort].toLowerCase() : b[this.currentSort];
if (this.currentSortDir === 'desc') modifier = -1;
if (valA < valB) return -1 * modifier;
if (valA > valB) return 1 * modifier;
return 0;
});
}
else
return this.localResults;
}
},
watch: {
results () {
this.resetSort();
this.localResults = this.results.rows ? this.results.rows.map(item => {
return { ...item, _id: uidGen() };
}) : [];
@@ -85,7 +125,7 @@ export default {
},
updated () {
if (this.$refs.resultTable)
this.resizeResults();
this.refreshScroller();
},
mounted () {
window.addEventListener('resize', this.resizeResults);
@@ -105,6 +145,14 @@ export default {
return type;
},
fieldPrecision (cKey) {
let length = 0;
const field = this.fields.filter(field => field.name === cKey)[0];
if (field)
length = field.precision;
return length;
},
keyName (key) {
switch (key) {
case 'pri':
@@ -117,7 +165,7 @@ export default {
return 'UNKNOWN ' + key;
}
},
resizeResults (e) {
resizeResults () {
if (this.$refs.resultTable) {
const el = this.$refs.resultTable.$el;
const footer = document.getElementById('footer');
@@ -126,20 +174,36 @@ export default {
const size = window.innerHeight - el.getBoundingClientRect().top - footer.offsetHeight;
this.resultsSize = size;
}
this.$refs.resultTable.updateWindow();
}
},
updateField (event, id) {
refreshScroller () {
this.resizeResults();
},
updateField (payload, id) {
if (!this.primaryField)
this.addNotification({ status: 'warning', message: this.$t('message.unableEditFieldWithoutPrimary') });
else {
const params = {
primary: this.primaryField.name,
id,
...event
...payload
};
this.$emit('updateField', params);
}
},
deleteSelected () {
if (!this.primaryField)
this.addNotification({ status: 'warning', message: this.$t('message.unableEditFieldWithoutPrimary') });
else {
const rowIDs = this.localResults.filter(row => this.selectedRows.includes(row._id)).map(row => row[this.primaryField.name]);
const params = {
primary: this.primaryField.name,
rows: rowIDs
};
this.$emit('deleteSelected', params);
}
},
applyUpdate (params) {
const { primary, id, field, content } = params;
this.localResults = this.localResults.map(row => {
@@ -148,6 +212,56 @@ export default {
return row;
});
},
selectRow (event, row) {
if (event.ctrlKey) {
if (this.selectedRows.includes(row))
this.selectedRows = this.selectedRows.filter(el => el !== row);
else
this.selectedRows.push(row);
}
else if (event.shiftKey) {
if (!this.selectedRows.length)
this.selectedRows.push(row);
else {
const lastID = this.selectedRows.slice(-1)[0];
const lastIndex = this.localResults.findIndex(el => el._id === lastID);
const clickedIndex = this.localResults.findIndex(el => el._id === row);
if (lastIndex > clickedIndex) {
for (let i = clickedIndex; i < lastIndex; i++)
this.selectedRows.push(this.localResults[i]._id);
}
else if (lastIndex < clickedIndex) {
for (let i = clickedIndex; i > lastIndex; i--)
this.selectedRows.push(this.localResults[i]._id);
}
}
}
else
this.selectedRows = [row];
},
contextMenu (event, cell) {
this.selectedCell = cell;
if (!this.selectedRows.includes(cell.id))
this.selectedRows = [cell.id];
this.contextEvent = event;
this.isContext = true;
},
sort (field) {
if (field === this.currentSort) {
if (this.currentSortDir === 'asc')
this.currentSortDir = 'desc';
else
this.resetSort();
}
else {
this.currentSortDir = 'asc';
this.currentSort = field;
}
},
resetSort () {
this.currentSort = '';
this.currentSortDir = 'asc';
}
}
};
@@ -160,11 +274,25 @@ export default {
overflow-anchor: none;
}
.column-resizable{
&:hover,
&:active{
resize: horizontal;
overflow: hidden;
}
}
.table-column-title{
display: flex;
align-items: center;
}
.sort-icon{
font-size: .7rem;
line-height: 1;
margin-left: .2rem;
}
.column-key{
transform: rotate(90deg);
font-size: .7rem;

View File

@@ -5,22 +5,35 @@
class="td"
:class="`type-${type} p-0`"
tabindex="0"
@contextmenu.prevent="$emit('contextmenu', $event)"
>
<span
v-if="!isEditing"
class="cell-content px-2"
:class="isNull(content)"
@dblclick="editON"
>{{ content | typeFormat(type) }}</span>
<input
v-else
ref="editField"
v-model="localContent"
:type="inputType"
autofocus
class="editable-field px-2"
@blur="editOFF"
>
>{{ content | typeFormat(type, precision) | cutText }}</span>
<template v-else>
<input
v-if="inputProps.mask"
ref="editField"
v-model="localContent"
v-mask="inputProps.mask"
:type="inputProps.type"
autofocus
class="editable-field px-2"
@blur="editOFF"
>
<input
v-else
ref="editField"
v-model="localContent"
:type="inputProps.type"
autofocus
class="editable-field px-2"
@blur="editOFF"
>
</template>
</div>
</template>
@@ -28,11 +41,16 @@
import moment from 'moment';
import { mimeFromHex, formatBytes } from 'common/libs/utilities';
import hexToBinary from 'common/libs/hexToBinary';
import { mask } from 'vue-the-mask';
export default {
name: 'WorkspaceQueryTableCell',
filters: {
typeFormat (val, type) {
cutText (val) {
if (typeof val !== 'string') return val;
return val.length > 128 ? `${val.substring(0, 128)}[...]` : val;
},
typeFormat (val, type, precision) {
if (!val) return val;
switch (type) {
@@ -40,12 +58,18 @@ export default {
case 'varchar':
case 'text':
case 'mediumtext':
return val.substring(0, 128);
case 'date':
return moment(val).format('YYYY-MM-DD');
return val;
case 'date': {
return moment(val).isValid() ? moment(val).format('YYYY-MM-DD') : val;
}
case 'datetime':
case 'timestamp':
return moment(val).format('YYYY-MM-DD HH:mm:ss.SSS');
case 'timestamp': {
let datePrecision = '';
for (let i = 0; i < precision; i++)
datePrecision += i === 0 ? '.S' : 'S';
return moment(val).isValid() ? moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`) : val;
}
case 'blob':
case 'mediumblob':
case 'longblob': {
@@ -64,9 +88,13 @@ export default {
}
}
},
directives: {
mask
},
props: {
type: String,
field: String,
precision: [Number, null],
content: [String, Number, Object, Date, Uint8Array]
},
data () {
@@ -76,28 +104,32 @@ export default {
};
},
computed: {
inputType () {
inputProps () {
switch (this.type) {
case 'char':
case 'varchar':
case 'text':
case 'mediumtext':
return 'text';
return { type: 'text', mask: false };
case 'int':
case 'tinyint':
case 'smallint':
case 'mediumint':
return 'number';
return { type: 'number', mask: false };
case 'date':
return 'date';
return { type: 'text', mask: '####-##-##' };
case 'datetime':
case 'timestamp':
return 'datetime-local';
// TODO: file uploader/viewer or bit field
case 'timestamp': {
let datetimeMask = '####-##-## ##:##:##';
for (let i = 0; i < this.precision; i++)
datetimeMask += i === 0 ? '.#' : '#';
return { type: 'text', mask: datetimeMask };
}
case 'blob':
case 'mediumblob':
case 'longblob':
case 'bit':
return { type: 'file', mask: false };
default:
return 'hidden';
}
@@ -108,7 +140,7 @@ export default {
return value === null ? ' is-null' : '';
},
editON () {
if (!['number', 'text'].includes(this.inputType)) return;// TODO: remove temporary block
if (['file'].includes(this.inputProps.type)) return;// TODO: remove temporary file block
this.$nextTick(() => {
this.$refs.cell.blur();
@@ -120,7 +152,7 @@ export default {
},
editOFF () {
this.isEditing = false;
if (this.localContent === this.content) return;
if (this.localContent === this.$options.filters.typeFormat(this.content, this.type)) return;
const { field, type, localContent: content } = this;
this.$emit('updateField', { field, type, content });
@@ -135,14 +167,12 @@ export default {
border: none;
line-height: 1;
width: 100%;
max-width: 200px;
}
.cell-content{
display: block;
min-height: .8rem;
text-overflow: ellipsis;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
}

View File

@@ -0,0 +1,73 @@
<template>
<BaseContextMenu
:context-event="contextEvent"
@closeContext="closeContext"
>
<div class="context-element" @click="showConfirmModal">
<i class="material-icons md-18 text-light pr-1">delete</i> {{ $tc('message.deleteRows', selectedRows.length) }}
</div>
<ConfirmModal
v-if="isConfirmModal"
@confirm="deleteRows()"
@hide="hideConfirmModal"
>
<template :slot="'header'">
{{ $tc('message.deleteRows', selectedRows.length) }}
</template>
<div :slot="'body'">
<div class="mb-2">
{{ $tc('message.confirmToDeleteRows', selectedRows.length) }}
</div>
</div>
</ConfirmModal>
</BaseContextMenu>
</template>
<script>
import { mapActions } from 'vuex';
import BaseContextMenu from '@/components/BaseContextMenu';
import ConfirmModal from '@/components/BaseConfirmModal';
export default {
name: 'WorkspaceQueryTableContext',
components: {
BaseContextMenu,
ConfirmModal
},
props: {
contextEvent: MouseEvent,
selectedRows: Array
},
data () {
return {
isConfirmModal: false
};
},
computed: {
},
methods: {
...mapActions({
deleteConnection: 'connections/deleteConnection',
showEditModal: 'application/showEditConnModal'
}),
showConfirmModal () {
this.isConfirmModal = true;
},
hideConfirmModal () {
this.isConfirmModal = false;
},
closeContext () {
this.$emit('closeContext');
},
deleteRows () {
this.$emit('deleteSelected');
this.closeContext();
}
}
};
</script>
<style>
</style>

View File

@@ -33,21 +33,24 @@
:results="results"
:fields="resultsFields"
@updateField="updateField"
@deleteSelected="deleteSelected"
/>
</div>
</div>
</template>
<script>
import Structure from '@/ipc-api/Structure';
import Tables from '@/ipc-api/Tables';
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
import { mapGetters, mapActions } from 'vuex';
import tableTabs from '@/mixins/tableTabs';
export default {
name: 'WorkspaceTableTab',
components: {
WorkspaceQueryTable
},
mixins: [tableTabs],
props: {
connection: Object,
table: String
@@ -75,19 +78,20 @@ export default {
return {
name: field.COLUMN_NAME,
key: field.COLUMN_KEY.toLowerCase(),
type: field.DATA_TYPE
type: field.DATA_TYPE,
precision: field.DATETIME_PRECISION
};
});
}
},
watch: {
table: function () {
table () {
if (this.isSelected) {
this.getTableData();
this.lastTable = this.table;
}
},
isSelected: function (val) {
isSelected (val) {
if (val && this.lastTable !== this.table) {
this.getTableData();
this.lastTable = this.table;
@@ -113,7 +117,7 @@ export default {
};
try {
const { status, response } = await Structure.getTableColumns(params);
const { status, response } = await Tables.getTableColumns(params);
if (status === 'success')
this.fields = response.rows;
else
@@ -124,7 +128,7 @@ export default {
}
try {
const { status, response } = await Structure.getTableData(params);
const { status, response } = await Tables.getTableData(params);
if (status === 'success')
this.results = response;
@@ -136,25 +140,6 @@ export default {
}
this.isQuering = false;
},
async updateField (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.workspace.breadcrumbs.table,
...payload
};
try {
const { status, response } = await Structure.updateTableCell(params);
if (status === 'success')
this.$refs.queryTable.applyUpdate(payload);
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
}
}
};

View File

@@ -52,7 +52,10 @@ module.exports = {
downloadingUpdate: 'Downloading update',
updateDownloaded: 'Update downloaded',
restartToInstall: 'Restart Antares to install',
unableEditFieldWithoutPrimary: 'Unable to edit a field without a primary key in resultset'
unableEditFieldWithoutPrimary: 'Unable to edit a field without a primary key in resultset',
editCell: 'Edit cell',
deleteRows: 'Delete row | Delete {count} rows',
confirmToDeleteRows: 'Do you confirm to delete one row? | Do you confirm to delete {count} rows?'
},
// Date and Time
short: {

View File

@@ -13,4 +13,8 @@ export default class {
static updateTableCell (params) {
return ipcRenderer.invoke('updateTableCell', params);
}
static deleteTableRows (params) {
return ipcRenderer.invoke('deleteTableRows', params);
}
}

View File

@@ -0,0 +1,47 @@
import Tables from '@/ipc-api/Tables';
export default {
methods: {
async updateField (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.table,
...payload
};
try {
const { status, response } = await Tables.updateTableCell(params);
if (status === 'success')
this.$refs.queryTable.applyUpdate(payload);
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
},
async deleteSelected (payload) {
const params = {
uid: this.connection.uid,
schema: this.workspace.breadcrumbs.schema,
table: this.workspace.breadcrumbs.table,
...payload
};
try {
const { status, response } = await Tables.deleteTableRows(params);
if (status === 'success') {
const { primary, rows } = params;
this.results = { ...this.results, rows: this.results.rows.filter(row => !rows.includes(row[primary])) };
this.$refs.queryTable.refreshScroller();// Necessary to re-render virtual scroller
}
else
this.addNotification({ status: 'error', message: response });
}
catch (err) {
this.addNotification({ status: 'error', message: err.stack });
}
}
}
};

View File

@@ -3,42 +3,41 @@
.type-#{$type} {
color: $color;
@if $type == 'number'{
@if $type == "number" {
text-align: right;
}
}
}
}
@include type-colors((
"char": seagreen,
"varchar": seagreen,
"text": seagreen,
"mediumtext": seagreen,
@include type-colors(
(
"char": seagreen,
"varchar": seagreen,
"text": seagreen,
"mediumtext": seagreen,
"longtext": seagreen,
"int": cornflowerblue,
"tinyint": cornflowerblue,
"smallint": cornflowerblue,
"mediumint": cornflowerblue,
"bigint": cornflowerblue,
"datetime": coral,
"date": coral,
"time": coral,
"timestamp": coral,
"bit": lightskyblue,
"blob": darkorchid,
"mediumblob": darkorchid,
"longblob": darkorchid,
"unknown": gray,
)
);
"int": cornflowerblue,
"tinyint": cornflowerblue,
"smallint": cornflowerblue,
"mediumint": cornflowerblue,
"datetime": coral,
"date": coral,
"time": coral,
"timestamp": coral,
"bit": lightskyblue,
"blob": darkorchid,
"mediumblob": darkorchid,
"longblob": darkorchid,
"unknown": gray,
));
.is-null{
.is-null {
color: gray;
&::after{
content: 'NULL';
&::after {
content: "NULL";
}
}
}

View File

@@ -1,26 +1,26 @@
.dbi{
.dbi {
display: inline-block;
width: 42px;
height: 42px;
background-size: cover;
&.dbi-mysql{
background-image: url('../images/svg/mysql.svg');
&.dbi-mysql {
background-image: url("../images/svg/mysql.svg");
}
&.dbi-maria{
background-image: url('../images/svg/mariadb.svg');
&.dbi-maria {
background-image: url("../images/svg/mariadb.svg");
}
&.dbi-mssql{
background-image: url('../images/svg/mssql.svg');
&.dbi-mssql {
background-image: url("../images/svg/mssql.svg");
}
&.dbi-pg{
background-image: url('../images/svg/pg.svg');
&.dbi-pg {
background-image: url("../images/svg/pg.svg");
}
&.dbi-oracledb{
background-image: url('../images/svg/oracledb.svg');
&.dbi-oracledb {
background-image: url("../images/svg/oracledb.svg");
}
}
}

View File

@@ -1,65 +1,69 @@
.table {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
display: table;
&.table-striped {
.tbody {
.tr:nth-of-type(odd) {
background: $bg-color;
}
}
}
&,
&.table-striped {
.tbody {
.tr {
&.active {
background: $bg-color-dark;
}
}
}
}
&.table-hover {
.tbody {
.tr {
&:hover {
background: $bg-color-dark;
}
}
}
}
// Scollable tables
&.table-scroll {
display: block;
overflow-x: auto;
padding-bottom: .75rem;
white-space: nowrap;
}
border-collapse: collapse;
border-spacing: 0;
width: 100%;
display: table;
table-layout: fixed;
.thead{
&.table-striped {
.tbody {
.tr:nth-of-type(odd) {
background: $bg-color;
}
}
}
&,
&.table-striped {
.tbody {
.tr {
&.selected {
background: #333 !important;
}
&.active {
background: $bg-color-dark;
}
}
}
}
&.table-hover {
.tbody {
.tr {
&:hover {
background: $bg-color-dark;
}
}
}
}
// Scollable tables
&.table-scroll {
display: block;
overflow-x: auto;
padding-bottom: 0.75rem;
white-space: nowrap;
}
.thead {
display: table-header-group;
}
.tbody{
}
.tbody {
display: table-row-group;
}
}
.tr{
.tr {
display: table-row;
}
}
.td,
.th {
border-bottom: $border-width solid $border-color;
padding: $unit-3 $unit-2;
display: table-cell;
}
.th {
border-bottom-width: $border-width-lg;
}
}
.td,
.th {
border-bottom: $border-width solid $border-color;
padding: $unit-3 $unit-2;
display: table-cell;
}
.th {
border-bottom-width: $border-width-lg;
}
}

View File

@@ -1,10 +1,11 @@
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
transition: all 0.3s ease;
}
.slide-fade-leave-active {
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}

View File

@@ -1,4 +1,3 @@
@import "~spectre.css/src/variables";
@import "variables";
@import "transitions";
@@ -9,7 +8,7 @@
@import "~spectre.css/src/spectre";
@import "~spectre.css/src/spectre-exp";
body{
body {
user-select: none;
}
@@ -19,21 +18,21 @@ body{
@include padding-variant(3, $unit-3);
@include padding-variant(4, $unit-4);
.btn.btn-gray{
.btn.btn-gray {
color: #fff;
background: $bg-color-gray;
&:hover{
&:hover {
background: $bg-color;
}
}
.p-vcentered{
display: flex!important;
.p-vcentered {
display: flex !important;
align-items: center;
}
.c-help{
.c-help {
cursor: help;
}
@@ -42,109 +41,108 @@ body{
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: $bg-color-light;
background: $bg-color-light;
}
::-webkit-scrollbar-thumb {
background: rgba($color: #FFF, $alpha: .5);
::-webkit-scrollbar-thumb {
background: rgba($color: #fff, $alpha: 0.5);
&:hover {
background: rgba($color: #FFF, $alpha: 1);
background: rgba($color: #fff, $alpha: 1);
}
}
// Animations
@keyframes rotation {
from {
transform: rotate(0deg);
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
transform: rotate(359deg);
}
}
}
.rotate {
animation: rotation .8s infinite linear;
animation: rotation 0.8s infinite linear;
}
/*Override*/
.modal{
.modal {
.modal-overlay,
&.active .modal-overlay{
&.active .modal-overlay {
background: rgba(255, 255, 255, 0.15);
}
.modal-sm .modal-container,
.modal-container{
.modal-container {
box-shadow: 0 0 1px 0px #000;
padding: 0;
background: $bg-color;
.modal-header{
padding: .4rem .8rem;
.modal-header {
padding: 0.4rem 0.8rem;
text-transform: uppercase;
background: $bg-color-gray;
display: flex;
justify-content: space-between;
align-items: center;
color: #FFF;
color: #fff;
}
}
}
.tab{
.tab {
border-color: #272727;
}
.panel{
.panel {
border: none;
}
.badge{
.badge {
&[data-badge],
&:not([data-badge]){
&:not([data-badge]) {
&::after {
box-shadow: none;
}
}
}
.form-select{
.form-select {
cursor: pointer;
}
.form-select,
.form-select:not([multiple]):not([size]),
.form-input,
.form-checkbox .form-icon,
.form-radio .form-icon{
.form-checkbox .form-icon,
.form-radio .form-icon {
border-color: $bg-color-light;
background: $bg-color-gray;
}
.form-select:not([multiple]):not([size]):focus{
.form-select:not([multiple]):not([size]):focus {
border-color: $primary-color;
}
.menu{
font-size: .7rem;
.menu {
font-size: 0.7rem;
.menu-item {
+ .menu-item{
+ .menu-item {
margin-top: 0;
}
}
}
}
.accordion-body {
max-height: 500rem!important;
max-height: 500rem !important;
}
.btn.loading {
> .material-icons,
> span{
> span {
visibility: hidden;
}
}
}

View File

@@ -17,7 +17,7 @@ module.exports = {
{
loader: 'sass-loader',
options: {
prependData: '@import "@/scss/_variables.scss";'
additionalData: '@import "@/scss/_variables.scss";'
}
}
]