mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
69 Commits
v0.7.16-be
...
v0.7.17-be
Author | SHA1 | Date | |
---|---|---|---|
6fc4418c02 | |||
b37781df84 | |||
9c66fd51cb | |||
98c1f43a4d | |||
12825c69d4 | |||
198ff0103b | |||
94ce615fc8 | |||
354928e302 | |||
6dceaf09be | |||
b321e64b83 | |||
7e36260cdb | |||
894087e196 | |||
922f56f69b | |||
7d84b4e81f | |||
495e48625c | |||
5934d3a990 | |||
cb92ca99f6 | |||
e7bec0aaaf | |||
9de5f67d18 | |||
13592425af | |||
0de5ef8a98 | |||
785bc40ad0 | |||
940f64e6ab | |||
535dd21d69 | |||
|
b43c4000d5 | ||
757a2b3cbf | |||
c78258219a | |||
fe23d86694 | |||
8d605ee287 | |||
fbe271af37 | |||
b838916937 | |||
77ab561058 | |||
|
7bb03b4922 | ||
de607a6b06 | |||
c5f89f9fdd | |||
bf46b89988 | |||
e6f45d71c7 | |||
|
8608c27f20 | ||
|
e031c75e28 | ||
c1891dd5de | |||
53fe986bcb | |||
661043b181 | |||
b74ec71b10 | |||
54df0e4aa8 | |||
d702ce3fa9 | |||
63544e95da | |||
6df214558f | |||
f5b86e59e7 | |||
28f14c9195 | |||
|
90922e6f96 | ||
|
4b414df7e4 | ||
27f0068415 | |||
|
52e42fa1b5 | ||
|
5b9b539bc7 | ||
832aa75ebe | |||
aba67f3872 | |||
5a1644f023 | |||
e372712556 | |||
d4727a7d20 | |||
|
f2c2f33afa | ||
|
6dc4bdd0c0 | ||
|
9c6f1a9ea5 | ||
dd264f802e | |||
fed0e10702 | |||
e7ce4ef6ed | |||
e03f2eef49 | |||
|
c0c33f8237 | ||
|
b4731d67a5 | ||
|
de40414a0d |
@@ -239,6 +239,24 @@
|
||||
"contributions": [
|
||||
"platform"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "markusand",
|
||||
"name": "Marc Vilella",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12972543?v=4",
|
||||
"profile": "https://github.com/markusand",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Lawondyss",
|
||||
"name": "Ladislav Vondráček",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/272130?v=4",
|
||||
"profile": "https://github.com/Lawondyss",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
@@ -18,7 +18,8 @@
|
||||
},
|
||||
"plugins": [
|
||||
"vue",
|
||||
"@typescript-eslint"
|
||||
"@typescript-eslint",
|
||||
"simple-import-sort"
|
||||
],
|
||||
"rules": {
|
||||
"space-infix-ops": "off",
|
||||
@@ -91,6 +92,8 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-var-requires": "off"
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error"
|
||||
}
|
||||
}
|
2
.github/workflows/build-beta.yml
vendored
2
.github/workflows/build-beta.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 18
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm i
|
||||
|
@@ -9,11 +9,13 @@ jobs:
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: master
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 18
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm i
|
||||
|
64
CHANGELOG.md
64
CHANGELOG.md
@@ -2,6 +2,70 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [0.7.17-beta.2](https://github.com/antares-sql/antares/compare/v0.7.17-beta.1...v0.7.17-beta.2) (2023-09-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add NOT LIKE to table filters, closes [#672](https://github.com/antares-sql/antares/issues/672) ([9c66fd5](https://github.com/antares-sql/antares/commit/9c66fd51cbbe6f21a1fa6a34cc962496d3db7a98))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* nsis updater not working ([198ff01](https://github.com/antares-sql/antares/commit/198ff0103bfa95e3491296d352c944165f31b87e))
|
||||
* **UI:** small icons in foreign key modal ([b37781d](https://github.com/antares-sql/antares/commit/b37781df84cf7ee99a69ecaa54480d662d79c4aa))
|
||||
|
||||
### [0.7.17-beta.1](https://github.com/antares-sql/antares/compare/v0.7.17-beta.0...v0.7.17-beta.1) (2023-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* flip not working on BaseIcon component ([922f56f](https://github.com/antares-sql/antares/commit/922f56f69b168302a9d1ff86565d3f09400d6a7c))
|
||||
* **SQLite:** field length lost when editing a table, fixes [#664](https://github.com/antares-sql/antares/issues/664) ([b321e64](https://github.com/antares-sql/antares/commit/b321e64b835e0b39da116c4a77bac50247f240f3))
|
||||
* **SQLite:** table content not refresh after an update, fixes [#665](https://github.com/antares-sql/antares/issues/665) ([6dceaf0](https://github.com/antares-sql/antares/commit/6dceaf09be7bd46f1915721abd03253ffc517256))
|
||||
* table filter not working when search string on integer field, [#671](https://github.com/antares-sql/antares/issues/671) ([7e36260](https://github.com/antares-sql/antares/commit/7e36260cdb0438197152b5c6ac61db8ae8a9791a))
|
||||
* **UI:** small icons in sidebar elements with long name ([354928e](https://github.com/antares-sql/antares/commit/354928e302437d608903d1434d99d68eb79aa6e9))
|
||||
|
||||
### [0.7.17-beta.0](https://github.com/antares-sql/antares/compare/v0.7.16...v0.7.17-beta.0) (2023-09-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* customize keep-alive-interval for ssh-tunnel ([b4731d6](https://github.com/antares-sql/antares/commit/b4731d67a5b819bf87c437eb626f30a7489477f9))
|
||||
* keep alive interval in seconds ([8d605ee](https://github.com/antares-sql/antares/commit/8d605ee2872c20495f0ac4de84bf17d61c6455ae))
|
||||
* **translation:** Update Dutch ([b43c400](https://github.com/antares-sql/antares/commit/b43c4000d5905838348c391f25b3228dc6a6b2ac))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* empty workspace deleting connections in some conditions ([0de5ef8](https://github.com/antares-sql/antares/commit/0de5ef8a985cc8d9f1fa4479eeaf7dbb20f5fd7c))
|
||||
* **SQLite:** disconnecting a sqlite connection does not truly close it, fixes [#661](https://github.com/antares-sql/antares/issues/661) ([757a2b3](https://github.com/antares-sql/antares/commit/757a2b3cbf0d7f4df37eb5d90faa2f9821794e5f))
|
||||
* **UI:** update notification indicator moves settings icon ([e6f45d7](https://github.com/antares-sql/antares/commit/e6f45d71c75206187a7ae87e5f90a22d288a53ef))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* **core:** improved app security, fixes [#666](https://github.com/antares-sql/antares/issues/666) ([1359242](https://github.com/antares-sql/antares/commit/13592425afc643fe7188463fe4a2d02b6e27f87c))
|
||||
* improved ipc validation on Linux ([9de5f67](https://github.com/antares-sql/antares/commit/9de5f67d189c9b56fff41b29e6df69a3909bfa26))
|
||||
* migration from font icons to svg icons ([e7bec0a](https://github.com/antares-sql/antares/commit/e7bec0aaaf019fe0c3040d2d9443233e46a60188))
|
||||
|
||||
### [0.7.16](https://github.com/antares-sql/antares/compare/v0.7.16-beta.1...v0.7.16) (2023-08-26)
|
||||
|
||||
### [0.7.16-beta.1](https://github.com/antares-sql/antares/compare/v0.7.16-beta.0...v0.7.16-beta.1) (2023-08-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* ability to export connections ([f5b86e5](https://github.com/antares-sql/antares/commit/f5b86e59e7e41bbbe1555ec8a85ec1f849e8271d))
|
||||
* ability to import connections ([6df2145](https://github.com/antares-sql/antares/commit/6df214558f8186dd5fbf101505465f4c07c8ad5f))
|
||||
* Add catalan language ([9c6f1a9](https://github.com/antares-sql/antares/commit/9c6f1a9ea52b4791082bdbae91b764c486684c3b))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add some missing titles of buttons ([52e42fa](https://github.com/antares-sql/antares/commit/52e42fa1b529512154c0680124c5e425964a5b1a))
|
||||
* **SQLite:** improved view body parsing ([832aa75](https://github.com/antares-sql/antares/commit/832aa75ebe46776b9c365dde2dd13db3746adcd5))
|
||||
|
||||
### [0.7.16-beta.0](https://github.com/antares-sql/antares/compare/v0.7.15...v0.7.16-beta.0) (2023-08-11)
|
||||
|
||||
|
||||
|
@@ -153,6 +153,8 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/m1khal3v"><img src="https://avatars.githubusercontent.com/u/41085561?v=4?s=100" width="100px;" alt="Anton Mikhalev"/><br /><sub><b>Anton Mikhalev</b></sub></a><br /><a href="#translation-m1khal3v" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://64k.nl/"><img src="https://avatars.githubusercontent.com/u/3864423?v=4?s=100" width="100px;" alt="René"/><br /><sub><b>René</b></sub></a><br /><a href="https://github.com/antares-sql/antares/commits?author=64knl" title="Code">💻</a> <a href="#translation-64knl" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zxp19821005"><img src="https://avatars.githubusercontent.com/u/4915850?v=4?s=100" width="100px;" alt="Woodenman"/><br /><sub><b>Woodenman</b></sub></a><br /><a href="#platform-zxp19821005" title="Packaging/porting to new platform">📦</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/markusand"><img src="https://avatars.githubusercontent.com/u/12972543?v=4?s=100" width="100px;" alt="Marc Vilella"/><br /><sub><b>Marc Vilella</b></sub></a><br /><a href="#translation-markusand" title="Translation">🌍</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Lawondyss"><img src="https://avatars.githubusercontent.com/u/272130?v=4?s=100" width="100px;" alt="Ladislav Vondráček"/><br /><sub><b>Ladislav Vondráček</b></sub></a><br /><a href="#translation-Lawondyss" title="Translation">🌍</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
361
package-lock.json
generated
361
package-lock.json
generated
@@ -1,21 +1,22 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"version": "0.7.16-beta.0",
|
||||
"version": "0.7.17-beta.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "antares",
|
||||
"version": "0.7.16-beta.0",
|
||||
"version": "0.7.17-beta.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/remote": "~2.0.1",
|
||||
"@faker-js/faker": "~6.1.2",
|
||||
"@mdi/font": "~7.1.96",
|
||||
"@jamescoyle/vue-icon": "~0.1.2",
|
||||
"@mdi/js": "~7.2.96",
|
||||
"@turf/helpers": "~6.5.0",
|
||||
"@vueuse/core": "~8.7.5",
|
||||
"ace-builds": "~1.14.0",
|
||||
"@vueuse/core": "~10.4.1",
|
||||
"ace-builds": "~1.24.1",
|
||||
"better-sqlite3": "~8.0.0",
|
||||
"electron-log": "~4.4.1",
|
||||
"electron-store": "~8.1.0",
|
||||
@@ -33,13 +34,13 @@
|
||||
"pg-connection-string": "~2.5.0",
|
||||
"pg-query-stream": "~4.2.3",
|
||||
"pgsql-ast-parser": "~7.2.1",
|
||||
"pinia": "~2.0.28",
|
||||
"pinia": "~2.1.6",
|
||||
"source-map-support": "~0.5.20",
|
||||
"spectre.css": "~0.5.9",
|
||||
"sql-formatter": "~12.2.0",
|
||||
"sql-formatter": "~13.0.0",
|
||||
"ssh2-promise": "~1.0.2",
|
||||
"v-mask": "~2.3.0",
|
||||
"vue": "~3.2.45",
|
||||
"vue": "~3.3.4",
|
||||
"vue-i18n": "~9.2.2",
|
||||
"vuedraggable": "~4.1.0"
|
||||
},
|
||||
@@ -62,13 +63,14 @@
|
||||
"chalk": "~4.1.2",
|
||||
"cross-env": "~7.0.2",
|
||||
"css-loader": "~6.5.0",
|
||||
"electron": "~22.0.3",
|
||||
"electron": "~22.3.23",
|
||||
"electron-builder": "~22.10.3",
|
||||
"eslint": "~7.32.0",
|
||||
"eslint-config-standard": "~16.0.3",
|
||||
"eslint-plugin-import": "~2.24.2",
|
||||
"eslint-plugin-node": "~11.1.0",
|
||||
"eslint-plugin-promise": "~5.2.0",
|
||||
"eslint-plugin-simple-import-sort": "~10.0.0",
|
||||
"eslint-plugin-vue": "~8.0.3",
|
||||
"file-loader": "~6.2.0",
|
||||
"html-webpack-plugin": "~5.5.0",
|
||||
@@ -2017,6 +2019,11 @@
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@jamescoyle/vue-icon": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jamescoyle/vue-icon/-/vue-icon-0.1.2.tgz",
|
||||
"integrity": "sha512-KFrImXx5TKIi6iQXlnyLEBl4rNosNKbTeRnr70ucTdUaciVmd9qK9d/pZAaKt1Ob/8xNnX2GMp8LisyHdKtEgw=="
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.3",
|
||||
"dev": true,
|
||||
@@ -2057,7 +2064,6 @@
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.15",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
@@ -2100,9 +2106,10 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@mdi/font": {
|
||||
"version": "7.1.96",
|
||||
"license": "Apache-2.0"
|
||||
"node_modules/@mdi/js": {
|
||||
"version": "7.2.96",
|
||||
"resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.2.96.tgz",
|
||||
"integrity": "sha512-paR9M9ZT7rKbh2boksNUynuSZMHhqRYnEZOm/KrZTjQ4/FzyhjLHuvw/8XYzP+E7fS4+/Ms/82EN1pl/OFsiIA=="
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
@@ -2496,8 +2503,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/web-bluetooth": {
|
||||
"version": "0.0.14",
|
||||
"license": "MIT"
|
||||
"version": "0.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz",
|
||||
"integrity": "sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA=="
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.4",
|
||||
@@ -2777,6 +2785,7 @@
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.2.47",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.16.4",
|
||||
@@ -2787,6 +2796,7 @@
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.2.47",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.2.47",
|
||||
@@ -2795,6 +2805,7 @@
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.2.47",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.16.4",
|
||||
@@ -2811,6 +2822,7 @@
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.2.47",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.2.47",
|
||||
@@ -2822,14 +2834,16 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.2.47",
|
||||
"license": "MIT",
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.3.4.tgz",
|
||||
"integrity": "sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==",
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.2.47"
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity-transform": {
|
||||
"version": "3.2.47",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.16.4",
|
||||
@@ -2839,89 +2853,110 @@
|
||||
"magic-string": "^0.25.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity/node_modules/@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
|
||||
},
|
||||
"node_modules/@vue/runtime-core": {
|
||||
"version": "3.2.47",
|
||||
"license": "MIT",
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.3.4.tgz",
|
||||
"integrity": "sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.2.47",
|
||||
"@vue/shared": "3.2.47"
|
||||
"@vue/reactivity": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-core/node_modules/@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
|
||||
},
|
||||
"node_modules/@vue/runtime-dom": {
|
||||
"version": "3.2.47",
|
||||
"license": "MIT",
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz",
|
||||
"integrity": "sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==",
|
||||
"dependencies": {
|
||||
"@vue/runtime-core": "3.2.47",
|
||||
"@vue/shared": "3.2.47",
|
||||
"csstype": "^2.6.8"
|
||||
"@vue/runtime-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4",
|
||||
"csstype": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-dom/node_modules/@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
|
||||
},
|
||||
"node_modules/@vue/server-renderer": {
|
||||
"version": "3.2.47",
|
||||
"license": "MIT",
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.3.4.tgz",
|
||||
"integrity": "sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==",
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.2.47",
|
||||
"@vue/shared": "3.2.47"
|
||||
"@vue/compiler-ssr": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.2.47"
|
||||
"vue": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
|
||||
"integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.21.3",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-dom": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
|
||||
"integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
|
||||
"integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer/node_modules/@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.2.47",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vueuse/core": {
|
||||
"version": "8.7.5",
|
||||
"license": "MIT",
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.4.1.tgz",
|
||||
"integrity": "sha512-DkHIfMIoSIBjMgRRvdIvxsyboRZQmImofLyOHADqiVbQVilP8VVHDhBX2ZqoItOgu7dWa8oXiNnScOdPLhdEXg==",
|
||||
"dependencies": {
|
||||
"@types/web-bluetooth": "^0.0.14",
|
||||
"@vueuse/metadata": "8.7.5",
|
||||
"@vueuse/shared": "8.7.5",
|
||||
"vue-demi": "*"
|
||||
"@types/web-bluetooth": "^0.0.17",
|
||||
"@vueuse/metadata": "10.4.1",
|
||||
"@vueuse/shared": "10.4.1",
|
||||
"vue-demi": ">=0.14.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.1.0",
|
||||
"vue": "^2.6.0 || ^3.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
},
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/core/node_modules/@vueuse/shared": {
|
||||
"version": "8.7.5",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"vue-demi": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.1.0",
|
||||
"vue": "^2.6.0 || ^3.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
},
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/core/node_modules/vue-demi": {
|
||||
"version": "0.14.5",
|
||||
"version": "0.14.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
|
||||
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
@@ -2943,12 +2978,49 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/metadata": {
|
||||
"version": "8.7.5",
|
||||
"license": "MIT",
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.4.1.tgz",
|
||||
"integrity": "sha512-2Sc8X+iVzeuMGHr6O2j4gv/zxvQGGOYETYXEc41h0iZXIRnRbJZGmY/QP8dvzqUelf8vg0p/yEA5VpCEu+WpZg==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/shared": {
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.4.1.tgz",
|
||||
"integrity": "sha512-vz5hbAM4qA0lDKmcr2y3pPdU+2EVw/yzfRsBdu+6+USGa4PxqSQRYIUC9/NcT06y+ZgaTsyURw2I9qOFaaXHAg==",
|
||||
"dependencies": {
|
||||
"vue-demi": ">=0.14.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/shared/node_modules/vue-demi": {
|
||||
"version": "0.14.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz",
|
||||
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@webassemblyjs/ast": {
|
||||
"version": "1.11.1",
|
||||
"dev": true,
|
||||
@@ -3141,8 +3213,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ace-builds": {
|
||||
"version": "1.14.0",
|
||||
"license": "BSD-3-Clause"
|
||||
"version": "1.24.1",
|
||||
"resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.24.1.tgz",
|
||||
"integrity": "sha512-TLcxMxiTRX5Eq9bBVSd/bTJlanCBULiv/IULLohJDDaCAfcpZKJBVSd4OWfN/j2c2jCLc+jhpNWGELiJZw3wPw=="
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "7.4.1",
|
||||
@@ -5136,8 +5209,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "2.6.21",
|
||||
"license": "MIT"
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||
},
|
||||
"node_modules/dargs": {
|
||||
"version": "7.0.0",
|
||||
@@ -5670,9 +5744,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "22.0.3",
|
||||
"version": "22.3.23",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-22.3.23.tgz",
|
||||
"integrity": "sha512-2p6NsLFPfM2RmgATchjKZKBUP3O6NxQMWOrHt9W5U2GRtfI8qWlicUR1wnh5D1VLt4c1YsjvpF6dct+1JNRubA==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/get": "^2.0.0",
|
||||
"@types/node": "^16.11.26",
|
||||
@@ -5958,8 +6033,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron/node_modules/@types/node": {
|
||||
"version": "16.18.34",
|
||||
"license": "MIT"
|
||||
"version": "16.18.48",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.48.tgz",
|
||||
"integrity": "sha512-mlaecDKQ7rIZrYD7iiKNdzFb6e/qD5I9U1rAhq+Fd+DWvYVs+G2kv74UFHmSOlg5+i/vF3XxuR522V4u8BqO+Q=="
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
@@ -6460,6 +6536,15 @@
|
||||
"eslint": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-simple-import-sort": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-10.0.0.tgz",
|
||||
"integrity": "sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"eslint": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-vue": {
|
||||
"version": "8.0.3",
|
||||
"dev": true,
|
||||
@@ -7471,7 +7556,6 @@
|
||||
},
|
||||
"node_modules/get-stdin": {
|
||||
"version": "8.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -9228,6 +9312,7 @@
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.25.9",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sourcemap-codec": "^1.4.8"
|
||||
@@ -10653,11 +10738,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
"version": "2.0.36",
|
||||
"license": "MIT",
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.6.tgz",
|
||||
"integrity": "sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.5.0",
|
||||
"vue-demi": "*"
|
||||
"vue-demi": ">=0.14.5"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
@@ -10665,7 +10751,7 @@
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.4.0",
|
||||
"typescript": ">=4.4.4",
|
||||
"vue": "^2.6.14 || ^3.2.0"
|
||||
"vue": "^2.6.14 || ^3.3.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
@@ -12387,6 +12473,7 @@
|
||||
},
|
||||
"node_modules/sourcemap-codec": {
|
||||
"version": "1.4.8",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/spdx-correct": {
|
||||
@@ -12472,11 +12559,12 @@
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/sql-formatter": {
|
||||
"version": "12.2.2",
|
||||
"resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-12.2.2.tgz",
|
||||
"integrity": "sha512-UBChSI2X6hd4GhmO+c7BmSFtc792FwogVaVqc9Y22/OqybvVfgl2OeAShc9fjivWVshXbm4UEK8WTM3tt+2Mvw==",
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-13.0.0.tgz",
|
||||
"integrity": "sha512-V21cVvge4rhn9Fa7K/fTKcmPM+x1yee6Vhq8ZwgaWh3VPBqApgsaoFB5kLAhiqRo5AmSaRyLU7LIdgnNwH01/w==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"get-stdin": "=8.0.0",
|
||||
"nearley": "^2.20.1"
|
||||
},
|
||||
"bin": {
|
||||
@@ -14177,14 +14265,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "3.2.47",
|
||||
"license": "MIT",
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz",
|
||||
"integrity": "sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.2.47",
|
||||
"@vue/compiler-sfc": "3.2.47",
|
||||
"@vue/runtime-dom": "3.2.47",
|
||||
"@vue/server-renderer": "3.2.47",
|
||||
"@vue/shared": "3.2.47"
|
||||
"@vue/compiler-dom": "3.3.4",
|
||||
"@vue/compiler-sfc": "3.3.4",
|
||||
"@vue/runtime-dom": "3.3.4",
|
||||
"@vue/server-renderer": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-eslint-parser": {
|
||||
@@ -14337,6 +14426,80 @@
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-core": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz",
|
||||
"integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.21.3",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-dom": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz",
|
||||
"integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz",
|
||||
"integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.20.15",
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/compiler-dom": "3.3.4",
|
||||
"@vue/compiler-ssr": "3.3.4",
|
||||
"@vue/reactivity-transform": "3.3.4",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.0",
|
||||
"postcss": "^8.1.10",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz",
|
||||
"integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.3.4",
|
||||
"@vue/shared": "3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/reactivity-transform": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz",
|
||||
"integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.20.15",
|
||||
"@vue/compiler-core": "3.3.4",
|
||||
"@vue/shared": "3.3.4",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue/node_modules/@vue/shared": {
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
|
||||
"integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
|
||||
},
|
||||
"node_modules/vue/node_modules/magic-string": {
|
||||
"version": "0.30.3",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz",
|
||||
"integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/vuedraggable": {
|
||||
"version": "4.1.0",
|
||||
"license": "MIT",
|
||||
|
20
package.json
20
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.7.16-beta.0",
|
||||
"version": "0.7.17-beta.2",
|
||||
"description": "A modern, fast and productivity driven SQL client with a focus in UX.",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/antares-sql/antares.git",
|
||||
@@ -67,7 +67,6 @@
|
||||
"target": "deb",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
},
|
||||
@@ -75,7 +74,6 @@
|
||||
"target": "AppImage",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
}
|
||||
@@ -122,10 +120,11 @@
|
||||
"dependencies": {
|
||||
"@electron/remote": "~2.0.1",
|
||||
"@faker-js/faker": "~6.1.2",
|
||||
"@mdi/font": "~7.1.96",
|
||||
"@jamescoyle/vue-icon": "~0.1.2",
|
||||
"@mdi/js": "~7.2.96",
|
||||
"@turf/helpers": "~6.5.0",
|
||||
"@vueuse/core": "~8.7.5",
|
||||
"ace-builds": "~1.14.0",
|
||||
"@vueuse/core": "~10.4.1",
|
||||
"ace-builds": "~1.24.1",
|
||||
"better-sqlite3": "~8.0.0",
|
||||
"electron-log": "~4.4.1",
|
||||
"electron-store": "~8.1.0",
|
||||
@@ -143,13 +142,13 @@
|
||||
"pg-connection-string": "~2.5.0",
|
||||
"pg-query-stream": "~4.2.3",
|
||||
"pgsql-ast-parser": "~7.2.1",
|
||||
"pinia": "~2.0.28",
|
||||
"pinia": "~2.1.6",
|
||||
"source-map-support": "~0.5.20",
|
||||
"spectre.css": "~0.5.9",
|
||||
"sql-formatter": "~12.2.0",
|
||||
"sql-formatter": "~13.0.0",
|
||||
"ssh2-promise": "~1.0.2",
|
||||
"v-mask": "~2.3.0",
|
||||
"vue": "~3.2.45",
|
||||
"vue": "~3.3.4",
|
||||
"vue-i18n": "~9.2.2",
|
||||
"vuedraggable": "~4.1.0"
|
||||
},
|
||||
@@ -172,13 +171,14 @@
|
||||
"chalk": "~4.1.2",
|
||||
"cross-env": "~7.0.2",
|
||||
"css-loader": "~6.5.0",
|
||||
"electron": "~22.0.3",
|
||||
"electron": "~22.3.23",
|
||||
"electron-builder": "~22.10.3",
|
||||
"eslint": "~7.32.0",
|
||||
"eslint-config-standard": "~16.0.3",
|
||||
"eslint-plugin-import": "~2.24.2",
|
||||
"eslint-plugin-node": "~11.1.0",
|
||||
"eslint-plugin-promise": "~5.2.0",
|
||||
"eslint-plugin-simple-import-sort": "~10.0.0",
|
||||
"eslint-plugin-vue": "~8.0.3",
|
||||
"file-loader": "~6.2.0",
|
||||
"html-webpack-plugin": "~5.5.0",
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import { localesNames } from '../src/renderer/i18n/supported-locales';
|
||||
import { enUS } from '../src/renderer/i18n/en-US';
|
||||
import { localesNames } from '../src/renderer/i18n/supported-locales';
|
||||
const locale = process.argv[2];
|
||||
let fullCount = 0;
|
||||
let checkCount = 0;
|
||||
|
@@ -31,10 +31,10 @@ parts:
|
||||
fi
|
||||
# Get the latest releases json
|
||||
echo "Get GitHub releases..."
|
||||
wget --quiet https://api.github.com/repos/fabio286/antares/releases/latest -O releases.json
|
||||
wget --quiet https://api.github.com/repos/fabio286/antares/releases -O releases.json
|
||||
# Get the version from the tag_name and the download URL.
|
||||
VERSION=$(jq . releases.json | grep tag_name | cut -d'"' -f4 | sed s'/release-//')
|
||||
DEB_URL=$(cat releases.json | jq -r ".assets[] | select(.name | test(\"${FILTER}\")) | .browser_download_url")
|
||||
VERSION=$(jq . releases.json | grep tag_name | head -1 | cut -d'"' -f4 | sed s'/release-//')
|
||||
DEB_URL=$(cat releases.json | jq -r ".[0].assets[] | select(.name | test(\"${FILTER}\")) | .browser_download_url")
|
||||
DEB=$(basename "${DEB_URL}")
|
||||
echo "Downloading ${DEB_URL}..."
|
||||
wget --quiet "${DEB_URL}" -O "${SNAPCRAFT_PART_INSTALL}/${DEB}"
|
||||
@@ -79,7 +79,7 @@ parts:
|
||||
- libdb5.3
|
||||
- libdbus-1-3
|
||||
- libexpat1
|
||||
- libffi7
|
||||
- libffi8
|
||||
- libgcc-s1
|
||||
- libgcrypt20
|
||||
- libglib2.0-0
|
||||
@@ -87,9 +87,9 @@ parts:
|
||||
- libgnutls30
|
||||
- libgpg-error0
|
||||
- libgssapi-krb5-2
|
||||
- libhogweed5
|
||||
- libhogweed6
|
||||
- libidn2-0
|
||||
- libjson-c4
|
||||
- libjson-c5
|
||||
- libk5crypto3
|
||||
- libkeyutils1
|
||||
- libkrb5-3
|
||||
@@ -97,12 +97,12 @@ parts:
|
||||
- liblz4-1
|
||||
- liblzma5
|
||||
- libmount1
|
||||
- libnettle7
|
||||
- libnettle8
|
||||
- libp11-kit0
|
||||
- libpcre2-8-0
|
||||
- libselinux1
|
||||
- libsqlite3-0
|
||||
- libssl1.1
|
||||
- libssl3
|
||||
- libstdc++6
|
||||
- libsystemd0
|
||||
- libtasn1-6
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import firebirdTypes from '../data-types/firebird';
|
||||
import { Customizations } from '../interfaces/customizations';
|
||||
import { defaults } from './defaults';
|
||||
import firebirdTypes from '../data-types/firebird';
|
||||
|
||||
export const customizations: Customizations = {
|
||||
...defaults,
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import * as firebird from 'common/customizations/firebird';
|
||||
import * as mysql from 'common/customizations/mysql';
|
||||
import * as postgresql from 'common/customizations/postgresql';
|
||||
import * as sqlite from 'common/customizations/sqlite';
|
||||
import * as firebird from 'common/customizations/firebird';
|
||||
import { Customizations } from 'common/interfaces/customizations';
|
||||
|
||||
export default {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import mysqlTypes from '../data-types/mysql';
|
||||
import { Customizations } from '../interfaces/customizations';
|
||||
import { defaults } from './defaults';
|
||||
import mysqlTypes from '../data-types/mysql';
|
||||
|
||||
export const customizations: Customizations = {
|
||||
...defaults,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import postgresqlTypes from '../data-types/postgresql';
|
||||
import { Customizations } from '../interfaces/customizations';
|
||||
import { defaults } from './defaults';
|
||||
import postgresqlTypes from '../data-types/postgresql';
|
||||
|
||||
export const customizations: Customizations = {
|
||||
...defaults,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import sqliteTypes from '../data-types/sqlite';
|
||||
import { Customizations } from '../interfaces/customizations';
|
||||
import { defaults } from './defaults';
|
||||
import sqliteTypes from '../data-types/sqlite';
|
||||
|
||||
export const customizations: Customizations = {
|
||||
...defaults,
|
||||
|
@@ -1,14 +1,15 @@
|
||||
import * as mysql from 'mysql2/promise';
|
||||
import * as pg from 'pg';
|
||||
import { FirebirdSQLClient } from 'src/main/libs/clients/FirebirdSQLClient';
|
||||
import MysqlExporter from 'src/main/libs/exporters/sql/MysqlExporter';
|
||||
import PostgreSQLExporter from 'src/main/libs/exporters/sql/PostgreSQLExporter';
|
||||
import MySQLImporter from 'src/main/libs/importers/sql/MySQLlImporter';
|
||||
import PostgreSQLImporter from 'src/main/libs/importers/sql/PostgreSQLImporter';
|
||||
import SSHConfig from 'ssh2-promise/lib/sshConfig';
|
||||
|
||||
import { MySQLClient } from '../../main/libs/clients/MySQLClient';
|
||||
import { PostgreSQLClient } from '../../main/libs/clients/PostgreSQLClient';
|
||||
import { SQLiteClient } from '../../main/libs/clients/SQLiteClient';
|
||||
import { FirebirdSQLClient } from 'src/main/libs/clients/FirebirdSQLClient';
|
||||
|
||||
export type Client = MySQLClient | PostgreSQLClient | SQLiteClient | FirebirdSQLClient
|
||||
export type ClientCode = 'mysql' | 'maria' | 'pg' | 'sqlite' | 'firebird'
|
||||
@@ -64,6 +65,7 @@ export interface ConnectionParams {
|
||||
sshKey?: string;
|
||||
sshPort?: number;
|
||||
sshPassphrase?: string;
|
||||
sshKeepAliveInterval?: number;
|
||||
}
|
||||
|
||||
export interface TypeInformations {
|
||||
|
@@ -21,10 +21,12 @@ export interface TableDeleteParams {
|
||||
rows: {[key: string]: any};
|
||||
}
|
||||
|
||||
export type TableFilterOperator = '=' | '!=' | '>' | '<' | '>=' | '<=' | 'IN' | 'NOT IN' | 'LIKE' | 'NOT LIKE' | 'BETWEEN' | 'IS NULL' | 'IS NOT NULL'
|
||||
|
||||
export interface TableFilterClausole {
|
||||
active: boolean;
|
||||
field: string;
|
||||
op: '=' | '!=' | '>' | '<' | '>=' | '<=' | 'IN' | 'NOT IN' | 'LIKE' | 'BETWEEN' | 'IS NULL' | 'IS NOT NULL';
|
||||
op:TableFilterOperator;
|
||||
value: '';
|
||||
value2: '';
|
||||
}
|
||||
|
28
src/common/libs/encrypter.ts
Normal file
28
src/common/libs/encrypter.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
const algorithm = 'aes-256-gcm';
|
||||
|
||||
function encrypt (text: string, password: string) {
|
||||
const iv = crypto.randomBytes(16);
|
||||
const key = crypto.scryptSync(password, 'antares', 32);
|
||||
const cipher = crypto.createCipheriv(algorithm, key, iv);
|
||||
const encrypted = Buffer.concat([cipher.update(text), cipher.final()]);
|
||||
const authTag = cipher.getAuthTag();
|
||||
|
||||
return {
|
||||
iv: iv.toString('hex'),
|
||||
authTag: authTag.toString('hex'),
|
||||
content: encrypted.toString('hex')
|
||||
};
|
||||
}
|
||||
|
||||
function decrypt (hash: { iv: string; content: string; authTag: string }, password: string) {
|
||||
const key = crypto.scryptSync(password, 'antares', 32);
|
||||
const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(hash.iv, 'hex'));
|
||||
decipher.setAuthTag(Buffer.from(hash.authTag, 'hex'));
|
||||
const decrpyted = decipher.update(hash.content, 'hex', 'utf8') + decipher.final('utf8');
|
||||
|
||||
return decrpyted;
|
||||
}
|
||||
|
||||
export { decrypt, encrypt };
|
@@ -1,12 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable no-useless-escape */
|
||||
import * as moment from 'moment';
|
||||
import { lineString, point, polygon } from '@turf/helpers';
|
||||
import { BIT, BLOB, DATE, DATETIME, FLOAT, IS_MULTI_SPATIAL, NUMBER, SPATIAL, TEXT_SEARCH } from 'common/fieldTypes';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import customizations from '../customizations';
|
||||
import { ClientCode } from '../interfaces/antares';
|
||||
import { BLOB, BIT, DATE, DATETIME, FLOAT, SPATIAL, IS_MULTI_SPATIAL, NUMBER, TEXT_SEARCH } from 'common/fieldTypes';
|
||||
import hexToBinary, { HexChar } from './hexToBinary';
|
||||
import { getArrayDepth } from './getArrayDepth';
|
||||
import hexToBinary, { HexChar } from './hexToBinary';
|
||||
|
||||
/**
|
||||
* Escapes a string fo SQL use
|
||||
|
@@ -135,4 +135,4 @@ for (let i = 1; i <= 9; i++) {
|
||||
});
|
||||
}
|
||||
|
||||
export { shortcuts, ShortcutRecord };
|
||||
export { ShortcutRecord, shortcuts };
|
||||
|
@@ -1,35 +1,44 @@
|
||||
import { app, ipcMain, dialog } from 'electron';
|
||||
import { app, dialog, ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
import { ShortcutRegister } from '../libs/ShortcutRegister';
|
||||
|
||||
export default () => {
|
||||
ipcMain.on('close-app', () => {
|
||||
ipcMain.on('close-app', (event) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
app.exit();
|
||||
});
|
||||
|
||||
ipcMain.handle('show-open-dialog', (event, options) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
return dialog.showOpenDialog(options);
|
||||
});
|
||||
|
||||
ipcMain.handle('get-download-dir-path', () => {
|
||||
ipcMain.handle('get-download-dir-path', (event) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
return app.getPath('downloads');
|
||||
});
|
||||
|
||||
ipcMain.handle('resotre-default-shortcuts', () => {
|
||||
ipcMain.handle('resotre-default-shortcuts', (event) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
const shortCutRegister = ShortcutRegister.getInstance();
|
||||
shortCutRegister.restoreDefaults();
|
||||
});
|
||||
|
||||
ipcMain.handle('reload-shortcuts', () => {
|
||||
ipcMain.handle('reload-shortcuts', (event) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
const shortCutRegister = ShortcutRegister.getInstance();
|
||||
shortCutRegister.reload();
|
||||
});
|
||||
|
||||
ipcMain.handle('update-shortcuts', (event, shortcuts) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
const shortCutRegister = ShortcutRegister.getInstance();
|
||||
shortCutRegister.updateShortcuts(shortcuts);
|
||||
});
|
||||
|
||||
ipcMain.handle('unregister-shortcuts', () => {
|
||||
ipcMain.handle('unregister-shortcuts', (event) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
const shortCutRegister = ShortcutRegister.getInstance();
|
||||
shortCutRegister.unregister();
|
||||
});
|
||||
|
@@ -1,11 +1,15 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as fs from 'fs';
|
||||
import { ipcMain } from 'electron';
|
||||
import { ClientsFactory } from '../libs/ClientsFactory';
|
||||
import * as fs from 'fs';
|
||||
import { SslOptions } from 'mysql2';
|
||||
|
||||
import { ClientsFactory } from '../libs/ClientsFactory';
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('test-connection', async (event, conn: antares.ConnectionParams) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
const params = {
|
||||
host: conn.host,
|
||||
port: +conn.port,
|
||||
@@ -23,6 +27,7 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
port: number;
|
||||
privateKey: string;
|
||||
passphrase: string;
|
||||
keepaliveInterval: number;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,7 +54,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
password: conn.sshPass,
|
||||
port: conn.sshPort ? conn.sshPort : 22,
|
||||
privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : null,
|
||||
passphrase: conn.sshPassphrase
|
||||
passphrase: conn.sshPassphrase,
|
||||
keepaliveInterval: conn.sshKeepAliveInterval ?? conn.sshKeepAliveInterval*1000
|
||||
};
|
||||
}
|
||||
|
||||
@@ -80,6 +86,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('connect', async (event, conn: antares.ConnectionParams) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
const params = {
|
||||
host: conn.host,
|
||||
port: +conn.port,
|
||||
@@ -98,6 +106,7 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
port: number;
|
||||
privateKey: string;
|
||||
passphrase: string;
|
||||
keepaliveInterval: number;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -127,7 +136,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
password: conn.sshPass,
|
||||
port: conn.sshPort ? conn.sshPort : 22,
|
||||
privateKey: conn.sshKey ? fs.readFileSync(conn.sshKey).toString() : null,
|
||||
passphrase: conn.sshPassphrase
|
||||
passphrase: conn.sshPassphrase,
|
||||
keepaliveInterval: conn.sshKeepAliveInterval ?? conn.sshKeepAliveInterval*1000
|
||||
};
|
||||
}
|
||||
|
||||
@@ -153,6 +163,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('disconnect', (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
connections[uid].destroy();
|
||||
delete connections[uid];
|
||||
});
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-databases', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[uid].getDatabases();
|
||||
return { status: 'success', response: result };
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-function-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getFunctionInformations(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -13,6 +17,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('drop-function', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].dropFunction(params);
|
||||
return { status: 'success' };
|
||||
@@ -23,6 +29,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('alter-function', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterFunction(params);
|
||||
return { status: 'success' };
|
||||
@@ -33,6 +41,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('alter-trigger-function', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterTriggerFunction(params);
|
||||
return { status: 'success' };
|
||||
@@ -43,6 +53,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('create-function', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createFunction(params);
|
||||
return { status: 'success' };
|
||||
@@ -53,6 +65,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('create-trigger-function', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createTriggerFunction(params);
|
||||
return { status: 'success' };
|
||||
|
@@ -1,17 +1,17 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
|
||||
import connection from './connection';
|
||||
import tables from './tables';
|
||||
import views from './views';
|
||||
import triggers from './triggers';
|
||||
import routines from './routines';
|
||||
import functions from './functions';
|
||||
import schedulers from './schedulers';
|
||||
import updates from './updates';
|
||||
import application from './application';
|
||||
import connection from './connection';
|
||||
import database from './database';
|
||||
import functions from './functions';
|
||||
import routines from './routines';
|
||||
import schedulers from './schedulers';
|
||||
import schema from './schema';
|
||||
import tables from './tables';
|
||||
import triggers from './triggers';
|
||||
import updates from './updates';
|
||||
import users from './users';
|
||||
import views from './views';
|
||||
|
||||
const connections: {[key: string]: antares.Client} = {};
|
||||
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-routine-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getRoutineInformations(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -13,6 +17,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('drop-routine', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].dropRoutine(params);
|
||||
return { status: 'success' };
|
||||
@@ -23,6 +29,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('alter-routine', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterRoutine(params);
|
||||
return { status: 'success' };
|
||||
@@ -33,6 +41,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('create-routine', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createRoutine(params);
|
||||
return { status: 'success' };
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-scheduler-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getEventInformations(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -13,6 +17,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('drop-scheduler', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].dropEvent(params);
|
||||
return { status: 'success' };
|
||||
@@ -23,6 +29,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('alter-scheduler', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterEvent(params);
|
||||
return { status: 'success' };
|
||||
@@ -33,6 +41,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('create-scheduler', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createEvent(params);
|
||||
return { status: 'success' };
|
||||
@@ -43,6 +53,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('toggle-scheduler', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
if (!params.enabled)
|
||||
await connections[params.uid].enableEvent({ ...params });
|
||||
|
@@ -1,9 +1,11 @@
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as workers from 'common/interfaces/workers';
|
||||
import { dialog, ipcMain } from 'electron';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import { ipcMain, dialog } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
|
||||
@@ -12,6 +14,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
let importer: ChildProcess = null;
|
||||
|
||||
ipcMain.handle('create-schema', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createSchema(params);
|
||||
|
||||
@@ -23,6 +27,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('update-schema', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterSchema(params);
|
||||
|
||||
@@ -34,6 +40,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('delete-schema', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].dropSchema(params);
|
||||
|
||||
@@ -45,6 +53,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-schema-collation', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const collation = await connections[params.uid].getDatabaseCollation(
|
||||
params
|
||||
@@ -61,6 +71,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-structure', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const structure: unknown = await connections[params.uid].getStructure(
|
||||
params.schemas
|
||||
@@ -74,6 +86,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-collations', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[uid].getCollations();
|
||||
|
||||
@@ -85,6 +99,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-variables', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[uid].getVariables();
|
||||
|
||||
@@ -96,6 +112,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-engines', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result: unknown = await connections[uid].getEngines();
|
||||
|
||||
@@ -107,6 +125,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-version', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[uid].getVersion();
|
||||
|
||||
@@ -118,6 +138,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-processes', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[uid].getProcesses();
|
||||
|
||||
@@ -129,6 +151,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('kill-process', async (event, { uid, pid }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[uid].killProcess(pid);
|
||||
|
||||
@@ -140,6 +164,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('use-schema', async (event, { uid, schema }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (!schema) return;
|
||||
|
||||
try {
|
||||
@@ -152,6 +178,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('raw-query', async (event, { uid, query, schema, tabUid, autocommit }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (!query) return;
|
||||
|
||||
try {
|
||||
@@ -171,6 +199,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('export', (event, { uid, type, tables, ...rest }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (exporter !== null) {
|
||||
exporter.kill();
|
||||
return;
|
||||
@@ -245,7 +275,9 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.handle('abort-export', async () => {
|
||||
ipcMain.handle('abort-export', async (event) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
let willAbort = false;
|
||||
|
||||
if (exporter) {
|
||||
@@ -267,6 +299,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('import-sql', async (event, options) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (importer !== null) {
|
||||
importer.kill();
|
||||
return;
|
||||
@@ -318,7 +352,9 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.handle('abort-import-sql', async () => {
|
||||
ipcMain.handle('abort-import-sql', async (event) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
let willAbort = false;
|
||||
|
||||
if (importer) {
|
||||
@@ -340,6 +376,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('kill-tab-query', async (event, { uid, tabUid }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (!tabUid) return;
|
||||
|
||||
try {
|
||||
@@ -352,6 +390,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('commit-tab', async (event, { uid, tabUid }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (!tabUid) return;
|
||||
|
||||
try {
|
||||
@@ -364,6 +404,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('rollback-tab', async (event, { uid, tabUid }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (!tabUid) return;
|
||||
|
||||
try {
|
||||
@@ -376,6 +418,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('destroy-connection-to-commit', async (event, { uid, tabUid }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (!tabUid) return;
|
||||
|
||||
try {
|
||||
|
@@ -1,15 +1,19 @@
|
||||
import * as fs from 'fs';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import customizations from 'common/customizations';
|
||||
import { ARRAY, BIT, BLOB, BOOLEAN, DATE, DATETIME, FLOAT, LONG_TEXT, NUMBER, TEXT, TEXT_SEARCH } from 'common/fieldTypes';
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { InsertRowsParams } from 'common/interfaces/tableApis';
|
||||
import { ipcMain } from 'electron';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import * as moment from 'moment';
|
||||
import { sqlEscaper } from 'common/libs/sqlUtils';
|
||||
import { TEXT, LONG_TEXT, ARRAY, TEXT_SEARCH, NUMBER, FLOAT, BLOB, BIT, DATE, DATETIME, BOOLEAN } from 'common/fieldTypes';
|
||||
import customizations from 'common/customizations';
|
||||
import { ipcMain } from 'electron';
|
||||
import * as fs from 'fs';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-table-columns', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getTableColumns(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -20,6 +24,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-table-data', async (event, { uid, schema, table, limit, page, sortParams, where }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const offset = (page - 1) * limit;
|
||||
const query = connections[uid]
|
||||
@@ -45,6 +51,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-table-count', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getTableApproximateCount(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -55,6 +63,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-table-options', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getTableOptions(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -65,6 +75,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-table-indexes', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getTableIndexes(params);
|
||||
|
||||
@@ -76,6 +88,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-table-ddl', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getTableDll(params);
|
||||
|
||||
@@ -87,6 +101,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-key-usage', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getKeyUsage(params);
|
||||
|
||||
@@ -98,6 +114,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('update-table-cell', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
delete params.row._antares_id;
|
||||
const { stringsWrapper: sw } = customizations[connections[params.uid]._client];
|
||||
|
||||
@@ -227,6 +245,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('delete-table-rows', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
if (params.primary) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const idString = params.rows.map((row: {[key: string]: any}) => {
|
||||
@@ -281,6 +301,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('insert-table-fake-rows', async (event, params: InsertRowsParams) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try { // TODO: move to client classes
|
||||
const rows: {[key: string]: string | number | boolean | Date | Buffer}[] = [];
|
||||
|
||||
@@ -403,6 +425,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('get-foreign-list', async (event, { uid, schema, table, column, description }) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const query = connections[uid]
|
||||
.select(`${column} AS foreign_column`)
|
||||
@@ -436,6 +460,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('create-table', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createTable(params);
|
||||
return { status: 'success' };
|
||||
@@ -446,6 +472,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('alter-table', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterTable(params);
|
||||
return { status: 'success' };
|
||||
@@ -456,6 +484,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('duplicate-table', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].duplicateTable(params);
|
||||
return { status: 'success' };
|
||||
@@ -466,6 +496,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('truncate-table', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].truncateTable(params);
|
||||
return { status: 'success' };
|
||||
@@ -476,6 +508,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('drop-table', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].dropTable(params);
|
||||
return { status: 'success' };
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-trigger-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getTriggerInformations(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -13,6 +17,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('drop-trigger', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].dropTrigger(params);
|
||||
return { status: 'success' };
|
||||
@@ -23,6 +29,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('alter-trigger', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterTrigger(params);
|
||||
return { status: 'success' };
|
||||
@@ -33,6 +41,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('create-trigger', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createTrigger(params);
|
||||
return { status: 'success' };
|
||||
@@ -43,6 +53,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('toggle-trigger', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
if (!params.enabled)
|
||||
await connections[params.uid].enableTrigger(params);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
import * as Store from 'electron-store';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
|
||||
const persistentStore = new Store({
|
||||
name: 'settings',
|
||||
@@ -51,8 +51,8 @@ export default () => {
|
||||
mainWindow.reply('update-not-available');
|
||||
});
|
||||
|
||||
autoUpdater.on('download-progress', data => {
|
||||
mainWindow.reply('download-progress', data);
|
||||
autoUpdater.on('download-progress', event => {
|
||||
mainWindow.reply('download-progress', event);
|
||||
});
|
||||
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-users', async (event, uid) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[uid].getUsers();
|
||||
return { status: 'success', response: result };
|
||||
|
@@ -1,8 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
import { validateSender } from '../libs/misc/validateSender';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-view-informations', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
const result = await connections[params.uid].getViewInformations(params);
|
||||
return { status: 'success', response: result };
|
||||
@@ -13,6 +17,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('drop-view', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].dropView(params);
|
||||
return { status: 'success' };
|
||||
@@ -23,6 +29,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('alter-view', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].alterView(params);
|
||||
return { status: 'success' };
|
||||
@@ -33,6 +41,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
});
|
||||
|
||||
ipcMain.handle('create-view', async (event, params) => {
|
||||
if (!validateSender(event.senderFrame)) return { status: 'error', response: 'Unauthorized process' };
|
||||
|
||||
try {
|
||||
await connections[params.uid].createView(params);
|
||||
return { status: 'success' };
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
|
||||
import { FirebirdSQLClient } from './clients/FirebirdSQLClient';
|
||||
import { MySQLClient } from './clients/MySQLClient';
|
||||
import { PostgreSQLClient } from './clients/PostgreSQLClient';
|
||||
import { SQLiteClient } from './clients/SQLiteClient';
|
||||
import { FirebirdSQLClient } from './clients/FirebirdSQLClient';
|
||||
|
||||
export class ClientsFactory {
|
||||
static getClient (args: antares.ClientParams) {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { ShortcutRecord, shortcuts } from 'common/shortcuts';
|
||||
import { BrowserWindow, globalShortcut, Menu, MenuItem, MenuItemConstructorOptions } from 'electron';
|
||||
import * as Store from 'electron-store';
|
||||
import { ShortcutRecord, shortcuts } from 'common/shortcuts';
|
||||
|
||||
const shortcutsStore = new Store({ name: 'shortcuts' });
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import * as path from 'path';
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as firebird from 'node-firebird';
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
import dataTypes from 'common/data-types/firebird';
|
||||
import { FLOAT, NUMBER } from 'common/fieldTypes';
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as firebird from 'node-firebird';
|
||||
import * as path from 'path';
|
||||
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
|
||||
export class FirebirdSQLClient extends AntaresCore {
|
||||
private _schema?: string;
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import dataTypes from 'common/data-types/mysql';
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as mysql from 'mysql2/promise';
|
||||
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
import dataTypes from 'common/data-types/mysql';
|
||||
import SSH2Promise = require('ssh2-promise');
|
||||
import SSHConfig from 'ssh2-promise/lib/sshConfig';
|
||||
|
||||
@@ -155,7 +156,6 @@ export class MySQLClient extends AntaresCore {
|
||||
|
||||
this._ssh = new SSH2Promise({
|
||||
...this._params.ssh,
|
||||
keepaliveInterval: 30*60*1000,
|
||||
debug: process.env.NODE_ENV !== 'production' ? (s) => console.log(s) : null
|
||||
});
|
||||
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import dataTypes from 'common/data-types/postgresql';
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as pg from 'pg';
|
||||
import * as pgAst from 'pgsql-ast-parser';
|
||||
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
import dataTypes from 'common/data-types/postgresql';
|
||||
import SSH2Promise = require('ssh2-promise');
|
||||
import SSHConfig from 'ssh2-promise/lib/sshConfig';
|
||||
import { ConnectionOptions } from 'tls';
|
||||
@@ -167,7 +168,6 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
try {
|
||||
this._ssh = new SSH2Promise({
|
||||
...this._params.ssh,
|
||||
keepaliveInterval: 30*60*1000,
|
||||
debug: process.env.NODE_ENV !== 'production' ? (s) => console.log(s) : null
|
||||
});
|
||||
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as sqlite from 'better-sqlite3';
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
import dataTypes from 'common/data-types/sqlite';
|
||||
import { NUMBER, FLOAT, TIME, DATETIME } from 'common/fieldTypes';
|
||||
import { DATETIME, FLOAT, NUMBER, TIME } from 'common/fieldTypes';
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
|
||||
import { AntaresCore } from '../AntaresCore';
|
||||
|
||||
export class SQLiteClient extends AntaresCore {
|
||||
private _schema?: string;
|
||||
@@ -34,8 +35,8 @@ export class SQLiteClient extends AntaresCore {
|
||||
});
|
||||
}
|
||||
|
||||
destroy (): void {
|
||||
return null;
|
||||
destroy () {
|
||||
this._connection.close();
|
||||
}
|
||||
|
||||
use (): void {
|
||||
@@ -295,7 +296,13 @@ export class SQLiteClient extends AntaresCore {
|
||||
// ADD FIELDS
|
||||
fields.forEach(field => {
|
||||
const typeInfo = this.getTypeInfo(field.type);
|
||||
const length = typeInfo?.length ? field.enumValues || field.numLength || field.charLength || field.datePrecision : false;
|
||||
const length = typeInfo?.length
|
||||
? field.enumValues ||
|
||||
field.numLength ||
|
||||
field.numPrecision ||
|
||||
field.charLength ||
|
||||
field.datePrecision
|
||||
: false;
|
||||
|
||||
newColumns.push(`"${field.name}"
|
||||
${field.type.toUpperCase()}${length ? `(${length})` : ''}
|
||||
@@ -425,7 +432,7 @@ export class SQLiteClient extends AntaresCore {
|
||||
|
||||
return results.rows.map(row => {
|
||||
return {
|
||||
sql: row.sql.match(/(?<=AS ).*?$/gs)[0],
|
||||
sql: row.sql.match(/(?<=(AS|as)( |\n)).*?$/gs)[0],
|
||||
name: view
|
||||
};
|
||||
})[0];
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import * as exporter from 'common/interfaces/exporter';
|
||||
import * as fs from 'fs';
|
||||
import { createGzip, Gzip } from 'zlib';
|
||||
import * as path from 'path';
|
||||
import * as EventEmitter from 'events';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { createGzip, Gzip } from 'zlib';
|
||||
|
||||
export class BaseExporter extends EventEmitter {
|
||||
protected _tables;
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import * as exporter from 'common/interfaces/exporter';
|
||||
import * as mysql from 'mysql2/promise';
|
||||
import { SqlExporter } from './SqlExporter';
|
||||
import { MySQLClient } from '../../clients/MySQLClient';
|
||||
import { valueToSqlString } from 'common/libs/sqlUtils';
|
||||
import * as mysql from 'mysql2/promise';
|
||||
|
||||
import { MySQLClient } from '../../clients/MySQLClient';
|
||||
import { SqlExporter } from './SqlExporter';
|
||||
|
||||
export default class MysqlExporter extends SqlExporter {
|
||||
protected _client: MySQLClient;
|
||||
|
@@ -1,11 +1,12 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as exporter from 'common/interfaces/exporter';
|
||||
import { SqlExporter } from './SqlExporter';
|
||||
import { valueToSqlString } from 'common/libs/sqlUtils';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import * as QueryStream from 'pg-query-stream';
|
||||
|
||||
import { PostgreSQLClient } from '../../clients/PostgreSQLClient';
|
||||
import { valueToSqlString } from 'common/libs/sqlUtils';
|
||||
import { SqlExporter } from './SqlExporter';
|
||||
|
||||
export default class PostgreSQLExporter extends SqlExporter {
|
||||
constructor (client: PostgreSQLClient, tables: exporter.TableParams[], options: exporter.ExportOptions) {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { MySQLClient } from '../../clients/MySQLClient';
|
||||
import { PostgreSQLClient } from '../../clients/PostgreSQLClient';
|
||||
import { BaseExporter } from '../BaseExporter';
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import * as importer from 'common/interfaces/importer';
|
||||
import * as fs from 'fs';
|
||||
import * as EventEmitter from 'events';
|
||||
import * as fs from 'fs';
|
||||
|
||||
export class BaseImporter extends EventEmitter {
|
||||
protected _options;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import * as mysql from 'mysql2';
|
||||
import * as importer from 'common/interfaces/importer';
|
||||
import * as fs from 'fs/promises';
|
||||
import * as mysql from 'mysql2';
|
||||
|
||||
import MySQLParser from '../../parsers/MySQLParser';
|
||||
import { BaseImporter } from '../BaseImporter';
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import * as pg from 'pg';
|
||||
import * as importer from 'common/interfaces/importer';
|
||||
import * as fs from 'fs/promises';
|
||||
import * as pg from 'pg';
|
||||
|
||||
import PostgreSQLParser from '../../parsers/PostgreSQLParser';
|
||||
import { BaseImporter } from '../BaseImporter';
|
||||
|
||||
|
15
src/main/libs/misc/validateSender.ts
Normal file
15
src/main/libs/misc/validateSender.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { WebFrameMain } from 'electron';
|
||||
import * as path from 'path';
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
const isWindows = process.platform === 'win32';
|
||||
const indexPath = path.resolve(__dirname, 'index.html').split(path.sep).join('/');
|
||||
|
||||
export function validateSender (frame: WebFrameMain) {
|
||||
const frameUrl = new URL(frame.url);
|
||||
const prefix = isWindows ? 'file:///' : 'file://';
|
||||
const framePath = frameUrl.href.replace(prefix, '');
|
||||
|
||||
if ((isDevelopment && frameUrl.host === 'localhost:9080') || framePath === indexPath) return true;
|
||||
return false;
|
||||
}
|
@@ -1,8 +1,8 @@
|
||||
import { app, BrowserWindow, nativeImage, ipcMain } from 'electron';
|
||||
import * as path from 'path';
|
||||
import * as remoteMain from '@electron/remote/main';
|
||||
import { app, BrowserWindow, ipcMain, nativeImage } from 'electron';
|
||||
import * as Store from 'electron-store';
|
||||
import * as windowStateKeeper from 'electron-window-state';
|
||||
import * as remoteMain from '@electron/remote/main';
|
||||
import * as path from 'path';
|
||||
|
||||
import ipcHandlers from './ipc-handlers';
|
||||
import { OsMenu, ShortcutRegister } from './libs/ShortcutRegister';
|
||||
@@ -142,6 +142,14 @@ else {
|
||||
const extensionPath = path.resolve(__dirname, `../../misc/${antares.devtoolsId}`);
|
||||
window.webContents.session.loadExtension(extensionPath, { allowFileAccess: true }).catch(console.error);
|
||||
}
|
||||
|
||||
window.webContents.on('will-navigate', (e) => { // Prevent browser navigation
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
window.webContents.on('did-create-window', (w) => { // Close new windows
|
||||
w.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { MySQLClient } from '../libs/clients/MySQLClient';
|
||||
import { PostgreSQLClient } from '../libs/clients/PostgreSQLClient';
|
||||
import { ClientsFactory } from '../libs/ClientsFactory';
|
||||
|
@@ -1,13 +1,14 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as pg from 'pg';
|
||||
import { ImportOptions } from 'common/interfaces/importer';
|
||||
import * as mysql from 'mysql2';
|
||||
import * as pg from 'pg';
|
||||
import SSHConfig from 'ssh2-promise/lib/sshConfig';
|
||||
|
||||
import { MySQLClient } from '../libs/clients/MySQLClient';
|
||||
import { PostgreSQLClient } from '../libs/clients/PostgreSQLClient';
|
||||
import { ClientsFactory } from '../libs/ClientsFactory';
|
||||
import MySQLImporter from '../libs/importers/sql/MySQLlImporter';
|
||||
import PostgreSQLImporter from '../libs/importers/sql/PostgreSQLImporter';
|
||||
import SSHConfig from 'ssh2-promise/lib/sshConfig';
|
||||
import { ImportOptions } from 'common/interfaces/importer';
|
||||
let importer: antares.Importer;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
@@ -34,18 +34,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineAsyncComponent, onMounted, Ref, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCurrentWindow, Menu } from '@electron/remote';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { defineAsyncComponent, onMounted, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { Menu, getCurrentWindow } from '@electron/remote';
|
||||
|
||||
import ModalExportSchema from '@/components/ModalExportSchema.vue';
|
||||
import TheSettingBar from '@/components/TheSettingBar.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useSchemaExportStore } from '@/stores/schemaExport';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import TheSettingBar from '@/components/TheSettingBar.vue';
|
||||
import ModalExportSchema from '@/components/ModalExportSchema.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -47,10 +47,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { computed, onBeforeUnmount, PropType, useSlots } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps({
|
||||
|
62
src/renderer/components/BaseIcon.vue
Normal file
62
src/renderer/components/BaseIcon.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<SvgIcon
|
||||
:type="type"
|
||||
:path="iconPath"
|
||||
:size="size"
|
||||
:rotate="rotate"
|
||||
:class="iconFlip"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SvgIcon from '@jamescoyle/vue-icon';
|
||||
import * as Icons from '@mdi/js';
|
||||
import { computed, PropType } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
iconName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 48
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: () => 'mdi'
|
||||
},
|
||||
flip: {
|
||||
type: String as PropType<'horizontal' | 'vertical' | 'both'>,
|
||||
default: () => null
|
||||
},
|
||||
rotate: {
|
||||
type: Number,
|
||||
default: () => null
|
||||
}
|
||||
});
|
||||
|
||||
const iconPath = computed(() => {
|
||||
return (Icons as {[k:string]: string})[props.iconName];
|
||||
});
|
||||
|
||||
const iconFlip = computed(() => {
|
||||
if (['horizontal', 'vertical', 'both'].includes(props.flip))
|
||||
return `flip-${props.flip}`;
|
||||
else return '';
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.flip-horizontal {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
.flip-vertical {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
|
||||
.flip-both {
|
||||
transform: scale(-1, -1);
|
||||
}
|
||||
</style>
|
@@ -3,15 +3,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, PropType, Ref, ref } from 'vue';
|
||||
import * as L from 'leaflet';
|
||||
import {
|
||||
point,
|
||||
lineString,
|
||||
point,
|
||||
polygon
|
||||
} from '@turf/helpers';
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import { getArrayDepth } from 'common/libs/getArrayDepth';
|
||||
import { GeoJsonObject } from 'geojson';
|
||||
import * as L from 'leaflet';
|
||||
import { onMounted, PropType, Ref, ref } from 'vue';
|
||||
|
||||
interface Coordinates { x: number; y: number }
|
||||
|
||||
|
@@ -1,13 +1,18 @@
|
||||
<template>
|
||||
<div class="toast mt-2" :class="notificationStatus.className">
|
||||
<span class="p-vcentered text-left" :class="{'expanded': isExpanded}">
|
||||
<i class="mdi mdi-24px mr-2" :class="notificationStatus.iconName" />
|
||||
<BaseIcon
|
||||
:icon-name="notificationStatus.iconName"
|
||||
class="mr-2"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="notification-message">{{ message }}</span>
|
||||
</span>
|
||||
<i
|
||||
<BaseIcon
|
||||
v-if="isExpandable"
|
||||
class="mdi mdi-24px c-hand expand-btn"
|
||||
:class="isExpanded ? 'mdi-chevron-up' : 'mdi-chevron-down'"
|
||||
:icon-name="isExpanded ? 'mdiChevronUp' : 'mdiChevronDown'"
|
||||
class=" c-hand expand-btn"
|
||||
:size="24"
|
||||
@click="toggleExpand"
|
||||
/>
|
||||
<button class="btn btn-clear ml-2" @click="hideToast" />
|
||||
@@ -17,6 +22,8 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
|
||||
const props = defineProps({
|
||||
message: {
|
||||
type: String,
|
||||
@@ -36,19 +43,19 @@ const notificationStatus = computed(() => {
|
||||
switch (props.status) {
|
||||
case 'success':
|
||||
className = 'toast-success';
|
||||
iconName = 'mdi-check';
|
||||
iconName = 'mdiCheck';
|
||||
break;
|
||||
case 'error':
|
||||
className = 'toast-error';
|
||||
iconName = 'mdi-alert-rhombus';
|
||||
iconName = 'mdiAlertRhombus';
|
||||
break;
|
||||
case 'warning':
|
||||
className = 'toast-warning';
|
||||
iconName = 'mdi-alert';
|
||||
iconName = 'mdiAlert';
|
||||
break;
|
||||
case 'primary':
|
||||
className = 'toast-primary';
|
||||
iconName = 'mdi-information-outline';
|
||||
iconName = 'mdiInformationOutline';
|
||||
break;
|
||||
}
|
||||
|
||||
|
@@ -70,7 +70,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, computed, ref, watch, nextTick, onMounted, onUnmounted } from 'vue';
|
||||
import { computed, defineComponent, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BaseSelect',
|
||||
|
@@ -10,12 +10,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, watch } from 'vue';
|
||||
/* eslint-disable simple-import-sort/imports */
|
||||
import * as ace from 'ace-builds';
|
||||
import 'ace-builds/webpack-resolver';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
/* eslint-enable simple-import-sort/imports */
|
||||
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { onMounted, watch } from 'vue';
|
||||
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: String,
|
||||
@@ -132,9 +136,4 @@ onMounted(() => {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.ace_.mdi {
|
||||
display: inline-block;
|
||||
width: 17px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,76 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
:style="{display: isVisible ? 'flex' : 'none'}"
|
||||
class="toast mt-2"
|
||||
:class="toastStatus.className"
|
||||
>
|
||||
<span class="p-vcentered text-left"><i class="mdi mdi-24px mr-1" :class="toastStatus.iconName" /> {{ message }}</span>
|
||||
<button class="btn btn-clear" @click="hideToast" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
message: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
});
|
||||
|
||||
const isVisible = ref(false);
|
||||
const message = ref(props.message);
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const toastStatus = computed(() => {
|
||||
let className = '';
|
||||
let iconName = '';
|
||||
switch (props.status) {
|
||||
case 'success':
|
||||
className = 'toast-success';
|
||||
iconName = 'mdi-check';
|
||||
break;
|
||||
case 'error':
|
||||
className = 'toast-error';
|
||||
iconName = 'mdi-alert-rhombus';
|
||||
break;
|
||||
case 'warning':
|
||||
className = 'toast-warning';
|
||||
iconName = 'mdi-alert';
|
||||
break;
|
||||
case 'primary':
|
||||
className = 'toast-primary';
|
||||
iconName = 'mdi-information-outline';
|
||||
break;
|
||||
}
|
||||
|
||||
return { className, iconName };
|
||||
});
|
||||
|
||||
watch(message, () => {
|
||||
if (message.value)
|
||||
isVisible.value = true;
|
||||
else
|
||||
isVisible.value = false;
|
||||
});
|
||||
|
||||
const hideToast = () => {
|
||||
isVisible.value = false;
|
||||
emit('close');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toast {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
user-select: text;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
@@ -1,14 +1,20 @@
|
||||
<template>
|
||||
<label :for="`id_${id}`" class="file-uploader">
|
||||
<span class="file-uploader-message">
|
||||
<i class="mdi mdi-folder-open mr-1" />{{ message }}
|
||||
<BaseIcon
|
||||
icon-name="mdiFolderOpen"
|
||||
class="mr-1 mt-1"
|
||||
:size="18"
|
||||
/>{{ message }}
|
||||
</span>
|
||||
<span class="text-ellipsis file-uploader-value">
|
||||
{{ lastPart(modelValue, 19) }}
|
||||
</span>
|
||||
<i
|
||||
<BaseIcon
|
||||
v-if="modelValue"
|
||||
class="file-uploader-reset mdi mdi-close"
|
||||
class="file-upload-icon-clear"
|
||||
icon-name="mdiClose"
|
||||
:size="18"
|
||||
@click.prevent="clear"
|
||||
/>
|
||||
<form :ref="`form_${id}`">
|
||||
@@ -16,6 +22,7 @@
|
||||
:id="`id_${id}`"
|
||||
class="file-uploader-input"
|
||||
type="file"
|
||||
:accept="accept"
|
||||
@change="$emit('change', $event)"
|
||||
>
|
||||
</form>
|
||||
@@ -24,6 +31,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
|
||||
const { lastPart } = useFilters();
|
||||
@@ -33,6 +42,10 @@ defineProps({
|
||||
default: 'Browse',
|
||||
type: String
|
||||
},
|
||||
accept: {
|
||||
default: '',
|
||||
type: String
|
||||
},
|
||||
modelValue: {
|
||||
default: '',
|
||||
type: String
|
||||
@@ -59,6 +72,12 @@ const clear = () => {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
|
||||
.file-upload-icon-clear {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
> span {
|
||||
padding: 0.25rem 0.4rem;
|
||||
}
|
||||
|
@@ -86,13 +86,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FakerMethods from 'common/FakerMethods';
|
||||
import { BIT, BLOB, DATE, DATETIME, FLOAT, IS_BIGINT, LONG_TEXT, NUMBER, TEXT, TIME, UUID } from 'common/fieldTypes';
|
||||
import { computed, PropType, Ref, ref, watch } from 'vue';
|
||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT, UUID, IS_BIGINT } from 'common/fieldTypes';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput.vue';
|
||||
import ForeignKeySelect from '@/components/ForeignKeySelect.vue';
|
||||
import FakerMethods from 'common/FakerMethods';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -13,15 +13,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, Ref, ref, watch } from 'vue';
|
||||
import { LONG_TEXT, TEXT } from 'common/fieldTypes';
|
||||
import { TableField } from 'common/interfaces/antares';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, Ref, ref, watch } from 'vue';
|
||||
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { TEXT, LONG_TEXT } from 'common/fieldTypes';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { TableField } from 'common/interfaces/antares';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: [String, Number],
|
||||
|
@@ -9,12 +9,18 @@
|
||||
@blur="isFocus = false"
|
||||
@keydown.prevent.stop="onKey"
|
||||
>
|
||||
<i class="form-icon mdi mdi-keyboard-outline mdi-24px" />
|
||||
<BaseIcon
|
||||
icon-name="mdiKeyboardOutline"
|
||||
class="form-icon"
|
||||
:size="24"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import Application from '@/ipc-api/Application';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-apps mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiApps"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('connection.allConnections') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,10 +28,17 @@
|
||||
:placeholder="t('connection.searchForConnections')"
|
||||
@keypress.esc="searchTerm = ''"
|
||||
>
|
||||
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px pr-4" />
|
||||
<i
|
||||
<BaseIcon
|
||||
v-if="!searchTerm"
|
||||
icon-name="mdiMagnify"
|
||||
class="form-icon pr-4"
|
||||
:size="18"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="form-icon c-hand mdi mdi-backspace mdi-18px pr-4"
|
||||
icon-name="mdiBackspace"
|
||||
class="form-icon c-hand pr-4"
|
||||
:size="18"
|
||||
@click="searchTerm = ''"
|
||||
/>
|
||||
</div>
|
||||
@@ -56,9 +67,11 @@
|
||||
{{ clients.get(connection.client) || connection.client }}
|
||||
</div>
|
||||
<div class="all-connections-buttons p-absolute d-flex" :style="'top: 0; right: 0;'">
|
||||
<i
|
||||
class="all-connections-delete mdi mdi-delete mdi-18px ml-2"
|
||||
<BaseIcon
|
||||
icon-name="mdiDelete"
|
||||
class="all-connections-delete ml-2"
|
||||
:title="t('general.delete')"
|
||||
:size="18"
|
||||
@click.stop="askToDelete(connection)"
|
||||
/>
|
||||
</div>
|
||||
@@ -66,32 +79,57 @@
|
||||
<div class="panel-body text-center">
|
||||
<div v-if="connection.databasePath">
|
||||
<div class="text-ellipsis" :title="connection.databasePath">
|
||||
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{
|
||||
<BaseIcon
|
||||
icon-name="mdiDatabase"
|
||||
class="p-relative"
|
||||
:style="'top:3px'"
|
||||
:size="18"
|
||||
/> <span class="text-bold">{{
|
||||
connection.databasePath
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="text-ellipsis" :title="`${connection.host}:${connection.port}`">
|
||||
<i class="mdi mdi-server d-inline" /> <span class="text-bold">{{ connection.host
|
||||
<BaseIcon
|
||||
icon-name="mdiServer"
|
||||
class="p-relative"
|
||||
:style="'top:3px'"
|
||||
:size="18"
|
||||
/> <span class="text-bold">{{ connection.host
|
||||
}}:{{ connection.port }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="connection.user">
|
||||
<div class="text-ellipsis">
|
||||
<i class="mdi mdi-account d-inline" /> <span class="text-bold">{{ connection.user
|
||||
<BaseIcon
|
||||
icon-name="mdiAccount"
|
||||
class="p-relative"
|
||||
:style="'top:3px'"
|
||||
:size="18"
|
||||
/> <span class="text-bold">{{ connection.user
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="connection.schema">
|
||||
<div class="text-ellipsis">
|
||||
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.schema
|
||||
<BaseIcon
|
||||
icon-name="mdiDatabase"
|
||||
class="p-relative"
|
||||
:style="'top:3px'"
|
||||
:size="18"
|
||||
/> <span class="text-bold">{{ connection.schema
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="connection.database">
|
||||
<div class="text-ellipsis">
|
||||
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{
|
||||
<BaseIcon
|
||||
icon-name="mdiDatabase"
|
||||
class="p-relative"
|
||||
:style="'top:3px'"
|
||||
:size="18"
|
||||
/> <span class="text-bold">{{
|
||||
connection.database
|
||||
}}</span>
|
||||
</div>
|
||||
@@ -99,11 +137,19 @@
|
||||
</div>
|
||||
<div class="panel-footer text-center py-0">
|
||||
<div v-if="connection.ssl" class="chip bg-success mt-2">
|
||||
<i class="mdi mdi-shield-key mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiShieldKey"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
SSL
|
||||
</div>
|
||||
<div v-if="connection.ssh" class="chip bg-success mt-2">
|
||||
<i class="mdi mdi-console-network mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiConsoleNetwork"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
SSH
|
||||
</div>
|
||||
</div>
|
||||
@@ -130,7 +176,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-server-remove mr-1" /> {{ t('connection.deleteConnection') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiServerRemove"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('connection.deleteConnection') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -143,14 +193,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-key-variant mr-1" /> {{ t('connection.credentials') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiKeyVariant"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('connection.credentials') }}
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -57,9 +61,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Ref, ref } from 'vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { trapRef } = useFocusTrap();
|
||||
|
@@ -8,7 +8,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-play mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiPlay"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('database.parameters') }}: {{ localRoutine.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -48,13 +52,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, Ref, ref } from 'vue';
|
||||
import { NUMBER, FLOAT } from 'common/fieldTypes';
|
||||
import { FLOAT, NUMBER } from 'common/fieldTypes';
|
||||
import { FunctionInfos, RoutineInfos } from 'common/interfaces/antares';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import { computed, PropType, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const { wrapNumber } = useFilters();
|
||||
|
@@ -6,8 +6,12 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-brush-variant mr-1" />
|
||||
<span class="cut-text">{{ t('connection.editConnectionAppearance') }}</span>
|
||||
<BaseIcon
|
||||
icon-name="mdiBrushVariant"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('application.editConnectionAppearance') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -37,11 +41,24 @@
|
||||
<div
|
||||
v-for="icon in icons"
|
||||
:key="icon.name"
|
||||
class="icon-box"
|
||||
:title="icon.name"
|
||||
:class="[icon.code ? `mdi ${icon.code} mdi-36px` : `dbi dbi-${connection.client}`, {'selected': localConnection.icon === icon.code}]"
|
||||
@click="localConnection.icon = icon.code"
|
||||
/>
|
||||
>
|
||||
<BaseIcon
|
||||
v-if="icon.code"
|
||||
:icon-name="camelize(icon.code)"
|
||||
:size="36"
|
||||
class="icon-box"
|
||||
:title="icon.name"
|
||||
:class="[{'selected': localConnection.icon === icon.code}]"
|
||||
@click="localConnection.icon = icon.code"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="icon-box"
|
||||
:title="icon.name"
|
||||
:class="[`dbi dbi-${connection.client}`, {'selected': localConnection.icon === icon.code}]"
|
||||
@click="localConnection.icon = icon.code"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -62,10 +79,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, PropType, Ref, ref } from 'vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { unproxify } from '@/libs/unproxify';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
|
||||
const connectionsStore = useConnectionsStore();
|
||||
|
||||
@@ -141,6 +160,16 @@ const editFolderAppearance = () => {
|
||||
closeModal();
|
||||
};
|
||||
|
||||
const camelize = (text: string) => {
|
||||
const textArr = text.split('-');
|
||||
for (let i = 0; i < textArr.length; i++) {
|
||||
if (i === 0) continue;
|
||||
textArr[i] = textArr[i].charAt(0).toUpperCase() + textArr[i].slice(1);
|
||||
}
|
||||
|
||||
return textArr.join('');
|
||||
};
|
||||
|
||||
const closeModal = () => emit('close');
|
||||
|
||||
const onKey =(e: KeyboardEvent) => {
|
||||
|
@@ -7,7 +7,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-content-save-alert mr-1" /> {{ t('application.unsavedChanges') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiContentSaveAlert"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.unsavedChanges') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -19,10 +23,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import { onBeforeUnmount } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const emit = defineEmits(['confirm', 'close']);
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-edit mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiDatabaseEdit"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('database.editSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,14 +68,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import Schema from '@/ipc-api/Schema';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-export mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiDatabaseExport"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('database.exportSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -26,7 +30,7 @@
|
||||
type="text"
|
||||
required
|
||||
readonly
|
||||
:placeholder="t('database.schemaName')"
|
||||
@click.prevent="openPathDialog"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
@@ -44,7 +48,11 @@
|
||||
<div class="column col-8 left">
|
||||
<div class="columns mb-2 mt-1 p-vcentered">
|
||||
<div class="column col-auto input-group d-flex text-italic" :style="'flex-grow: 1'">
|
||||
<i class="input-group-addon mdi mdi-file-document-outline" />
|
||||
<BaseIcon
|
||||
icon-name="mdiFileDocumentOutline"
|
||||
class="input-group-addon"
|
||||
:size="36"
|
||||
/>
|
||||
<input
|
||||
v-model="chosenFilename"
|
||||
class="form-input"
|
||||
@@ -56,27 +64,27 @@
|
||||
|
||||
<div class="column col-auto col-ml-auto ">
|
||||
<button
|
||||
class="btn btn-dark btn-sm"
|
||||
class="btn btn-dark btn-sm pt-1"
|
||||
:title="t('general.refresh')"
|
||||
@click="refresh"
|
||||
>
|
||||
<i class="mdi mdi-refresh" />
|
||||
<BaseIcon icon-name="mdiRefresh" :size="15" />
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm mx-1"
|
||||
class="btn btn-dark btn-sm mx-1 pt-1"
|
||||
:title="t('database.uncheckAllTables')"
|
||||
:disabled="isRefreshing"
|
||||
@click="uncheckAllTables"
|
||||
>
|
||||
<i class="mdi mdi-checkbox-blank-outline" />
|
||||
<BaseIcon icon-name="mdiCheckboxBlankOutline" :size="15" />
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm"
|
||||
class="btn btn-dark btn-sm pt-1"
|
||||
:title="t('database.checkAllTables')"
|
||||
:disabled="isRefreshing"
|
||||
@click="checkAllTables"
|
||||
>
|
||||
<i class="mdi mdi-checkbox-marked-outline" />
|
||||
<BaseIcon icon-name="mdiCheckboxMarkedOutline" :size="15" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -251,7 +259,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="column col-auto px-0">
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
<button class="btn btn-link mr-2" @click.stop="closeModal">
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
<button
|
||||
@@ -271,21 +279,23 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import * as moment from 'moment';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ClientCode, SchemaInfos } from 'common/interfaces/antares';
|
||||
import { Customizations } from 'common/interfaces/customizations';
|
||||
import { ExportOptions, ExportState } from 'common/interfaces/exporter';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useSchemaExportStore } from '@/stores/schemaExport';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import * as moment from 'moment';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import Application from '@/ipc-api/Application';
|
||||
import Schema from '@/ipc-api/Schema';
|
||||
import { Customizations } from 'common/interfaces/customizations';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useSchemaExportStore } from '@/stores/schemaExport';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
const { t } = useI18n();
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-playlist-plus mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiPlaylistPlus"
|
||||
:size="24"
|
||||
class="mr-1"
|
||||
/>
|
||||
<span class="cut-text">{{ t('database.insertRow', 2) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,7 +68,7 @@
|
||||
:disabled="isInserting"
|
||||
>
|
||||
<span class="input-group-addon">
|
||||
<i class="mdi mdi-24px mdi-repeat" />
|
||||
<BaseIcon icon-name="mdiRepeat" :size="24" />
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -98,19 +102,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeMount, onMounted, Prop, Ref, ref, watch } from 'vue';
|
||||
import * as moment from 'moment';
|
||||
import { BIT, BLOB, DATE, DATETIME, FLOAT, LONG_TEXT, NUMBER, TEXT, TIME } from 'common/fieldTypes';
|
||||
import { TableField, TableForeign } from 'common/interfaces/antares';
|
||||
import * as moment from 'moment';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { computed, onBeforeMount, onMounted, Prop, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import FakerSelect from '@/components/FakerSelect.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import FakerSelect from '@/components/FakerSelect.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-folder-edit mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiFolderEdit"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('application.editFolder') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,7 +47,11 @@
|
||||
:style="`background-color: ${color.hex}`"
|
||||
@click="localFolder.color = color.hex"
|
||||
>
|
||||
<i v-if="localFolder.color === color.hex" class="mdi mdi-check" />
|
||||
<BaseIcon
|
||||
v-if="localFolder.color === color.hex"
|
||||
icon-name="mdiCheck"
|
||||
:size="16"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,10 +73,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, PropType, Ref, ref } from 'vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { unproxify } from '@/libs/unproxify';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
|
||||
const connectionsStore = useConnectionsStore();
|
||||
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-history mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiHistory"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('general.history') }}: {{ connectionName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,17 +28,24 @@
|
||||
type="text"
|
||||
:placeholder="t('database.searchForQueries')"
|
||||
>
|
||||
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px pr-4" />
|
||||
<i
|
||||
<BaseIcon
|
||||
v-if="!searchTerm"
|
||||
icon-name="mdiMagnify"
|
||||
class="form-icon pr-2"
|
||||
:size="18"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="form-icon c-hand mdi mdi-backspace mdi-18px pr-4"
|
||||
icon-name="mdiBackspace"
|
||||
class="form-icon c-hand pr-2"
|
||||
:size="18"
|
||||
@click="searchTerm = ''"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="history.length"
|
||||
ref="tableWrapper"
|
||||
class="vscroll px-1 "
|
||||
class="vscroll px-1"
|
||||
:style="{'height': resultsSize+'px'}"
|
||||
>
|
||||
<div ref="table">
|
||||
@@ -53,7 +64,11 @@
|
||||
tabindex="0"
|
||||
>
|
||||
<div class="tile-icon">
|
||||
<i class="mdi mdi-code-tags pr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiCodeTags"
|
||||
class="pr-1"
|
||||
:size="24"
|
||||
/>
|
||||
</div>
|
||||
<div class="tile-content">
|
||||
<div class="tile-title">
|
||||
@@ -67,13 +82,25 @@
|
||||
<small class="tile-subtitle">{{ query.schema }} · {{ formatDate(query.date) }}</small>
|
||||
<div class="tile-history-buttons">
|
||||
<button class="btn btn-link pl-1" @click.stop="$emit('select-query', query.sql)">
|
||||
<i class="mdi mdi-open-in-app pr-1" /> {{ t('general.select') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiOpenInApp"
|
||||
class="pr-1"
|
||||
:size="22"
|
||||
/> {{ t('general.select') }}
|
||||
</button>
|
||||
<button class="btn btn-link pl-1" @click="copyQuery(query.sql)">
|
||||
<i class="mdi mdi-content-copy pr-1" /> {{ t('general.copy') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiContentCopy"
|
||||
class="pr-1"
|
||||
:size="22"
|
||||
/> {{ t('general.copy') }}
|
||||
</button>
|
||||
<button class="btn btn-link pl-1" @click="deleteQuery(query)">
|
||||
<i class="mdi mdi-delete-forever pr-1" /> {{ t('general.delete') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiDeleteForever"
|
||||
class="pr-1"
|
||||
:size="22"
|
||||
/> {{ t('general.delete') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -85,7 +112,7 @@
|
||||
</div>
|
||||
<div v-else class="empty">
|
||||
<div class="empty-icon">
|
||||
<i class="mdi mdi-history mdi-48px" />
|
||||
<BaseIcon icon-name="mdiHistory" :size="48" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ t('database.thereIsNoQueriesYet') }}
|
||||
@@ -98,14 +125,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { Component, computed, ComputedRef, onBeforeUnmount, onMounted, onUpdated, Prop, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { HistoryRecord, useHistoryStore } from '@/stores/history';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { HistoryRecord, useHistoryStore } from '@/stores/history';
|
||||
|
||||
const { t } = useI18n();
|
||||
const { formatDate } = useFilters();
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-import mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiDatabaseImport"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('database.importSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -50,15 +54,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { ImportState } from 'common/interfaces/importer';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import * as moment from 'moment';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import Schema from '@/ipc-api/Schema';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import Schema from '@/ipc-api/Schema';
|
||||
import { ImportState } from 'common/interfaces/importer';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-plus mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiDatabasePlus"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('database.createNewSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,14 +71,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import Schema from '@/ipc-api/Schema';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -16,7 +16,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-memory mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiMemory"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('database.processesList') }}: {{ connectionName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -32,11 +36,21 @@
|
||||
:title="`${t('general.refresh')}`"
|
||||
@click="getProcessesList"
|
||||
>
|
||||
<i v-if="!+autorefreshTimer" class="mdi mdi-24px mdi-refresh mr-1" />
|
||||
<i v-else class="mdi mdi-24px mdi-history mdi-flip-h mr-1" />
|
||||
<BaseIcon
|
||||
v-if="!+autorefreshTimer"
|
||||
icon-name="mdiRefresh"
|
||||
:size="24"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
icon-name="mdiHistory"
|
||||
flip="horizontal"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
</button>
|
||||
<div class="btn btn-dark btn-sm dropdown-toggle pl-0 pr-0" tabindex="0">
|
||||
<i class="mdi mdi-24px mdi-menu-down" />
|
||||
<BaseIcon icon-name="mdiMenuDown" :size="24" />
|
||||
</div>
|
||||
<div class="menu px-3">
|
||||
<span>{{ t('general.autoRefresh') }}: <b>{{ +autorefreshTimer ? `${autorefreshTimer}s` : 'OFF' }}</b></span>
|
||||
@@ -58,9 +72,9 @@
|
||||
class="btn btn-dark btn-sm dropdown-toggle d-flex mr-0 pr-0"
|
||||
tabindex="0"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||
<BaseIcon icon-name="mdiFileExport" :size="24" />
|
||||
<span>{{ t('database.export') }}</span>
|
||||
<i class="mdi mdi-24px mdi-menu-down" />
|
||||
<BaseIcon icon-name="mdiMenuDown" :size="24" />
|
||||
</button>
|
||||
<ul class="menu text-left">
|
||||
<li class="menu-item">
|
||||
@@ -95,10 +109,12 @@
|
||||
<div ref="columnResize" class="column-resizable">
|
||||
<div class="table-column-title" @click="sort(field)">
|
||||
<span>{{ field.toUpperCase() }}</span>
|
||||
<i
|
||||
|
||||
<BaseIcon
|
||||
v-if="currentSort === field"
|
||||
class="mdi sort-icon"
|
||||
:class="currentSortDir === 'asc' ? 'mdi-sort-ascending':'mdi-sort-descending'"
|
||||
:icon-name="currentSortDir === 'asc' ? 'mdiSortAscending':'mdiSortDescending'"
|
||||
:size="18"
|
||||
class="ml-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,18 +150,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Component, computed, onBeforeUnmount, onMounted, onUpdated, Prop, Ref, ref } from 'vue';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { exportRows } from '../libs/exportRows';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { Component, computed, onBeforeUnmount, onMounted, onUpdated, Prop, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue';
|
||||
import ModalProcessesListContext from '@/components/ModalProcessesListContext.vue';
|
||||
import ModalProcessesListRow from '@/components/ModalProcessesListRow.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import Schema from '@/ipc-api/Schema';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue';
|
||||
import ModalProcessesListRow from '@/components/ModalProcessesListRow.vue';
|
||||
import ModalProcessesListContext from '@/components/ModalProcessesListContext.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
|
||||
import { exportRows } from '../libs/exportRows';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -4,8 +4,16 @@
|
||||
@close-context="closeContext"
|
||||
>
|
||||
<div v-if="props.selectedRow" class="context-element">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-copy text-light pr-1" /> {{ t('general.copy') }}</span>
|
||||
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
|
||||
<span class="d-flex"><BaseIcon
|
||||
icon-name="mdiContentCopy"
|
||||
class="text-light mt-1 mr-1"
|
||||
:size="18"
|
||||
/> {{ t('general.copy') }}</span>
|
||||
<BaseIcon
|
||||
icon-name="mdiChevronRight"
|
||||
class="text-light"
|
||||
:size="18"
|
||||
/>
|
||||
<div class="context-submenu">
|
||||
<div
|
||||
v-if="props.selectedRow"
|
||||
@@ -13,7 +21,12 @@
|
||||
@click="copyCell"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-numeric-0 mdi-rotate-90 text-light pr-1" /> {{ t('database.cell', 1) }}
|
||||
<BaseIcon
|
||||
icon-name="mdiNumeric0"
|
||||
:rotate="90"
|
||||
class="text-light mt-1 mr-1"
|
||||
:size="18"
|
||||
/> {{ t('database.cell', 1) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -22,7 +35,11 @@
|
||||
@click="copyRow"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('database.row', 1) }}
|
||||
<BaseIcon
|
||||
icon-name="mdiTableRow"
|
||||
class="text-light mt-1 mr-1"
|
||||
:size="18"
|
||||
/> {{ t('database.row', 1) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,16 +50,22 @@
|
||||
@click="killProcess"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-close-circle-outline text-light pr-1" /> {{ t('database.killProcess') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiCloseCircleOutline"
|
||||
class="text-light mt-1 mr-1"
|
||||
:size="18"
|
||||
/> {{ t('database.killProcess') }}
|
||||
</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps({
|
||||
|
@@ -24,7 +24,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-information-outline mr-1" /> {{ t('database.processInfo') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiInformationOutline"
|
||||
:size="24"
|
||||
class="mr-1"
|
||||
/> {{ t('database.processInfo') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -46,10 +50,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import TextEditor from '@/components/BaseTextEditor.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -6,7 +6,11 @@
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-cog mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiCog"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ t('application.settings') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -37,6 +41,13 @@
|
||||
>
|
||||
<a class="tab-link">{{ t('application.shortcuts') }}</a>
|
||||
</li>
|
||||
<li
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'data'}"
|
||||
@click="selectTab('data')"
|
||||
>
|
||||
<a class="tab-link">{{ t('application.data') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="updateStatus !== 'disabled'"
|
||||
class="tab-item c-hand"
|
||||
@@ -71,7 +82,11 @@
|
||||
<div class="form-group column col-12">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
<i class="mdi mdi-18px mdi-translate mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiTranslate"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -267,7 +282,11 @@
|
||||
>
|
||||
<img :src="darkPreview" class="img-responsive img-fit-cover s-rounded">
|
||||
<div class="theme-name text-light">
|
||||
<i class="mdi mdi-moon-waning-crescent mdi-48px" />
|
||||
<BaseIcon
|
||||
icon-name="mdiMoonWaningCrescent"
|
||||
class="mr-1"
|
||||
:size="48"
|
||||
/>
|
||||
<div class="h6 mt-4">
|
||||
{{ t('application.dark') }}
|
||||
</div>
|
||||
@@ -280,7 +299,11 @@
|
||||
>
|
||||
<img :src="lightPreview" class="img-responsive img-fit-cover s-rounded">
|
||||
<div class="theme-name text-dark">
|
||||
<i class="mdi mdi-white-balance-sunny mdi-48px" />
|
||||
<BaseIcon
|
||||
icon-name="mdiWhiteBalanceSunny"
|
||||
class="mr-1"
|
||||
:size="48"
|
||||
/>
|
||||
<div class="h6 mt-4">
|
||||
{{ t('application.light') }}
|
||||
</div>
|
||||
@@ -366,6 +389,9 @@
|
||||
<div v-show="selectedTab === 'shortcuts'" class="panel-body py-4">
|
||||
<ModalSettingsShortcuts />
|
||||
</div>
|
||||
<div v-show="selectedTab === 'data'" class="panel-body py-4">
|
||||
<ModalSettingsData />
|
||||
</div>
|
||||
<div v-show="selectedTab === 'update'" class="panel-body py-4">
|
||||
<ModalSettingsUpdate />
|
||||
</div>
|
||||
@@ -379,7 +405,39 @@
|
||||
<h4>{{ appName }}</h4>
|
||||
<p class="mb-2">
|
||||
{{ t('general.version') }} {{ appVersion }}<br>
|
||||
<a class="c-hand" @click="openOutside('https://github.com/antares-sql/antares')"><i class="mdi mdi-github d-inline" /> GitHub</a> • <a class="c-hand" @click="openOutside('https://twitter.com/AntaresSQL')"><i class="mdi mdi-twitter d-inline" /> Twitter</a> • <a class="c-hand" @click="openOutside('https://antares-sql.app/')"><i class="mdi mdi-web d-inline" /> Website</a><br>
|
||||
<a
|
||||
class="c-hand"
|
||||
:style="'align-items: center; display: inline-flex;'"
|
||||
@click="openOutside('https://github.com/antares-sql/antares')"
|
||||
><BaseIcon
|
||||
icon-name="mdiGithub"
|
||||
class="d-inline mr-1"
|
||||
:size="16"
|
||||
/> GitHub</a> • <a
|
||||
class="c-hand"
|
||||
:style="'align-items: center; display: inline-flex;'"
|
||||
@click="openOutside('https://fosstodon.org/@AntaresSQL')"
|
||||
><BaseIcon
|
||||
icon-name="mdiMastodon"
|
||||
class="d-inline mr-1"
|
||||
:size="16"
|
||||
/> Mastodon</a> • <a
|
||||
class="c-hand"
|
||||
:style="'align-items: center; display: inline-flex;'"
|
||||
@click="openOutside('https://twitter.com/AntaresSQL')"
|
||||
><BaseIcon
|
||||
icon-name="mdiTwitter"
|
||||
class="d-inline mr-1"
|
||||
:size="16"
|
||||
/> Twitter</a> • <a
|
||||
class="c-hand"
|
||||
:style="'align-items: center; display: inline-flex;'"
|
||||
@click="openOutside('https://antares-sql.app/')"
|
||||
><BaseIcon
|
||||
icon-name="mdiWeb"
|
||||
class="d-inline mr-1"
|
||||
:size="16"
|
||||
/> Website</a><br>
|
||||
<small>{{ t('general.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">{{ appAuthor }}</a></small><br>
|
||||
</p>
|
||||
<div class="mb-2">
|
||||
@@ -399,21 +457,24 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, Ref, ref, computed } from 'vue';
|
||||
import { shell } from 'electron';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import BaseTextEditor from '@/components/BaseTextEditor.vue';
|
||||
import ModalSettingsChangelog from '@/components/ModalSettingsChangelog.vue';
|
||||
import ModalSettingsData from '@/components/ModalSettingsData.vue';
|
||||
import ModalSettingsShortcuts from '@/components/ModalSettingsShortcuts.vue';
|
||||
import ModalSettingsUpdate from '@/components/ModalSettingsUpdate.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { AvailableLocale } from '@/i18n';
|
||||
import { localesNames } from '@/i18n/supported-locales';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { localesNames } from '@/i18n/supported-locales';
|
||||
import ModalSettingsUpdate from '@/components/ModalSettingsUpdate.vue';
|
||||
import ModalSettingsChangelog from '@/components/ModalSettingsChangelog.vue';
|
||||
import ModalSettingsShortcuts from '@/components/ModalSettingsShortcuts.vue';
|
||||
import BaseTextEditor from '@/components/BaseTextEditor.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { AvailableLocale } from '@/i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -648,10 +709,14 @@ onBeforeUnmount(() => {
|
||||
.modal-body {
|
||||
overflow: hidden;
|
||||
|
||||
.tab-link {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
.tab-item {
|
||||
max-width: 20%;
|
||||
|
||||
.tab-link {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
|
@@ -8,17 +8,19 @@
|
||||
/>
|
||||
<div v-if="isError" class="empty">
|
||||
<div class="empty-icon">
|
||||
<i class="mdi mdi-48px mdi-alert-outline" />
|
||||
<BaseIcon icon-name="mdiAlertOutline" :size="48" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { shell } from 'electron';
|
||||
import { marked } from 'marked';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseLoader from '@/components/BaseLoader.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { ref } from 'vue';
|
||||
import { shell } from 'electron';
|
||||
|
||||
const { appVersion } = useApplicationStore();
|
||||
|
||||
|
69
src/renderer/components/ModalSettingsData.vue
Normal file
69
src/renderer/components/ModalSettingsData.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-12 h6 text-uppercase mb-2">
|
||||
{{ t('application.exportData') }}
|
||||
</div>
|
||||
<div class="column col-12">
|
||||
{{ t('application.exportDataExplanation') }}
|
||||
</div>
|
||||
<div class="column col-12 text-right">
|
||||
<button
|
||||
class="btn btn-primary d-inline-flex"
|
||||
@click="isExportModal=true"
|
||||
>
|
||||
<BaseIcon
|
||||
icon-name="mdiTrayArrowUp"
|
||||
class="mr-2"
|
||||
:size="24"
|
||||
/>
|
||||
<span>{{ t('application.exportData') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="columns mt-4 mb-2">
|
||||
<div class="column col-12 h6 text-uppercase mb-2 mt-4">
|
||||
{{ t('application.importData') }}
|
||||
</div>
|
||||
<div class="column col-12">
|
||||
{{ t('application.importDataExplanation') }}
|
||||
</div>
|
||||
<div class="column col-12 text-right">
|
||||
<button
|
||||
class="btn btn-dark d-inline-flex ml-auto"
|
||||
@click="isImportModal=true"
|
||||
>
|
||||
<BaseIcon
|
||||
icon-name="mdiTrayArrowDown"
|
||||
class="mr-2"
|
||||
:size="24"
|
||||
/>
|
||||
<span>{{ t('application.importData') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ModalSettingsDataExport
|
||||
v-if="isExportModal"
|
||||
@close="isExportModal = false"
|
||||
/>
|
||||
<ModalSettingsDataImport
|
||||
v-if="isImportModal"
|
||||
@close="isImportModal = false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import ModalSettingsDataExport from '@/components/ModalSettingsDataExport.vue';
|
||||
import ModalSettingsDataImport from '@/components/ModalSettingsDataImport.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const isExportModal = ref(false);
|
||||
const isImportModal = ref(false);
|
||||
|
||||
</script>
|
347
src/renderer/components/ModalSettingsDataExport.vue
Normal file
347
src/renderer/components/ModalSettingsDataExport.vue
Normal file
@@ -0,0 +1,347 @@
|
||||
<template>
|
||||
<Teleport to="#window-content">
|
||||
<div class="modal active">
|
||||
<a class="modal-overlay" @click.stop="closeModal" />
|
||||
<div ref="trapRef" class="modal-container p-0">
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<BaseIcon
|
||||
icon-name="mdiTrayArrowUp"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.exportData') }}
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
</div>
|
||||
<div class="modal-body pb-0">
|
||||
<div class="columns export-options">
|
||||
<div class="column col-8 left">
|
||||
<div class="workspace-query-results" :style="'min-height: 300px;'">
|
||||
<div ref="table" class="table table-hover">
|
||||
<div class="thead">
|
||||
<div class="tr text-center">
|
||||
<div class="th no-border" :style="'width:50%'" />
|
||||
<div class="th no-border" />
|
||||
<div class="th no-border">
|
||||
<label
|
||||
class="form-checkbox m-0 px-2 form-inline"
|
||||
@click.prevent="toggleAllConnections()"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:indeterminate="includeConnectionStatus === 2"
|
||||
:checked="!!includeConnectionStatus"
|
||||
>
|
||||
<i class="form-icon" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tr">
|
||||
<div class="th">
|
||||
<div class="table-column-title">
|
||||
<span>{{ t('connection.connectionName') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th">
|
||||
<div class="table-column-title">
|
||||
<span>{{ t('connection.client') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th text-center">
|
||||
<div class="table-column-title">
|
||||
<span>{{ t('general.include') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tbody">
|
||||
<div
|
||||
v-for="(item, i) in connections"
|
||||
:key="i"
|
||||
class="tr"
|
||||
>
|
||||
<div class="td">
|
||||
{{ getConnectionName(item.uid) }}
|
||||
</div>
|
||||
<div class="td">
|
||||
{{ item.client }}
|
||||
</div>
|
||||
<div class="td text-center">
|
||||
<label class="form-checkbox m-0 px-2 form-inline">
|
||||
<input v-model="connectionToggles[item.uid]" type="checkbox">
|
||||
<i class="form-icon" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column col-4">
|
||||
<h5 class="h5">
|
||||
{{ t('general.options') }}
|
||||
</h5>
|
||||
<label class="form-checkbox">
|
||||
<input v-model="options.includes.passwords" type="checkbox">
|
||||
<i class="form-icon" />
|
||||
{{ t(`application.includeConnectionPasswords`) }}
|
||||
</label>
|
||||
<label class="form-checkbox">
|
||||
<input v-model="options.includes.folders" type="checkbox">
|
||||
<i class="form-icon" />
|
||||
{{ t(`application.includeFolders`) }}
|
||||
</label>
|
||||
<div class="h6 mt-4 mb-2">
|
||||
{{ t('application.encryptionPassword') }}
|
||||
</div>
|
||||
<fieldset class="form-group" :class="{'has-error': isPasswordError}">
|
||||
<div class="input-group">
|
||||
<input
|
||||
ref="passkey"
|
||||
v-model="options.passkey"
|
||||
:type="isPasswordVisible ? 'text' : 'password'"
|
||||
class="form-input"
|
||||
:placeholder="t('application.required')"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-link input-group-addon"
|
||||
@click="isPasswordVisible = !isPasswordVisible"
|
||||
>
|
||||
<BaseIcon
|
||||
v-if="isPasswordVisible"
|
||||
icon-name="mdiEye"
|
||||
class="mt-1 mx-1"
|
||||
:size="16"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
icon-name="mdiEyeOff"
|
||||
class="mt-1 mx-1"
|
||||
:size="16"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<span v-if="isPasswordError" class="form-input-hint">
|
||||
{{ t('application.encryptionPasswordError') }}
|
||||
</span>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-link mr-2" @click.stop="closeModal">
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary mr-2"
|
||||
autofocus
|
||||
@click.prevent="exportData()"
|
||||
>
|
||||
{{ t('database.export') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { encrypt } from 'common/libs/encrypter';
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import * as moment from 'moment';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { unproxify } from '@/libs/unproxify';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
|
||||
const { t } = useI18n();
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const { trapRef } = useFocusTrap();
|
||||
|
||||
const { getConnectionName } = useConnectionsStore();
|
||||
const { connectionsOrder, connections } = storeToRefs(useConnectionsStore());
|
||||
const localConnections = unproxify<ConnectionParams[]>(connections.value);
|
||||
const localConnectionsOrder = unproxify<SidebarElement[]>(connectionsOrder.value);
|
||||
|
||||
const isPasswordVisible = ref(false);
|
||||
const isPasswordError = ref(false);
|
||||
const connectionToggles: Ref<{[k:string]: boolean}> = ref({});
|
||||
const options = ref({
|
||||
passkey: '',
|
||||
includes: {
|
||||
passwords: true,
|
||||
folders: true
|
||||
}
|
||||
});
|
||||
const filename = computed(() => {
|
||||
const date = moment().format('YYYY-MM-DD');
|
||||
return `backup_${date}`;
|
||||
});
|
||||
const includeConnectionStatus = computed(() => {
|
||||
if (Object.values(connectionToggles.value).every(item => item)) return 1;
|
||||
else if (Object.values(connectionToggles.value).some(item => item)) return 2;
|
||||
else return 0;
|
||||
});
|
||||
|
||||
const exportData = () => {
|
||||
if (options.value.passkey.length < 8)
|
||||
isPasswordError.value = true;
|
||||
else {
|
||||
isPasswordError.value = false;
|
||||
const connectionsToInclude: string[] = [];
|
||||
const connectionsUidMap = new Map<string, string>();
|
||||
for (const cUid in connectionToggles.value)
|
||||
if (connectionToggles.value[cUid]) connectionsToInclude.push(cUid);
|
||||
|
||||
let filteredConnections = unproxify<typeof localConnections>(localConnections.filter(conn => connectionsToInclude.includes(conn.uid)));
|
||||
filteredConnections = filteredConnections.map(c => {
|
||||
const newUid = uidGen('C');
|
||||
connectionsUidMap.set(c.uid, newUid);
|
||||
c.uid = newUid;
|
||||
return c;
|
||||
});
|
||||
|
||||
if (!options.value.includes.passwords) { // Remove passwords and set ask:true
|
||||
filteredConnections.map(c => {
|
||||
if (c.password) {
|
||||
c.password = '';
|
||||
c.ask = true;
|
||||
}
|
||||
return c;
|
||||
});
|
||||
}
|
||||
|
||||
let filteredOrders = [];
|
||||
for (const [oldVal, newVal] of connectionsUidMap) {
|
||||
const connOrder = unproxify(localConnectionsOrder.find(c => c.uid === oldVal));
|
||||
connOrder.uid = newVal;
|
||||
filteredOrders.push(connOrder);
|
||||
}
|
||||
|
||||
if (options.value.includes.folders) { // Includes folders
|
||||
const oldConnUids = Array.from(connectionsUidMap.keys());
|
||||
const newConnUids = Array.from(connectionsUidMap.values());
|
||||
const foldersToInclude = unproxify(localConnectionsOrder).filter(f => (
|
||||
f.isFolder && oldConnUids.some(uid => f.connections.includes(uid))
|
||||
)).map(f => {
|
||||
f.uid = uidGen('F');
|
||||
f.connections = f.connections
|
||||
.map(fc => connectionsUidMap.get(fc))
|
||||
.filter(fc => newConnUids.includes(fc));
|
||||
return f;
|
||||
});
|
||||
|
||||
filteredOrders = [...filteredOrders, ...foldersToInclude];
|
||||
}
|
||||
|
||||
const exportObj = encrypt(JSON.stringify({
|
||||
connections: filteredConnections,
|
||||
connectionsOrder: filteredOrders
|
||||
}), options.value.passkey);
|
||||
|
||||
// console.log(exportObj, JSON.parse(decrypt(exportObj, options.value.passkey)));
|
||||
|
||||
const blobContent = Buffer.from(JSON.stringify(exportObj), 'utf-8').toString('hex');
|
||||
const file = new Blob([blobContent], { type: 'application/octet-stream' });
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.download = `${filename.value}.antares`;
|
||||
downloadLink.href = window.URL.createObjectURL(file);
|
||||
downloadLink.style.display = 'none';
|
||||
document.body.appendChild(downloadLink);
|
||||
downloadLink.click();
|
||||
downloadLink.remove();
|
||||
|
||||
closeModal();
|
||||
}
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
e.stopPropagation();
|
||||
if (e.key === 'Escape')
|
||||
closeModal();
|
||||
};
|
||||
|
||||
const toggleAllConnections = () => {
|
||||
if (includeConnectionStatus.value !== 1) {
|
||||
connectionToggles.value = localConnections.reduce((acc, curr) => {
|
||||
acc[curr.uid] = true;
|
||||
return acc;
|
||||
}, {} as {[k:string]: boolean});
|
||||
}
|
||||
else {
|
||||
connectionToggles.value = localConnections.reduce((acc, curr) => {
|
||||
acc[curr.uid] = false;
|
||||
return acc;
|
||||
}, {} as {[k:string]: boolean});
|
||||
}
|
||||
};
|
||||
|
||||
connectionToggles.value = localConnections.reduce((acc, curr) => {
|
||||
acc[curr.uid] = true;
|
||||
return acc;
|
||||
}, {} as {[k:string]: boolean});
|
||||
|
||||
window.addEventListener('keydown', onKey);
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('keydown', onKey);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.export-options {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.workspace-query-results {
|
||||
flex: 1 0 1px;
|
||||
|
||||
.table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.form-checkbox {
|
||||
min-height: 0.8rem;
|
||||
padding: 0;
|
||||
|
||||
.form-icon {
|
||||
top: 0.1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
.modal-container {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
max-height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
284
src/renderer/components/ModalSettingsDataImport.vue
Normal file
284
src/renderer/components/ModalSettingsDataImport.vue
Normal file
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<Teleport to="#window-content">
|
||||
<div class="modal modal-sm active">
|
||||
<a class="modal-overlay" @click.stop="closeModal" />
|
||||
<div ref="trapRef" class="modal-container p-0">
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<BaseIcon
|
||||
icon-name="mdiTrayArrowDown"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.importData') }}
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
</div>
|
||||
<div class="modal-body pb-0">
|
||||
<div class="mb-2">
|
||||
<div class="h6 mb-2">
|
||||
{{ t('application.choseFile') }}
|
||||
</div>
|
||||
<BaseUploadInput
|
||||
:model-value="filePath"
|
||||
:message="t('general.browse')"
|
||||
accept=".antares"
|
||||
@clear="clearPath"
|
||||
@change="filesChange($event)"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<div class="h6 mb-2">
|
||||
{{ t('application.password') }}
|
||||
</div>
|
||||
<fieldset class="form-group" :class="{'has-error': isPasswordError}">
|
||||
<div class="input-group">
|
||||
<input
|
||||
ref="passkey"
|
||||
v-model="options.passkey"
|
||||
:type="isPasswordVisible ? 'text' : 'password'"
|
||||
class="form-input"
|
||||
:placeholder="t('application.required')"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-link input-group-addon"
|
||||
@click="isPasswordVisible = !isPasswordVisible"
|
||||
>
|
||||
<BaseIcon
|
||||
v-if="isPasswordVisible"
|
||||
icon-name="mdiEye"
|
||||
class="mt-1 mx-1"
|
||||
:size="16"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
icon-name="mdiEyeOff"
|
||||
class="mt-1 mx-1"
|
||||
:size="16"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<span v-if="isPasswordError" class="form-input-hint">
|
||||
{{ t('application.encryptionPasswordError') }}
|
||||
</span>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-checkbox">
|
||||
<input v-model="options.ignoreDuplicates" type="checkbox">
|
||||
<i class="form-icon" />
|
||||
{{ t(`application.ignoreDuplicates`) }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
class="btn btn-link mr-2"
|
||||
@click.stop="closeModal"
|
||||
>
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary mr-2"
|
||||
:disabled="!filePath"
|
||||
@click.prevent="importData()"
|
||||
>
|
||||
{{ t('database.import') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { decrypt } from 'common/libs/encrypter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { onBeforeUnmount, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput.vue';
|
||||
import { unproxify } from '@/libs/unproxify';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
|
||||
const { t } = useI18n();
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const { addNotification } = useNotificationsStore();
|
||||
|
||||
const connectionsStore = useConnectionsStore();
|
||||
const { importConnections } = connectionsStore;
|
||||
const { connections } = storeToRefs(connectionsStore);
|
||||
|
||||
const filePath = ref('');
|
||||
const fileContent = ref(null);
|
||||
const isPasswordVisible = ref(false);
|
||||
const isPasswordError = ref(false);
|
||||
const options = ref({
|
||||
passkey: '',
|
||||
ignoreDuplicates: true
|
||||
});
|
||||
|
||||
const closeModal = () => {
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const filesChange = ({ target } : {target: HTMLInputElement }) => {
|
||||
const { files } = target;
|
||||
if (!files.length) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.readAsText(files[0]);
|
||||
reader.onload = () => {
|
||||
fileContent.value = reader.result;
|
||||
filePath.value = files[0].path;
|
||||
};
|
||||
};
|
||||
|
||||
const clearPath = () => {
|
||||
filePath.value = '';
|
||||
fileContent.value = null;
|
||||
};
|
||||
|
||||
const importData = () => {
|
||||
if (options.value.passkey.length < 8)
|
||||
isPasswordError.value = true;
|
||||
else {
|
||||
try {
|
||||
const hash = JSON.parse(Buffer.from(fileContent.value, 'hex').toString('utf-8'));
|
||||
|
||||
try {
|
||||
const importObj: {
|
||||
connections: ConnectionParams[];
|
||||
connectionsOrder: SidebarElement[];
|
||||
} = JSON.parse(decrypt(hash, options.value.passkey));
|
||||
|
||||
if (options.value.ignoreDuplicates) {
|
||||
const actualConnections = unproxify(connections.value).map(c => {
|
||||
delete c.uid;
|
||||
|
||||
delete c.name;
|
||||
delete c.password;
|
||||
delete c.ask;
|
||||
|
||||
delete c.key;
|
||||
delete c.cert;
|
||||
delete c.ca;
|
||||
|
||||
delete c.sshKey;
|
||||
|
||||
return JSON.stringify(c);
|
||||
});
|
||||
|
||||
const incomingConnections = unproxify<ConnectionParams[]>(importObj.connections).map(c => {
|
||||
const uid = c.uid;
|
||||
delete c.uid;
|
||||
|
||||
delete c.name;
|
||||
delete c.password;
|
||||
delete c.ask;
|
||||
|
||||
delete c.key;
|
||||
delete c.cert;
|
||||
delete c.ca;
|
||||
|
||||
delete c.sshKey;
|
||||
|
||||
return { uid, jsonString: JSON.stringify(c) };
|
||||
});
|
||||
|
||||
const newConnectionsUid = incomingConnections
|
||||
.filter(c => !actualConnections.includes(c.jsonString))
|
||||
.reduce((acc, cur) => {
|
||||
acc.push(cur.uid);
|
||||
return acc;
|
||||
}, [] as string[]);
|
||||
|
||||
importObj.connections = importObj.connections.filter(c => newConnectionsUid.includes(c.uid));
|
||||
importObj.connectionsOrder = importObj.connectionsOrder
|
||||
.filter(c => newConnectionsUid
|
||||
.includes(c.uid) ||
|
||||
(c.isFolder && c.connections.every(c => newConnectionsUid.includes(c))));
|
||||
}
|
||||
|
||||
importConnections(importObj);
|
||||
|
||||
addNotification({
|
||||
status: 'success',
|
||||
message: t('application.dataImportSuccess')
|
||||
});
|
||||
closeModal();
|
||||
}
|
||||
catch (error) {
|
||||
addNotification({
|
||||
status: 'error',
|
||||
message: t('application.wrongImportPassword')
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
addNotification({
|
||||
status: 'error',
|
||||
message: t('application.wrongFileFormat')
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onKey = (e: KeyboardEvent) => {
|
||||
e.stopPropagation();
|
||||
if (e.key === 'Escape')
|
||||
closeModal();
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', onKey);
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('keydown', onKey);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.export-options {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.workspace-query-results {
|
||||
flex: 1 0 1px;
|
||||
|
||||
.table {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.form-checkbox {
|
||||
min-height: 0.8rem;
|
||||
padding: 0;
|
||||
|
||||
.form-icon {
|
||||
top: 0.1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
.modal-body {
|
||||
max-height: 60vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@@ -2,10 +2,18 @@
|
||||
<div class="p-relative">
|
||||
<div class="shortcuts-tools pb-2 px-2">
|
||||
<button class="btn btn-dark btn-sm d-flex ml-2" @click="showAddModal">
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /><span>{{ t('application.addShortcut') }}</span>
|
||||
<BaseIcon
|
||||
icon-name="mdiPlus"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/><span>{{ t('application.addShortcut') }}</span>
|
||||
</button>
|
||||
<button class="btn btn-dark btn-sm d-flex ml-2" @click="isConfirmRestoreModal = true">
|
||||
<i class="mdi mdi-24px mdi-undo mr-1" /><span>{{ t('application.restoreDefaults') }}</span>
|
||||
<BaseIcon
|
||||
icon-name="mdiUndo"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/><span>{{ t('application.restoreDefaults') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="container workspace-query-results">
|
||||
@@ -43,10 +51,20 @@
|
||||
/>
|
||||
<div class="td py-1 pr-2">
|
||||
<button class="shortcut-button btn btn-link btn-sm d-flex p-0 px-1 mr-2" @click="showEditModal({...shortcut, index: i})">
|
||||
<span>{{ t('general.edit') }}</span><i class="mdi mdi-pencil ml-1" />
|
||||
<span>{{ t('general.edit') }}</span>
|
||||
<BaseIcon
|
||||
icon-name="mdiPencil"
|
||||
class="ml-1"
|
||||
:size="16"
|
||||
/>
|
||||
</button>
|
||||
<button class="shortcut-button btn btn-link btn-sm d-flex p-0 px-1" @click="showDeleteModal(shortcut)">
|
||||
<span>{{ t('general.delete') }}</span><i class="mdi mdi-delete-outline ml-1" />
|
||||
<span>{{ t('general.delete') }}</span>
|
||||
<BaseIcon
|
||||
icon-name="mdiDeleteOutline"
|
||||
class="ml-1"
|
||||
:size="16"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,7 +83,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /> {{ t('application.addShortcut') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiPlus"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.addShortcut') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -99,7 +121,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /> {{ t('application.editShortcut') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiPencil"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.editShortcut') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -132,7 +158,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-delete mr-1" /> {{ t('application.deleteShortcut') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiDelete"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.deleteShortcut') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -150,7 +180,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-undo mr-1" /> {{ t('application.restoreDefaults') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiUndo"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.restoreDefaults') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -162,17 +196,20 @@
|
||||
</Teleport>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Ref, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import KeyPressDetector from './KeyPressDetector.vue';
|
||||
import Application from '@/ipc-api/Application';
|
||||
import { shortcutEvents, ShortcutRecord } from 'common/shortcuts';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { computed } from '@vue/reactivity';
|
||||
import { shortcutEvents, ShortcutRecord } from 'common/shortcuts';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import Application from '@/ipc-api/Application';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
|
||||
import KeyPressDetector from './KeyPressDetector.vue';
|
||||
|
||||
const { parseKeys } = useFilters();
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="empty">
|
||||
<div class="empty-icon">
|
||||
<i class="mdi mdi-48px mdi-cloud-download" />
|
||||
<BaseIcon icon-name="mdiCloudDownload" :size="48" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ updateMessage }}
|
||||
@@ -53,10 +53,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ipcRenderer, shell } from 'electron';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
|
||||
|
@@ -9,16 +9,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, Prop, Ref, ref, toRef, watch } from 'vue';
|
||||
/* eslint-disable simple-import-sort/imports */
|
||||
import * as ace from 'ace-builds';
|
||||
import 'ace-builds/webpack-resolver';
|
||||
import '../libs/ext-language_tools';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import 'ace-builds/webpack-resolver';
|
||||
/* eslint-enable simple-import-sort/imports */
|
||||
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onMounted, Prop, Ref, ref, toRef, watch } from 'vue';
|
||||
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { Workspace } from '@/stores/workspaces';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
|
||||
const editor: Ref<ace.Ace.Editor> = ref(null);
|
||||
const applicationStore = useApplicationStore();
|
||||
@@ -399,11 +403,6 @@ defineExpose({ editor });
|
||||
}
|
||||
}
|
||||
|
||||
.ace_.mdi {
|
||||
display: inline-block;
|
||||
width: 17px;
|
||||
}
|
||||
|
||||
.ace_gutter-cell.ace_breakpoint {
|
||||
&::before {
|
||||
content: '\F0403';
|
||||
|
@@ -41,12 +41,28 @@
|
||||
@dragleave="coveredElement = false"
|
||||
@change="createFolder"
|
||||
/>
|
||||
<i v-if="coveredElement === element.uid && draggedElement !== coveredElement" class="settingbar-element-icon mdi mdi-folder-plus mdi-36px" />
|
||||
<BaseIcon
|
||||
v-if="coveredElement === element.uid && draggedElement !== coveredElement"
|
||||
class="settingbar-element-icon"
|
||||
icon-name="mdiFolderPlus"
|
||||
:size="36"
|
||||
/>
|
||||
<template v-else>
|
||||
<div class="settingbar-element-icon-wrapper">
|
||||
<i
|
||||
<div
|
||||
v-if="element.icon"
|
||||
class="settingbar-element-icon"
|
||||
:class="[getStatusBadge(element.uid)]"
|
||||
>
|
||||
<BaseIcon
|
||||
:icon-name="camelize(element.icon)"
|
||||
:size="36"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="settingbar-element-icon dbi"
|
||||
:class="[element.icon ? `mdi ${element.icon} mdi-36px`: `dbi-${element.client}`, getStatusBadge(element.uid)]"
|
||||
:class="[`dbi-${element.client}`, getStatusBadge(element.uid)]"
|
||||
/>
|
||||
<small class="settingbar-element-name">{{ element.name || getConnectionName(element.uid) }}</small>
|
||||
</div>
|
||||
@@ -71,12 +87,14 @@
|
||||
</Draggable>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, Ref, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, PropType, Ref, ref, watch } from 'vue';
|
||||
import * as Draggable from 'vuedraggable';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import SettingBarConnectionsFolder from '@/components/SettingBarConnectionsFolder.vue';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import SettingBarConnectionsFolder from '@/components/SettingBarConnectionsFolder.vue';
|
||||
|
||||
const workspacesStore = useWorkspacesStore();
|
||||
const connectionsStore = useConnectionsStore();
|
||||
@@ -147,6 +165,16 @@ const getStatusBadge = (uid: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
const camelize = (text: string) => {
|
||||
const textArr = text.split('-');
|
||||
for (let i = 0; i < textArr.length; i++) {
|
||||
if (i === 0) continue;
|
||||
textArr[i] = textArr[i].charAt(0).toUpperCase() + textArr[i].slice(1);
|
||||
}
|
||||
|
||||
return textArr.join('');
|
||||
};
|
||||
|
||||
watch(() => dummyNested.value.length, () => {
|
||||
dummyNested.value = [];
|
||||
});
|
||||
|
@@ -38,8 +38,16 @@
|
||||
:style="`color: ${folder.color};`"
|
||||
@click="closeFolder"
|
||||
>
|
||||
<i class="folder-icon-open mdi mdi-folder-open mdi-36px" />
|
||||
<i class="folder-icon-close mdi mdi-folder mdi-36px" />
|
||||
<BaseIcon
|
||||
class="folder-icon-open"
|
||||
icon-name="mdiFolderOpen"
|
||||
:size="36"
|
||||
/>
|
||||
<BaseIcon
|
||||
class="folder-icon-close"
|
||||
icon-name="mdiFolder"
|
||||
:size="36"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #item="{ element }">
|
||||
@@ -55,9 +63,20 @@
|
||||
@click="emit('select-workspace', element)"
|
||||
@contextmenu.stop="emit('context', {event: $event, content: getConnectionOrderByUid(element)})"
|
||||
>
|
||||
<i
|
||||
<div
|
||||
v-if="getConnectionOrderByUid(element).icon"
|
||||
class="folder-element-icon"
|
||||
:class="[getStatusBadge(element)]"
|
||||
>
|
||||
<BaseIcon
|
||||
:icon-name="camelize(getConnectionOrderByUid(element).icon)"
|
||||
:size="36"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="folder-element-icon dbi"
|
||||
:class="[getConnectionOrderByUid(element)?.icon ? `mdi ${getConnectionOrderByUid(element).icon}`: `dbi-${getConnectionOrderByUid(element)?.client}`, getStatusBadge(element)]"
|
||||
:class="[`dbi-${getConnectionOrderByUid(element).client}`, getStatusBadge(element)]"
|
||||
/>
|
||||
<small v-if="isOpen" class="folder-element-name">{{ getConnectionOrderByUid(element)?.name || getConnectionName(element) }}</small>
|
||||
</div>
|
||||
@@ -76,12 +95,14 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, PropType, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, PropType, ref, watch } from 'vue';
|
||||
import * as Draggable from 'vuedraggable';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import SettingBarConnections from '@/components/SettingBarConnections.vue';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import SettingBarConnections from '@/components/SettingBarConnections.vue';
|
||||
|
||||
const workspacesStore = useWorkspacesStore();
|
||||
const connectionsStore = useConnectionsStore();
|
||||
@@ -176,6 +197,16 @@ const dragStop = () => {
|
||||
emit('folder-drag', false);
|
||||
};
|
||||
|
||||
const camelize = (text: string) => {
|
||||
const textArr = text.split('-');
|
||||
for (let i = 0; i < textArr.length; i++) {
|
||||
if (i === 0) continue;
|
||||
textArr[i] = textArr[i].charAt(0).toUpperCase() + textArr[i].slice(1);
|
||||
}
|
||||
|
||||
return textArr.join('');
|
||||
};
|
||||
|
||||
watch(() => dummyNested.value.length, () => {
|
||||
dummyNested.value = [];
|
||||
});
|
||||
@@ -388,7 +419,8 @@ emit('folder-sort');// To apply changes on component key change
|
||||
&:not(.opened){
|
||||
.folder-element {
|
||||
|
||||
.folder-element-icon {
|
||||
.folder-element-icon,
|
||||
.folder-element-icon svg {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
font-size: 16px;
|
||||
|
@@ -8,20 +8,40 @@
|
||||
class="context-element"
|
||||
@click="disconnect"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-power text-light pr-1" /> {{ t('connection.disconnect') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiPower"
|
||||
:size="18"
|
||||
/> {{ t('connection.disconnect') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="!contextConnection.isFolder"
|
||||
class="context-element"
|
||||
@click="duplicateConnection"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ t('general.duplicate') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiContentDuplicate"
|
||||
:size="18"
|
||||
/> {{ t('general.duplicate') }}</span>
|
||||
</div>
|
||||
<div class="context-element" @click.stop="showAppearanceModal">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-brush-variant text-light pr-1" /> {{ t('application.appearance') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiBrushVariant"
|
||||
:size="18"
|
||||
/> {{ t('application.appearance') }}</span>
|
||||
</div>
|
||||
<div class="context-element" @click="showConfirmModal">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ t('general.delete') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiDelete"
|
||||
:size="18"
|
||||
/> {{ t('general.delete') }}</span>
|
||||
</div>
|
||||
|
||||
<ConfirmModal
|
||||
@@ -31,7 +51,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mr-1" :class="[contextConnection.isFolder ? 'mdi-folder-remove' : 'mdi-server-remove']" /> {{ t(contextConnection.isFolder ? 'application.deleteFolder' : 'connection.deleteConnection') }}
|
||||
<BaseIcon
|
||||
class="text-light mr-1"
|
||||
:icon-name="contextConnection.isFolder ? 'mdiFolderRemove' : 'mdiServerRemove'"
|
||||
:size="24"
|
||||
/> {{ t(contextConnection.isFolder ? 'application.deleteFolder' : 'connection.deleteConnection') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -54,16 +78,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, Prop, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import { computed, Prop, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import ModalConnectionAppearance from '@/components/ModalConnectionAppearance.vue';
|
||||
import ModalFolderAppearance from '@/components/ModalFolderAppearance.vue';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import ModalFolderAppearance from '@/components/ModalFolderAppearance.vue';
|
||||
import ModalConnectionAppearance from '@/components/ModalConnectionAppearance.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -77,10 +102,8 @@ const {
|
||||
} = connectionsStore;
|
||||
|
||||
const workspacesStore = useWorkspacesStore();
|
||||
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
||||
|
||||
const {
|
||||
selectWorkspace,
|
||||
removeConnected: disconnectWorkspace,
|
||||
getWorkspace
|
||||
} = workspacesStore;
|
||||
@@ -100,8 +123,8 @@ const connectionName = computed(() => props.contextConnection.name || getConnect
|
||||
const isConnected = computed(() => getWorkspace(props.contextConnection.uid)?.connectionStatus === 'connected');
|
||||
|
||||
const confirmDeleteConnection = () => {
|
||||
if (selectedWorkspace.value === props.contextConnection.uid)
|
||||
selectWorkspace(null);
|
||||
if (isConnected.value)
|
||||
disconnectWorkspace(props.contextConnection.uid);
|
||||
deleteConnection(props.contextConnection);
|
||||
closeContext();
|
||||
};
|
||||
|
@@ -7,19 +7,35 @@
|
||||
<div class="footer-left-elements">
|
||||
<ul class="footer-elements">
|
||||
<li class="footer-element">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiServer"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
<small>{{ versionString }}</small>
|
||||
</li>
|
||||
<li v-if="connectionInfos && connectionInfos.readonly" class="footer-element">
|
||||
<i class="mdi mdi-18px mdi-lock mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiLock"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
<small>{{ t('connection.readOnlyMode') }}</small>
|
||||
</li>
|
||||
<li v-if="connectionInfos && connectionInfos.ssl" class="footer-element">
|
||||
<i class="mdi mdi-18px mdi-shield-key mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiShieldKey"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
<small>SSL</small>
|
||||
</li>
|
||||
<li v-if="connectionInfos && connectionInfos.ssh" class="footer-element">
|
||||
<i class="mdi mdi-18px mdi-console-network mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiConsoleNetwork"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
<small>SSH</small>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -32,11 +48,19 @@
|
||||
class="footer-element footer-link"
|
||||
@click="toggleConsole()"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-console-line mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiConsoleLine"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
<small>{{ t('application.console') }}</small>
|
||||
</li>
|
||||
<li class="footer-element footer-link" @click="openOutside('https://www.paypal.com/paypalme/fabiodistasio')">
|
||||
<i class="mdi mdi-18px mdi-coffee mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiCoffee"
|
||||
class="mr-1"
|
||||
:size="18"
|
||||
/>
|
||||
<small>{{ t('general.donate') }}</small>
|
||||
</li>
|
||||
<li
|
||||
@@ -44,14 +68,14 @@
|
||||
:title="t('application.reportABug')"
|
||||
@click="openOutside('https://github.com/antares-sql/antares/issues')"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-bug" />
|
||||
<BaseIcon icon-name="mdiBug" :size="18" />
|
||||
</li>
|
||||
<li
|
||||
class="footer-element footer-link"
|
||||
:title="t('application.about')"
|
||||
@click="showSettingModal('about')"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-information-outline" />
|
||||
<BaseIcon icon-name="mdiInformationOutline" :size="18" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -61,12 +85,14 @@
|
||||
<script setup lang="ts">
|
||||
import { shell } from 'electron';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { computed, ComputedRef } from 'vue';
|
||||
import { useConsoleStore } from '@/stores/console';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useConsoleStore } from '@/stores/console';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -17,11 +17,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, Ref, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, Ref, ref, watch } from 'vue';
|
||||
|
||||
import BaseNotification from '@/components/BaseNotification.vue';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import BaseNotification from '@/components/BaseNotification.vue';
|
||||
|
||||
const notificationsStore = useNotificationsStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
|
@@ -8,7 +8,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-notebook-edit-outline mr-1" /> {{ t('application.scratchpad') }}
|
||||
<BaseIcon
|
||||
icon-name="mdiNotebookEditOutline"
|
||||
class="mr-1"
|
||||
:size="24"
|
||||
/> {{ t('application.scratchpad') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -29,13 +33,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, Ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import TextEditor from '@/components/BaseTextEditor.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useScratchpadStore } from '@/stores/scratchpad';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import TextEditor from '@/components/BaseTextEditor.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -28,7 +28,11 @@
|
||||
@click="emit('show-connections-modal')"
|
||||
>
|
||||
<div class="settingbar-element-icon-wrapper">
|
||||
<i class="settingbar-element-icon mdi mdi-24px mdi-dots-horizontal text-light" />
|
||||
<BaseIcon
|
||||
icon-name="mdiDotsHorizontal"
|
||||
class="settingbar-element-icon text-light"
|
||||
:size="24"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
@@ -42,7 +46,11 @@
|
||||
@click="selectWorkspace('NEW')"
|
||||
>
|
||||
<div class="settingbar-element-icon-wrapper">
|
||||
<i class="settingbar-element-icon mdi mdi-24px mdi-plus text-light" />
|
||||
<BaseIcon
|
||||
icon-name="mdiPlus"
|
||||
class="settingbar-element-icon text-light"
|
||||
:size="24"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -60,7 +68,11 @@
|
||||
class="settingbar-element btn btn-link"
|
||||
@click="showScratchpad"
|
||||
>
|
||||
<i class="settingbar-element-icon mdi mdi-24px mdi-notebook-edit-outline text-light" />
|
||||
<BaseIcon
|
||||
icon-name="mdiNotebookEditOutline"
|
||||
class="settingbar-element-icon text-light"
|
||||
:size="24"
|
||||
/>
|
||||
</li>
|
||||
<li
|
||||
v-tooltip="{
|
||||
@@ -71,10 +83,14 @@
|
||||
class="settingbar-element btn btn-link"
|
||||
@click="showSettingModal('general')"
|
||||
>
|
||||
<i
|
||||
class="settingbar-element-icon mdi mdi-24px mdi-cog text-light"
|
||||
:class="{ ' badge badge-update': hasUpdates }"
|
||||
/>
|
||||
<div class="settingbar-element-icon-wrapper">
|
||||
<BaseIcon
|
||||
icon-name="mdiCog"
|
||||
class="settingbar-element-icon text-light"
|
||||
:class="{ 'badge badge-update': hasUpdates }"
|
||||
:size="24"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -82,17 +98,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, Ref, computed, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { useConnectionsStore, SidebarElement } from '@/stores/connections';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import SettingBarContext from '@/components/SettingBarContext.vue';
|
||||
import SettingBarConnections from '@/components/SettingBarConnections.vue';
|
||||
import { useElementBounding } from '@vueuse/core';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import SettingBarConnections from '@/components/SettingBarConnections.vue';
|
||||
import SettingBarContext from '@/components/SettingBarContext.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
localStorage.setItem('opened-folders', '[]');
|
||||
|
||||
@@ -238,7 +256,7 @@ if (!connectionsArr.value.length)
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
|
||||
.settingbar-element-icon-wrapper{
|
||||
.settingbar-element-icon-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
@@ -21,14 +21,14 @@
|
||||
class="titlebar-element"
|
||||
@click="openDevTools"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-code-tags" />
|
||||
<BaseIcon icon-name="mdiCodeTags" :size="24" />
|
||||
</div>
|
||||
<div
|
||||
v-if="isDevelopment"
|
||||
class="titlebar-element"
|
||||
@click="reload"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-refresh" />
|
||||
<BaseIcon icon-name="mdiRefresh" :size="24" />
|
||||
</div>
|
||||
<div v-if="isWindows" :style="'width: 140px;'" />
|
||||
</div>
|
||||
@@ -36,13 +36,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onUnmounted, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { getCurrentWindow } from '@electron/remote';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onUnmounted, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -40,7 +40,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-code-tags mr-1" />
|
||||
<BaseIcon
|
||||
class="mt-1 mr-1"
|
||||
icon-name="mdiCodeTags"
|
||||
:size="18"
|
||||
/>
|
||||
<span>
|
||||
<span>{{ cutText(element.content || 'Query', 20, true) }} #{{ element.index }}</span>
|
||||
<span
|
||||
@@ -57,7 +61,11 @@
|
||||
class="tab-link"
|
||||
@dblclick="openAsPermanentTab(element)"
|
||||
>
|
||||
<i class="mdi mdi-18px mr-1" :class="element.elementType === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
|
||||
<BaseIcon
|
||||
class="mt-1 mr-1"
|
||||
:icon-name="element.elementType === 'view' ? 'mdiTableEye' : 'mdiTable'"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
<span class=" text-italic">{{ cutText(element.elementName, 20, true) }}</span>
|
||||
<span
|
||||
@@ -70,7 +78,11 @@
|
||||
</a>
|
||||
|
||||
<a v-else-if="element.type === 'data'" class="tab-link">
|
||||
<i class="mdi mdi-18px mr-1" :class="element.elementType === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
|
||||
<BaseIcon
|
||||
class="mt-1 mr-1"
|
||||
:icon-name="element.elementType === 'view' ? 'mdiTableEye' : 'mdiTable'"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
@@ -87,7 +99,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiShapeSquarePlus"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newTable') }}
|
||||
<span
|
||||
@@ -104,7 +120,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-wrench-cog mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiWrenchCog"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
@@ -121,7 +141,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-wrench-cog mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiWrenchCog"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.view`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
@@ -138,7 +162,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiShapeSquarePlus"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newView') }}
|
||||
<span
|
||||
@@ -155,7 +183,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiShapeSquarePlus"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newTrigger') }}
|
||||
<span
|
||||
@@ -172,7 +204,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiShapeSquarePlus"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newRoutine') }}
|
||||
<span
|
||||
@@ -189,7 +225,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiShapeSquarePlus"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newFunction') }}
|
||||
<span
|
||||
@@ -206,7 +246,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiShapeSquarePlus"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newTriggerFunction') }}
|
||||
<span
|
||||
@@ -223,7 +267,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiShapeSquarePlus"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newScheduler') }}
|
||||
<span
|
||||
@@ -241,7 +289,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
@dblclick="openAsPermanentTab(element)"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-wrench-cog mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiWrenchCog"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
<span class=" text-italic">{{ cutText(element.elementName, 20, true) }}</span>
|
||||
<span
|
||||
@@ -258,7 +310,11 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-wrench-cog mr-1" />
|
||||
<BaseIcon
|
||||
class="mr-1"
|
||||
icon-name="mdiWrenchCog"
|
||||
:size="18"
|
||||
/>
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
@@ -281,18 +337,26 @@
|
||||
tabindex="0"
|
||||
:title="t('general.tools')"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-tools" />
|
||||
<BaseIcon icon-name="mdiTools" :size="24" />
|
||||
</a>
|
||||
<ul v-if="hasTools" class="menu text-left text-uppercase">
|
||||
<li class="menu-item">
|
||||
<a class="c-hand p-vcentered" @click="showProcessesModal">
|
||||
<i class="mdi mdi-memory mr-1 tool-icon" />
|
||||
<BaseIcon
|
||||
icon-name="mdiMemory"
|
||||
:size="18"
|
||||
class="mr-1 tool-icon"
|
||||
/>
|
||||
<span>{{ t('database.processesList') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="c-hand p-vcentered" @click="toggleConsole">
|
||||
<i class="mdi mdi-console-line mr-1 tool-icon" />
|
||||
<BaseIcon
|
||||
icon-name="mdiConsoleLine"
|
||||
:size="18"
|
||||
class="mr-1 tool-icon"
|
||||
/>
|
||||
<span>{{ t('application.console') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -302,7 +366,11 @@
|
||||
title="Coming..."
|
||||
>
|
||||
<a class="c-hand p-vcentered disabled">
|
||||
<i class="mdi mdi-shape mr-1 tool-icon" />
|
||||
<BaseIcon
|
||||
icon-name="mdiShape"
|
||||
:size="18"
|
||||
class="mr-1 tool-icon"
|
||||
/>
|
||||
<span>{{ t('database.variables') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -312,7 +380,11 @@
|
||||
title="Coming..."
|
||||
>
|
||||
<a class="c-hand p-vcentered disabled">
|
||||
<i class="mdi mdi-account-group mr-1 tool-icon" />
|
||||
<BaseIcon
|
||||
icon-name="mdiAccountGroup"
|
||||
:size="18"
|
||||
class="mr-1 tool-icon"
|
||||
/>
|
||||
<span>{{ t('database.manageUsers') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -326,7 +398,7 @@
|
||||
:title="t('application.openNewTab')"
|
||||
@click="addQueryTab"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-plus" />
|
||||
<BaseIcon icon-name="mdiPlus" :size="24" />
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
@@ -488,42 +560,41 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { computed, onMounted, Prop, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import * as Draggable from 'vuedraggable';
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import { useWorkspacesStore, WorkspaceTab } from '@/stores/workspaces';
|
||||
import { useConsoleStore } from '@/stores/console';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, onMounted, Prop, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import * as Draggable from 'vuedraggable';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import ModalDiscardChanges from '@/components/ModalDiscardChanges.vue';
|
||||
import ModalProcessesList from '@/components/ModalProcessesList.vue';
|
||||
import WorkspaceEditConnectionPanel from '@/components/WorkspaceEditConnectionPanel.vue';
|
||||
import WorkspaceEmptyState from '@/components/WorkspaceEmptyState.vue';
|
||||
import WorkspaceExploreBar from '@/components/WorkspaceExploreBar.vue';
|
||||
import WorkspaceEditConnectionPanel from '@/components/WorkspaceEditConnectionPanel.vue';
|
||||
import WorkspaceTabQuery from '@/components/WorkspaceTabQuery.vue';
|
||||
import WorkspaceTabTable from '@/components/WorkspaceTabTable.vue';
|
||||
import WorkspaceQueryConsole from '@/components/WorkspaceQueryConsole.vue';
|
||||
|
||||
import WorkspaceTabNewTable from '@/components/WorkspaceTabNewTable.vue';
|
||||
import WorkspaceTabNewView from '@/components/WorkspaceTabNewView.vue';
|
||||
import WorkspaceTabNewTrigger from '@/components/WorkspaceTabNewTrigger.vue';
|
||||
import WorkspaceTabNewRoutine from '@/components/WorkspaceTabNewRoutine.vue';
|
||||
import WorkspaceTabNewFunction from '@/components/WorkspaceTabNewFunction.vue';
|
||||
import WorkspaceTabNewRoutine from '@/components/WorkspaceTabNewRoutine.vue';
|
||||
import WorkspaceTabNewScheduler from '@/components/WorkspaceTabNewScheduler.vue';
|
||||
import WorkspaceTabNewTable from '@/components/WorkspaceTabNewTable.vue';
|
||||
import WorkspaceTabNewTrigger from '@/components/WorkspaceTabNewTrigger.vue';
|
||||
import WorkspaceTabNewTriggerFunction from '@/components/WorkspaceTabNewTriggerFunction.vue';
|
||||
import WorkspaceTabsContext from '@/components/WorkspaceTabsContext.vue';
|
||||
|
||||
import WorkspaceTabNewView from '@/components/WorkspaceTabNewView.vue';
|
||||
import WorkspaceTabPropsFunction from '@/components/WorkspaceTabPropsFunction.vue';
|
||||
import WorkspaceTabPropsRoutine from '@/components/WorkspaceTabPropsRoutine.vue';
|
||||
import WorkspaceTabPropsScheduler from '@/components/WorkspaceTabPropsScheduler.vue';
|
||||
import WorkspaceTabPropsTable from '@/components/WorkspaceTabPropsTable.vue';
|
||||
import WorkspaceTabPropsView from '@/components/WorkspaceTabPropsView.vue';
|
||||
import WorkspaceTabPropsTrigger from '@/components/WorkspaceTabPropsTrigger.vue';
|
||||
import WorkspaceTabPropsTriggerFunction from '@/components/WorkspaceTabPropsTriggerFunction.vue';
|
||||
import WorkspaceTabPropsRoutine from '@/components/WorkspaceTabPropsRoutine.vue';
|
||||
import WorkspaceTabPropsFunction from '@/components/WorkspaceTabPropsFunction.vue';
|
||||
import WorkspaceTabPropsScheduler from '@/components/WorkspaceTabPropsScheduler.vue';
|
||||
import ModalProcessesList from '@/components/ModalProcessesList.vue';
|
||||
import ModalDiscardChanges from '@/components/ModalDiscardChanges.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import WorkspaceTabPropsView from '@/components/WorkspaceTabPropsView.vue';
|
||||
import WorkspaceTabQuery from '@/components/WorkspaceTabQuery.vue';
|
||||
import WorkspaceTabsContext from '@/components/WorkspaceTabsContext.vue';
|
||||
import WorkspaceTabTable from '@/components/WorkspaceTabTable.vue';
|
||||
import { useFilters } from '@/composables/useFilters';
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import { useConsoleStore } from '@/stores/console';
|
||||
import { useWorkspacesStore, WorkspaceTab } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -33,10 +33,10 @@
|
||||
<form class="form-horizontal">
|
||||
<fieldset class="m-0" :disabled="isBusy">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.connectionName') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="connection.name"
|
||||
@@ -46,10 +46,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.client') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseSelect
|
||||
v-model="connection.client"
|
||||
:options="clients"
|
||||
@@ -60,10 +60,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="connection.client === 'pg'" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.connectionString') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
ref="pgString"
|
||||
v-model="connection.pgConnString"
|
||||
@@ -73,10 +73,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.host"
|
||||
class="form-input"
|
||||
@@ -85,10 +85,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.databasePath"
|
||||
:message="t('general.browse')"
|
||||
@@ -98,10 +98,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.port"
|
||||
class="form-input"
|
||||
@@ -112,10 +112,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.database" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.database"
|
||||
class="form-input"
|
||||
@@ -125,10 +125,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.user"
|
||||
class="form-input"
|
||||
@@ -138,10 +138,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.password"
|
||||
class="form-input"
|
||||
@@ -151,10 +151,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.connectionSchema" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('database.schema') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.schema"
|
||||
class="form-input"
|
||||
@@ -164,16 +164,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.readOnlyMode" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="connection.readonly" type="checkbox"><i class="form-icon" /> {{ t('connection.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="connection.ask" type="checkbox"><i class="form-icon" /> {{ t('connection.askCredentials') }}
|
||||
</label>
|
||||
@@ -187,12 +187,12 @@
|
||||
<div>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('connection.enableSsl') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-switch d-inline-block" @click.prevent="toggleSsl">
|
||||
<input type="checkbox" :checked="connection.ssl">
|
||||
<i class="form-icon" />
|
||||
@@ -201,10 +201,10 @@
|
||||
</div>
|
||||
<fieldset class="m-0" :disabled="isBusy || !connection.ssl">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.key"
|
||||
:message="t('general.browse')"
|
||||
@@ -214,10 +214,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.certificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.cert"
|
||||
:message="t('general.browse')"
|
||||
@@ -227,10 +227,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.caCertificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.ca"
|
||||
:message="t('general.browse')"
|
||||
@@ -240,10 +240,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.ciphers') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="connection.ciphers"
|
||||
@@ -253,8 +253,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="connection.untrustedConnection" type="checkbox"><i class="form-icon" /> {{ t('connection.untrustedConnection') }}
|
||||
</label>
|
||||
@@ -268,12 +268,12 @@
|
||||
<div>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('connection.enableSsh') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-switch d-inline-block" @click.prevent="toggleSsh">
|
||||
<input type="checkbox" :checked="connection.ssh">
|
||||
<i class="form-icon" />
|
||||
@@ -282,10 +282,10 @@
|
||||
</div>
|
||||
<fieldset class="m-0" :disabled="isBusy || !connection.ssh">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.sshHost"
|
||||
class="form-input"
|
||||
@@ -294,10 +294,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.sshUser"
|
||||
class="form-input"
|
||||
@@ -306,10 +306,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.sshPass"
|
||||
class="form-input"
|
||||
@@ -318,10 +318,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.sshPort"
|
||||
class="form-input"
|
||||
@@ -332,10 +332,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.sshKey"
|
||||
:message="t('general.browse')"
|
||||
@@ -345,10 +345,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.passphrase') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="connection.sshPassphrase"
|
||||
class="form-input"
|
||||
@@ -356,6 +356,22 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.keepAliveInterval') }}</label>
|
||||
</div>
|
||||
<div class="column col-7 col-sm-12">
|
||||
<div class="input-group">
|
||||
<input
|
||||
v-model="connection.sshKeepAliveInterval"
|
||||
class="form-input"
|
||||
type="number"
|
||||
min="1"
|
||||
>
|
||||
<span class="input-group-addon">{{ t('general.seconds') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -368,7 +384,11 @@
|
||||
:disabled="isBusy"
|
||||
@click="startTest"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-lightning-bolt mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiLightningBolt"
|
||||
:size="24"
|
||||
class="mr-1"
|
||||
/>
|
||||
{{ t('connection.testConnection') }}
|
||||
</button>
|
||||
<button
|
||||
@@ -377,7 +397,11 @@
|
||||
:disabled="isBusy"
|
||||
@click="saveConnection"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiContentSave"
|
||||
:size="24"
|
||||
class="mr-1"
|
||||
/>
|
||||
{{ t('general.save') }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -391,18 +415,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, Ref, ref, watch } from 'vue';
|
||||
import customizations from 'common/customizations';
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import { computed, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput.vue';
|
||||
import ModalAskCredentials from '@/components/ModalAskCredentials.vue';
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import ModalAskCredentials from '@/components/ModalAskCredentials.vue';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -442,8 +468,10 @@ const connection = ref({
|
||||
sshHost: '',
|
||||
sshUser: '',
|
||||
sshPass: '',
|
||||
sshPassphrase: null,
|
||||
sshKey: '',
|
||||
sshPort: 22,
|
||||
sshKeepAliveInterval: 1800,
|
||||
pgConnString: ''
|
||||
}) as Ref<ConnectionParams & { pgConnString: string }>;
|
||||
|
||||
|
@@ -33,10 +33,10 @@
|
||||
<form class="form-horizontal">
|
||||
<fieldset class="m-0" :disabled="isBusy">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.connectionName') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="localConnection.name"
|
||||
@@ -46,10 +46,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.client') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseSelect
|
||||
v-model="localConnection.client"
|
||||
:options="clients"
|
||||
@@ -62,10 +62,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="localConnection.client === 'pg'" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.connectionString') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
ref="pgString"
|
||||
v-model="localConnection.pgConnString"
|
||||
@@ -75,10 +75,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.host"
|
||||
class="form-input"
|
||||
@@ -87,10 +87,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.databasePath"
|
||||
:message="t('general.browse')"
|
||||
@@ -100,10 +100,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.port"
|
||||
class="form-input"
|
||||
@@ -114,10 +114,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.database" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.database"
|
||||
class="form-input"
|
||||
@@ -127,10 +127,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.user"
|
||||
class="form-input"
|
||||
@@ -140,10 +140,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.password"
|
||||
class="form-input"
|
||||
@@ -153,10 +153,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.connectionSchema" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('database.schema') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.schema"
|
||||
class="form-input"
|
||||
@@ -166,16 +166,16 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="clientCustomizations.readOnlyMode" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localConnection.readonly" type="checkbox"><i class="form-icon" /> {{ t('connection.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localConnection.ask" type="checkbox"><i class="form-icon" /> {{ t('connection.askCredentials') }}
|
||||
</label>
|
||||
@@ -189,12 +189,12 @@
|
||||
<div>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('connection.enableSsl') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-switch d-inline-block" @click.prevent="toggleSsl">
|
||||
<input type="checkbox" :checked="localConnection.ssl">
|
||||
<i class="form-icon" />
|
||||
@@ -203,10 +203,10 @@
|
||||
</div>
|
||||
<fieldset class="m-0" :disabled="isBusy || !localConnection.ssl">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.key"
|
||||
:message="t('general.browse')"
|
||||
@@ -216,10 +216,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.certificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.cert"
|
||||
:message="t('general.browse')"
|
||||
@@ -229,10 +229,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.caCertificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.ca"
|
||||
:message="t('general.browse')"
|
||||
@@ -242,10 +242,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.ciphers') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="localConnection.ciphers"
|
||||
@@ -255,8 +255,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-5 col-sm-12" />
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localConnection.untrustedConnection" type="checkbox"><i class="form-icon" /> {{ t('connection.untrustedConnection') }}
|
||||
</label>
|
||||
@@ -270,12 +270,12 @@
|
||||
<div>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('connection.enableSsh') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<label class="form-switch d-inline-block" @click.prevent="toggleSsh">
|
||||
<input type="checkbox" :checked="localConnection.ssh">
|
||||
<i class="form-icon" />
|
||||
@@ -284,10 +284,10 @@
|
||||
</div>
|
||||
<fieldset class="m-0" :disabled="isBusy || !localConnection.ssh">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.sshHost"
|
||||
class="form-input"
|
||||
@@ -296,10 +296,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.sshUser"
|
||||
class="form-input"
|
||||
@@ -308,10 +308,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.sshPass"
|
||||
class="form-input"
|
||||
@@ -320,10 +320,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.sshPort"
|
||||
class="form-input"
|
||||
@@ -334,10 +334,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.sshKey"
|
||||
:message="t('general.browse')"
|
||||
@@ -347,10 +347,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.passphrase') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<div class="column col-7 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.sshPassphrase"
|
||||
class="form-input"
|
||||
@@ -358,6 +358,22 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-5 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('connection.keepAliveInterval') }}</label>
|
||||
</div>
|
||||
<div class="column col-7 col-sm-12">
|
||||
<div class="input-group">
|
||||
<input
|
||||
v-model="localConnection.sshKeepAliveInterval"
|
||||
class="form-input"
|
||||
type="number"
|
||||
min="1"
|
||||
>
|
||||
<span class="input-group-addon">{{ t('general.seconds') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -370,7 +386,11 @@
|
||||
:disabled="isBusy"
|
||||
@click="startTest"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-lightning-bolt mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiLightningBolt"
|
||||
:size="24"
|
||||
class="mr-1"
|
||||
/>
|
||||
{{ t('connection.testConnection') }}
|
||||
</button>
|
||||
<button
|
||||
@@ -379,7 +399,11 @@
|
||||
:disabled="isBusy || !hasChanges"
|
||||
@click="saveConnection"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiContentSave"
|
||||
:size="24"
|
||||
class="mr-1"
|
||||
/>
|
||||
{{ t('general.save') }}
|
||||
</button>
|
||||
<button
|
||||
@@ -389,7 +413,11 @@
|
||||
:disabled="isBusy"
|
||||
@click="startConnection"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-connection mr-1" />
|
||||
<BaseIcon
|
||||
icon-name="mdiConnection"
|
||||
:size="24"
|
||||
class="mr-1"
|
||||
/>
|
||||
{{ t('connection.connect') }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -403,17 +431,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, Prop, Ref, ref, watch } from 'vue';
|
||||
import customizations from 'common/customizations';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { computed, Prop, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput.vue';
|
||||
import ModalAskCredentials from '@/components/ModalAskCredentials.vue';
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import ModalAskCredentials from '@/components/ModalAskCredentials.vue';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -8,18 +8,24 @@
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<button class="btn btn-primary d-flex" @click="emit('new-tab')">
|
||||
<i class="mdi mdi-24px mdi-tab-plus mr-2" />
|
||||
<BaseIcon
|
||||
icon-name="mdiTabPlus"
|
||||
:size="24"
|
||||
class="mr-2"
|
||||
/>
|
||||
{{ t('application.openNewTab') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@@ -23,23 +23,33 @@
|
||||
</div>
|
||||
<span v-else class="workspace-explorebar-title">{{ connectionName }}</span>
|
||||
<span v-if="workspace.connectionStatus === 'connected'" class="workspace-explorebar-tools">
|
||||
<i
|
||||
v-if="customizations.schemas"
|
||||
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
|
||||
:title="t('database.createNewSchema')"
|
||||
@click="showNewDBModal"
|
||||
/>
|
||||
<i
|
||||
class="mdi mdi-18px mdi-refresh c-hand mr-2"
|
||||
:class="{'rotate':isRefreshing}"
|
||||
:title="t('general.refresh')"
|
||||
@click="refresh"
|
||||
/>
|
||||
<i
|
||||
class="mdi mdi-18px mdi-power c-hand"
|
||||
:title="t('connection.disconnect')"
|
||||
@click="disconnectWorkspace(connection.uid)"
|
||||
/>
|
||||
<div :title="t('database.createNewSchema')">
|
||||
<BaseIcon
|
||||
v-if="customizations.schemas"
|
||||
icon-name="mdiDatabasePlus"
|
||||
:size="18"
|
||||
class="c-hand mr-2"
|
||||
@click="showNewDBModal"
|
||||
/>
|
||||
</div>
|
||||
<div :title="t('general.refresh')">
|
||||
<BaseIcon
|
||||
v-if="customizations.schemas"
|
||||
icon-name="mdiRefresh"
|
||||
:size="18"
|
||||
class="c-hand mr-2"
|
||||
:class="{'rotate':isRefreshing}"
|
||||
@click="refresh"
|
||||
/>
|
||||
</div>
|
||||
<div :title="t('connection.disconnect')">
|
||||
<BaseIcon
|
||||
icon-name="mdiPower"
|
||||
:size="18"
|
||||
class="c-hand"
|
||||
@click="disconnectWorkspace(connection.uid)"
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="workspace-explorebar-search">
|
||||
@@ -49,7 +59,7 @@
|
||||
:title="t('application.switchSearchMethod')"
|
||||
@click="toggleSearchMethod"
|
||||
>
|
||||
<i class="mdi mdi-18px" :class="[searchMethod === 'elements' ? 'mdi-shape' : 'mdi-database']" />
|
||||
<BaseIcon :icon-name="searchMethod === 'elements' ? 'mdiShape' : 'mdiDatabase'" :size="18" />
|
||||
</div>
|
||||
<input
|
||||
ref="searchInput"
|
||||
@@ -58,10 +68,17 @@
|
||||
type="text"
|
||||
:placeholder="searchMethod === 'elements' ? t('database.searchForElements') : t('database.searchForSchemas')"
|
||||
>
|
||||
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px" />
|
||||
<i
|
||||
<BaseIcon
|
||||
v-if="!searchTerm"
|
||||
class="form-icon"
|
||||
icon-name="mdiMagnify"
|
||||
:size="18"
|
||||
/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="form-icon c-hand mdi mdi-backspace mdi-18px pr-1"
|
||||
class="form-icon c-hand pr-1"
|
||||
icon-name="mdiBackspace"
|
||||
:size="18"
|
||||
@click="searchTerm = ''"
|
||||
/>
|
||||
</div>
|
||||
@@ -135,27 +152,26 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Component, computed, onMounted, Prop, Ref, ref, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import Views from '@/ipc-api/Views';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { Component, computed, onMounted, Prop, Ref, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import ModalNewSchema from '@/components/ModalNewSchema.vue';
|
||||
import MiscContext from '@/components/WorkspaceExploreBarMiscContext.vue';
|
||||
import MiscFolderContext from '@/components/WorkspaceExploreBarMiscFolderContext.vue';
|
||||
import WorkspaceExploreBarSchema from '@/components/WorkspaceExploreBarSchema.vue';
|
||||
import DatabaseContext from '@/components/WorkspaceExploreBarSchemaContext.vue';
|
||||
import TableContext from '@/components/WorkspaceExploreBarTableContext.vue';
|
||||
import MiscContext from '@/components/WorkspaceExploreBarMiscContext.vue';
|
||||
import MiscFolderContext from '@/components/WorkspaceExploreBarMiscFolderContext.vue';
|
||||
import ModalNewSchema from '@/components/ModalNewSchema.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import Databases from '@/ipc-api/Databases';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import Views from '@/ipc-api/Views';
|
||||
import { useConnectionsStore } from '@/stores/connections';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useSettingsStore } from '@/stores/settings';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -528,7 +544,7 @@ const toggleSearchMethod = () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> i {
|
||||
svg {
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s;
|
||||
display: flex;
|
||||
|
@@ -8,7 +8,12 @@
|
||||
class="context-element"
|
||||
@click="runElementCheck"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('general.run') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiPlay"
|
||||
:size="18"
|
||||
/> {{ t('general.run') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedMisc.type === 'trigger' && customizations.triggerEnableDisable"
|
||||
@@ -16,10 +21,18 @@
|
||||
@click="toggleTrigger"
|
||||
>
|
||||
<span v-if="!selectedMisc.enabled" class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('general.enable') }}
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiPlay"
|
||||
:size="18"
|
||||
/> {{ t('general.enable') }}
|
||||
</span>
|
||||
<span v-else class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-pause text-light pr-1" /> {{ t('general.disable') }}
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiPause"
|
||||
:size="18"
|
||||
/> {{ t('general.disable') }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -28,14 +41,27 @@
|
||||
@click="toggleScheduler"
|
||||
>
|
||||
<span v-if="!selectedMisc.enabled" class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('general.enable') }}
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiPlay"
|
||||
:size="18"
|
||||
/> {{ t('general.enable') }}
|
||||
</span>
|
||||
<span v-else class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-pause text-light pr-1" /> {{ t('general.disable') }}
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiPause"
|
||||
:size="18"
|
||||
/> {{ t('general.disable') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="context-element" @click="showDeleteModal">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-remove text-light pr-1" /> {{ t('general.delete') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiTableRemove"
|
||||
:size="18"
|
||||
/> {{ t('general.delete') }}</span>
|
||||
</div>
|
||||
<ConfirmModal
|
||||
v-if="isDeleteModal"
|
||||
@@ -44,7 +70,11 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-delete mr-1" />
|
||||
<BaseIcon
|
||||
class="text-light mr-1"
|
||||
icon-name="mdiDelete"
|
||||
:size="24"
|
||||
/>
|
||||
<span class="cut-text">{{ deleteMessage }}</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -65,19 +95,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, Prop, Ref, ref } from 'vue';
|
||||
import { EventInfos, FunctionInfos, IpcResponse, RoutineInfos, TriggerInfos } from 'common/interfaces/antares';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { computed, Prop, Ref, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
import ModalAskParameters from '@/components/ModalAskParameters.vue';
|
||||
import Functions from '@/ipc-api/Functions';
|
||||
import Routines from '@/ipc-api/Routines';
|
||||
import Schedulers from '@/ipc-api/Schedulers';
|
||||
import Triggers from '@/ipc-api/Triggers';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import ModalAskParameters from '@/components/ModalAskParameters.vue';
|
||||
import Triggers from '@/ipc-api/Triggers';
|
||||
import Routines from '@/ipc-api/Routines';
|
||||
import Functions from '@/ipc-api/Functions';
|
||||
import Schedulers from '@/ipc-api/Schedulers';
|
||||
import { EventInfos, FunctionInfos, IpcResponse, RoutineInfos, TriggerInfos } from 'common/interfaces/antares';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -118,6 +150,7 @@ const deleteMessage = computed(() => {
|
||||
switch (props.selectedMisc.type) {
|
||||
case 'trigger':
|
||||
return t('database.deleteTrigger');
|
||||
case 'routine':
|
||||
case 'procedure':
|
||||
return t('database.deleteRoutine');
|
||||
case 'function':
|
||||
|
@@ -8,42 +8,69 @@
|
||||
class="context-element"
|
||||
@click="emit('open-create-trigger-tab')"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ t('database.createNewTrigger') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiTableCog"
|
||||
:size="18"
|
||||
/> {{ t('database.createNewTrigger') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="['procedure', 'routine'].includes(props.selectedMisc)"
|
||||
class="context-element"
|
||||
@click="emit('open-create-routine-tab')"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle text-light pr-1" /> {{ t('database.createNewRoutine') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiSyncCircle"
|
||||
:size="18"
|
||||
/> {{ t('database.createNewRoutine') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.selectedMisc === 'function'"
|
||||
class="context-element"
|
||||
@click="emit('open-create-function-tab')"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box text-light pr-1" /> {{ t('database.createNewFunction') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiArrowRightBoldBox"
|
||||
:size="18"
|
||||
/> {{ t('database.createNewFunction') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.selectedMisc === 'triggerFunction'"
|
||||
class="context-element"
|
||||
@click="emit('open-create-trigger-function-tab')"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-cog-clockwise text-light pr-1" /> {{ t('database.createNewFunction') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiCogClockwise"
|
||||
:size="18"
|
||||
/> {{ t('database.createNewFunction') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="props.selectedMisc === 'scheduler'"
|
||||
class="context-element"
|
||||
@click="emit('open-create-scheduler-tab')"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ t('database.createNewScheduler') }}</span>
|
||||
<span class="d-flex">
|
||||
<BaseIcon
|
||||
class="text-light mt-1 mr-1"
|
||||
icon-name="mdiCalendarClock"
|
||||
:size="18"
|
||||
/> {{ t('database.createNewScheduler') }}</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import BaseIcon from '@/components/BaseIcon.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user