mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
98 Commits
Author | SHA1 | Date | |
---|---|---|---|
c1891dd5de | |||
53fe986bcb | |||
d702ce3fa9 | |||
63544e95da | |||
6df214558f | |||
f5b86e59e7 | |||
28f14c9195 | |||
|
90922e6f96 | ||
|
4b414df7e4 | ||
27f0068415 | |||
|
52e42fa1b5 | ||
|
5b9b539bc7 | ||
832aa75ebe | |||
aba67f3872 | |||
5a1644f023 | |||
e372712556 | |||
d4727a7d20 | |||
|
f2c2f33afa | ||
|
6dc4bdd0c0 | ||
|
9c6f1a9ea5 | ||
dd264f802e | |||
fed0e10702 | |||
e7ce4ef6ed | |||
e03f2eef49 | |||
3a77f0818d | |||
6cd2f89bbf | |||
16ec82eb7e | |||
84b2255bf4 | |||
2e39d810b5 | |||
56918d89c7 | |||
083198af8f | |||
ad7e459c68 | |||
8c4c93cb07 | |||
eee85d24b7 | |||
92fe029906 | |||
1dd2147b68 | |||
5a54e7ac33 | |||
c19bac2373 | |||
7b1cb4ff86 | |||
f120af25f4 | |||
83b3ca563a | |||
0fab3bc43c | |||
473c4636cf | |||
2e11a0c032 | |||
193042b92d | |||
51b14195a8 | |||
f831fcd442 | |||
3104847b92 | |||
|
bc0b029369 | ||
efee7f3a0e | |||
7c820b1827 | |||
38ec703705 | |||
|
2afb66a2e6 | ||
|
5a5af3af5e | ||
8f0e5407ae | |||
8bed7c2f34 | |||
f4a2f43ea4 | |||
|
6063b3f697 | ||
2f5fa0f2e4 | |||
703a515462 | |||
9d8e9a5e1f | |||
1c73503138 | |||
32bbc45329 | |||
9d90dc362e | |||
e808b86c52 | |||
6e01f0f2e7 | |||
38bfea279c | |||
0044522390 | |||
|
462ede8dc7 | ||
60dd4df5ec | |||
fa006798cf | |||
c5abc3d6b2 | |||
|
a8dc30c9dd | ||
|
2cfed3e79b | ||
|
001983c5a2 | ||
470f7455c0 | |||
|
70e00a7ee6 | ||
|
b76247e304 | ||
f58c30ff17 | |||
5bdbebfbc3 | |||
|
03c4a1c797 | ||
|
e18604b3ce | ||
|
3ff8d2571b | ||
|
f22f8d2317 | ||
|
8a4a099e37 | ||
|
702ffb81ef | ||
|
93e16fdda2 | ||
|
575c8ea8ca | ||
|
4ff1d107b8 | ||
3ad1e51f42 | |||
e07e7b736e | |||
89815bf5e7 | |||
9d00f58998 | |||
f5d001846a | |||
0a6907b549 | |||
322f92b734 | |||
|
038e4494f5 | ||
|
12f3e03b45 |
@@ -220,8 +220,46 @@
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "64knl",
|
||||
"name": "René",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3864423?v=4",
|
||||
"profile": "https://64k.nl/",
|
||||
"contributions": [
|
||||
"code",
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zxp19821005",
|
||||
"name": "Woodenman",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4915850?v=4",
|
||||
"profile": "https://github.com/zxp19821005",
|
||||
"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,
|
||||
"skipCi": true
|
||||
"skipCi": true,
|
||||
"commitType": "docs"
|
||||
}
|
||||
|
1
.github/dependabot.yml
vendored
1
.github/dependabot.yml
vendored
@@ -11,3 +11,4 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
target-branch: "develop"
|
||||
|
42
.github/workflows/build-beta.yml
vendored
Normal file
42
.github/workflows/build-beta.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
name: Build & release [BETA]
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+'
|
||||
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11, ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: beta
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm i
|
||||
|
||||
- name: "Build"
|
||||
run: npm run build
|
||||
|
||||
- name: Release
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "build/*.AppImage,build/*.yml,build/*.deb,build/*.dmg,build/*.blockmap,build/*.zip,build/*.exe"
|
||||
allowUpdates: true
|
||||
draft: true
|
||||
generateReleaseNotes: true
|
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
@@ -1,9 +1,12 @@
|
||||
name: Build & release
|
||||
name: Build & release [STABLE]
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
|
||||
|
||||
jobs:
|
||||
release:
|
||||
@@ -11,11 +14,19 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-11, ubuntu-20.04, windows-latest]
|
||||
os: [macos-11, ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- name: Exit if not on master branch
|
||||
if: contains(env.BRANCH_NAME, 'master') == false
|
||||
run: |
|
||||
echo "Wrong environment ${{env.BRANCH_NAME}}"
|
||||
exit 0
|
||||
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: master
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
|
5
.github/workflows/test-e2e-win.yml
vendored
5
.github/workflows/test-e2e-win.yml
vendored
@@ -1,6 +1,9 @@
|
||||
name: Test end-to-end [WINDOWS]
|
||||
|
||||
on: push
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
release:
|
||||
|
95
CHANGELOG.md
95
CHANGELOG.md
@@ -2,6 +2,101 @@
|
||||
|
||||
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.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)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* ability to change sql dump file name ([2e39d81](https://github.com/antares-sql/antares/commit/2e39d810b519401d0410cbb76520c07c595329fc))
|
||||
* ability to export a table dump from table context menu ([84b2255](https://github.com/antares-sql/antares/commit/84b2255bf405431070511890b2bca770fc4cc2bc))
|
||||
* support to links in changelog ([ad7e459](https://github.com/antares-sql/antares/commit/ad7e459c689d70ca664b9a3091d3dcab3f26ce4d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **MySQL:** missing error details on mysql importer with some exceptione ([7b1cb4f](https://github.com/antares-sql/antares/commit/7b1cb4ff86dddb5fb4b4d960b47ea17f38a24aa6))
|
||||
|
||||
### [0.7.15](https://github.com/antares-sql/antares/compare/v0.7.14...v0.7.15) (2023-07-31)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* export file name with hour, minutes and seconds, closes [#610](https://github.com/antares-sql/antares/issues/610) ([2f5fa0f](https://github.com/antares-sql/antares/commit/2f5fa0f2e416e88753c9dc2bf32edefba8c4e072))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* display content of BLOB fields if not binary, fixes [#628](https://github.com/antares-sql/antares/issues/628) ([f831fcd](https://github.com/antares-sql/antares/commit/f831fcd442f16a03f0ea83ff5bf77a4a79906eb6))
|
||||
* **MySQL:** error insertinf new fields with some MySQL configurations, fixes [#360](https://github.com/antares-sql/antares/issues/360) ([51b1419](https://github.com/antares-sql/antares/commit/51b14195a8a6c7e7f1b12bd4b86b7164a56b2aa5))
|
||||
* **MySQL:** unable to set more than one value in SET fields ([7c820b1](https://github.com/antares-sql/antares/commit/7c820b18276e4ed5e381d91110acd032862a5be9))
|
||||
|
||||
### [0.7.14](https://github.com/antares-sql/antares/compare/v0.7.13...v0.7.14) (2023-07-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* button to open view settings tab ([32bbc45](https://github.com/antares-sql/antares/commit/32bbc453294736970ddbcadd3cc45597277f5bda))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* unable to insert new rows ([1c73503](https://github.com/antares-sql/antares/commit/1c735031380c48aa8b08ed5ce3df80008dc72af8))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* **PostgreSQL:** minor improvement to schema selection ([9d8e9a5](https://github.com/antares-sql/antares/commit/9d8e9a5e1fda190ee7b3d4fd59e6178dd5ec1651))
|
||||
|
||||
### [0.7.13](https://github.com/antares-sql/antares/compare/v0.7.12...v0.7.13) (2023-07-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* button to open table settings tab, closes [#608](https://github.com/antares-sql/antares/issues/608) ([38bfea2](https://github.com/antares-sql/antares/commit/38bfea279ce93366dfd2021d0e91622a5a88878e))
|
||||
* update connection ([462ede8](https://github.com/antares-sql/antares/commit/462ede8dc701aaf9c6089b3ec41eea0f31babdf9))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **PostgreSQL:** unable to connect to database, fixes [#614](https://github.com/antares-sql/antares/issues/614) ([e808b86](https://github.com/antares-sql/antares/commit/e808b86c52b8488e0c079a9f0ddce225338af4c0))
|
||||
* unable to copy as sql inserts with BIT fileds, fixes [#613](https://github.com/antares-sql/antares/issues/613) ([6e01f0f](https://github.com/antares-sql/antares/commit/6e01f0f2e7194284341f89a44839d16398358f9b))
|
||||
|
||||
### [0.7.12](https://github.com/antares-sql/antares/compare/v0.7.11...v0.7.12) (2023-07-03)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add Dutch language support ([4ff1d10](https://github.com/antares-sql/antares/commit/4ff1d107b8837887ceb3ffecaed46b9bdb908127))
|
||||
* format options of csv export, closes [#196](https://github.com/antares-sql/antares/issues/196) ([3ad1e51](https://github.com/antares-sql/antares/commit/3ad1e51f42f3cc37ad66bdab64e9a8a0eadea74b))
|
||||
* more translations ([575c8ea](https://github.com/antares-sql/antares/commit/575c8ea8cabc1fb315bad1693df6cd4ccd869838))
|
||||
* **PostgreSQL:** ability to switch the database, closes [#432](https://github.com/antares-sql/antares/issues/432) ([89815bf](https://github.com/antares-sql/antares/commit/89815bf5e7c4062950b7418b31b45552ae0e1276))
|
||||
* Sort available languages alphabetically ([3ff8d25](https://github.com/antares-sql/antares/commit/3ff8d2571be306a8a72e5ad2b9f963b285e8db26))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **PostgreSQL:** unable to export as sql inserts ([e07e7b7](https://github.com/antares-sql/antares/commit/e07e7b736ef29368262ec4b17d9e1f54ef3ec390))
|
||||
* rename components and variables in SettingBarContext ([8a4a099](https://github.com/antares-sql/antares/commit/8a4a099e37c9bbc1365f322f6276f32153e24379))
|
||||
* spelling corrections ([93e16fd](https://github.com/antares-sql/antares/commit/93e16fdda29601f3e898b1a9470bd8546ea95df6))
|
||||
* update source string to fix spelling ([001983c](https://github.com/antares-sql/antares/commit/001983c5a2ebe17c943a9be3a58cc587f5cd09e3))
|
||||
|
||||
### [0.7.11](https://github.com/antares-sql/antares/compare/v0.7.10...v0.7.11) (2023-06-04)
|
||||
|
||||
|
||||
|
16
README.md
16
README.md
@@ -7,7 +7,8 @@
|
||||
|
||||
# Antares SQL Client
|
||||
|
||||
  [](https://actions-badge.atrox.dev/fabio286/antares/goto) [](https://snapcraft.io/antares) [](https://snapcraft.io/antares) [](https://twitter.com/AntaresSQL) [](https://www.treedom.net/en/user/fabio-di-stasio/event/antares-for-the-planet)
|
||||
  [](https://actions-badge.atrox.dev/fabio286/antares/goto) [](https://snapcraft.io/antares) [](https://snapcraft.io/antares)
|
||||
 [](https://twitter.com/AntaresSQL) [](https://www.treedom.net/en/user/fabio-di-stasio/event/antares-for-the-planet)
|
||||
|
||||
Antares is an SQL client based on [Electron.js](https://github.com/electron/electron) and [Vue.js](https://github.com/vuejs/vue) that aims to become a useful tool, especially for developers.
|
||||
Our target is to support as many databases as possible, and all major operating systems, including the ARM versions.
|
||||
@@ -17,9 +18,12 @@ However, there are all the features necessary to have a pleasant database manage
|
||||
We are actively working on it, hoping to provide new cool features, improvements and fixes as soon as possible.
|
||||
|
||||
🔗 If you are curious to try Antares you can download and install the [latest release](https://github.com/Fabio286/antares/releases/latest).
|
||||
👁 To stay tuned for new releases [follow Antares SQL](https://twitter.com/AntaresSQL) on Twitter.
|
||||
👁 To stay tuned for new releases follow Antares SQL on [Mastodon](https://fosstodon.org/@AntaresSQL) or [Twitter](https://twitter.com/AntaresSQL).
|
||||
🌟 Don't forget to **leave a star** if you appreciate this project.
|
||||
🗳️ Poll: **[Which is the main OS you use Antares on?](https://github.com/antares-sql/antares/discussions/379)**
|
||||
|
||||
🗳️ Polls:
|
||||
- **[Which is the main OS you use Antares on?](https://github.com/antares-sql/antares/discussions/379)**
|
||||
- **[Which database do you use the most?](https://github.com/antares-sql/antares/discussions/594)**
|
||||
|
||||
## Current key features
|
||||
|
||||
@@ -63,7 +67,7 @@ On macOS you can run `.dmg` distribution following [this guide](https://support.
|
||||
|
||||
## Download
|
||||
|
||||
[](https://snapcraft.io/antares) [](https://aur.archlinux.org/packages/antares-sql/) [<img src="https://developer.microsoft.com/store/badges/images/English_get-it-from-MS.png" style="height: 56px">](https://www.microsoft.com/p/antares-sql-client/9nhtb9sq51r1?cid=storebadge&ocid=badge&rtc=1&activetab=pivot:overviewtab)
|
||||
[](https://snapcraft.io/antares) [](https://aur.archlinux.org/packages/antares-sql-bin) [<img src="https://developer.microsoft.com/store/badges/images/English_get-it-from-MS.png" style="height: 56px">](https://www.microsoft.com/p/antares-sql-client/9nhtb9sq51r1?cid=storebadge&ocid=badge&rtc=1&activetab=pivot:overviewtab)
|
||||
🚀 **[Other Downloads](https://github.com/Fabio286/antares/releases/latest)**
|
||||
|
||||
## Coming soon
|
||||
@@ -147,6 +151,10 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/555cider"><img src="https://avatars.githubusercontent.com/u/73565447?v=4?s=100" width="100px;" alt="555cider"/><br /><sub><b>555cider</b></sub></a><br /><a href="#translation-555cider" title="Translation">🌍</a></td>
|
||||
<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>
|
||||
|
4974
package-lock.json
generated
4974
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.7.11",
|
||||
"version": "0.7.16",
|
||||
"description": "A modern, fast and productivity driven SQL client with a focus in UX.",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/antares-sql/antares.git",
|
||||
@@ -16,9 +16,10 @@
|
||||
"build:appx": "npm run build -- --win appx",
|
||||
"rebuild:electron": "rimraf ./dist && npm run postinstall && npm run devtools:install",
|
||||
"release": "standard-version",
|
||||
"release:pre": "npm run release -- --prerelease alpha",
|
||||
"release:beta": "npm run release -- --prerelease beta",
|
||||
"devtools:install": "node scripts/devtoolsInstaller",
|
||||
"postinstall": "electron-builder install-app-deps",
|
||||
"translation:check": "ts-node ./scripts/translationCheck.ts",
|
||||
"test:e2e": "npm run compile && npm run test:e2e-dry",
|
||||
"test:e2e-dry": "xvfb-maybe -- playwright test",
|
||||
"lint": "eslint . --ext .js,.ts,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"",
|
||||
@@ -66,6 +67,7 @@
|
||||
"target": "deb",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
},
|
||||
@@ -73,6 +75,7 @@
|
||||
"target": "AppImage",
|
||||
"arch": [
|
||||
"x64",
|
||||
"arm64",
|
||||
"armv7l"
|
||||
]
|
||||
}
|
||||
@@ -134,16 +137,16 @@
|
||||
"leaflet": "~1.7.1",
|
||||
"marked": "~4.0.19",
|
||||
"moment": "~2.29.4",
|
||||
"mysql2": "~2.3.2",
|
||||
"mysql2": "~3.5.2",
|
||||
"node-firebird": "~1.1.4",
|
||||
"pg": "~8.7.1",
|
||||
"pg": "~8.11.1",
|
||||
"pg-connection-string": "~2.5.0",
|
||||
"pg-query-stream": "~4.2.3",
|
||||
"pgsql-ast-parser": "~7.2.1",
|
||||
"pinia": "~2.0.28",
|
||||
"source-map-support": "~0.5.20",
|
||||
"spectre.css": "~0.5.9",
|
||||
"sql-formatter": "~12.0.3",
|
||||
"sql-formatter": "~12.2.0",
|
||||
"ssh2-promise": "~1.0.2",
|
||||
"v-mask": "~2.3.0",
|
||||
"vue": "~3.2.45",
|
||||
@@ -196,6 +199,7 @@
|
||||
"stylelint-scss": "~4.3.0",
|
||||
"tree-kill": "~1.2.2",
|
||||
"ts-loader": "~9.2.8",
|
||||
"ts-node": "~10.9.1",
|
||||
"typescript": "~4.6.3",
|
||||
"unzip-crx-3": "~0.2.0",
|
||||
"vue-eslint-parser": "~8.3.0",
|
||||
|
45
scripts/translationCheck.ts
Normal file
45
scripts/translationCheck.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import { localesNames } from '../src/renderer/i18n/supported-locales';
|
||||
import { enUS } from '../src/renderer/i18n/en-US';
|
||||
const locale = process.argv[2];
|
||||
let fullCount = 0;
|
||||
let checkCount = 0;
|
||||
|
||||
if (!locale) {
|
||||
console.log('Please specify locale code as first argument.');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
if (!Object.keys(localesNames).includes(locale)) {
|
||||
console.log(`Translation ${locale} not fount in supported locales.`);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
console.log('Checking missing translations for:', locale);
|
||||
|
||||
const i18nFile = require(`../src/renderer/i18n/${locale}`)[locale.replace('-', '')];
|
||||
|
||||
for (const group in enUS) {
|
||||
// @ts-ignore
|
||||
fullCount += Object.keys(enUS[group]).length;
|
||||
|
||||
if (!Object.keys(i18nFile).includes(group)) {
|
||||
console.log(`Group "\u001b[31m${group}\u001b[0m" missing!`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
for (const term in enUS[group]) {
|
||||
if (!Object.keys(i18nFile[group]).includes(term))
|
||||
console.log(`Translation "\u001b[33m${group}.${term}\u001b[0m" missing!`);
|
||||
// @ts-ignore
|
||||
else if (i18nFile[group][term] === enUS[group][term]) {
|
||||
console.log(`Term "\u001b[36m${group}.${term}\u001b[0m" not translated!`);
|
||||
checkCount++;
|
||||
}
|
||||
else
|
||||
checkCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(checkCount, 'of', fullCount, 'strings are present in', locale, `(\u001b[32m${(checkCount*100/fullCount).toFixed(1)}%\u001b[0m)`);
|
@@ -4,7 +4,7 @@ summary: Open source SQL client made to be simple and complete.
|
||||
description: |
|
||||
Antares is an SQL client that aims to become an useful and complete tool, especially for developers.
|
||||
The target is to support as many databases as possible, and all major operating systems, including the ARM versions.
|
||||
base: core20
|
||||
base: core22
|
||||
|
||||
grade: stable
|
||||
confinement: strict
|
||||
@@ -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
|
||||
@@ -119,10 +119,10 @@ parts:
|
||||
cleanup:
|
||||
after: [antares]
|
||||
plugin: nil
|
||||
build-snaps: [gnome-3-38-2004]
|
||||
build-snaps: [gnome-42-2204]
|
||||
override-prime: |
|
||||
set -eux
|
||||
cd /snap/gnome-3-38-2004/current
|
||||
cd /snap/gnome-42-2204/current
|
||||
find . -type f,l -exec rm -f $SNAPCRAFT_PRIME/{} \;
|
||||
|
||||
mdns-lookup:
|
||||
@@ -136,7 +136,7 @@ parts:
|
||||
- libnss-mdns
|
||||
override-prime: |
|
||||
set -eux
|
||||
sed -Ee 's/^\s*hosts:(\s+)files/hosts:\1files mdns4_minimal \[NOTFOUND=return\]/' /snap/core20/current/etc/nsswitch.conf > $SNAPCRAFT_STAGE/etc/nsswitch.conf
|
||||
sed -Ee 's/^\s*hosts:(\s+)files/hosts:\1files mdns4_minimal \[NOTFOUND=return\]/' /snap/core22/current/etc/nsswitch.conf > $SNAPCRAFT_STAGE/etc/nsswitch.conf
|
||||
snapcraftctl prime
|
||||
prime:
|
||||
- lib/$SNAPCRAFT_ARCH_TRIPLET/libnss_mdns4_minimal*
|
||||
@@ -146,10 +146,7 @@ apps:
|
||||
antares:
|
||||
command: opt/Antares/antares --no-sandbox
|
||||
desktop: usr/share/applications/antares.desktop
|
||||
extensions: [gnome-3-38]
|
||||
environment:
|
||||
# Fallback to XWayland if running in a Wayland session.
|
||||
DISABLE_WAYLAND: 1
|
||||
extensions: [gnome]
|
||||
plugs:
|
||||
- browser-support
|
||||
- cups-control
|
||||
|
31
src/common/libs/encrypter.ts
Normal file
31
src/common/libs/encrypter.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
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 {
|
||||
encrypt,
|
||||
decrypt
|
||||
};
|
@@ -72,7 +72,7 @@ export const escapeAndQuote = (val: string, client: ClientCode) => {
|
||||
export const valueToSqlString = (args: {
|
||||
val: any;
|
||||
client: ClientCode;
|
||||
field: {type: string; datePrecision: number; isArray?: boolean};
|
||||
field: {type: string; datePrecision?: number; precision?: number | false; isArray?: boolean};
|
||||
}): string => {
|
||||
let parsedValue;
|
||||
const { val, client, field } = args;
|
||||
@@ -105,7 +105,7 @@ export const valueToSqlString = (args: {
|
||||
else if (TEXT_SEARCH.includes(field.type))
|
||||
parsedValue = `'${val.replaceAll('\'', '\'\'')}'`;
|
||||
else if (BIT.includes(field.type))
|
||||
parsedValue = `b'${hexToBinary(Buffer.from(val).toString('hex') as undefined as HexChar[])}'`;
|
||||
parsedValue = `b'${hexToBinary(Buffer.from(new Uint8Array(Object.values(val))).toString('hex') as undefined as HexChar[])}'`;
|
||||
else if (BLOB.includes(field.type)) {
|
||||
let buffer: Buffer;
|
||||
if (val instanceof Uint8Array)
|
||||
|
@@ -1,22 +1,22 @@
|
||||
export const shortcutEvents: { [key: string]: { l18n: string; l18nParam?: string | number; context?: 'tab' }} = {
|
||||
'run-or-reload': { l18n: 'message.runOrReload', context: 'tab' },
|
||||
'open-new-tab': { l18n: 'message.openNewTab', context: 'tab' },
|
||||
'close-tab': { l18n: 'message.closeTab', context: 'tab' },
|
||||
'format-query': { l18n: 'message.formatQuery', context: 'tab' },
|
||||
'kill-query': { l18n: 'message.killQuery', context: 'tab' },
|
||||
'query-history': { l18n: 'message.queryHistory', context: 'tab' },
|
||||
'clear-query': { l18n: 'message.clearQuery', context: 'tab' },
|
||||
'next-tab': { l18n: 'message.nextTab' },
|
||||
'prev-tab': { l18n: 'message.previousTab' },
|
||||
'open-all-connections': { l18n: 'message.openAllConnections' },
|
||||
'open-filter': { l18n: 'message.openFilter' },
|
||||
'next-page': { l18n: 'message.nextResultsPage' },
|
||||
'prev-page': { l18n: 'message.previousResultsPage' },
|
||||
'toggle-console': { l18n: 'message.toggleConsole' },
|
||||
'save-content': { l18n: 'message.saveContent' },
|
||||
'create-connection': { l18n: 'message.createNewConnection' },
|
||||
'open-settings': { l18n: 'message.openSettings' },
|
||||
'open-scratchpad': { l18n: 'message.openScratchpad' }
|
||||
'run-or-reload': { l18n: 'application.runOrReload', context: 'tab' },
|
||||
'open-new-tab': { l18n: 'application.openNewTab', context: 'tab' },
|
||||
'close-tab': { l18n: 'application.closeTab', context: 'tab' },
|
||||
'format-query': { l18n: 'database.formatQuery', context: 'tab' },
|
||||
'kill-query': { l18n: 'database.killQuery', context: 'tab' },
|
||||
'query-history': { l18n: 'database.queryHistory', context: 'tab' },
|
||||
'clear-query': { l18n: 'database.clearQuery', context: 'tab' },
|
||||
'next-tab': { l18n: 'application.nextTab' },
|
||||
'prev-tab': { l18n: 'application.previousTab' },
|
||||
'open-all-connections': { l18n: 'application.openAllConnections' },
|
||||
'open-filter': { l18n: 'application.openFilter' },
|
||||
'next-page': { l18n: 'application.nextResultsPage' },
|
||||
'prev-page': { l18n: 'application.previousResultsPage' },
|
||||
'toggle-console': { l18n: 'application.toggleConsole' },
|
||||
'save-content': { l18n: 'application.saveContent' },
|
||||
'create-connection': { l18n: 'connection.createNewConnection' },
|
||||
'open-settings': { l18n: 'application.openSettings' },
|
||||
'open-scratchpad': { l18n: 'application.openScratchpad' }
|
||||
};
|
||||
|
||||
interface ShortcutRecord {
|
||||
@@ -124,7 +124,7 @@ const shortcuts: ShortcutRecord[] = [
|
||||
|
||||
for (let i = 1; i <= 9; i++) {
|
||||
shortcutEvents[`select-tab-${i}`] = {
|
||||
l18n: 'message.selectTabNumber',
|
||||
l18n: 'application.selectTabNumber',
|
||||
l18nParam: i
|
||||
};
|
||||
|
||||
|
14
src/main/ipc-handlers/database.ts
Normal file
14
src/main/ipc-handlers/database.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
export default (connections: {[key: string]: antares.Client}) => {
|
||||
ipcMain.handle('get-databases', async (event, uid) => {
|
||||
try {
|
||||
const result = await connections[uid].getDatabases();
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
};
|
@@ -9,6 +9,7 @@ import functions from './functions';
|
||||
import schedulers from './schedulers';
|
||||
import updates from './updates';
|
||||
import application from './application';
|
||||
import database from './database';
|
||||
import schema from './schema';
|
||||
import users from './users';
|
||||
|
||||
@@ -22,6 +23,7 @@ export default () => {
|
||||
routines(connections);
|
||||
functions(connections);
|
||||
schedulers(connections);
|
||||
database(connections);
|
||||
schema(connections);
|
||||
users(connections);
|
||||
updates();
|
||||
|
@@ -1,11 +1,20 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
import * as Store from 'electron-store';
|
||||
const persistentStore = new Store({ name: 'settings', clearInvalidConfig: true });
|
||||
const isMacOS = process.platform === 'darwin';
|
||||
|
||||
const persistentStore = new Store({
|
||||
name: 'settings',
|
||||
clearInvalidConfig: true,
|
||||
migrations: {
|
||||
'0.7.15': store => {
|
||||
store.set('allow_prerelease', false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const isMacOS = process.platform === 'darwin';
|
||||
let mainWindow: Electron.IpcMainEvent;
|
||||
autoUpdater.allowPrerelease = persistentStore.get('allow_prerelease', true) as boolean;
|
||||
autoUpdater.allowPrerelease = persistentStore.get('allow_prerelease', false) as boolean;
|
||||
|
||||
export default () => {
|
||||
ipcMain.on('check-for-updates', event => {
|
||||
|
@@ -162,6 +162,10 @@ export abstract class AntaresCore {
|
||||
throw new Error('Method "getDbConfig" not implemented');
|
||||
}
|
||||
|
||||
getDatabases () {
|
||||
throw new Error('Method "getDatabases" not implemented');
|
||||
}
|
||||
|
||||
createSchema (...args: any) {
|
||||
throw new Error('Method "createSchema" not implemented');
|
||||
}
|
||||
|
@@ -582,7 +582,7 @@ export class MySQLClient extends AntaresCore {
|
||||
return rows.map((field) => {
|
||||
const numLengthMatch = field.COLUMN_TYPE.match(/int\(([^)]+)\)/);
|
||||
const numLength = numLengthMatch ? +numLengthMatch.pop() : field.NUMERIC_PRECISION || null;
|
||||
const enumValues = /(enum|set)/.test(field.COLUMN_TYPE)
|
||||
const enumValues = /(enum)/.test(field.COLUMN_TYPE)
|
||||
? field.COLUMN_TYPE.match(/\(([^)]+)\)/)[0].slice(1, -1)
|
||||
: null;
|
||||
|
||||
@@ -865,21 +865,23 @@ export class MySQLClient extends AntaresCore {
|
||||
options
|
||||
} = params;
|
||||
|
||||
let sql = `ALTER TABLE \`${schema}\`.\`${table}\` `;
|
||||
const alterColumns: string[] = [];
|
||||
const sql = `ALTER TABLE \`${schema}\`.\`${table}\` `;
|
||||
const alterColumnsAdd: string[] = [];
|
||||
const alterColumnsChange: string[] = [];
|
||||
const alterColumnsDrop: string[] = [];
|
||||
|
||||
// OPTIONS
|
||||
if ('comment' in options) alterColumns.push(`COMMENT='${options.comment}'`);
|
||||
if ('engine' in options) alterColumns.push(`ENGINE=${options.engine}`);
|
||||
if ('autoIncrement' in options) alterColumns.push(`AUTO_INCREMENT=${+options.autoIncrement}`);
|
||||
if ('collation' in options) alterColumns.push(`COLLATE='${options.collation}'`);
|
||||
if ('comment' in options) alterColumnsChange.push(`COMMENT='${options.comment}'`);
|
||||
if ('engine' in options) alterColumnsChange.push(`ENGINE=${options.engine}`);
|
||||
if ('autoIncrement' in options) alterColumnsChange.push(`AUTO_INCREMENT=${+options.autoIncrement}`);
|
||||
if ('collation' in options) alterColumnsChange.push(`COLLATE='${options.collation}'`);
|
||||
|
||||
// ADD FIELDS
|
||||
additions.forEach(addition => {
|
||||
const typeInfo = this.getTypeInfo(addition.type);
|
||||
const length = typeInfo.length ? addition.enumValues || addition.numLength || addition.charLength || addition.datePrecision : false;
|
||||
|
||||
alterColumns.push(`ADD COLUMN \`${addition.name}\`
|
||||
alterColumnsAdd.push(`ADD COLUMN \`${addition.name}\`
|
||||
${addition.type.toUpperCase()}${length ? `(${length}${addition.numScale ? `,${addition.numScale}` : ''})` : ''}
|
||||
${addition.unsigned ? 'UNSIGNED' : ''}
|
||||
${addition.zerofill ? 'ZEROFILL' : ''}
|
||||
@@ -898,18 +900,18 @@ export class MySQLClient extends AntaresCore {
|
||||
let type = addition.type;
|
||||
|
||||
if (type === 'PRIMARY')
|
||||
alterColumns.push(`ADD PRIMARY KEY (${fields})`);
|
||||
alterColumnsAdd.push(`ADD PRIMARY KEY (${fields})`);
|
||||
else {
|
||||
if (type === 'UNIQUE')
|
||||
type = 'UNIQUE INDEX';
|
||||
|
||||
alterColumns.push(`ADD ${type} \`${addition.name}\` (${fields})`);
|
||||
alterColumnsAdd.push(`ADD ${type} \`${addition.name}\` (${fields})`);
|
||||
}
|
||||
});
|
||||
|
||||
// ADD FOREIGN KEYS
|
||||
foreignChanges.additions.forEach(addition => {
|
||||
alterColumns.push(`ADD CONSTRAINT \`${addition.constraintName}\` FOREIGN KEY (\`${addition.field}\`) REFERENCES \`${addition.refTable}\` (\`${addition.refField}\`) ON UPDATE ${addition.onUpdate} ON DELETE ${addition.onDelete}`);
|
||||
alterColumnsAdd.push(`ADD CONSTRAINT \`${addition.constraintName}\` FOREIGN KEY (\`${addition.field}\`) REFERENCES \`${addition.refTable}\` (\`${addition.refField}\`) ON UPDATE ${addition.onUpdate} ON DELETE ${addition.onDelete}`);
|
||||
});
|
||||
|
||||
// CHANGE FIELDS
|
||||
@@ -917,7 +919,7 @@ export class MySQLClient extends AntaresCore {
|
||||
const typeInfo = this.getTypeInfo(change.type);
|
||||
const length = typeInfo.length ? change.enumValues || change.numLength || change.charLength || change.datePrecision : false;
|
||||
|
||||
alterColumns.push(`CHANGE COLUMN \`${change.orgName}\` \`${change.name}\`
|
||||
alterColumnsChange.push(`CHANGE COLUMN \`${change.orgName}\` \`${change.name}\`
|
||||
${change.type.toUpperCase()}${length ? `(${length}${change.numScale ? `,${change.numScale}` : ''})` : ''}
|
||||
${change.unsigned ? 'UNSIGNED' : ''}
|
||||
${change.zerofill ? 'ZEROFILL' : ''}
|
||||
@@ -933,53 +935,56 @@ export class MySQLClient extends AntaresCore {
|
||||
// CHANGE INDEX
|
||||
indexChanges.changes.forEach(change => {
|
||||
if (change.oldType === 'PRIMARY')
|
||||
alterColumns.push('DROP PRIMARY KEY');
|
||||
alterColumnsChange.push('DROP PRIMARY KEY');
|
||||
else
|
||||
alterColumns.push(`DROP INDEX \`${change.oldName}\``);
|
||||
alterColumnsChange.push(`DROP INDEX \`${change.oldName}\``);
|
||||
|
||||
const fields = change.fields.map(field => `\`${field}\``).join(',');
|
||||
let type = change.type;
|
||||
|
||||
if (type === 'PRIMARY')
|
||||
alterColumns.push(`ADD PRIMARY KEY (${fields})`);
|
||||
alterColumnsChange.push(`ADD PRIMARY KEY (${fields})`);
|
||||
else {
|
||||
if (type === 'UNIQUE')
|
||||
type = 'UNIQUE INDEX';
|
||||
|
||||
alterColumns.push(`ADD ${type} \`${change.name}\` (${fields})`);
|
||||
alterColumnsChange.push(`ADD ${type} \`${change.name}\` (${fields})`);
|
||||
}
|
||||
});
|
||||
|
||||
// CHANGE FOREIGN KEYS
|
||||
foreignChanges.changes.forEach(change => {
|
||||
alterColumns.push(`DROP FOREIGN KEY \`${change.oldName}\``);
|
||||
alterColumns.push(`ADD CONSTRAINT \`${change.constraintName}\` FOREIGN KEY (\`${change.field}\`) REFERENCES \`${change.refTable}\` (\`${change.refField}\`) ON UPDATE ${change.onUpdate} ON DELETE ${change.onDelete}`);
|
||||
alterColumnsChange.push(`DROP FOREIGN KEY \`${change.oldName}\``);
|
||||
alterColumnsChange.push(`ADD CONSTRAINT \`${change.constraintName}\` FOREIGN KEY (\`${change.field}\`) REFERENCES \`${change.refTable}\` (\`${change.refField}\`) ON UPDATE ${change.onUpdate} ON DELETE ${change.onDelete}`);
|
||||
});
|
||||
|
||||
// DROP FIELDS
|
||||
deletions.forEach(deletion => {
|
||||
alterColumns.push(`DROP COLUMN \`${deletion.name}\``);
|
||||
alterColumnsDrop.push(`DROP COLUMN \`${deletion.name}\``);
|
||||
});
|
||||
|
||||
// DROP INDEX
|
||||
indexChanges.deletions.forEach(deletion => {
|
||||
if (deletion.type === 'PRIMARY')
|
||||
alterColumns.push('DROP PRIMARY KEY');
|
||||
alterColumnsDrop.push('DROP PRIMARY KEY');
|
||||
else
|
||||
alterColumns.push(`DROP INDEX \`${deletion.name}\``);
|
||||
alterColumnsDrop.push(`DROP INDEX \`${deletion.name}\``);
|
||||
});
|
||||
|
||||
// DROP FOREIGN KEYS
|
||||
foreignChanges.deletions.forEach(deletion => {
|
||||
alterColumns.push(`DROP FOREIGN KEY \`${deletion.constraintName}\``);
|
||||
alterColumnsDrop.push(`DROP FOREIGN KEY \`${deletion.constraintName}\``);
|
||||
});
|
||||
|
||||
sql += alterColumns.join(', ');
|
||||
const alterQueryes = [];
|
||||
if (alterColumnsAdd.length) alterQueryes.push(sql+alterColumnsAdd.join(', '));
|
||||
if (alterColumnsChange.length) alterQueryes.push(sql+alterColumnsChange.join(', '));
|
||||
if (alterColumnsDrop.length) alterQueryes.push(sql+alterColumnsDrop.join(', '));
|
||||
|
||||
// RENAME
|
||||
if (options.name) sql += `; RENAME TABLE \`${schema}\`.\`${table}\` TO \`${schema}\`.\`${options.name}\``;
|
||||
if (options.name) alterQueryes.push(`RENAME TABLE \`${schema}\`.\`${table}\` TO \`${schema}\`.\`${options.name}\``);
|
||||
|
||||
return await this.raw(sql);
|
||||
return await this.raw(alterQueryes.join(';'));
|
||||
}
|
||||
|
||||
async duplicateTable (params: { schema: string; table: string }) {
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import * as antares from 'common/interfaces/antares';
|
||||
import * as mysql from 'mysql2';
|
||||
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';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function pgToString (value: any) {
|
||||
@@ -98,7 +98,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
_varchar: 'CHARACTER VARYING'
|
||||
}
|
||||
|
||||
_params: pg.ClientConfig & {schema: string; ssl?: mysql.SslOptions; ssh?: SSHConfig; readonly: boolean};
|
||||
_params: pg.ClientConfig & {schema: string; ssl?: ConnectionOptions; ssh?: SSHConfig; readonly: boolean};
|
||||
|
||||
constructor (args: antares.ClientParams) {
|
||||
super(args);
|
||||
@@ -154,9 +154,9 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
host: this._params.host,
|
||||
port: this._params.port,
|
||||
user: this._params.user,
|
||||
database: undefined as string | undefined,
|
||||
database: 'postgres' as string,
|
||||
password: this._params.password,
|
||||
ssl: null as mysql.SslOptions
|
||||
ssl: null as ConnectionOptions
|
||||
};
|
||||
|
||||
if (this._params.database?.length) dbConfig.database = this._params.database;
|
||||
@@ -262,6 +262,18 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
return [];
|
||||
}
|
||||
|
||||
async getDatabases () {
|
||||
const { rows } = await this.raw('SELECT datname FROM pg_database WHERE datistemplate = false');
|
||||
if (rows) {
|
||||
return rows.reduce((acc, cur) => {
|
||||
acc.push(cur.datname);
|
||||
return acc;
|
||||
}, [] as string[]);
|
||||
}
|
||||
else
|
||||
return [];
|
||||
}
|
||||
|
||||
async getStructure (schemas: Set<string>) {
|
||||
/* eslint-disable camelcase */
|
||||
interface ShowTableResult {
|
||||
@@ -1567,7 +1579,7 @@ export class PostgreSQLClient extends AntaresCore {
|
||||
if (args.tabUid && isPool)
|
||||
this._runningConnections.set(args.tabUid, (connection as pg.PoolClient & { processID: number }).processID);
|
||||
|
||||
if (args.schema && args.schema !== 'public')
|
||||
if (args.schema)
|
||||
await this.use(args.schema, connection);
|
||||
|
||||
for (const query of queries) {
|
||||
|
@@ -425,7 +425,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];
|
||||
|
@@ -47,7 +47,7 @@ export default class MySQLImporter extends BaseImporter {
|
||||
catch (error) {
|
||||
this.emit('query-error', {
|
||||
sql: query,
|
||||
message: error.sqlMessage,
|
||||
message: error.sqlMessage || error.message,
|
||||
sqlSnippet: error.sql,
|
||||
time: new Date().getTime()
|
||||
});
|
||||
|
@@ -124,8 +124,8 @@ else {
|
||||
if (isWindows)
|
||||
mainWindow.show();
|
||||
|
||||
if (isDevelopment)
|
||||
mainWindow.webContents.openDevTools();
|
||||
// if (isDevelopment)
|
||||
// mainWindow.webContents.openDevTools();
|
||||
|
||||
process.on('uncaughtException', error => {
|
||||
mainWindow.webContents.send('unhandled-exception', error);
|
||||
|
@@ -21,7 +21,15 @@
|
||||
<BaseTextEditor class="d-none" value="" />
|
||||
</div>
|
||||
</div>
|
||||
<ModalAllConnections v-if="isAllConnectionsModal" @close="isAllConnectionsModal = false" />
|
||||
<ModalAllConnections
|
||||
v-if="isAllConnectionsModal"
|
||||
@close="isAllConnectionsModal = false"
|
||||
/>
|
||||
|
||||
<ModalExportSchema
|
||||
v-if="isExportSchemaModal"
|
||||
@close="hideExportModal"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -33,9 +41,11 @@ import { useI18n } from 'vue-i18n';
|
||||
import { Menu, getCurrentWindow } from '@electron/remote';
|
||||
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();
|
||||
|
||||
@@ -65,6 +75,10 @@ const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
||||
const { checkVersionUpdate } = applicationStore;
|
||||
const { changeApplicationTheme } = settingsStore;
|
||||
|
||||
const schemaExportStore = useSchemaExportStore();
|
||||
const { hideExportModal } = schemaExportStore;
|
||||
const { isExportModal: isExportSchemaModal } = storeToRefs(schemaExportStore);
|
||||
|
||||
const isAllConnectionsModal: Ref<boolean> = ref(false);
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
@@ -95,22 +109,22 @@ onMounted(() => {
|
||||
|
||||
const InputMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: t('word.cut'),
|
||||
label: t('general.cut'),
|
||||
role: 'cut'
|
||||
},
|
||||
{
|
||||
label: t('word.copy'),
|
||||
label: t('general.copy'),
|
||||
role: 'copy'
|
||||
},
|
||||
{
|
||||
label: t('word.paste'),
|
||||
label: t('general.paste'),
|
||||
role: 'paste'
|
||||
},
|
||||
{
|
||||
type: 'separator'
|
||||
},
|
||||
{
|
||||
label: t('message.selectAll'),
|
||||
label: t('general.selectAll'),
|
||||
role: 'selectAll'
|
||||
}
|
||||
]);
|
||||
|
@@ -31,13 +31,13 @@
|
||||
class="btn btn-primary mr-2"
|
||||
@click.stop="confirmModal"
|
||||
>
|
||||
{{ confirmText || t('word.confirm') }}
|
||||
{{ confirmText || t('general.confirm') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-link"
|
||||
@click="hideModal"
|
||||
>
|
||||
{{ cancelText || t('word.cancel') }}
|
||||
{{ cancelText || t('general.cancel') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -16,6 +16,7 @@
|
||||
:id="`id_${id}`"
|
||||
class="file-uploader-input"
|
||||
type="file"
|
||||
:accept="accept"
|
||||
@change="$emit('change', $event)"
|
||||
>
|
||||
</form>
|
||||
@@ -33,6 +34,10 @@ defineProps({
|
||||
default: 'Browse',
|
||||
type: String
|
||||
},
|
||||
accept: {
|
||||
default: '',
|
||||
type: String
|
||||
},
|
||||
modelValue: {
|
||||
default: '',
|
||||
type: String
|
||||
|
@@ -4,7 +4,7 @@
|
||||
v-model="selectedGroup"
|
||||
class="form-select"
|
||||
:options="[{name: 'manual'}, ...fakerGroups]"
|
||||
:option-label="(opt: any) => opt.name === 'manual' ? t('message.manualValue') : t(`faker.${opt.name}`)"
|
||||
:option-label="(opt: any) => opt.name === 'manual' ? t('general.manualValue') : t(`faker.${opt.name}`)"
|
||||
option-track-by="name"
|
||||
:disabled="!isChecked"
|
||||
:style="'flex-grow: 0;'"
|
||||
@@ -41,7 +41,7 @@
|
||||
<BaseUploadInput
|
||||
v-else-if="inputProps().type === 'file'"
|
||||
:model-value="selectedValue"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="clearValue"
|
||||
@change="filesChange($event)"
|
||||
/>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
class="form-input"
|
||||
type="text"
|
||||
:value="pressedKeys"
|
||||
:placeholder="t('message.registerAShortcut')"
|
||||
:placeholder="t('application.registerAShortcut')"
|
||||
@focus="isFocus = true"
|
||||
@blur="isFocus = false"
|
||||
@keydown.prevent.stop="onKey"
|
||||
@@ -49,7 +49,7 @@ const pressedKeys = computed(() => {
|
||||
keys.push('Shift');
|
||||
if (keyboardEvent.value.code) {
|
||||
if (keys.length === 0 && (keyboardEvent.value.key.length === 1 || singleKeysToIgnore.includes(keyboardEvent.value.key)))
|
||||
return t('message.invalidShortcutMessage');
|
||||
return t('application.invalidShortcutMessage');
|
||||
else if (!specialKeys.includes(keyboardEvent.value.key)) {
|
||||
if (keyboardEvent.value.key === 'Dead') {
|
||||
keys.push(keyboardEvent.value.code
|
||||
@@ -82,7 +82,7 @@ const pressedKeys = computed(() => {
|
||||
}
|
||||
}
|
||||
else
|
||||
return t('message.invalidShortcutMessage');
|
||||
return t('application.invalidShortcutMessage');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ const onKey = (e: KeyboardEvent) => {
|
||||
};
|
||||
|
||||
watch(pressedKeys, (value) => {
|
||||
if (value !== t('message.invalidShortcutMessage'))
|
||||
if (value !== t('application.invalidShortcutMessage'))
|
||||
emit('update:modelValue', pressedKeys.value);
|
||||
});
|
||||
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-apps mr-1" />
|
||||
<span class="cut-text">{{ t('message.allConnections') }}</span>
|
||||
<span class="cut-text">{{ t('connection.allConnections') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -21,7 +21,7 @@
|
||||
v-model="searchTerm"
|
||||
class="form-input"
|
||||
type="text"
|
||||
:placeholder="t('message.searchForConnections')"
|
||||
:placeholder="t('connection.searchForConnections')"
|
||||
@keypress.esc="searchTerm = ''"
|
||||
>
|
||||
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px pr-4" />
|
||||
@@ -58,7 +58,7 @@
|
||||
<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"
|
||||
:title="t('word.delete')"
|
||||
:title="t('general.delete')"
|
||||
@click.stop="askToDelete(connection)"
|
||||
/>
|
||||
</div>
|
||||
@@ -130,12 +130,12 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-server-remove mr-1" /> {{ t('message.deleteConnection') }}
|
||||
<i class="mdi mdi-24px mdi-server-remove mr-1" /> {{ t('connection.deleteConnection') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.deleteCorfirm') }} <b>{{ selectedConnectionName }}</b>?
|
||||
{{ t('general.deleteConfirm') }} <b>{{ selectedConnectionName }}</b>?
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<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('word.credentials') }}
|
||||
<i class="mdi mdi-24px mdi-key-variant mr-1" /> {{ t('connection.credentials') }}
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -16,7 +16,7 @@
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.user') }}</label>
|
||||
<label class="form-label">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.password') }}</label>
|
||||
<label class="form-label">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
@@ -44,10 +44,10 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary mr-2" @click.stop="sendCredentials">
|
||||
{{ t('word.send') }}
|
||||
{{ t('general.send') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ t('word.close') }}
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.run')"
|
||||
:cancel-text="t('word.cancel')"
|
||||
:confirm-text="t('general.run')"
|
||||
:cancel-text="t('general.cancel')"
|
||||
size="400"
|
||||
@confirm="runRoutine"
|
||||
@hide="closeModal"
|
||||
@@ -9,7 +9,7 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-play mr-1" />
|
||||
<span class="cut-text">{{ t('word.parameters') }}: {{ localRoutine.name }}</span>
|
||||
<span class="cut-text">{{ t('database.parameters') }}: {{ localRoutine.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-brush-variant mr-1" />
|
||||
<span class="cut-text">{{ t('message.editConnectionAppearence') }}</span>
|
||||
<span class="cut-text">{{ t('application.editConnectionAppearance') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -17,7 +17,7 @@
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group mb-4">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.label') }}</label>
|
||||
<label class="form-label">{{ t('application.label') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.icon') }}</label>
|
||||
<label class="form-label">{{ t('application.icon') }}</label>
|
||||
</div>
|
||||
<div class="col-9 icons-wrapper">
|
||||
<div
|
||||
@@ -48,11 +48,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary mr-2" @click.stop="editFolderAppearence">
|
||||
{{ t('word.update') }}
|
||||
<button class="btn btn-primary mr-2" @click.stop="editFolderAppearance">
|
||||
{{ t('application.update') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ t('word.close') }}
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -136,7 +136,7 @@ const { trapRef } = useFocusTrap();
|
||||
const firstInput: Ref<HTMLInputElement> = ref(null);
|
||||
const localConnection: Ref<SidebarElement> = ref(unproxify(props.connection));
|
||||
|
||||
const editFolderAppearence = () => {
|
||||
const editFolderAppearance = () => {
|
||||
updateConnectionOrder(localConnection.value);
|
||||
closeModal();
|
||||
};
|
@@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.discard')"
|
||||
:cancel-text="t('word.stay')"
|
||||
:confirm-text="t('general.discard')"
|
||||
:cancel-text="t('general.stay')"
|
||||
@confirm="emit('confirm')"
|
||||
@hide="emit('close')"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-content-save-alert mr-1" /> {{ t('message.unsavedChanges') }}
|
||||
<i class="mdi mdi-24px mdi-content-save-alert mr-1" /> {{ t('application.unsavedChanges') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div>
|
||||
{{ t('message.discardUnsavedChanges') }}
|
||||
{{ t('application.discardUnsavedChanges') }}
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-edit mr-1" />
|
||||
<span class="cut-text">{{ t('message.editSchema') }}</span>
|
||||
<span class="cut-text">{{ t('database.editSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -17,7 +17,7 @@
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
@@ -26,14 +26,14 @@
|
||||
class="form-input"
|
||||
type="text"
|
||||
required
|
||||
:placeholder="t('message.schemaName')"
|
||||
:placeholder="t('database.schemaName')"
|
||||
readonly
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.collation') }}</label>
|
||||
<label class="form-label">{{ t('database.collation') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<BaseSelect
|
||||
@@ -44,7 +44,7 @@
|
||||
option-label="collation"
|
||||
option-track-by="collation"
|
||||
/>
|
||||
<small>{{ t('message.serverDefault') }}: {{ defaultCollation }}</small>
|
||||
<small>{{ t('database.serverDefault') }}: {{ defaultCollation }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -52,10 +52,10 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary mr-2" @click.stop="updateSchema">
|
||||
{{ t('word.update') }}
|
||||
{{ t('application.update') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ t('word.close') }}
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-export mr-1" />
|
||||
<span class="cut-text">{{ t('message.exportSchema') }}</span>
|
||||
<span class="cut-text">{{ t('database.exportSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -16,7 +16,7 @@
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('message.directoryPath') }}</label>
|
||||
<label class="form-label">{{ t('general.directoryPath') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<fieldset class="input-group">
|
||||
@@ -26,14 +26,14 @@
|
||||
type="text"
|
||||
required
|
||||
readonly
|
||||
:placeholder="t('message.schemaName')"
|
||||
@click.prevent="openPathDialog"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary input-group-btn"
|
||||
@click.prevent="openPathDialog"
|
||||
>
|
||||
{{ t('word.change') }}
|
||||
{{ t('general.change') }}
|
||||
</button>
|
||||
</fieldset>
|
||||
</div>
|
||||
@@ -42,35 +42,41 @@
|
||||
|
||||
<div class="columns export-options">
|
||||
<div class="column col-8 left">
|
||||
<div class="columns mb-2">
|
||||
<div class="column col-auto d-flex text-italic ">
|
||||
<i class="mdi mdi-file-document-outline mr-2" />
|
||||
{{ filename }}
|
||||
<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" />
|
||||
<input
|
||||
v-model="chosenFilename"
|
||||
class="form-input"
|
||||
type="text"
|
||||
:placeholder="filename"
|
||||
:title="t('application.fileName')"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="column col-auto col-ml-auto ">
|
||||
<button
|
||||
class="btn btn-dark btn-sm"
|
||||
:title="t('word.refresh')"
|
||||
:title="t('general.refresh')"
|
||||
@click="refresh"
|
||||
>
|
||||
<i class="mdi mdi-database-refresh" />
|
||||
<i class="mdi mdi-refresh" />
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm mx-1"
|
||||
:title="t('message.uncheckAllTables')"
|
||||
:title="t('database.uncheckAllTables')"
|
||||
:disabled="isRefreshing"
|
||||
@click="uncheckAllTables"
|
||||
>
|
||||
<i class="mdi mdi-file-tree-outline" />
|
||||
<i class="mdi mdi-checkbox-blank-outline" />
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm"
|
||||
:title="t('message.checkAllTables')"
|
||||
:title="t('database.checkAllTables')"
|
||||
:disabled="isRefreshing"
|
||||
@click="checkAllTables"
|
||||
>
|
||||
<i class="mdi mdi-file-tree" />
|
||||
<i class="mdi mdi-checkbox-marked-outline" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -122,22 +128,22 @@
|
||||
<div class="tr">
|
||||
<div class="th" :style="'width: 50%;'">
|
||||
<div class="table-column-title">
|
||||
<span>{{ t('word.table') }}</span>
|
||||
<span>{{ t('database.table') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th text-center">
|
||||
<div class="table-column-title">
|
||||
<span>{{ t('word.structure') }}</span>
|
||||
<span>{{ t('database.structure') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th text-center">
|
||||
<div class="table-column-title">
|
||||
<span>{{ t('word.content') }}</span>
|
||||
<span>{{ t('general.content') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th text-center">
|
||||
<div class="table-column-title">
|
||||
<span>{{ t('word.drop') }}</span>
|
||||
<span>{{ t('database.drop') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -148,6 +154,7 @@
|
||||
v-for="item in tables"
|
||||
:key="item.table"
|
||||
class="tr"
|
||||
:class="{'selected': item.table === selectedTable}"
|
||||
>
|
||||
<div class="td">
|
||||
{{ item.table }}
|
||||
@@ -183,19 +190,19 @@
|
||||
</div>
|
||||
<div class="column col-4">
|
||||
<h5 class="h5">
|
||||
{{ t('word.options') }}
|
||||
{{ t('general.options') }}
|
||||
</h5>
|
||||
<span class="h6">{{ t('word.includes') }}:</span>
|
||||
<span class="h6">{{ t('general.includes') }}:</span>
|
||||
<label
|
||||
v-for="(_, key) in options.includes"
|
||||
:key="key"
|
||||
class="form-checkbox"
|
||||
>
|
||||
<input v-model="options.includes[key]" type="checkbox"><i class="form-icon" /> {{ t(`word.${key}`, 2) }}
|
||||
<input v-model="options.includes[key]" type="checkbox"><i class="form-icon" /> {{ t(`database.${String(key).slice(0, -1)}`, 2) }}
|
||||
</label>
|
||||
<div v-if="clientCustoms.exportByChunks">
|
||||
<div class="h6 mt-4 mb-2">
|
||||
{{ t('message.newInserStmtEvery') }}:
|
||||
{{ t('database.newInsertStmtEvery') }}:
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column col-6">
|
||||
@@ -209,21 +216,21 @@
|
||||
<BaseSelect
|
||||
v-model="options.sqlInsertDivider"
|
||||
class="form-select"
|
||||
:options="[{value: 'bytes', label: 'KiB'}, {value: 'rows', label: t('word.row', 2)}]"
|
||||
:options="[{value: 'bytes', label: 'KiB'}, {value: 'rows', label: t('database.row', 2)}]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h6 mb-2 mt-4">
|
||||
{{ t('message.ourputFormat') }}:
|
||||
{{ t('general.outputFormat') }}:
|
||||
</div>
|
||||
<div class="columns">
|
||||
<div class="column h5 mb-4">
|
||||
<BaseSelect
|
||||
v-model="options.outputFormat"
|
||||
class="form-select"
|
||||
:options="[{value: 'sql', label: t('message.singleFile', {ext: '.sql'})}, {value: 'sql.zip', label: t('message.zipCompressedFile', {ext: '.sql'})}]"
|
||||
:options="[{value: 'sql', label: t('general.singleFile', {ext: '.sql'})}, {value: 'sql.zip', label: t('general.zipCompressedFile', {ext: '.sql'})}]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -244,8 +251,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="column col-auto px-0">
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ t('word.close') }}
|
||||
<button class="btn btn-link mr-2" @click.stop="closeModal">
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary mr-2"
|
||||
@@ -254,7 +261,7 @@
|
||||
autofocus
|
||||
@click.prevent="startExport"
|
||||
>
|
||||
{{ t('word.export') }}
|
||||
{{ t('database.export') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -272,6 +279,7 @@ import { useI18n } from 'vue-i18n';
|
||||
import { ClientCode, SchemaInfos } from 'common/interfaces/antares';
|
||||
import { ExportOptions, ExportState } from 'common/interfaces/exporter';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useSchemaExportStore } from '@/stores/schemaExport';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import Application from '@/ipc-api/Application';
|
||||
@@ -279,15 +287,12 @@ import Schema from '@/ipc-api/Schema';
|
||||
import { Customizations } from 'common/interfaces/customizations';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
|
||||
const props = defineProps({
|
||||
selectedSchema: String
|
||||
});
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
const { t } = useI18n();
|
||||
|
||||
const { addNotification } = useNotificationsStore();
|
||||
const workspacesStore = useWorkspacesStore();
|
||||
const schemaExportStore = useSchemaExportStore();
|
||||
|
||||
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
||||
|
||||
@@ -298,6 +303,8 @@ const {
|
||||
refreshSchema
|
||||
} = workspacesStore;
|
||||
|
||||
const { selectedTable, selectedSchema } = storeToRefs(schemaExportStore);
|
||||
|
||||
const isExporting = ref(false);
|
||||
const isRefreshing = ref(false);
|
||||
const progressPercentage = ref(0);
|
||||
@@ -309,28 +316,29 @@ const tables: Ref<{
|
||||
includeDropStatement: boolean;
|
||||
}[]> = ref([]);
|
||||
const options: Ref<Partial<ExportOptions>> = ref({
|
||||
schema: props.selectedSchema,
|
||||
schema: selectedSchema.value,
|
||||
includes: {} as {[key: string]: boolean},
|
||||
outputFormat: 'sql' as 'sql' | 'sql.zip',
|
||||
sqlInsertAfter: 250,
|
||||
sqlInsertDivider: 'bytes' as 'bytes' | 'rows'
|
||||
});
|
||||
const basePath = ref('');
|
||||
const chosenFilename = ref('');
|
||||
|
||||
const currentWorkspace = computed(() => getWorkspace(selectedWorkspace.value));
|
||||
const clientCustoms: Ref<Customizations> = computed(() => currentWorkspace.value.customizations);
|
||||
const schemaItems = computed(() => {
|
||||
const db: SchemaInfos = currentWorkspace.value.structure.find((db: SchemaInfos) => db.name === props.selectedSchema);
|
||||
const db: SchemaInfos = currentWorkspace.value.structure.find((db: SchemaInfos) => db.name === selectedSchema.value);
|
||||
if (db)
|
||||
return db.tables.filter(table => table.type === 'table');
|
||||
|
||||
return [];
|
||||
});
|
||||
const filename = computed(() => {
|
||||
const date = moment().format('YYYY-MM-DD');
|
||||
return `${props.selectedSchema}_${date}.${options.value.outputFormat}`;
|
||||
const date = moment().format('YYYY-MM-DD_HH-mm-ss');
|
||||
return `${selectedTable.value || selectedSchema.value}_${date}`;
|
||||
});
|
||||
const dumpFilePath = computed(() => `${basePath.value}/${filename.value}`);
|
||||
const dumpFilePath = computed(() => `${basePath.value}/${chosenFilename.value || filename.value}.${options.value.outputFormat}`);
|
||||
const includeStructureStatus = computed(() => {
|
||||
if (tables.value.every(item => item.includeStructure)) return 1;
|
||||
else if (tables.value.some(item => item.includeStructure)) return 2;
|
||||
@@ -353,7 +361,7 @@ const startExport = async () => {
|
||||
const params = {
|
||||
uid,
|
||||
type: client,
|
||||
schema: props.selectedSchema,
|
||||
schema: selectedSchema.value,
|
||||
outputFile: dumpFilePath.value,
|
||||
tables: [...tables.value],
|
||||
...options.value
|
||||
@@ -362,7 +370,7 @@ const startExport = async () => {
|
||||
try {
|
||||
const { status, response } = await Schema.export(params);
|
||||
if (status === 'success')
|
||||
progressStatus.value = response.cancelled ? t('word.aborted') : t('word.completed');
|
||||
progressStatus.value = response.cancelled ? t('general.aborted') : t('general.completed');
|
||||
else {
|
||||
progressStatus.value = response;
|
||||
addNotification({ status: 'error', message: response });
|
||||
@@ -379,13 +387,13 @@ const updateProgress = (event: Event, state: ExportState) => {
|
||||
progressPercentage.value = Number((state.currentItemIndex / state.totalItems * 100).toFixed(1));
|
||||
switch (state.op) {
|
||||
case 'PROCESSING':
|
||||
progressStatus.value = t('message.processingTableExport', { table: state.currentItem });
|
||||
progressStatus.value = t('database.processingTableExport', { table: state.currentItem });
|
||||
break;
|
||||
case 'FETCH':
|
||||
progressStatus.value = t('message.fechingTableExport', { table: state.currentItem });
|
||||
progressStatus.value = t('database.fetchingTableExport', { table: state.currentItem });
|
||||
break;
|
||||
case 'WRITE':
|
||||
progressStatus.value = t('message.writingTableExport', { table: state.currentItem });
|
||||
progressStatus.value = t('database.writingTableExport', { table: state.currentItem });
|
||||
break;
|
||||
}
|
||||
};
|
||||
@@ -431,7 +439,7 @@ const toggleAllTablesOption = (option: 'includeStructure' | 'includeContent' |'i
|
||||
|
||||
const refresh = async () => {
|
||||
isRefreshing.value = true;
|
||||
await refreshSchema({ uid: currentWorkspace.value.uid, schema: props.selectedSchema });
|
||||
await refreshSchema({ uid: currentWorkspace.value.uid, schema: selectedSchema.value });
|
||||
isRefreshing.value = false;
|
||||
};
|
||||
|
||||
@@ -446,12 +454,31 @@ const openPathDialog = async () => {
|
||||
|
||||
window.addEventListener('keydown', onKey);
|
||||
|
||||
if (selectedTable.value) {
|
||||
setTimeout(() => {
|
||||
const element = document.querySelector<HTMLElement>('.modal.active .selected');
|
||||
|
||||
if (element) {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const elemTop = rect.top;
|
||||
const elemBottom = rect.bottom;
|
||||
const isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
|
||||
|
||||
if (!isVisible) {
|
||||
element.setAttribute('tabindex', '-1');
|
||||
element.focus();
|
||||
element.removeAttribute('tabindex');
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
basePath.value = await Application.getDownloadPathDirectory();
|
||||
tables.value = schemaItems.value.map(item => ({
|
||||
table: item.name,
|
||||
includeStructure: true,
|
||||
includeContent: true,
|
||||
includeDropStatement: true
|
||||
includeStructure: !selectedTable.value ? true : selectedTable.value === item.name,
|
||||
includeContent: !selectedTable.value ? true : selectedTable.value === item.name,
|
||||
includeDropStatement: !selectedTable.value ? true : selectedTable.value === item.name
|
||||
}));
|
||||
|
||||
const structure = ['functions', 'views', 'triggers', 'routines', 'schedulers'];
|
||||
@@ -459,7 +486,7 @@ const openPathDialog = async () => {
|
||||
structure.forEach((feat: keyof Customizations) => {
|
||||
const val = clientCustoms.value[feat];
|
||||
if (val)
|
||||
options.value.includes[feat] = true;
|
||||
options.value.includes[feat] = !selectedTable.value;
|
||||
});
|
||||
|
||||
ipcRenderer.on('export-progress', updateProgress);
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-playlist-plus mr-1" />
|
||||
<span class="cut-text">{{ t('message.insertRow', 2) }}</span>
|
||||
<span class="cut-text">{{ t('database.insertRow', 2) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -39,7 +39,7 @@
|
||||
<span class="input-group-addon field-type" :class="typeClass(field.type)">
|
||||
{{ field.type }} {{ wrapNumber(fieldLength(field)) }}
|
||||
</span>
|
||||
<label class="form-checkbox ml-3" :title="t('word.insert')">
|
||||
<label class="form-checkbox ml-3" :title="t('general.insert')">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="!fieldsToExclude.includes(field.name)"
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
<div class="modal-footer columns">
|
||||
<div class="column d-flex" :class="hasFakes ? 'col-4' : 'col-2'">
|
||||
<div class="input-group tooltip tooltip-right" :data-tooltip="t('message.numberOfInserts')">
|
||||
<div class="input-group tooltip tooltip-right" :data-tooltip="t('database.numberOfInserts')">
|
||||
<input
|
||||
v-model="nInserts"
|
||||
type="number"
|
||||
@@ -70,7 +70,7 @@
|
||||
<div
|
||||
v-if="hasFakes"
|
||||
class="tooltip tooltip-right ml-2"
|
||||
:data-tooltip="t('message.fakeDataLanguage')"
|
||||
:data-tooltip="t('database.fakeDataLanguage')"
|
||||
>
|
||||
<BaseSelect
|
||||
v-model="fakerLocale"
|
||||
@@ -85,10 +85,10 @@
|
||||
:class="{'loading': isInserting}"
|
||||
@click.stop="insertRows"
|
||||
>
|
||||
{{ t('word.insert') }}
|
||||
{{ t('general.insert') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ t('word.close') }}
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-folder-edit mr-1" />
|
||||
<span class="cut-text">{{ t('message.editFolder') }}</span>
|
||||
<span class="cut-text">{{ t('application.editFolder') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -17,7 +17,7 @@
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group mb-4">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
@@ -26,13 +26,13 @@
|
||||
class="form-input"
|
||||
type="text"
|
||||
required
|
||||
:placeholder="t('message.folderName')"
|
||||
:placeholder="t('application.folderName')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.color') }}</label>
|
||||
<label class="form-label">{{ t('application.color') }}</label>
|
||||
</div>
|
||||
<div class="col-9 color-wrapper">
|
||||
<div
|
||||
@@ -51,11 +51,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary mr-2" @click.stop="editFolderAppearence">
|
||||
{{ t('word.update') }}
|
||||
<button class="btn btn-primary mr-2" @click.stop="editFolderAppearance">
|
||||
{{ t('application.update') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ t('word.close') }}
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -110,7 +110,7 @@ const { trapRef } = useFocusTrap();
|
||||
const firstInput: Ref<HTMLInputElement> = ref(null);
|
||||
const localFolder: Ref<SidebarElement> = ref(unproxify(props.folder));
|
||||
|
||||
const editFolderAppearence = () => {
|
||||
const editFolderAppearance = () => {
|
||||
updateConnectionOrder(localFolder.value);
|
||||
closeModal();
|
||||
};
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-history mr-1" />
|
||||
<span class="cut-text">{{ t('word.history') }}: {{ connectionName }}</span>
|
||||
<span class="cut-text">{{ t('general.history') }}: {{ connectionName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -22,7 +22,7 @@
|
||||
v-model="searchTerm"
|
||||
class="form-input"
|
||||
type="text"
|
||||
:placeholder="t('message.searchForQueries')"
|
||||
:placeholder="t('database.searchForQueries')"
|
||||
>
|
||||
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px pr-4" />
|
||||
<i
|
||||
@@ -67,13 +67,13 @@
|
||||
<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('word.select') }}
|
||||
<i class="mdi mdi-open-in-app pr-1" /> {{ t('general.select') }}
|
||||
</button>
|
||||
<button class="btn btn-link pl-1" @click="copyQuery(query.sql)">
|
||||
<i class="mdi mdi-content-copy pr-1" /> {{ t('word.copy') }}
|
||||
<i class="mdi mdi-content-copy pr-1" /> {{ t('general.copy') }}
|
||||
</button>
|
||||
<button class="btn btn-link pl-1" @click="deleteQuery(query)">
|
||||
<i class="mdi mdi-delete-forever pr-1" /> {{ t('word.delete') }}
|
||||
<i class="mdi mdi-delete-forever pr-1" /> {{ t('general.delete') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -88,7 +88,7 @@
|
||||
<i class="mdi mdi-history mdi-48px" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ t('message.thereIsNoQueriesYet') }}
|
||||
{{ t('database.thereIsNoQueriesYet') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-import mr-1" />
|
||||
<span class="cut-text">{{ t('message.importSchema') }}</span>
|
||||
<span class="cut-text">{{ t('database.importSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="modal-body pb-0">
|
||||
{{ sqlFile }}
|
||||
<div v-if="queryErrors.length > 0" class="mt-2">
|
||||
<label>{{ t('message.importQueryErrors', queryErrors.length) }}</label>
|
||||
<label>{{ t('database.importQueryErrors', queryErrors.length) }}</label>
|
||||
<textarea
|
||||
v-model="formattedQueryErrors"
|
||||
class="form-input"
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="column col modal-progress-wrapper text-left">
|
||||
<div class="import-progress">
|
||||
<span class="progress-status">
|
||||
{{ progressPercentage }}% - {{ progressStatus }} - {{ t('message.executedQueries', queryCount) }}
|
||||
{{ progressPercentage }}% - {{ progressStatus }} - {{ t('database.executedQueries', queryCount) }}
|
||||
</span>
|
||||
<progress
|
||||
class="progress d-block"
|
||||
@@ -39,7 +39,7 @@
|
||||
</div>
|
||||
<div class="column col-auto px-0">
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ completed ? t('word.close') : t('word.cancel') }}
|
||||
{{ completed ? t('general.close') : t('general.cancel') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,7 +108,7 @@ const startImport = async (file: string) => {
|
||||
const { status, response } = await Schema.import(params);
|
||||
|
||||
if (status === 'success')
|
||||
progressStatus.value = response.cancelled ? t('word.aborted') : t('word.completed');
|
||||
progressStatus.value = response.cancelled ? t('general.aborted') : t('general.completed');
|
||||
else {
|
||||
progressStatus.value = response;
|
||||
addNotification({ status: 'error', message: response });
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-plus mr-1" />
|
||||
<span class="cut-text">{{ t('message.createNewSchema') }}</span>
|
||||
<span class="cut-text">{{ t('database.createNewSchema') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -17,7 +17,7 @@
|
||||
<form class="form-horizontal" @submit.prevent="createSchema">
|
||||
<div class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input
|
||||
@@ -26,13 +26,13 @@
|
||||
class="form-input"
|
||||
type="text"
|
||||
required
|
||||
:placeholder="t('message.schemaName')"
|
||||
:placeholder="t('database.schemaName')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizations.collations" class="form-group">
|
||||
<div class="col-3">
|
||||
<label class="form-label">{{ t('word.collation') }}</label>
|
||||
<label class="form-label">{{ t('database.collation') }}</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<BaseSelect
|
||||
@@ -43,7 +43,7 @@
|
||||
option-label="collation"
|
||||
option-track-by="collation"
|
||||
/>
|
||||
<small>{{ t('message.serverDefault') }}: {{ defaultCollation }}</small>
|
||||
<small>{{ t('database.serverDefault') }}: {{ defaultCollation }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -55,10 +55,10 @@
|
||||
:class="{'loading': isLoading}"
|
||||
@click.stop="createSchema"
|
||||
>
|
||||
{{ t('word.add') }}
|
||||
{{ t('general.add') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ t('word.close') }}
|
||||
{{ t('general.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-memory mr-1" />
|
||||
<span class="cut-text">{{ t('message.processesList') }}: {{ connectionName }}</span>
|
||||
<span class="cut-text">{{ t('database.processesList') }}: {{ connectionName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
@@ -29,7 +29,7 @@
|
||||
<button
|
||||
class="btn btn-dark btn-sm mr-0 pr-1 d-flex"
|
||||
:class="{'loading':isQuering}"
|
||||
:title="`${t('word.refresh')}`"
|
||||
:title="`${t('general.refresh')}`"
|
||||
@click="getProcessesList"
|
||||
>
|
||||
<i v-if="!+autorefreshTimer" class="mdi mdi-24px mdi-refresh mr-1" />
|
||||
@@ -39,7 +39,7 @@
|
||||
<i class="mdi mdi-24px mdi-menu-down" />
|
||||
</div>
|
||||
<div class="menu px-3">
|
||||
<span>{{ t('word.autoRefresh') }}: <b>{{ +autorefreshTimer ? `${autorefreshTimer}s` : 'OFF' }}</b></span>
|
||||
<span>{{ t('general.autoRefresh') }}: <b>{{ +autorefreshTimer ? `${autorefreshTimer}s` : 'OFF' }}</b></span>
|
||||
<input
|
||||
v-model="autorefreshTimer"
|
||||
class="slider no-border"
|
||||
@@ -59,7 +59,7 @@
|
||||
tabindex="0"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||
<span>{{ t('word.export') }}</span>
|
||||
<span>{{ t('database.export') }}</span>
|
||||
<i class="mdi mdi-24px mdi-menu-down" />
|
||||
</button>
|
||||
<ul class="menu text-left">
|
||||
@@ -74,7 +74,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div v-if="sortedResults.length">
|
||||
{{ t('word.processes') }}: <b>{{ sortedResults.length.toLocaleString() }}</b>
|
||||
{{ t('database.processes') }}: <b>{{ sortedResults.length.toLocaleString() }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
@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('word.copy') }}</span>
|
||||
<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" />
|
||||
<div class="context-submenu">
|
||||
<div
|
||||
@@ -13,7 +13,7 @@
|
||||
@click="copyCell"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-numeric-0 mdi-rotate-90 text-light pr-1" /> {{ t('word.cell', 1) }}
|
||||
<i class="mdi mdi-18px mdi-numeric-0 mdi-rotate-90 text-light pr-1" /> {{ t('database.cell', 1) }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -22,7 +22,7 @@
|
||||
@click="copyRow"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('word.row', 1) }}
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('database.row', 1) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
@click="killProcess"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-close-circle-outline text-light pr-1" /> {{ t('message.killProcess') }}
|
||||
<i class="mdi mdi-18px mdi-close-circle-outline text-light pr-1" /> {{ t('database.killProcess') }}
|
||||
</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
|
@@ -16,15 +16,15 @@
|
||||
</div>
|
||||
<ConfirmModal
|
||||
v-if="isInfoModal"
|
||||
:confirm-text="t('word.update')"
|
||||
:cancel-text="t('word.close')"
|
||||
:confirm-text="t('application.update')"
|
||||
:cancel-text="t('general.close')"
|
||||
size="medium"
|
||||
:hide-footer="true"
|
||||
@hide="hideInfoModal"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-information-outline mr-1" /> {{ t('message.processInfo') }}
|
||||
<i class="mdi mdi-24px mdi-information-outline mr-1" /> {{ t('database.processInfo') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-cog mr-1" />
|
||||
<span class="cut-text">{{ t('word.settings') }}</span>
|
||||
<span class="cut-text">{{ t('application.settings') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click="closeModal" />
|
||||
@@ -21,21 +21,28 @@
|
||||
:class="{'active': selectedTab === 'general'}"
|
||||
@click="selectTab('general')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.general') }}</a>
|
||||
<a class="tab-link">{{ t('application.general') }}</a>
|
||||
</li>
|
||||
<li
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'themes'}"
|
||||
@click="selectTab('themes')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.themes') }}</a>
|
||||
<a class="tab-link">{{ t('application.themes') }}</a>
|
||||
</li>
|
||||
<li
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'shortcuts'}"
|
||||
@click="selectTab('shortcuts')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.shortcuts') }}</a>
|
||||
<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'"
|
||||
@@ -43,21 +50,21 @@
|
||||
:class="{'active': selectedTab === 'update'}"
|
||||
@click="selectTab('update')"
|
||||
>
|
||||
<a class="tab-link" :class="{'badge badge-update': hasUpdates}">{{ t('word.update') }}</a>
|
||||
<a class="tab-link" :class="{'badge badge-update': hasUpdates}">{{ t('application.update') }}</a>
|
||||
</li>
|
||||
<li
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'changelog'}"
|
||||
@click="selectTab('changelog')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.changelog') }}</a>
|
||||
<a class="tab-link">{{ t('application.changelog') }}</a>
|
||||
</li>
|
||||
<li
|
||||
class="tab-item c-hand"
|
||||
:class="{'active': selectedTab === 'about'}"
|
||||
@click="selectTab('about')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.about') }}</a>
|
||||
<a class="tab-link">{{ t('application.about') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -65,14 +72,14 @@
|
||||
<div class="container">
|
||||
<form class="form-horizontal columns">
|
||||
<div class="column col-12 h6 text-uppercase mb-1">
|
||||
{{ t('word.application') }}
|
||||
{{ t('application.application') }}
|
||||
</div>
|
||||
<div class="column col-12 col-sm-12 mb-2 columns">
|
||||
<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" />
|
||||
{{ t('word.language') }}
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -87,15 +94,15 @@
|
||||
</div>
|
||||
<div class="col-4 col-sm-12 px-2 p-vcentered">
|
||||
<small class="d-block" :style="'line-height: 1.1; font-size: 70%;'">
|
||||
{{ t('message.missingOrIncompleteTranslation') }}<br>
|
||||
<a class="text-bold c-hand" @click="openOutside('https://github.com/antares-sql/antares/wiki/Translate-Antares')">{{ t('message.findOutHowToContribute') }}</a>
|
||||
{{ t('application.missingOrIncompleteTranslation') }}<br>
|
||||
<a class="text-bold c-hand" @click="openOutside('https://github.com/antares-sql/antares/wiki/Translate-Antares')">{{ t('application.findOutHowToContribute') }}</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group column col-12">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.dataTabPageSize') }}
|
||||
{{ t('application.dataTabPageSize') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -110,7 +117,7 @@
|
||||
<div class="form-group column col-12 mb-0">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.restorePreviourSession') }}
|
||||
{{ t('application.restorePreviousSession') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -123,7 +130,7 @@
|
||||
<div class="form-group column col-12 mb-0">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.showTableSize') }}
|
||||
{{ t('application.showTableSize') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-1 col-sm-12">
|
||||
@@ -134,14 +141,14 @@
|
||||
</div>
|
||||
<div class="col-6 col-sm-12 px-2 p-vcentered">
|
||||
<small class="d-block" :style="'line-height: 1.1; font-size: 70%;'">
|
||||
{{ t('message.showTableSizeDescription') }}
|
||||
{{ t('application.showTableSizeDescription') }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group column col-12 mb-0">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.disableBlur') }}
|
||||
{{ t('application.disableBlur') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -154,7 +161,7 @@
|
||||
<div class="form-group column col-12 mb-0">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.disableScratchpad') }}
|
||||
{{ t('application.disableScratchpad') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -167,7 +174,7 @@
|
||||
<div class="form-group column col-12">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.notificationsTimeout') }}
|
||||
{{ t('application.notificationsTimeout') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -179,19 +186,19 @@
|
||||
min="1"
|
||||
@focusout="checkNotificationsTimeout"
|
||||
>
|
||||
<span class="input-group-addon">{{ t('word.seconds') }}</span>
|
||||
<span class="input-group-addon">{{ t('general.seconds') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column col-12 h6 mt-4 text-uppercase mb-1">
|
||||
{{ t('word.editor') }}
|
||||
{{ t('application.editor') }}
|
||||
</div>
|
||||
<div class="column col-12 col-sm-12 columns">
|
||||
<div class="form-group column col-12 mb-0">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('word.autoCompletion') }}
|
||||
{{ t('application.autoCompletion') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -204,7 +211,7 @@
|
||||
<div class="form-group column col-12 mb-0">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.wrapLongLines') }}
|
||||
{{ t('application.wrapLongLines') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -217,7 +224,7 @@
|
||||
<div class="form-group column col-12 mb-0">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.executeSelectedQuery') }}
|
||||
{{ t('database.executeSelectedQuery') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -229,13 +236,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="column col-12 h6 mt-4 text-uppercase mb-1">
|
||||
{{ t('word.resultsTable') }}
|
||||
{{ t('database.resultsTable') }}
|
||||
</div>
|
||||
<div class="column col-12 col-sm-12 columns">
|
||||
<div class="form-group column col-12">
|
||||
<div class="col-5 col-sm-12">
|
||||
<label class="form-label">
|
||||
{{ t('message.defaultCopyType') }}
|
||||
{{ t('application.defaultCopyType') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-3 col-sm-12">
|
||||
@@ -258,7 +265,7 @@
|
||||
<div class="container">
|
||||
<div class="columns">
|
||||
<div class="column col-12 h6 text-uppercase mb-2">
|
||||
{{ t('message.applicationTheme') }}
|
||||
{{ t('application.applicationTheme') }}
|
||||
</div>
|
||||
<div
|
||||
class="column col-6 c-hand theme-block"
|
||||
@@ -269,7 +276,7 @@
|
||||
<div class="theme-name text-light">
|
||||
<i class="mdi mdi-moon-waning-crescent mdi-48px" />
|
||||
<div class="h6 mt-4">
|
||||
{{ t('word.dark') }}
|
||||
{{ t('application.dark') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -282,7 +289,7 @@
|
||||
<div class="theme-name text-dark">
|
||||
<i class="mdi mdi-white-balance-sunny mdi-48px" />
|
||||
<div class="h6 mt-4">
|
||||
{{ t('word.light') }}
|
||||
{{ t('application.light') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -290,7 +297,7 @@
|
||||
|
||||
<div class="columns mt-4">
|
||||
<div class="column col-12 h6 text-uppercase mb-2 mt-4">
|
||||
{{ t('message.editorTheme') }}
|
||||
{{ t('application.editorTheme') }}
|
||||
</div>
|
||||
<div class="column col-5 h5 mb-4">
|
||||
<BaseSelect
|
||||
@@ -366,6 +373,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>
|
||||
@@ -378,16 +388,16 @@
|
||||
<img :src="appLogo" width="128">
|
||||
<h4>{{ appName }}</h4>
|
||||
<p class="mb-2">
|
||||
{{ t('word.version') }} {{ appVersion }}<br>
|
||||
{{ 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>
|
||||
<small>{{ t('word.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">{{ appAuthor }}</a></small><br>
|
||||
<small>{{ t('general.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">{{ appAuthor }}</a></small><br>
|
||||
</p>
|
||||
<div class="mb-2">
|
||||
<small class="d-block text-uppercase">{{ t('word.contributors') }}:</small>
|
||||
<small class="d-block text-uppercase">{{ t('general.contributors') }}:</small>
|
||||
<div class="d-block py-1">
|
||||
<small v-for="(contributor, i) in otherContributors" :key="i">{{ i !== 0 ? ', ' : '' }}{{ contributor }}</small>
|
||||
</div>
|
||||
<small>{{ t('message.madeWithJS') }}</small>
|
||||
<small>{{ t('application.madeWithJS') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -411,6 +421,7 @@ 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 ModalSettingsData from '@/components/ModalSettingsData.vue';
|
||||
import BaseTextEditor from '@/components/BaseTextEditor.vue';
|
||||
import BaseSelect from '@/components/BaseSelect.vue';
|
||||
import { AvailableLocale } from '@/i18n';
|
||||
@@ -500,7 +511,7 @@ const selectedTab: Ref<string> = ref('general');
|
||||
|
||||
const editorThemes = computed(() => [
|
||||
{
|
||||
group: t('word.light'),
|
||||
group: t('application.light'),
|
||||
themes: [
|
||||
{ code: 'chrome', name: 'Chrome' },
|
||||
{ code: 'clouds', name: 'Clouds' },
|
||||
@@ -520,7 +531,7 @@ const editorThemes = computed(() => [
|
||||
]
|
||||
},
|
||||
{
|
||||
group: t('word.dark'),
|
||||
group: t('application.dark'),
|
||||
themes: [
|
||||
{ code: 'ambiance', name: 'Ambiance' },
|
||||
{ code: 'chaos', name: 'Chaos' },
|
||||
@@ -553,12 +564,12 @@ const locales = computed(() => {
|
||||
for (const locale of Object.keys(localesNames))
|
||||
locales.push({ code: locale, name: localesNames[locale] });
|
||||
|
||||
return locales;
|
||||
return locales.sort((a, b) => (a.name.localeCompare(b.name)));
|
||||
});
|
||||
|
||||
const copyTypes = computed(() => [
|
||||
{ code: 'cell', name: t('word.cell') },
|
||||
{ code: 'html', name: t('word.table') },
|
||||
{ code: 'cell', name: t('database.cell') },
|
||||
{ code: 'html', name: t('database.table') },
|
||||
{ code: 'json', name: 'JSON' },
|
||||
{ code: 'csv', name: 'CSV' },
|
||||
{ code: 'sql', name: 'SQL insert' }
|
||||
@@ -648,10 +659,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 {
|
||||
|
@@ -18,6 +18,7 @@ import { marked } from 'marked';
|
||||
import BaseLoader from '@/components/BaseLoader.vue';
|
||||
import { useApplicationStore } from '@/stores/application';
|
||||
import { ref } from 'vue';
|
||||
import { shell } from 'electron';
|
||||
|
||||
const { appVersion } = useApplicationStore();
|
||||
|
||||
@@ -26,6 +27,10 @@ const isLoading = ref(true);
|
||||
const error = ref('');
|
||||
const isError = ref(false);
|
||||
|
||||
const openOutside = (link: string) => {
|
||||
shell.openExternal(link);
|
||||
};
|
||||
|
||||
const getChangelog = async () => {
|
||||
try {
|
||||
const apiRes = await fetch(`https://api.github.com/repos/antares-sql/antares/releases/tags/v${appVersion}`, {
|
||||
@@ -40,7 +45,7 @@ const getChangelog = async () => {
|
||||
|
||||
const renderer = {
|
||||
link (href: string, title: string, text: string) {
|
||||
return text;
|
||||
return `<a class="changelog-link" href="${href}" title="${title || ''}" target="_blank">${text}</a>`;
|
||||
},
|
||||
listitem (text: string) {
|
||||
return `<li>${text.replace(/ *\([^)]*\) */g, '')}</li>`;
|
||||
@@ -57,6 +62,17 @@ const getChangelog = async () => {
|
||||
}
|
||||
|
||||
isLoading.value = false;
|
||||
|
||||
setTimeout(() => {
|
||||
const links = document.querySelectorAll<HTMLAnchorElement>('.changelog-link');
|
||||
|
||||
for (const link of links) {
|
||||
link.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
openOutside(link.href);
|
||||
});
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
getChangelog();
|
||||
|
60
src/renderer/components/ModalSettingsData.vue
Normal file
60
src/renderer/components/ModalSettingsData.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<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"
|
||||
>
|
||||
<i class="mdi mdi-tray-arrow-up mdi-24px pr-2" />
|
||||
<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"
|
||||
>
|
||||
<i class="mdi mdi-tray-arrow-down mdi-24px pr-2" />
|
||||
<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 { useApplicationStore } from '@/stores/application';
|
||||
import ModalSettingsDataExport from '@/components/ModalSettingsDataExport.vue';
|
||||
import ModalSettingsDataImport from '@/components/ModalSettingsDataImport.vue';
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const isExportModal = ref(false);
|
||||
const isImportModal = ref(false);
|
||||
|
||||
</script>
|
331
src/renderer/components/ModalSettingsDataExport.vue
Normal file
331
src/renderer/components/ModalSettingsDataExport.vue
Normal file
@@ -0,0 +1,331 @@
|
||||
<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">
|
||||
<i class="mdi mdi-24px mdi-tray-arrow-up mr-1" /> {{ 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"
|
||||
>
|
||||
<i v-if="isPasswordVisible" class="mdi mdi-eye px-1" />
|
||||
<i v-else class="mdi mdi-eye-off px-1" />
|
||||
</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 { computed, onBeforeUnmount, Ref, ref } from 'vue';
|
||||
import * as moment from 'moment';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { unproxify } from '@/libs/unproxify';
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { encrypt } from 'common/libs/encrypter';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
|
||||
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>
|
263
src/renderer/components/ModalSettingsDataImport.vue
Normal file
263
src/renderer/components/ModalSettingsDataImport.vue
Normal file
@@ -0,0 +1,263 @@
|
||||
<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">
|
||||
<i class="mdi mdi-24px mdi-tray-arrow-down mr-1" /> {{ 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="filePath = ''"
|
||||
@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"
|
||||
>
|
||||
<i v-if="isPasswordVisible" class="mdi mdi-eye px-1" />
|
||||
<i v-else class="mdi mdi-eye-off px-1" />
|
||||
</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 { onBeforeUnmount, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput.vue';
|
||||
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { unproxify } from '@/libs/unproxify';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { decrypt } from 'common/libs/encrypter';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { ConnectionParams } from 'common/interfaces/antares';
|
||||
|
||||
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 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,10 @@
|
||||
<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('message.addShortcut') }}</span>
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /><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('message.restoreDefaults') }}</span>
|
||||
<i class="mdi mdi-24px mdi-undo mr-1" /><span>{{ t('application.restoreDefaults') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="container workspace-query-results">
|
||||
@@ -14,12 +14,12 @@
|
||||
<div class="tr text-uppercase">
|
||||
<div class="th no-border">
|
||||
<div>
|
||||
{{ t('word.event') }}
|
||||
{{ t('application.event') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="th no-border" style="width: 100%;">
|
||||
<div>
|
||||
{{ t('word.key', 2) }}
|
||||
{{ t('application.key', 2) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="th no-border" />
|
||||
@@ -43,10 +43,10 @@
|
||||
/>
|
||||
<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('word.edit') }}</span><i class="mdi mdi-pencil ml-1" />
|
||||
<span>{{ t('general.edit') }}</span><i class="mdi mdi-pencil ml-1" />
|
||||
</button>
|
||||
<button class="shortcut-button btn btn-link btn-sm d-flex p-0 px-1" @click="showDeleteModal(shortcut)">
|
||||
<span>{{ t('word.delete') }}</span><i class="mdi mdi-delete-outline ml-1" />
|
||||
<span>{{ t('general.delete') }}</span><i class="mdi mdi-delete-outline ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,20 +58,20 @@
|
||||
<ConfirmModal
|
||||
v-if="isConfirmAddModal"
|
||||
:disable-autofocus="true"
|
||||
:confirm-text="t('word.save')"
|
||||
:confirm-text="t('general.save')"
|
||||
:close-on-confirm="false"
|
||||
@confirm="addShortcut"
|
||||
@hide="closeAddModal"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /> {{ t('message.addShortcut') }}
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /> {{ t('application.addShortcut') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.event') }}</label>
|
||||
<label class="form-label">{{ t('application.event') }}</label>
|
||||
<BaseSelect
|
||||
v-model="shortcutToAdd.event"
|
||||
class="form-select"
|
||||
@@ -81,31 +81,31 @@
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.key', 2) }}</label>
|
||||
<label class="form-label">{{ t('application.key', 2) }}</label>
|
||||
<KeyPressDetector v-model="typedShortcut" />
|
||||
</div>
|
||||
</div>
|
||||
<small v-if="doesShortcutExists" class="text-warning">{{ t('message.shortcutAlreadyExists') }}</small>
|
||||
<small v-if="doesShortcutExists" class="text-warning">{{ t('application.shortcutAlreadyExists') }}</small>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
|
||||
<ConfirmModal
|
||||
v-if="isConfirmEditModal"
|
||||
:disable-autofocus="true"
|
||||
:confirm-text="t('word.save')"
|
||||
:confirm-text="t('general.save')"
|
||||
:close-on-confirm="false"
|
||||
@confirm="editShortcut"
|
||||
@hide="closeEditModal"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /> {{ t('message.editShortcut') }}
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" /> {{ t('application.editShortcut') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.event') }}</label>
|
||||
<label class="form-label">{{ t('application.event') }}</label>
|
||||
<BaseSelect
|
||||
v-model="shortcutToEdit.event"
|
||||
class="form-select"
|
||||
@@ -116,11 +116,11 @@
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.key', 2) }}</label>
|
||||
<label class="form-label">{{ t('application.key', 2) }}</label>
|
||||
<KeyPressDetector v-model="shortcutToEdit.keys[0]" />
|
||||
</div>
|
||||
</div>
|
||||
<small v-if="doesShortcutExists" class="text-warning">{{ t('message.shortcutAlreadyExists') }}</small>
|
||||
<small v-if="doesShortcutExists" class="text-warning">{{ t('application.shortcutAlreadyExists') }}</small>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
|
||||
@@ -132,12 +132,12 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-delete mr-1" /> {{ t('message.deleteShortcut') }}
|
||||
<i class="mdi mdi-24px mdi-delete mr-1" /> {{ t('application.deleteShortcut') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.deleteCorfirm') }} <b>{{ t(shortcutEvents[shortcutToDelete.event].l18n, {param: shortcutEvents[shortcutToDelete.event].l18nParam}) }} (<span v-html="parseKeys(shortcutToDelete.keys)" />)</b>?
|
||||
{{ t('general.deleteConfirm') }} <b>{{ t(shortcutEvents[shortcutToDelete.event].l18n, {param: shortcutEvents[shortcutToDelete.event].l18nParam}) }} (<span v-html="parseKeys(shortcutToDelete.keys)" />)</b>?
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
@@ -150,12 +150,12 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-undo mr-1" /> {{ t('message.restoreDefaults') }}
|
||||
<i class="mdi mdi-24px mdi-undo mr-1" /> {{ t('application.restoreDefaults') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.restoreDefaultsQuestion') }}
|
||||
{{ t('application.restoreDefaultsQuestion') }}
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
|
@@ -26,27 +26,27 @@
|
||||
:class="{'loading': updateStatus === 'checking'}"
|
||||
@click="checkForUpdates"
|
||||
>
|
||||
{{ t('message.checkForUpdates') }}
|
||||
{{ t('application.checkForUpdates') }}
|
||||
</button>
|
||||
<button
|
||||
v-else-if="updateStatus === 'downloaded'"
|
||||
class="btn btn-primary"
|
||||
@click="restartToUpdate"
|
||||
>
|
||||
{{ t('message.restartToInstall') }}
|
||||
{{ t('application.restartToInstall') }}
|
||||
</button>
|
||||
<button
|
||||
v-else-if="updateStatus === 'link'"
|
||||
class="btn btn-primary"
|
||||
@click="openOutside('https://antares-sql.app/download.html')"
|
||||
>
|
||||
{{ t('message.goToDownloadPage') }}
|
||||
{{ t('application.goToDownloadPage') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-group mt-4">
|
||||
<label class="form-switch d-inline-block disabled" @click.prevent="toggleAllowPrerelease">
|
||||
<label class="form-switch d-inline-block" @click.prevent="toggleAllowPrerelease">
|
||||
<input type="checkbox" :checked="allowPrerelease">
|
||||
<i class="form-icon" /> {{ t('message.includeBetaUpdates') }}
|
||||
<i class="form-icon" /> {{ t('application.includeBetaUpdates') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,19 +76,19 @@ const { changeAllowPrerelease } = settingsStore;
|
||||
const updateMessage = computed(() => {
|
||||
switch (updateStatus.value) {
|
||||
case 'noupdate':
|
||||
return t('message.noUpdatesAvailable');
|
||||
return t('application.noUpdatesAvailable');
|
||||
case 'checking':
|
||||
return t('message.checkingForUpdate');
|
||||
return t('application.checkingForUpdate');
|
||||
case 'nocheck':
|
||||
return t('message.checkFailure');
|
||||
return t('application.checkFailure');
|
||||
case 'available':
|
||||
return t('message.updateAvailable');
|
||||
return t('application.updateAvailable');
|
||||
case 'downloading':
|
||||
return t('message.downloadingUpdate');
|
||||
return t('application.downloadingUpdate');
|
||||
case 'downloaded':
|
||||
return t('message.updateDownloaded');
|
||||
return t('application.updateDownloaded');
|
||||
case 'link':
|
||||
return t('message.updateAvailable');
|
||||
return t('application.updateAvailable');
|
||||
default:
|
||||
return updateStatus.value;
|
||||
}
|
||||
|
@@ -380,7 +380,7 @@ emit('folder-sort');// To apply changes on component key change
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1;
|
||||
line-height: 1.02;
|
||||
transition: bottom .2s;
|
||||
}
|
||||
}
|
||||
@@ -444,7 +444,7 @@ emit('folder-sort');// To apply changes on component key change
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1;
|
||||
line-height: 1.02;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,20 +8,20 @@
|
||||
class="context-element"
|
||||
@click="disconnect"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-power text-light pr-1" /> {{ t('word.disconnect') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-power text-light pr-1" /> {{ 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('word.duplicate') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ t('general.duplicate') }}</span>
|
||||
</div>
|
||||
<div class="context-element" @click.stop="showAppearenceModal">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-brush-variant text-light pr-1" /> {{ t('word.appearence') }}</span>
|
||||
<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>
|
||||
</div>
|
||||
<div class="context-element" @click="showConfirmModal">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ t('word.delete') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ t('general.delete') }}</span>
|
||||
</div>
|
||||
|
||||
<ConfirmModal
|
||||
@@ -31,24 +31,24 @@
|
||||
>
|
||||
<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 ? 'message.deleteFolder' : 'message.deleteConnection') }}
|
||||
<i class="mdi mdi-24px mr-1" :class="[contextConnection.isFolder ? 'mdi-folder-remove' : 'mdi-server-remove']" /> {{ t(contextConnection.isFolder ? 'application.deleteFolder' : 'connection.deleteConnection') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.deleteCorfirm') }} <b>{{ connectionName }}</b>?
|
||||
{{ t('general.deleteConfirm') }} <b>{{ connectionName }}</b>?
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
<ModalFolderAppearence
|
||||
<ModalFolderAppearance
|
||||
v-if="isFolderEdit"
|
||||
:folder="contextConnection"
|
||||
@close="hideAppearenceModal"
|
||||
@close="hideAppearanceModal"
|
||||
/>
|
||||
<ModalConnectionAppearence
|
||||
<ModalConnectionAppearance
|
||||
v-if="isConnectionEdit"
|
||||
:connection="contextConnection"
|
||||
@close="hideAppearenceModal"
|
||||
@close="hideAppearanceModal"
|
||||
/>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
@@ -62,8 +62,8 @@ import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import ModalFolderAppearence from '@/components/ModalFolderAppearence.vue';
|
||||
import ModalConnectionAppearence from '@/components/ModalConnectionAppearence.vue';
|
||||
import ModalFolderAppearance from '@/components/ModalFolderAppearance.vue';
|
||||
import ModalConnectionAppearance from '@/components/ModalConnectionAppearance.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -96,7 +96,7 @@ const isConfirmModal = ref(false);
|
||||
const isFolderEdit = ref(false);
|
||||
const isConnectionEdit = ref(false);
|
||||
|
||||
const connectionName = computed(() => props.contextConnection.name || getConnectionName(props.contextConnection.uid) || t('word.folder', 1));
|
||||
const connectionName = computed(() => props.contextConnection.name || getConnectionName(props.contextConnection.uid) || t('general.folder', 1));
|
||||
const isConnected = computed(() => getWorkspace(props.contextConnection.uid)?.connectionStatus === 'connected');
|
||||
|
||||
const confirmDeleteConnection = () => {
|
||||
@@ -118,14 +118,14 @@ const duplicateConnection = () => {
|
||||
closeContext();
|
||||
};
|
||||
|
||||
const showAppearenceModal = () => {
|
||||
const showAppearanceModal = () => {
|
||||
if (props.contextConnection.isFolder)
|
||||
isFolderEdit.value = true;
|
||||
else
|
||||
isConnectionEdit.value = true;
|
||||
};
|
||||
|
||||
const hideAppearenceModal = () => {
|
||||
const hideAppearanceModal = () => {
|
||||
isConnectionEdit.value = false;
|
||||
isFolderEdit.value = false;
|
||||
closeContext();
|
||||
|
@@ -12,7 +12,7 @@
|
||||
</li>
|
||||
<li v-if="connectionInfos && connectionInfos.readonly" class="footer-element">
|
||||
<i class="mdi mdi-18px mdi-lock mr-1" />
|
||||
<small>{{ t('message.readOnlyMode') }}</small>
|
||||
<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" />
|
||||
@@ -33,22 +33,22 @@
|
||||
@click="toggleConsole()"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-console-line mr-1" />
|
||||
<small>{{ t('word.console') }}</small>
|
||||
<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" />
|
||||
<small>{{ t('word.donate') }}</small>
|
||||
<small>{{ t('general.donate') }}</small>
|
||||
</li>
|
||||
<li
|
||||
class="footer-element footer-link"
|
||||
:title="t('message.reportABug')"
|
||||
:title="t('application.reportABug')"
|
||||
@click="openOutside('https://github.com/antares-sql/antares/issues')"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-bug" />
|
||||
</li>
|
||||
<li
|
||||
class="footer-element footer-link"
|
||||
:title="t('word.about')"
|
||||
:title="t('application.about')"
|
||||
@click="showSettingModal('about')"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-information-outline" />
|
||||
|
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.update')"
|
||||
:cancel-text="t('word.close')"
|
||||
:confirm-text="t('application.update')"
|
||||
:cancel-text="t('general.close')"
|
||||
size="large"
|
||||
:hide-footer="true"
|
||||
@hide="hideScratchpad"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-notebook-edit-outline mr-1" /> {{ t('word.scratchpad') }}
|
||||
<i class="mdi mdi-24px mdi-notebook-edit-outline mr-1" /> {{ t('application.scratchpad') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -22,7 +22,7 @@
|
||||
:show-line-numbers="false"
|
||||
/>
|
||||
</div>
|
||||
<small class="text-gray">{{ t('message.markdownSupported') }}</small>
|
||||
<small class="text-gray">{{ t('application.markdownSupported') }}</small>
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
|
@@ -22,7 +22,7 @@
|
||||
v-tooltip="{
|
||||
strategy: 'fixed',
|
||||
placement: 'right',
|
||||
content: t('message.allConnections')
|
||||
content: t('connection.allConnections')
|
||||
}"
|
||||
class="settingbar-element btn btn-link"
|
||||
@click="emit('show-connections-modal')"
|
||||
@@ -35,7 +35,7 @@
|
||||
v-tooltip="{
|
||||
strategy: 'fixed',
|
||||
placement: 'right',
|
||||
content: t('message.addConnection')
|
||||
content: t('connection.addConnection')
|
||||
}"
|
||||
class="settingbar-element btn btn-link"
|
||||
:class="{ 'selected': 'NEW' === selectedWorkspace }"
|
||||
@@ -55,7 +55,7 @@
|
||||
v-tooltip="{
|
||||
strategy: 'fixed',
|
||||
placement: 'right',
|
||||
content: t('word.scratchpad')
|
||||
content: t('application.scratchpad')
|
||||
}"
|
||||
class="settingbar-element btn btn-link"
|
||||
@click="showScratchpad"
|
||||
@@ -66,7 +66,7 @@
|
||||
v-tooltip="{
|
||||
strategy: 'fixed',
|
||||
placement: 'right',
|
||||
content: t('word.settings')
|
||||
content: t('application.settings')
|
||||
}"
|
||||
class="settingbar-element btn btn-link"
|
||||
@click="showSettingModal('general')"
|
||||
|
@@ -63,7 +63,7 @@ const isLinux = process.platform === 'linux';
|
||||
|
||||
const windowTitle = computed(() => {
|
||||
if (!selectedWorkspace.value) return '';
|
||||
if (selectedWorkspace.value === 'NEW') return t('message.createNewConnection');
|
||||
if (selectedWorkspace.value === 'NEW') return t('connection.createNewConnection');
|
||||
|
||||
const connectionName = getConnectionName(selectedWorkspace.value);
|
||||
const workspace = getWorkspace(selectedWorkspace.value);
|
||||
|
@@ -45,7 +45,7 @@
|
||||
<span>{{ cutText(element.content || 'Query', 20, true) }} #{{ element.index }}</span>
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -58,11 +58,11 @@
|
||||
@dblclick="openAsPermanentTab(element)"
|
||||
>
|
||||
<i class="mdi mdi-18px mr-1" :class="element.elementType === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
|
||||
<span :title="`${t('word.data').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
<span class=" text-italic">{{ cutText(element.elementName, 20, true) }}</span>
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -71,11 +71,11 @@
|
||||
|
||||
<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'" />
|
||||
<span :title="`${t('word.data').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
<span :title="`${t('general.data').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -88,11 +88,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<span :title="`${t('word.new').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
{{ t('message.newTable') }}
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newTable') }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -104,12 +104,12 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-tune-vertical-variant mdi-18px mr-1" />
|
||||
<span :title="`${t('word.settings').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
<i class="mdi mdi-wrench-cog mdi-18px mr-1" />
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -121,12 +121,12 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-tune-vertical-variant mdi-18px mr-1" />
|
||||
<span :title="`${t('word.settings').toUpperCase()}: ${t(`word.view`)}`">
|
||||
<i class="mdi mdi-wrench-cog mdi-18px mr-1" />
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.view`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -139,11 +139,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<span :title="`${t('word.new').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
{{ t('message.newView') }}
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newView') }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -156,11 +156,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<span :title="`${t('word.new').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
{{ t('message.newTrigger') }}
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newTrigger') }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -173,11 +173,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<span :title="`${t('word.new').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
{{ t('message.newRoutine') }}
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newRoutine') }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -190,11 +190,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<span :title="`${t('word.new').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
{{ t('message.newFunction') }}
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newFunction') }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -207,11 +207,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<span :title="`${t('word.new').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
{{ t('message.newTriggerFunction') }}
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newTriggerFunction') }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -224,11 +224,11 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-shape-square-plus mdi-18px mr-1" />
|
||||
<span :title="`${t('word.new').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
{{ t('message.newScheduler') }}
|
||||
<span :title="`${t('general.new').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ t('database.newScheduler') }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -241,12 +241,12 @@
|
||||
:class="{'badge': element.isChanged}"
|
||||
@dblclick="openAsPermanentTab(element)"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-tune-vertical-variant mr-1" />
|
||||
<span :title="`${t('word.settings').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
<i class="mdi mdi-18px mdi-wrench-cog mr-1" />
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
<span class=" text-italic">{{ cutText(element.elementName, 20, true) }}</span>
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -258,12 +258,12 @@
|
||||
class="tab-link"
|
||||
:class="{'badge': element.isChanged}"
|
||||
>
|
||||
<i class="mdi mdi-18px mdi-tune-vertical-variant mr-1" />
|
||||
<span :title="`${t('word.settings').toUpperCase()}: ${t(`word.${element.elementType}`)}`">
|
||||
<i class="mdi mdi-18px mdi-wrench-cog mr-1" />
|
||||
<span :title="`${t('application.settings').toUpperCase()}: ${t(`database.${element.elementType}`)}`">
|
||||
{{ cutText(element.elementName, 20, true) }}
|
||||
<span
|
||||
class="btn btn-clear"
|
||||
:title="t('word.close')"
|
||||
:title="t('general.close')"
|
||||
@mousedown.left.stop
|
||||
@click.stop="closeTab(element)"
|
||||
/>
|
||||
@@ -279,7 +279,7 @@
|
||||
<a
|
||||
class="tab-link workspace-tools-link dropdown-toggle"
|
||||
tabindex="0"
|
||||
:title="t('word.tools')"
|
||||
:title="t('general.tools')"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-tools" />
|
||||
</a>
|
||||
@@ -287,13 +287,13 @@
|
||||
<li class="menu-item">
|
||||
<a class="c-hand p-vcentered" @click="showProcessesModal">
|
||||
<i class="mdi mdi-memory mr-1 tool-icon" />
|
||||
<span>{{ t('message.processesList') }}</span>
|
||||
<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" />
|
||||
<span>{{ t('word.console') }}</span>
|
||||
<span>{{ t('application.console') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
@@ -303,7 +303,7 @@
|
||||
>
|
||||
<a class="c-hand p-vcentered disabled">
|
||||
<i class="mdi mdi-shape mr-1 tool-icon" />
|
||||
<span>{{ t('word.variables') }}</span>
|
||||
<span>{{ t('database.variables') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
@@ -313,7 +313,7 @@
|
||||
>
|
||||
<a class="c-hand p-vcentered disabled">
|
||||
<i class="mdi mdi-account-group mr-1 tool-icon" />
|
||||
<span>{{ t('message.manageUsers') }}</span>
|
||||
<span>{{ t('database.manageUsers') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -323,7 +323,7 @@
|
||||
<li class="tab-item">
|
||||
<a
|
||||
class="tab-add"
|
||||
:title="t('message.openNewTab')"
|
||||
:title="t('application.openNewTab')"
|
||||
@click="addQueryTab"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-plus" />
|
||||
@@ -331,8 +331,8 @@
|
||||
</li>
|
||||
</template>
|
||||
</Draggable>
|
||||
<WorkspaceEmptyState v-if="!workspace.tabs.length" @new-tab="addQueryTab" />
|
||||
<template v-for="tab of workspace.tabs" :key="tab.uid">
|
||||
<WorkspaceEmptyState v-if="!draggableTabs.length" @new-tab="addQueryTab" />
|
||||
<template v-for="tab of draggableTabs" :key="tab.uid">
|
||||
<WorkspaceTabQuery
|
||||
v-if="tab.type ==='query'"
|
||||
:tab-uid="tab.uid"
|
||||
@@ -565,7 +565,11 @@ const workspace = computed(() => getWorkspace(props.connection.uid));
|
||||
|
||||
const draggableTabs = computed<WorkspaceTab[]>({
|
||||
get () {
|
||||
return workspace.value.tabs;
|
||||
if (workspace.value.customizations.database)
|
||||
return workspace.value.tabs.filter(tab => tab.type === 'query' || tab.database === workspace.value.database);
|
||||
|
||||
else
|
||||
return workspace.value.tabs;
|
||||
},
|
||||
set (val) {
|
||||
updateTabs({ uid: props.connection.uid, tabs: val });
|
||||
|
@@ -8,7 +8,7 @@
|
||||
:class="{'active': selectedTab === 'general'}"
|
||||
@click="selectTab('general')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.general') }}</a>
|
||||
<a class="tab-link">{{ t('application.general') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="clientCustomizations.sslConnection"
|
||||
@@ -16,7 +16,7 @@
|
||||
:class="{'active': selectedTab === 'ssl'}"
|
||||
@click="selectTab('ssl')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.ssl') }}</a>
|
||||
<a class="tab-link">{{ t('connection.ssl') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="clientCustomizations.sshConnection"
|
||||
@@ -24,7 +24,7 @@
|
||||
:class="{'active': selectedTab === 'ssh'}"
|
||||
@click="selectTab('ssh')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.sshTunnel') }}</a>
|
||||
<a class="tab-link">{{ t('connection.sshTunnel') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -34,7 +34,7 @@
|
||||
<fieldset class="m-0" :disabled="isBusy">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.connectionName') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.connectionName') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.client') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.client') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseSelect
|
||||
@@ -61,7 +61,7 @@
|
||||
</div>
|
||||
<div v-if="connection.client === 'pg'" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.connectionString') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.connectionString') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -74,7 +74,7 @@
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.hostName') }}/IP</label>
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -86,12 +86,12 @@
|
||||
</div>
|
||||
<div v-if="clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.database') }}</label>
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.databasePath"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('databasePath')"
|
||||
@change="pathSelection($event, 'databasePath')"
|
||||
/>
|
||||
@@ -99,7 +99,7 @@
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.port') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -113,19 +113,20 @@
|
||||
</div>
|
||||
<div v-if="clientCustomizations.database" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.database') }}</label>
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
v-model="connection.database"
|
||||
class="form-input"
|
||||
type="text"
|
||||
:placeholder="clientCustomizations.defaultDatabase"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.user') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -138,7 +139,7 @@
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.password') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -151,14 +152,14 @@
|
||||
</div>
|
||||
<div v-if="clientCustomizations.connectionSchema" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.schema') }}</label>
|
||||
<label class="form-label cut-text">{{ t('database.schema') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
v-model="connection.schema"
|
||||
class="form-input"
|
||||
type="text"
|
||||
:placeholder="t('word.all')"
|
||||
:placeholder="t('general.all')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -166,7 +167,7 @@
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="connection.readonly" type="checkbox"><i class="form-icon" /> {{ t('message.readOnlyMode') }}
|
||||
<input v-model="connection.readonly" type="checkbox"><i class="form-icon" /> {{ t('connection.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -174,7 +175,7 @@
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="connection.ask" type="checkbox"><i class="form-icon" /> {{ t('message.askCredentials') }}
|
||||
<input v-model="connection.ask" type="checkbox"><i class="form-icon" /> {{ t('connection.askCredentials') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -188,7 +189,7 @@
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('message.enableSsl') }}
|
||||
{{ t('connection.enableSsl') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
@@ -201,12 +202,12 @@
|
||||
<fieldset class="m-0" :disabled="isBusy || !connection.ssl">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.privateKey') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.key"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('key')"
|
||||
@change="pathSelection($event, 'key')"
|
||||
/>
|
||||
@@ -214,12 +215,12 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.certificate') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.certificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.cert"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('cert')"
|
||||
@change="pathSelection($event, 'cert')"
|
||||
/>
|
||||
@@ -227,12 +228,12 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.caCertificate') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.caCertificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.ca"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('ca')"
|
||||
@change="pathSelection($event, 'ca')"
|
||||
/>
|
||||
@@ -240,7 +241,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.ciphers') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.ciphers') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -255,7 +256,7 @@
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="connection.untrustedConnection" type="checkbox"><i class="form-icon" /> {{ t('message.untrustedConnection') }}
|
||||
<input v-model="connection.untrustedConnection" type="checkbox"><i class="form-icon" /> {{ t('connection.untrustedConnection') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -269,7 +270,7 @@
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('message.enableSsh') }}
|
||||
{{ t('connection.enableSsh') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
@@ -282,7 +283,7 @@
|
||||
<fieldset class="m-0" :disabled="isBusy || !connection.ssh">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.hostName') }}/IP</label>
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -294,7 +295,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.user') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -306,7 +307,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.password') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -318,7 +319,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.port') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -332,12 +333,12 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.privateKey') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="connection.sshKey"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('sshKey')"
|
||||
@change="pathSelection($event, 'sshKey')"
|
||||
/>
|
||||
@@ -345,7 +346,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.passphrase') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.passphrase') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -368,7 +369,7 @@
|
||||
@click="startTest"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-lightning-bolt mr-1" />
|
||||
{{ t('message.testConnection') }}
|
||||
{{ t('connection.testConnection') }}
|
||||
</button>
|
||||
<button
|
||||
id="connection-save"
|
||||
@@ -377,7 +378,7 @@
|
||||
@click="saveConnection"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
{{ t('word.save') }}
|
||||
{{ t('general.save') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -483,7 +484,7 @@ const startTest = async () => {
|
||||
if (res.status === 'error')
|
||||
addNotification({ status: 'error', message: res.response.message || res.response.toString() });
|
||||
else
|
||||
addNotification({ status: 'success', message: t('message.connectionSuccessfullyMade') });
|
||||
addNotification({ status: 'success', message: t('connection.connectionSuccessfullyMade') });
|
||||
}
|
||||
catch (err) {
|
||||
addNotification({ status: 'error', message: err.stack });
|
||||
@@ -507,7 +508,7 @@ const continueTest = async (credentials: { user: string; password: string }) =>
|
||||
if (res.status === 'error')
|
||||
addNotification({ status: 'error', message: res.response.message || res.response.toString() });
|
||||
else
|
||||
addNotification({ status: 'success', message: t('message.connectionSuccessfullyMade') });
|
||||
addNotification({ status: 'success', message: t('connection.connectionSuccessfullyMade') });
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
|
@@ -8,7 +8,7 @@
|
||||
:class="{'active': selectedTab === 'general'}"
|
||||
@click="selectTab('general')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.general') }}</a>
|
||||
<a class="tab-link">{{ t('application.general') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="clientCustomizations.sslConnection"
|
||||
@@ -16,7 +16,7 @@
|
||||
:class="{'active': selectedTab === 'ssl'}"
|
||||
@click="selectTab('ssl')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.ssl') }}</a>
|
||||
<a class="tab-link">{{ t('connection.ssl') }}</a>
|
||||
</li>
|
||||
<li
|
||||
v-if="clientCustomizations.sshConnection"
|
||||
@@ -24,7 +24,7 @@
|
||||
:class="{'active': selectedTab === 'ssh'}"
|
||||
@click="selectTab('ssh')"
|
||||
>
|
||||
<a class="tab-link">{{ t('word.sshTunnel') }}</a>
|
||||
<a class="tab-link">{{ t('connection.sshTunnel') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -34,7 +34,7 @@
|
||||
<fieldset class="m-0" :disabled="isBusy">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.connectionName') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.connectionName') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.client') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.client') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseSelect
|
||||
@@ -63,7 +63,7 @@
|
||||
</div>
|
||||
<div v-if="localConnection.client === 'pg'" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.connectionString') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.connectionString') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -76,7 +76,7 @@
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.hostName') }}/IP</label>
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -88,12 +88,12 @@
|
||||
</div>
|
||||
<div v-if="clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.database') }}</label>
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.databasePath"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('databasePath')"
|
||||
@change="pathSelection($event, 'databasePath')"
|
||||
/>
|
||||
@@ -101,7 +101,7 @@
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.port') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -115,19 +115,20 @@
|
||||
</div>
|
||||
<div v-if="clientCustomizations.database" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.database') }}</label>
|
||||
<label class="form-label cut-text">{{ t('database.database') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.database"
|
||||
class="form-input"
|
||||
type="text"
|
||||
:placeholder="clientCustomizations.defaultDatabase"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.user') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -140,7 +141,7 @@
|
||||
</div>
|
||||
<div v-if="!clientCustomizations.fileConnection" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.password') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -153,14 +154,14 @@
|
||||
</div>
|
||||
<div v-if="clientCustomizations.connectionSchema" class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.schema') }}</label>
|
||||
<label class="form-label cut-text">{{ t('database.schema') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
v-model="localConnection.schema"
|
||||
class="form-input"
|
||||
type="text"
|
||||
:placeholder="t('word.all')"
|
||||
:placeholder="t('general.all')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,7 +169,7 @@
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localConnection.readonly" type="checkbox"><i class="form-icon" /> {{ t('message.readOnlyMode') }}
|
||||
<input v-model="localConnection.readonly" type="checkbox"><i class="form-icon" /> {{ t('connection.readOnlyMode') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -176,7 +177,7 @@
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localConnection.ask" type="checkbox"><i class="form-icon" /> {{ t('message.askCredentials') }}
|
||||
<input v-model="localConnection.ask" type="checkbox"><i class="form-icon" /> {{ t('connection.askCredentials') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -190,7 +191,7 @@
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('message.enableSsl') }}
|
||||
{{ t('connection.enableSsl') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
@@ -203,12 +204,12 @@
|
||||
<fieldset class="m-0" :disabled="isBusy || !localConnection.ssl">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.privateKey') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.key"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('key')"
|
||||
@change="pathSelection($event, 'key')"
|
||||
/>
|
||||
@@ -216,12 +217,12 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.certificate') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.certificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.cert"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('cert')"
|
||||
@change="pathSelection($event, 'cert')"
|
||||
/>
|
||||
@@ -229,12 +230,12 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.caCertificate') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.caCertificate') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.ca"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('ca')"
|
||||
@change="pathSelection($event, 'ca')"
|
||||
/>
|
||||
@@ -242,7 +243,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.ciphers') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.ciphers') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -257,7 +258,7 @@
|
||||
<div class="column col-4 col-sm-12" />
|
||||
<div class="column col-8 col-sm-12">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localConnection.untrustedConnection" type="checkbox"><i class="form-icon" /> {{ t('message.untrustedConnection') }}
|
||||
<input v-model="localConnection.untrustedConnection" type="checkbox"><i class="form-icon" /> {{ t('connection.untrustedConnection') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -271,7 +272,7 @@
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">
|
||||
{{ t('message.enableSsh') }}
|
||||
{{ t('connection.enableSsh') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
@@ -284,7 +285,7 @@
|
||||
<fieldset class="m-0" :disabled="isBusy || !localConnection.ssh">
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.hostName') }}/IP</label>
|
||||
<label class="form-label cut-text">{{ t('connection.hostName') }}/IP</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -296,7 +297,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.user') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.user') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -308,7 +309,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.password') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.password') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -320,7 +321,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.port') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.port') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -334,12 +335,12 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.privateKey') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.privateKey') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:model-value="localConnection.sshKey"
|
||||
:message="t('word.browse')"
|
||||
:message="t('general.browse')"
|
||||
@clear="pathClear('sshKey')"
|
||||
@change="pathSelection($event, 'sshKey')"
|
||||
/>
|
||||
@@ -347,7 +348,7 @@
|
||||
</div>
|
||||
<div class="form-group columns">
|
||||
<div class="column col-4 col-sm-12">
|
||||
<label class="form-label cut-text">{{ t('word.passphrase') }}</label>
|
||||
<label class="form-label cut-text">{{ t('connection.passphrase') }}</label>
|
||||
</div>
|
||||
<div class="column col-8 col-sm-12">
|
||||
<input
|
||||
@@ -370,7 +371,7 @@
|
||||
@click="startTest"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-lightning-bolt mr-1" />
|
||||
{{ t('message.testConnection') }}
|
||||
{{ t('connection.testConnection') }}
|
||||
</button>
|
||||
<button
|
||||
id="connection-save"
|
||||
@@ -379,7 +380,7 @@
|
||||
@click="saveConnection"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
{{ t('word.save') }}
|
||||
{{ t('general.save') }}
|
||||
</button>
|
||||
<button
|
||||
id="connection-connect"
|
||||
@@ -389,7 +390,7 @@
|
||||
@click="startConnection"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-connection mr-1" />
|
||||
{{ t('word.connect') }}
|
||||
{{ t('connection.connect') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -478,7 +479,7 @@ const startTest = async () => {
|
||||
if (res.status === 'error')
|
||||
addNotification({ status: 'error', message: res.response.message || res.response.toString() });
|
||||
else
|
||||
addNotification({ status: 'success', message: t('message.connectionSuccessfullyMade') });
|
||||
addNotification({ status: 'success', message: t('connection.connectionSuccessfullyMade') });
|
||||
}
|
||||
catch (err) {
|
||||
addNotification({ status: 'error', message: err.stack });
|
||||
@@ -502,7 +503,7 @@ const continueTest = async (credentials: {user: string; password: string }) => {
|
||||
if (res.status === 'error')
|
||||
addNotification({ status: 'error', message: res.response.message || res.response.toString() });
|
||||
else
|
||||
addNotification({ status: 'success', message: t('message.connectionSuccessfullyMade') });
|
||||
addNotification({ status: 'success', message: t('connection.connectionSuccessfullyMade') });
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
|
@@ -4,12 +4,12 @@
|
||||
<img :src="logos[applicationTheme]" width="200">
|
||||
</div>
|
||||
<p class="h6 empty-subtitle">
|
||||
{{ t('message.noOpenTabs') }}
|
||||
{{ t('application.noOpenTabs') }}
|
||||
</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" />
|
||||
{{ t('message.openNewTab') }}
|
||||
{{ t('application.openNewTab') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -10,23 +10,34 @@
|
||||
@keydown="explorebarSearch"
|
||||
>
|
||||
<div class="workspace-explorebar-header">
|
||||
<span class="workspace-explorebar-title">{{ connectionName }}</span>
|
||||
<div
|
||||
v-if="customizations.database"
|
||||
class="workspace-explorebar-database-switch"
|
||||
:title="t('database.switchDatabase')"
|
||||
>
|
||||
<BaseSelect
|
||||
v-model="selectedDatabase"
|
||||
:options="databases"
|
||||
class="form-select select-sm text-bold my-0"
|
||||
/>
|
||||
</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('message.createNewSchema')"
|
||||
:title="t('database.createNewSchema')"
|
||||
@click="showNewDBModal"
|
||||
/>
|
||||
<i
|
||||
class="mdi mdi-18px mdi-refresh c-hand mr-2"
|
||||
:class="{'rotate':isRefreshing}"
|
||||
:title="t('word.refresh')"
|
||||
:title="t('general.refresh')"
|
||||
@click="refresh"
|
||||
/>
|
||||
<i
|
||||
class="mdi mdi-18px mdi-power c-hand"
|
||||
:title="t('word.disconnect')"
|
||||
:title="t('connection.disconnect')"
|
||||
@click="disconnectWorkspace(connection.uid)"
|
||||
/>
|
||||
</span>
|
||||
@@ -35,7 +46,7 @@
|
||||
<div v-if="workspace.connectionStatus === 'connected'" class="input-group has-icon-right">
|
||||
<div
|
||||
class="input-group-addon px-1 py-0 p-vcentered c-hand"
|
||||
:title="t('message.switchSearchMethod')"
|
||||
:title="t('application.switchSearchMethod')"
|
||||
@click="toggleSearchMethod"
|
||||
>
|
||||
<i class="mdi mdi-18px" :class="[searchMethod === 'elements' ? 'mdi-shape' : 'mdi-database']" />
|
||||
@@ -45,7 +56,7 @@
|
||||
v-model="searchTerm"
|
||||
class="form-input input-sm"
|
||||
type="text"
|
||||
:placeholder="searchMethod === 'elements' ? t('message.searchForElements') : t('message.searchForSchemas')"
|
||||
:placeholder="searchMethod === 'elements' ? t('database.searchForElements') : t('database.searchForSchemas')"
|
||||
>
|
||||
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px" />
|
||||
<i
|
||||
@@ -124,10 +135,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Component, computed, onMounted, Ref, ref, watch } from 'vue';
|
||||
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';
|
||||
@@ -141,12 +153,14 @@ 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';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps({
|
||||
connection: Object,
|
||||
connection: Object as Prop<ConnectionParams>,
|
||||
isSelected: Boolean
|
||||
});
|
||||
|
||||
@@ -160,11 +174,13 @@ const { explorebarSize } = storeToRefs(settingsStore);
|
||||
const { changeExplorebarSize } = settingsStore;
|
||||
const {
|
||||
getWorkspace,
|
||||
switchConnection,
|
||||
removeConnected: disconnectWorkspace,
|
||||
refreshStructure,
|
||||
newTab,
|
||||
removeTabs,
|
||||
setSearchTerm,
|
||||
setDatabase,
|
||||
addLoadingElement,
|
||||
removeLoadingElement
|
||||
} = workspacesStore;
|
||||
@@ -172,6 +188,7 @@ const {
|
||||
const searchInput: Ref<HTMLInputElement> = ref(null);
|
||||
const explorebar: Ref<HTMLInputElement> = ref(null);
|
||||
const resizer: Ref<HTMLInputElement> = ref(null);
|
||||
const databases: Ref<string[]> = ref([]);
|
||||
const schema: Ref<Component & { selectSchema: (name: string) => void; $refs: {schemaAccordion: HTMLDetailsElement} }[]> = ref(null);
|
||||
const isRefreshing = ref(false);
|
||||
const isNewDBModal = ref(false);
|
||||
@@ -185,6 +202,7 @@ const isMiscFolderContext = ref(false);
|
||||
const databaseContextEvent = ref(null);
|
||||
const tableContextEvent = ref(null);
|
||||
const miscContextEvent = ref(null);
|
||||
const selectedDatabase = ref(props.connection.database);
|
||||
const selectedSchema = ref('');
|
||||
const selectedTable = ref(null);
|
||||
const selectedMisc = ref(null);
|
||||
@@ -230,9 +248,14 @@ watch(searchTerm, () => {
|
||||
}, 200);
|
||||
});
|
||||
|
||||
watch(selectedDatabase, (val, oldVal) => {
|
||||
if (oldVal)
|
||||
switchConnection({ ...props.connection, database: selectedDatabase.value });
|
||||
});
|
||||
|
||||
localWidth.value = explorebarSize.value;
|
||||
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
resizer.value.addEventListener('mousedown', (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
@@ -240,10 +263,28 @@ onMounted(() => {
|
||||
window.addEventListener('mouseup', stopResize);
|
||||
});
|
||||
|
||||
if (workspace.value.structure.length === 1) { // Auto-open if juust one schema
|
||||
if (workspace.value.structure.length === 1) { // Auto-open if just one schema
|
||||
schema.value[0].selectSchema(workspace.value.structure[0].name);
|
||||
schema.value[0].$refs.schemaAccordion.open = true;
|
||||
}
|
||||
|
||||
if (customizations.value.database) {
|
||||
try {
|
||||
const { status, response } = await Databases.getDatabases(props.connection.uid);
|
||||
if (status === 'success') {
|
||||
databases.value = response;
|
||||
if (selectedDatabase.value === '') {
|
||||
selectedDatabase.value = response[0];
|
||||
setDatabase(selectedDatabase.value);
|
||||
}
|
||||
}
|
||||
else
|
||||
addNotification({ status: 'error', message: response });
|
||||
}
|
||||
catch (err) {
|
||||
addNotification({ status: 'error', message: err.stack });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const refresh = async () => {
|
||||
@@ -254,8 +295,11 @@ const refresh = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const explorebarSearch = () => {
|
||||
searchInput.value.focus();
|
||||
const explorebarSearch = (event: KeyboardEvent) => {
|
||||
const isLetter = (event.key >= 'a' && event.key <= 'z');
|
||||
const isNumber = (event.key >= '0' && event.key <= '9');
|
||||
if (isLetter || isNumber)
|
||||
searchInput.value.focus();
|
||||
};
|
||||
|
||||
const resize = (e: MouseEvent) => {
|
||||
@@ -497,13 +541,31 @@ const toggleSearchMethod = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.workspace-explorebar-database-switch {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
z-index: 20;
|
||||
margin-right: 5px;
|
||||
margin-left: -4px;
|
||||
margin-top: -3px;
|
||||
margin-bottom: -0.5rem;
|
||||
height: 24px;
|
||||
|
||||
.form-select.select-sm {
|
||||
font-size: 0.6rem;
|
||||
height: 1.2rem;
|
||||
line-height: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.workspace-explorebar-search {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.6rem;
|
||||
height: 28px;
|
||||
margin: 5px 0;
|
||||
margin: 0 0 5px 0;
|
||||
z-index: 10;
|
||||
|
||||
.has-icon-right {
|
||||
@@ -533,7 +595,7 @@ const toggleSearchMethod = () => {
|
||||
|
||||
.workspace-explorebar-body {
|
||||
width: 100%;
|
||||
height: calc((100vh - 68px) - #{$excluding-size});
|
||||
height: calc((100vh - 63px) - #{$excluding-size});
|
||||
overflow: overlay;
|
||||
padding: 0 0.1rem;
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
class="context-element"
|
||||
@click="runElementCheck"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('word.run') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('general.run') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedMisc.type === 'trigger' && customizations.triggerEnableDisable"
|
||||
@@ -16,10 +16,10 @@
|
||||
@click="toggleTrigger"
|
||||
>
|
||||
<span v-if="!selectedMisc.enabled" class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('word.enable') }}
|
||||
<i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('general.enable') }}
|
||||
</span>
|
||||
<span v-else class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-pause text-light pr-1" /> {{ t('word.disable') }}
|
||||
<i class="mdi mdi-18px mdi-pause text-light pr-1" /> {{ t('general.disable') }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -28,14 +28,14 @@
|
||||
@click="toggleScheduler"
|
||||
>
|
||||
<span v-if="!selectedMisc.enabled" class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('word.enable') }}
|
||||
<i class="mdi mdi-18px mdi-play text-light pr-1" /> {{ t('general.enable') }}
|
||||
</span>
|
||||
<span v-else class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-pause text-light pr-1" /> {{ t('word.disable') }}
|
||||
<i class="mdi mdi-18px mdi-pause text-light pr-1" /> {{ 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('word.delete') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-remove text-light pr-1" /> {{ t('general.delete') }}</span>
|
||||
</div>
|
||||
<ConfirmModal
|
||||
v-if="isDeleteModal"
|
||||
@@ -50,7 +50,7 @@
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.deleteCorfirm') }} "<b>{{ selectedMisc.name }}</b>"?
|
||||
{{ t('general.deleteConfirm') }} "<b>{{ selectedMisc.name }}</b>"?
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
@@ -117,14 +117,14 @@ const customizations = computed(() => {
|
||||
const deleteMessage = computed(() => {
|
||||
switch (props.selectedMisc.type) {
|
||||
case 'trigger':
|
||||
return t('message.deleteTrigger');
|
||||
return t('database.deleteTrigger');
|
||||
case 'procedure':
|
||||
return t('message.deleteRoutine');
|
||||
return t('database.deleteRoutine');
|
||||
case 'function':
|
||||
case 'triggerFunction':
|
||||
return t('message.deleteFunction');
|
||||
return t('database.deleteFunction');
|
||||
case 'scheduler':
|
||||
return t('message.deleteScheduler');
|
||||
return t('database.deleteScheduler');
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
@@ -8,35 +8,35 @@
|
||||
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('message.createNewTrigger') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ 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('message.createNewRoutine') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle text-light pr-1" /> {{ 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('message.createNewFunction') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box text-light pr-1" /> {{ 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('message.createNewFunction') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-cog-clockwise text-light pr-1" /> {{ 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('message.createNewScheduler') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ t('database.createNewScheduler') }}</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
|
@@ -60,7 +60,7 @@
|
||||
@contextmenu.prevent="showMiscFolderContext($event, 'trigger')"
|
||||
>
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-cog mr-1" />
|
||||
{{ t('word.trigger', 2) }}
|
||||
{{ t('database.trigger', 2) }}
|
||||
</summary>
|
||||
<div class="accordion-body">
|
||||
<div>
|
||||
@@ -82,7 +82,7 @@
|
||||
<div
|
||||
v-if="trigger.enabled === false"
|
||||
class="tooltip tooltip-left disabled-indicator"
|
||||
:data-tooltip="t('word.disabled')"
|
||||
:data-tooltip="t('general.disabled')"
|
||||
>
|
||||
<i class="table-icon mdi mdi-pause mdi-18px mr-1" />
|
||||
</div>
|
||||
@@ -101,7 +101,7 @@
|
||||
@contextmenu.prevent="showMiscFolderContext($event, 'routine')"
|
||||
>
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-sync mr-1" />
|
||||
{{ t('word.storedRoutine', 2) }}
|
||||
{{ t('database.storedRoutine', 2) }}
|
||||
</summary>
|
||||
<div class="accordion-body">
|
||||
<div>
|
||||
@@ -134,7 +134,7 @@
|
||||
@contextmenu.prevent="showMiscFolderContext($event, 'triggerFunction')"
|
||||
>
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-refresh mr-1" />
|
||||
{{ t('word.triggerFunction', 2) }}
|
||||
{{ t('database.triggerFunction', 2) }}
|
||||
</summary>
|
||||
<div class="accordion-body">
|
||||
<div>
|
||||
@@ -167,7 +167,7 @@
|
||||
@contextmenu.prevent="showMiscFolderContext($event, 'function')"
|
||||
>
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-move mr-1" />
|
||||
{{ t('word.function', 2) }}
|
||||
{{ t('database.function', 2) }}
|
||||
</summary>
|
||||
<div class="accordion-body">
|
||||
<div>
|
||||
@@ -200,7 +200,7 @@
|
||||
@contextmenu.prevent="showMiscFolderContext($event, 'scheduler')"
|
||||
>
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-clock mr-1" />
|
||||
{{ t('word.scheduler', 2) }}
|
||||
{{ t('database.scheduler', 2) }}
|
||||
</summary>
|
||||
<div class="accordion-body">
|
||||
<div>
|
||||
@@ -222,7 +222,7 @@
|
||||
<div
|
||||
v-if="scheduler.enabled === false"
|
||||
class="tooltip tooltip-left disabled-indicator"
|
||||
:data-tooltip="t('word.disabled')"
|
||||
:data-tooltip="t('general.disabled')"
|
||||
>
|
||||
<i class="table-icon mdi mdi-pause mdi-18px mr-1" />
|
||||
</div>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
@close-context="closeContext"
|
||||
>
|
||||
<div class="context-element">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-plus text-light pr-1" /> {{ t('word.add') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-plus text-light pr-1" /> {{ t('general.add') }}</span>
|
||||
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
|
||||
<div class="context-submenu">
|
||||
<div
|
||||
@@ -12,49 +12,49 @@
|
||||
class="context-element"
|
||||
@click="openCreateTableTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table text-light pr-1" /> {{ t('word.table') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table text-light pr-1" /> {{ t('database.table') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.viewAdd"
|
||||
class="context-element"
|
||||
@click="openCreateViewTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-eye text-light pr-1" /> {{ t('word.view') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-eye text-light pr-1" /> {{ t('database.view') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.triggerAdd"
|
||||
class="context-element"
|
||||
@click="openCreateTriggerTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ t('word.trigger', 1) }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ t('database.trigger', 1) }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.routineAdd"
|
||||
class="context-element"
|
||||
@click="openCreateRoutineTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle pr-1" /> {{ t('word.storedRoutine', 1) }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle pr-1" /> {{ t('database.storedRoutine', 1) }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.functionAdd"
|
||||
class="context-element"
|
||||
@click="openCreateFunctionTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box pr-1" /> {{ t('word.function', 1) }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box pr-1" /> {{ t('database.function', 1) }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.triggerFunctionAdd"
|
||||
class="context-element"
|
||||
@click="openCreateTriggerFunctionTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-cog-clockwise pr-1" /> {{ t('word.triggerFunction', 1) }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-cog-clockwise pr-1" /> {{ t('database.triggerFunction', 1) }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.schedulerAdd"
|
||||
class="context-element"
|
||||
@click="openCreateSchedulerTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ t('word.scheduler', 1) }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ t('database.scheduler', 1) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -63,28 +63,28 @@
|
||||
class="context-element"
|
||||
@click="showExportSchemaModal"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-export text-light pr-1" /> {{ t('word.export') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-export text-light pr-1" /> {{ t('database.export') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.schemaImport"
|
||||
class="context-element"
|
||||
@click="initImport"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-import text-light pr-1" /> {{ t('word.import') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-import text-light pr-1" /> {{ t('database.import') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.schemaEdit"
|
||||
class="context-element"
|
||||
@click="showEditModal"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-edit text-light pr-1" /> {{ t('word.edit') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-edit text-light pr-1" /> {{ t('database.editSchema') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="workspace.customizations.schemaDrop"
|
||||
class="context-element"
|
||||
@click="showDeleteModal"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-remove text-light pr-1" /> {{ t('word.delete') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-database-remove text-light pr-1" /> {{ t('database.deleteSchema') }}</span>
|
||||
</div>
|
||||
|
||||
<ConfirmModal
|
||||
@@ -95,12 +95,12 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-database-remove mr-1" />
|
||||
<span class="cut-text">{{ t('message.deleteSchema') }}</span>
|
||||
<span class="cut-text">{{ t('database.deleteSchema') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.deleteCorfirm') }} "<b>{{ selectedSchema }}</b>"?
|
||||
{{ t('general.deleteConfirm') }} "<b>{{ selectedSchema }}</b>"?
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
@@ -109,11 +109,6 @@
|
||||
:selected-schema="selectedSchema"
|
||||
@close="hideEditModal"
|
||||
/>
|
||||
<ModalExportSchema
|
||||
v-if="isExportSchemaModal"
|
||||
:selected-schema="selectedSchema"
|
||||
@close="hideExportSchemaModal"
|
||||
/>
|
||||
<ModalImportSchema
|
||||
v-if="isImportSchemaModal"
|
||||
ref="importModalRef"
|
||||
@@ -128,10 +123,10 @@ import { Component, computed, nextTick, Ref, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { useSchemaExportStore } from '@/stores/schemaExport';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import ModalEditSchema from '@/components/ModalEditSchema.vue';
|
||||
import ModalExportSchema from '@/components/ModalExportSchema.vue';
|
||||
import ModalImportSchema from '@/components/ModalImportSchema.vue';
|
||||
import Schema from '@/ipc-api/Schema';
|
||||
import Application from '@/ipc-api/Application';
|
||||
@@ -158,6 +153,8 @@ const emit = defineEmits([
|
||||
|
||||
const { addNotification } = useNotificationsStore();
|
||||
const workspacesStore = useWorkspacesStore();
|
||||
const schemaExportStore = useSchemaExportStore();
|
||||
const { showExportModal } = schemaExportStore;
|
||||
|
||||
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
||||
|
||||
@@ -169,7 +166,6 @@ const {
|
||||
const importModalRef: Ref<Component & {startImport: (file: string) => void}> = ref(null);
|
||||
const isDeleteModal = ref(false);
|
||||
const isEditModal = ref(false);
|
||||
const isExportSchemaModal = ref(false);
|
||||
const isImportSchemaModal = ref(false);
|
||||
|
||||
const workspace = computed(() => getWorkspace(selectedWorkspace.value));
|
||||
@@ -220,11 +216,7 @@ const hideEditModal = () => {
|
||||
};
|
||||
|
||||
const showExportSchemaModal = () => {
|
||||
isExportSchemaModal.value = true;
|
||||
};
|
||||
|
||||
const hideExportSchemaModal = () => {
|
||||
isExportSchemaModal.value = false;
|
||||
showExportModal(props.selectedSchema);
|
||||
closeContext();
|
||||
};
|
||||
|
||||
|
@@ -8,31 +8,38 @@
|
||||
class="context-element"
|
||||
@click="openTableSettingTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-tune-vertical-variant text-light pr-1" /> {{ t('word.settings') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-wrench-cog text-light pr-1" /> {{ t('application.settings') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedTable && selectedTable.type === 'table' && customizations.schemaExport"
|
||||
class="context-element"
|
||||
@click="showTableExportModal"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-arrow-right text-light pr-1" /> {{ t('database.exportTable') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedTable && selectedTable.type === 'view' && customizations.viewSettings"
|
||||
class="context-element"
|
||||
@click="openViewSettingTab"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-tune-vertical-variant text-light pr-1" /> {{ t('word.settings') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-wrench-cog text-light pr-1" /> {{ t('application.settings') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedTable && selectedTable.type === 'table' && customizations.tableDuplicate"
|
||||
class="context-element"
|
||||
@click="duplicateTable"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-multiple text-light pr-1" /> {{ t('message.duplicateTable') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-multiple text-light pr-1" /> {{ t('database.duplicateTable') }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="selectedTable && selectedTable.type === 'table'"
|
||||
class="context-element"
|
||||
@click="showEmptyModal"
|
||||
>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-off text-light pr-1" /> {{ t('message.emptyTable') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-off text-light pr-1" /> {{ t('database.emptyTable') }}</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('word.delete') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-remove text-light pr-1" /> {{ t('database.deleteTable') }}</span>
|
||||
</div>
|
||||
|
||||
<ConfirmModal
|
||||
@@ -42,16 +49,16 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-table-off mr-1" /> <span class="cut-text">{{ t('message.emptyTable') }}</span>
|
||||
<i class="mdi mdi-24px mdi-table-off mr-1" /> <span class="cut-text">{{ t('database.emptyTable') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.emptyCorfirm') }} "<b>{{ selectedTable.name }}</b>"?
|
||||
{{ t('database.emptyConfirm') }} "<b>{{ selectedTable.name }}</b>"?
|
||||
</div>
|
||||
<div v-if="customizations.tableTruncateDisableFKCheck">
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="forceTruncate" type="checkbox"><i class="form-icon" /> {{ t('message.disableFKChecks') }}
|
||||
<input v-model="forceTruncate" type="checkbox"><i class="form-icon" /> {{ t('database.disableFKChecks') }}
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
@@ -64,12 +71,12 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-table-remove mr-1" />
|
||||
<span class="cut-text">{{ selectedTable.type === 'table' ? t('message.deleteTable') : t('message.deleteView') }}</span>
|
||||
<span class="cut-text">{{ selectedTable.type === 'table' ? t('database.deleteTable') : t('database.deleteView') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.deleteCorfirm') }} "<b>{{ selectedTable.name }}</b>"?
|
||||
{{ t('general.deleteConfirm') }} "<b>{{ selectedTable.name }}</b>"?
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
@@ -81,6 +88,7 @@ import { computed, ref } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useNotificationsStore } from '@/stores/notifications';
|
||||
import { useWorkspacesStore } from '@/stores/workspaces';
|
||||
import { useSchemaExportStore } from '@/stores/schemaExport';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
@@ -98,6 +106,7 @@ const emit = defineEmits(['close-context', 'duplicate-table', 'reload', 'delete-
|
||||
|
||||
const { addNotification } = useNotificationsStore();
|
||||
const workspacesStore = useWorkspacesStore();
|
||||
const { showExportModal } = useSchemaExportStore();
|
||||
|
||||
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
||||
|
||||
@@ -116,6 +125,11 @@ const forceTruncate = ref(false);
|
||||
const workspace = computed(() => getWorkspace(selectedWorkspace.value));
|
||||
const customizations = computed(() => workspace.value && workspace.value.customizations ? workspace.value.customizations : null);
|
||||
|
||||
const showTableExportModal = () => {
|
||||
showExportModal(props.selectedSchema, props.selectedTable.name);
|
||||
closeContext();
|
||||
};
|
||||
|
||||
const showDeleteModal = () => {
|
||||
isDeleteModal.value = true;
|
||||
};
|
||||
|
@@ -13,7 +13,7 @@
|
||||
:style="{height: localHeight ? localHeight+'px' : ''}"
|
||||
>
|
||||
<div class="query-console-header">
|
||||
<div>{{ t('word.console') }}</div>
|
||||
<div>{{ t('application.console') }}</div>
|
||||
<button class="btn btn-clear mr-1" @click="resizeConsole(0)" />
|
||||
</div>
|
||||
<div ref="queryConsoleBody" class="query-console-body">
|
||||
@@ -35,7 +35,7 @@
|
||||
@close-context="isContext = false"
|
||||
>
|
||||
<div class="context-element" @click="copyQuery">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-copy text-light pr-1" /> {{ t('word.copy') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-copy text-light pr-1" /> {{ t('general.copy') }}</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
|
@@ -10,27 +10,27 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
|
||||
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
||||
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||
<span>{{ t('word.parameters') }}</span>
|
||||
<span>{{ t('database.parameters') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,7 +41,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
@@ -54,7 +54,7 @@
|
||||
<div v-if="customizations.languages" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.language') }}
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.language"
|
||||
@@ -66,11 +66,11 @@
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.definer') }}
|
||||
{{ t('database.definer') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.definer"
|
||||
:options="[{value: '', name:t('message.currentUser')}, ...workspace.users]"
|
||||
:options="[{value: '', name:t('database.currentUser')}, ...workspace.users]"
|
||||
:option-label="(user: any) => user.value === '' ? user.name : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
@@ -80,7 +80,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.returns') }}
|
||||
{{ t('database.returns') }}
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<BaseSelect
|
||||
@@ -100,7 +100,7 @@
|
||||
class="form-input"
|
||||
type="number"
|
||||
min="0"
|
||||
:placeholder="t('word.length')"
|
||||
:placeholder="t('database.length')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -108,7 +108,7 @@
|
||||
<div v-if="customizations.comment" class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.comment') }}
|
||||
{{ t('database.comment') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="localFunction.comment"
|
||||
@@ -120,7 +120,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.sqlSecurity') }}
|
||||
{{ t('database.sqlSecurity') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.security"
|
||||
@@ -132,7 +132,7 @@
|
||||
<div v-if="customizations.functionDataAccess" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.dataAccess') }}
|
||||
{{ t('database.dataAccess') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.dataAccess"
|
||||
@@ -145,7 +145,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label d-invisible">.</label>
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localFunction.deterministic" type="checkbox"><i class="form-icon" /> {{ t('word.deterministic') }}
|
||||
<input v-model="localFunction.deterministic" type="checkbox"><i class="form-icon" /> {{ t('database.deterministic') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,7 +153,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.functionBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.functionBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,27 +10,27 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
|
||||
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
||||
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||
<span>{{ t('word.parameters') }}</span>
|
||||
<span>{{ t('database.parameters') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,7 +41,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
@@ -54,7 +54,7 @@
|
||||
<div v-if="customizations.languages" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.language') }}
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.language"
|
||||
@@ -66,11 +66,11 @@
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.definer') }}
|
||||
{{ t('database.definer') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.definer"
|
||||
:options="[{value: '', name:t('message.currentUser')}, ...workspace.users]"
|
||||
:options="[{value: '', name:t('database.currentUser')}, ...workspace.users]"
|
||||
:option-label="(user: any) => user.value === '' ? user.name : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
@@ -80,7 +80,7 @@
|
||||
<div v-if="customizations.comment" class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.comment') }}
|
||||
{{ t('database.comment') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="localRoutine.comment"
|
||||
@@ -92,7 +92,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.sqlSecurity') }}
|
||||
{{ t('database.sqlSecurity') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.security"
|
||||
@@ -104,7 +104,7 @@
|
||||
<div v-if="customizations.procedureDataAccess" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.dataAccess') }}
|
||||
{{ t('database.dataAccess') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.dataAccess"
|
||||
@@ -117,7 +117,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label d-invisible">.</label>
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localRoutine.deterministic" type="checkbox"><i class="form-icon" /> {{ t('word.deterministic') }}
|
||||
<input v-model="localRoutine.deterministic" type="checkbox"><i class="form-icon" /> {{ t('database.deterministic') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -125,7 +125,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.routineBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.routineBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,26 +10,26 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
<button class="btn btn-dark btn-sm" @click="showTimingModal">
|
||||
<i class="mdi mdi-24px mdi-timer mr-1" />
|
||||
<span>{{ t('word.timing') }}</span>
|
||||
<span>{{ t('database.timing') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
<div class="columns">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="localScheduler.name"
|
||||
@@ -50,11 +50,11 @@
|
||||
</div>
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.definer') }}</label>
|
||||
<label class="form-label">{{ t('database.definer') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localScheduler.definer"
|
||||
:options="users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -62,7 +62,7 @@
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.comment') }}</label>
|
||||
<label class="form-label">{{ t('database.comment') }}</label>
|
||||
<input
|
||||
v-model="localScheduler.comment"
|
||||
class="form-input"
|
||||
@@ -72,7 +72,7 @@
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label mr-2">{{ t('word.state') }}</label>
|
||||
<label class="form-label mr-2">{{ t('database.state') }}</label>
|
||||
<label class="form-radio form-inline">
|
||||
<input
|
||||
v-model="localScheduler.state"
|
||||
@@ -103,7 +103,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.schedulerBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.schedulerBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,16 +10,16 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged || isSaving"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
@@ -27,32 +27,33 @@
|
||||
<button
|
||||
:disabled="isSaving"
|
||||
class="btn btn-dark btn-sm"
|
||||
:title="t('message.addNewField')"
|
||||
:title="t('database.addNewField')"
|
||||
@click="addField"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-playlist-plus mr-1" />
|
||||
<span>{{ t('word.add') }}</span>
|
||||
<span>{{ t('general.add') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="isSaving || !localFields.length"
|
||||
class="btn btn-dark btn-sm"
|
||||
:title="t('message.manageIndexes')"
|
||||
:title="t('database.manageIndexes')"
|
||||
@click="showIntdexesModal"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-key mdi-rotate-45 mr-1" />
|
||||
<span>{{ t('word.indexes') }}</span>
|
||||
<span>{{ t('database.indexes') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm"
|
||||
:disabled="isSaving || !localFields.length"
|
||||
:title="t('database.manageForeignKeys')"
|
||||
@click="showForeignModal"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-key-link mr-1" />
|
||||
<span>{{ t('word.foreignKeys') }}</span>
|
||||
<span>{{ t('database.foreignKeys') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,7 +63,7 @@
|
||||
<div class="columns mb-4">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="localOptions.name"
|
||||
@@ -73,7 +74,7 @@
|
||||
</div>
|
||||
<div v-if="workspace.customizations.comment" class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.comment') }}</label>
|
||||
<label class="form-label">{{ t('database.comment') }}</label>
|
||||
<input
|
||||
v-model="localOptions.comment"
|
||||
class="form-input"
|
||||
@@ -85,7 +86,7 @@
|
||||
<div v-if="workspace.customizations.collations" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.collation') }}
|
||||
{{ t('database.collation') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localOptions.collation"
|
||||
@@ -100,7 +101,7 @@
|
||||
<div v-if="workspace.customizations.engines" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.engine') }}
|
||||
{{ t('database.engine') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localOptions.engine"
|
||||
@@ -315,7 +316,7 @@ const addField = () => {
|
||||
const uid = uidGen();
|
||||
localFields.value.push({
|
||||
_antares_id: uid,
|
||||
name: `${t('word.field', 1)}_${uid.substring(0, 4)}`,
|
||||
name: `${t('database.field', 1)}_${uid.substring(0, 4)}`,
|
||||
key: '',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type: (workspace.value.dataTypes[0] as any).types[0].name,
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="column col-12 empty">
|
||||
<p class="h6 empty-subtitle">
|
||||
{{ t('message.thereAreNoTableFields') }}
|
||||
{{ t('database.thereAreNoTableFields') }}
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<button class="btn btn-gray d-flex" @click="emit('new-field')">
|
||||
<i class="mdi mdi-24px mdi-playlist-plus mr-2" />
|
||||
{{ t('message.addNewField') }}
|
||||
{{ t('database.addNewField') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -10,20 +10,20 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="columns">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="localTrigger.name"
|
||||
@@ -44,11 +44,11 @@
|
||||
</div>
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.definer') }}</label>
|
||||
<label class="form-label">{{ t('database.definer') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localTrigger.definer"
|
||||
:options="users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -57,7 +57,7 @@
|
||||
<fieldset class="column columns mb-0" :disabled="customizations.triggerOnlyRename">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.table') }}</label>
|
||||
<label class="form-label">{{ t('database.table') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localTrigger.table"
|
||||
:options="schemaTables"
|
||||
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.event') }}</label>
|
||||
<label class="form-label">{{ t('database.event') }}</label>
|
||||
<div class="input-group">
|
||||
<BaseSelect
|
||||
v-model="localTrigger.activation"
|
||||
@@ -100,7 +100,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.triggerStatement') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.triggerStatement') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,16 +10,16 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,7 +29,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
@@ -42,7 +42,7 @@
|
||||
<div v-if="customizations.triggerFunctionlanguages" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.language') }}
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.language"
|
||||
@@ -54,12 +54,12 @@
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.definer') }}
|
||||
{{ t('database.definer') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.definer"
|
||||
:options="workspace.users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -67,7 +67,7 @@
|
||||
</div>
|
||||
<div v-if="customizations.comment" class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.comment') }}
|
||||
{{ t('database.comment') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="localFunction.comment"
|
||||
@@ -79,7 +79,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.functionBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.functionBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,20 +10,20 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="columns">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
v-model="localView.name"
|
||||
@@ -44,11 +44,11 @@
|
||||
</div>
|
||||
<div class="column col-auto">
|
||||
<div v-if="workspace.customizations.definer" class="form-group">
|
||||
<label class="form-label">{{ t('word.definer') }}</label>
|
||||
<label class="form-label">{{ t('database.definer') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.definer"
|
||||
:options="users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<div class="column col-auto mr-2">
|
||||
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
|
||||
<label class="form-label">{{ t('message.sqlSecurity') }}</label>
|
||||
<label class="form-label">{{ t('database.sqlSecurity') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.security"
|
||||
:options="['DEFINER', 'INVOKER']"
|
||||
@@ -66,7 +66,7 @@
|
||||
</div>
|
||||
<div class="column col-auto mr-2">
|
||||
<div v-if="workspace.customizations.viewAlgorithm" class="form-group">
|
||||
<label class="form-label">{{ t('word.algorithm') }}</label>
|
||||
<label class="form-label">{{ t('database.algorithm') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.algorithm"
|
||||
:options="['UNDEFINED', 'MERGE', 'TEMPTABLE']"
|
||||
@@ -76,7 +76,7 @@
|
||||
</div>
|
||||
<div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('message.updateOption') }}</label>
|
||||
<label class="form-label">{{ t('database.updateOption') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.updateOption"
|
||||
:option-track-by="(user: any) => user.value"
|
||||
@@ -89,7 +89,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.selectStatement') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.selectStatement') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,16 +10,16 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
@@ -30,15 +30,15 @@
|
||||
@click="runFunctionCheck"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-play mr-1" />
|
||||
<span>{{ t('word.run') }}</span>
|
||||
<span>{{ t('general.run') }}</span>
|
||||
</button>
|
||||
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
||||
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||
<span>{{ t('word.parameters') }}</span>
|
||||
<span>{{ t('database.parameters') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
@@ -63,7 +63,7 @@
|
||||
<div v-if="customizations.languages" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.language') }}
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.language"
|
||||
@@ -75,11 +75,11 @@
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.definer') }}
|
||||
{{ t('database.definer') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.definer"
|
||||
:options="[{value: '', name:t('message.currentUser')}, ...workspace.users]"
|
||||
:options="[{value: '', name:t('database.currentUser')}, ...workspace.users]"
|
||||
:option-label="(user: any) => user.value === '' ? user.name : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
@@ -89,7 +89,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.returns') }}
|
||||
{{ t('database.returns') }}
|
||||
</label>
|
||||
<div class="input-group">
|
||||
<BaseSelect
|
||||
@@ -109,7 +109,7 @@
|
||||
class="form-input"
|
||||
type="number"
|
||||
min="0"
|
||||
:placeholder="t('word.length')"
|
||||
:placeholder="t('database.length')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
@@ -117,7 +117,7 @@
|
||||
<div v-if="customizations.comment" class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.comment') }}
|
||||
{{ t('database.comment') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="localFunction.comment"
|
||||
@@ -129,7 +129,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.sqlSecurity') }}
|
||||
{{ t('database.sqlSecurity') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.security"
|
||||
@@ -141,7 +141,7 @@
|
||||
<div v-if="customizations.functionDataAccess" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.dataAccess') }}
|
||||
{{ t('database.dataAccess') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.dataAccess"
|
||||
@@ -154,7 +154,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label d-invisible">.</label>
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localFunction.deterministic" type="checkbox"><i class="form-icon" /> {{ t('word.deterministic') }}
|
||||
<input v-model="localFunction.deterministic" type="checkbox"><i class="form-icon" /> {{ t('database.deterministic') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,7 +162,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.functionBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.functionBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.confirm')"
|
||||
:confirm-text="t('general.confirm')"
|
||||
size="medium"
|
||||
class="options-modal"
|
||||
@confirm="confirmParametersChange"
|
||||
@@ -9,7 +9,7 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||
<span class="cut-text">{{ t('word.parameters') }} "{{ func }}"</span>
|
||||
<span class="cut-text">{{ t('database.parameters') }} "{{ func }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -20,16 +20,16 @@
|
||||
<div class="d-flex">
|
||||
<button class="btn btn-dark btn-sm d-flex" @click="addParameter">
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" />
|
||||
<span>{{ t('word.add') }}</span>
|
||||
<span>{{ t('general.add') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
:disabled="!isChanged"
|
||||
@click.prevent="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
<div class="tile-action">
|
||||
<button
|
||||
class="btn btn-link remove-field p-0 mr-2"
|
||||
:title="t('word.delete')"
|
||||
:title="t('general.delete')"
|
||||
@click.prevent="removeParameter(param._antares_id)"
|
||||
>
|
||||
<i class="mdi mdi-close" />
|
||||
@@ -74,7 +74,7 @@
|
||||
>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -86,7 +86,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.type') }}
|
||||
{{ t('database.type') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<BaseSelect
|
||||
@@ -102,7 +102,7 @@
|
||||
</div>
|
||||
<div v-if="customizations.parametersLength" class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.length') }}
|
||||
{{ t('database.length') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -115,7 +115,7 @@
|
||||
</div>
|
||||
<div v-if="customizations.functionContext" class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.context') }}
|
||||
{{ t('database.context') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<label class="form-radio">
|
||||
@@ -150,11 +150,11 @@
|
||||
<i class="mdi mdi-dots-horizontal mdi-48px" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ t('message.thereAreNoParameters') }}
|
||||
{{ t('database.thereAreNoParameters') }}
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<button class="btn btn-primary" @click="addParameter">
|
||||
{{ t('message.createNewParameter') }}
|
||||
{{ t('database.createNewParameter') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -10,16 +10,16 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
@@ -30,15 +30,15 @@
|
||||
@click="runRoutineCheck"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-play mr-1" />
|
||||
<span>{{ t('word.run') }}</span>
|
||||
<span>{{ t('general.run') }}</span>
|
||||
</button>
|
||||
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
||||
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||
<span>{{ t('word.parameters') }}</span>
|
||||
<span>{{ t('database.parameters') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
@@ -63,7 +63,7 @@
|
||||
<div v-if="customizations.languages" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.language') }}
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.language"
|
||||
@@ -75,11 +75,11 @@
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.definer') }}
|
||||
{{ t('database.definer') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.definer"
|
||||
:options="[{value: '', name: t('message.currentUser')}, ...workspace.users]"
|
||||
:options="[{value: '', name: t('database.currentUser')}, ...workspace.users]"
|
||||
:option-label="(user: any) => user.value === '' ? user.name : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
@@ -89,7 +89,7 @@
|
||||
<div v-if="customizations.comment" class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.comment') }}
|
||||
{{ t('database.comment') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="localRoutine.comment"
|
||||
@@ -101,7 +101,7 @@
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.sqlSecurity') }}
|
||||
{{ t('database.sqlSecurity') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.security"
|
||||
@@ -113,7 +113,7 @@
|
||||
<div v-if="customizations.procedureDataAccess" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('message.dataAccess') }}
|
||||
{{ t('database.dataAccess') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localRoutine.dataAccess"
|
||||
@@ -126,7 +126,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label d-invisible">.</label>
|
||||
<label class="form-checkbox form-inline">
|
||||
<input v-model="localRoutine.deterministic" type="checkbox"><i class="form-icon" /> {{ t('word.deterministic') }}
|
||||
<input v-model="localRoutine.deterministic" type="checkbox"><i class="form-icon" /> {{ t('database.deterministic') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,7 +134,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.routineBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.routineBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.confirm')"
|
||||
:confirm-text="t('general.confirm')"
|
||||
size="medium"
|
||||
class="options-modal"
|
||||
@confirm="confirmParametersChange"
|
||||
@@ -9,7 +9,7 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||
<span class="cut-text">{{ t('word.parameters') }} "{{ routine }}"</span>
|
||||
<span class="cut-text">{{ t('database.parameters') }} "{{ routine }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -20,16 +20,16 @@
|
||||
<div class="d-flex">
|
||||
<button class="btn btn-dark btn-sm d-flex" @click="addParameter">
|
||||
<i class="mdi mdi-24px mdi-plus mr-1" />
|
||||
<span>{{ t('word.add') }}</span>
|
||||
<span>{{ t('general.add') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
:disabled="!isChanged"
|
||||
@click.prevent="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
<div class="tile-action">
|
||||
<button
|
||||
class="btn btn-link remove-field p-0 mr-2"
|
||||
:title="t('word.delete')"
|
||||
:title="t('general.delete')"
|
||||
@click.prevent="removeParameter(param._antares_id)"
|
||||
>
|
||||
<i class="mdi mdi-close" />
|
||||
@@ -74,7 +74,7 @@
|
||||
>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -86,7 +86,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.type') }}
|
||||
{{ t('database.type') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<BaseSelect
|
||||
@@ -102,7 +102,7 @@
|
||||
</div>
|
||||
<div v-if="customizations.parametersLength" class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.length') }}
|
||||
{{ t('database.length') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -115,7 +115,7 @@
|
||||
</div>
|
||||
<div v-if="customizations.procedureContext" class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.context') }}
|
||||
{{ t('database.context') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<label
|
||||
@@ -138,11 +138,11 @@
|
||||
<i class="mdi mdi-dots-horizontal mdi-48px" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ t('message.thereAreNoParameters') }}
|
||||
{{ t('database.thereAreNoParameters') }}
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<button class="btn btn-primary" @click="addParameter">
|
||||
{{ t('message.createNewParameter') }}
|
||||
{{ t('database.createNewParameter') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -10,26 +10,26 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
<button class="btn btn-dark btn-sm" @click="showTimingModal">
|
||||
<i class="mdi mdi-24px mdi-timer mr-1" />
|
||||
<span>{{ t('word.timing') }}</span>
|
||||
<span>{{ t('database.timing') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
<div class="columns">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
v-model="localScheduler.name"
|
||||
class="form-input"
|
||||
@@ -49,11 +49,11 @@
|
||||
</div>
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.definer') }}</label>
|
||||
<label class="form-label">{{ t('database.definer') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localScheduler.definer"
|
||||
:options="users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -61,7 +61,7 @@
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.comment') }}</label>
|
||||
<label class="form-label">{{ t('database.comment') }}</label>
|
||||
<input
|
||||
v-model="localScheduler.comment"
|
||||
class="form-input"
|
||||
@@ -71,7 +71,7 @@
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label mr-2">{{ t('word.state') }}</label>
|
||||
<label class="form-label mr-2">{{ t('database.state') }}</label>
|
||||
<label class="form-radio form-inline">
|
||||
<input
|
||||
v-model="localScheduler.state"
|
||||
@@ -102,7 +102,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.schedulerBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.schedulerBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.confirm')"
|
||||
:confirm-text="t('general.confirm')"
|
||||
size="400"
|
||||
:disable-autofocus="true"
|
||||
@confirm="confirmOptionsChange"
|
||||
@@ -9,14 +9,14 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-timer mr-1" />
|
||||
<span class="cut-text">{{ t('word.timing') }} "{{ localOptions.name }}"</span>
|
||||
<span class="cut-text">{{ t('database.timing') }} "{{ localOptions.name }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<label class="form-label col-4">
|
||||
{{ t('word.execution') }}
|
||||
{{ t('database.execution') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<BaseSelect
|
||||
@@ -62,7 +62,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-4">
|
||||
{{ t('word.starts') }}
|
||||
{{ t('database.starts') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<div class="input-group">
|
||||
@@ -83,7 +83,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-4">
|
||||
{{ t('word.ends') }}
|
||||
{{ t('database.ends') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<div class="input-group">
|
||||
@@ -125,7 +125,7 @@
|
||||
<div class="col-4" />
|
||||
<div class="column">
|
||||
<label class="form-checkbox form-inline mt-2">
|
||||
<input v-model="optionsProxy.preserve" type="checkbox"><i class="form-icon" /> {{ t('message.preserveOnCompletion') }}
|
||||
<input v-model="optionsProxy.preserve" type="checkbox"><i class="form-icon" /> {{ t('database.preserveOnCompletion') }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -10,16 +10,16 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged || isSaving"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
@@ -27,28 +27,29 @@
|
||||
<button
|
||||
:disabled="isSaving"
|
||||
class="btn btn-dark btn-sm"
|
||||
:title="t('message.addNewField')"
|
||||
:title="t('database.addNewField')"
|
||||
@click="addField"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-playlist-plus mr-1" />
|
||||
<span>{{ t('word.add') }}</span>
|
||||
<span>{{ t('general.add') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="isSaving"
|
||||
class="btn btn-dark btn-sm"
|
||||
:title="t('message.manageIndexes')"
|
||||
:title="t('database.manageIndexes')"
|
||||
@click="showIntdexesModal"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-key mdi-rotate-45 mr-1" />
|
||||
<span>{{ t('word.indexes') }}</span>
|
||||
<span>{{ t('database.indexes') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm mr-0"
|
||||
:disabled="isSaving"
|
||||
:title="t('database.manageIndexes')"
|
||||
@click="showForeignModal"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-key-link mr-1" />
|
||||
<span>{{ t('word.foreignKeys') }}</span>
|
||||
<span>{{ t('database.foreignKeys') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
@@ -60,11 +61,11 @@
|
||||
@click="showDdlModal"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-code-tags mr-1" />
|
||||
<span>{{ t('word.ddl') }}</span>
|
||||
<span>{{ t('database.ddl') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -74,7 +75,7 @@
|
||||
<div class="columns mb-4">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
v-model="localOptions.name"
|
||||
class="form-input"
|
||||
@@ -84,7 +85,7 @@
|
||||
</div>
|
||||
<div v-if="workspace.customizations.comment" class="column">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.comment') }}</label>
|
||||
<label class="form-label">{{ t('database.comment') }}</label>
|
||||
<input
|
||||
v-model="localOptions.comment"
|
||||
class="form-input"
|
||||
@@ -96,7 +97,7 @@
|
||||
<div v-if="workspace.customizations.autoIncrement" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.autoIncrement') }}
|
||||
{{ t('database.autoIncrement') }}
|
||||
</label>
|
||||
<input
|
||||
ref="firstInput"
|
||||
@@ -110,7 +111,7 @@
|
||||
<div v-if="workspace.customizations.collations" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.collation') }}
|
||||
{{ t('database.collation') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localOptions.collation"
|
||||
@@ -125,7 +126,7 @@
|
||||
<div v-if="workspace.customizations.engines" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.engine') }}
|
||||
{{ t('database.engine') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localOptions.engine"
|
||||
@@ -559,7 +560,7 @@ const addField = () => {
|
||||
const uid = uidGen();
|
||||
localFields.value.push({
|
||||
_antares_id: uid,
|
||||
name: `${t('word.field', 1)}_${uid.substring(0, 4)}`,
|
||||
name: `${t('database.field', 1)}_${uid.substring(0, 4)}`,
|
||||
key: '',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type: (workspace.value.dataTypes[0] as any).types[0].name,
|
||||
|
@@ -4,7 +4,7 @@
|
||||
@close-context="closeContext"
|
||||
>
|
||||
<div class="context-element">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-key-plus text-light pr-1" /> {{ t('message.createNewIndex') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-key-plus text-light pr-1" /> {{ t('database.createNewIndex') }}</span>
|
||||
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
|
||||
<div class="context-submenu">
|
||||
<div
|
||||
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="indexes.length" class="context-element">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-key-arrow-right text-light pr-1" /> {{ t('message.addToIndex') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-key-arrow-right text-light pr-1" /> {{ t('database.addToIndex') }}</span>
|
||||
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
|
||||
<div class="context-submenu">
|
||||
<div
|
||||
@@ -34,10 +34,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-element" @click="duplicateField">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ t('word.duplicate') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ t('general.duplicate') }}</span>
|
||||
</div>
|
||||
<div class="context-element" @click="deleteField">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ t('message.deleteField') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ t('database.deleteField') }}</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
|
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.confirm')"
|
||||
:confirm-text="t('general.confirm')"
|
||||
size="large"
|
||||
class="options-modal"
|
||||
:cancel-text="t('word.close')"
|
||||
:cancel-text="t('general.close')"
|
||||
:hide-footer="true"
|
||||
@hide="$emit('hide')"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-code-tags mr-1" />
|
||||
<span class="cut-text">{{ t('word.ddl') }} "{{ table }}"</span>
|
||||
<span class="cut-text">{{ t('database.ddl') }} "{{ table }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
|
@@ -21,81 +21,81 @@
|
||||
<div class="tr">
|
||||
<div class="th">
|
||||
<div class="text-right">
|
||||
{{ t('word.order') }}
|
||||
{{ t('database.order') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="th">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.key', 2) }}
|
||||
{{ t('database.key', 2) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="th">
|
||||
<div class="column-resizable min-100">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th">
|
||||
<div class="column-resizable min-100">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.type') }}
|
||||
{{ t('database.type') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizations.tableArray" class="th">
|
||||
<div class="column-resizable">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.array') }}
|
||||
{{ t('database.array') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th">
|
||||
<div class="column-resizable">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.length') }}
|
||||
{{ t('database.length') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizations.unsigned" class="th">
|
||||
<div class="column-resizable">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.unsigned') }}
|
||||
{{ t('database.unsigned') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizations.nullable" class="th">
|
||||
<div class="column-resizable">
|
||||
<div class="table-column-title">
|
||||
{{ t('message.allowNull') }}
|
||||
{{ t('database.allowNull') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizations.zerofill" class="th">
|
||||
<div class="column-resizable">
|
||||
<div class="table-column-title">
|
||||
{{ t('message.zeroFill') }}
|
||||
{{ t('database.zeroFill') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="th">
|
||||
<div class="column-resizable">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.default') }}
|
||||
{{ t('database.default') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizations.comment" class="th">
|
||||
<div class="column-resizable">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.comment') }}
|
||||
{{ t('database.comment') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizations.collation" class="th">
|
||||
<div class="column-resizable min-100">
|
||||
<div class="table-column-title">
|
||||
{{ t('word.collation') }}
|
||||
{{ t('database.collation') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.confirm')"
|
||||
:confirm-text="t('general.confirm')"
|
||||
size="medium"
|
||||
class="options-modal"
|
||||
@confirm="confirmForeignsChange"
|
||||
@@ -9,7 +9,7 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-key-link mr-1" />
|
||||
<span class="cut-text">{{ t('word.foreignKeys') }} "{{ table }}"</span>
|
||||
<span class="cut-text">{{ t('database.foreignKeys') }} "{{ table }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -20,16 +20,16 @@
|
||||
<div class="d-flex">
|
||||
<button class="btn btn-dark btn-sm d-flex" @click="addForeign">
|
||||
<i class="mdi mdi-24px mdi-link-plus mr-1" />
|
||||
<span>{{ t('word.add') }}</span>
|
||||
<span>{{ t('general.add') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
:disabled="!isChanged"
|
||||
@click.prevent="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="tile-action">
|
||||
<button
|
||||
class="btn btn-link remove-field p-0 mr-2"
|
||||
:title="t('word.delete')"
|
||||
:title="t('general.delete')"
|
||||
@click.prevent="removeIndex(foreign._antares_id)"
|
||||
>
|
||||
<i class="mdi mdi-close" />
|
||||
@@ -86,7 +86,7 @@
|
||||
>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -98,7 +98,7 @@
|
||||
</div>
|
||||
<div class="form-group mb-4">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.field', 1) }}
|
||||
{{ t('database.field', 1) }}
|
||||
</label>
|
||||
<div class="fields-list column pt-1">
|
||||
<label
|
||||
@@ -114,7 +114,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('message.referenceTable') }}
|
||||
{{ t('database.referenceTable') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<BaseSelect
|
||||
@@ -129,7 +129,7 @@
|
||||
</div>
|
||||
<div class="form-group mb-4">
|
||||
<label class="form-label col-3">
|
||||
{{ t('message.referenceField') }}
|
||||
{{ t('database.referenceField') }}
|
||||
</label>
|
||||
<div class="fields-list column pt-1">
|
||||
<label
|
||||
@@ -145,7 +145,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('message.onUpdate') }}
|
||||
{{ t('database.onUpdate') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<BaseSelect
|
||||
@@ -157,7 +157,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('message.onDelete') }}
|
||||
{{ t('database.onDelete') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<BaseSelect
|
||||
@@ -174,11 +174,11 @@
|
||||
<i class="mdi mdi-key-link mdi-48px" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ t('message.thereAreNoForeign') }}
|
||||
{{ t('database.thereAreNoForeign') }}
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<button class="btn btn-primary" @click="addForeign">
|
||||
{{ t('message.createNewForeign') }}
|
||||
{{ t('database.createNewForeign') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<ConfirmModal
|
||||
:confirm-text="t('word.confirm')"
|
||||
:confirm-text="t('general.confirm')"
|
||||
size="medium"
|
||||
class="options-modal"
|
||||
@confirm="confirmIndexesChange"
|
||||
@@ -9,7 +9,7 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-key mdi-rotate-45 mr-1" />
|
||||
<span class="cut-text">{{ t('word.indexes') }} "{{ table }}"</span>
|
||||
<span class="cut-text">{{ t('database.indexes') }} "{{ table }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -20,16 +20,16 @@
|
||||
<div class="d-flex">
|
||||
<button class="btn btn-dark btn-sm d-flex" @click="addIndex">
|
||||
<i class="mdi mdi-24px mdi-key-plus mr-1" />
|
||||
<span>{{ t('word.add') }}</span>
|
||||
<span>{{ t('general.add') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
:disabled="!isChanged"
|
||||
@click.prevent="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -50,12 +50,12 @@
|
||||
<div class="tile-title">
|
||||
{{ index.name }}
|
||||
</div>
|
||||
<small class="tile-subtitle text-gray">{{ index.type }} · {{ index.fields.length }} {{ t('word.field', index.fields.length) }}</small>
|
||||
<small class="tile-subtitle text-gray">{{ index.type }} · {{ index.fields.length }} {{ t('database.field', index.fields.length) }}</small>
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button
|
||||
class="btn btn-link remove-field p-0 mr-2"
|
||||
:title="t('word.delete')"
|
||||
:title="t('general.delete')"
|
||||
@click.prevent="removeIndex(index._antares_id)"
|
||||
>
|
||||
<i class="mdi mdi-close" />
|
||||
@@ -74,7 +74,7 @@
|
||||
>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.name') }}
|
||||
{{ t('general.name') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -86,7 +86,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.type') }}
|
||||
{{ t('database.type') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<BaseSelect
|
||||
@@ -99,7 +99,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label col-3">
|
||||
{{ t('word.field', fields.length) }}
|
||||
{{ t('database.field', fields.length) }}
|
||||
</label>
|
||||
<div class="fields-list column pt-1">
|
||||
<label
|
||||
@@ -119,11 +119,11 @@
|
||||
<i class="mdi mdi-key-outline mdi-48px" />
|
||||
</div>
|
||||
<p class="empty-title h5">
|
||||
{{ t('message.thereAreNoIndexes') }}
|
||||
{{ t('database.thereAreNoIndexes') }}
|
||||
</p>
|
||||
<div class="empty-action">
|
||||
<button class="btn btn-primary" @click="addIndex">
|
||||
{{ t('message.createNewIndex') }}
|
||||
{{ t('database.createNewIndex') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -220,7 +220,7 @@
|
||||
</div>
|
||||
<ConfirmModal
|
||||
v-if="isDefaultModal"
|
||||
:confirm-text="t('word.confirm')"
|
||||
:confirm-text="t('general.confirm')"
|
||||
size="400"
|
||||
@confirm="editOFF"
|
||||
@hide="hideDefaultModal"
|
||||
@@ -228,7 +228,7 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-playlist-edit mr-1" />
|
||||
<span class="cut-text">{{ t('word.default') }} "{{ row.name }}"</span>
|
||||
<span class="cut-text">{{ t('database.default') }} "{{ row.name }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -251,7 +251,7 @@
|
||||
value="custom"
|
||||
type="radio"
|
||||
name="default"
|
||||
><i class="form-icon" /> {{ t('message.customValue') }}
|
||||
><i class="form-icon" /> {{ t('database.customValue') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -292,7 +292,7 @@
|
||||
type="radio"
|
||||
name="default"
|
||||
value="expression"
|
||||
><i class="form-icon" /> {{ t('word.expression') }}
|
||||
><i class="form-icon" /> {{ t('database.expression') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
@@ -307,7 +307,7 @@
|
||||
<div v-if="customizations.onUpdate">
|
||||
<div class="form-group">
|
||||
<label class="form-label col-4">
|
||||
{{ t('message.onUpdate') }}
|
||||
{{ t('database.onUpdate') }}
|
||||
</label>
|
||||
<div class="column">
|
||||
<input
|
||||
|
@@ -10,20 +10,20 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="columns">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
v-model="localTrigger.name"
|
||||
class="form-input"
|
||||
@@ -43,11 +43,11 @@
|
||||
</div>
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.definer') }}</label>
|
||||
<label class="form-label">{{ t('database.definer') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localTrigger.definer"
|
||||
:options="users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -56,7 +56,7 @@
|
||||
<fieldset class="column columns mb-0" :disabled="customizations.triggerOnlyRename">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.table') }}</label>
|
||||
<label class="form-label">{{ t('database.table') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localTrigger.table"
|
||||
:options="schemaTables"
|
||||
@@ -68,7 +68,7 @@
|
||||
</div>
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.event') }}</label>
|
||||
<label class="form-label">{{ t('database.event') }}</label>
|
||||
<div class="input-group">
|
||||
<BaseSelect
|
||||
v-model="localTrigger.activation"
|
||||
@@ -100,7 +100,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.triggerStatement') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.triggerStatement') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,16 +10,16 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,7 +29,7 @@
|
||||
<div v-if="customizations.triggerFunctionlanguages" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.language') }}
|
||||
{{ t('application.language') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.language"
|
||||
@@ -41,12 +41,12 @@
|
||||
<div v-if="customizations.definer" class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.definer') }}
|
||||
{{ t('database.definer') }}
|
||||
</label>
|
||||
<BaseSelect
|
||||
v-model="localFunction.definer"
|
||||
:options="workspace.users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -54,7 +54,7 @@
|
||||
</div>
|
||||
<div v-if="customizations.comment" class="form-group">
|
||||
<label class="form-label">
|
||||
{{ t('word.comment') }}
|
||||
{{ t('database.comment') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="localFunction.comment"
|
||||
@@ -66,7 +66,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.functionBody') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.functionBody') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -10,20 +10,20 @@
|
||||
@click="saveChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||
<span>{{ t('word.save') }}</span>
|
||||
<span>{{ t('general.save') }}</span>
|
||||
</button>
|
||||
<button
|
||||
:disabled="!isChanged"
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
:title="t('message.clearChanges')"
|
||||
:title="t('database.clearChanges')"
|
||||
@click="clearChanges"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="columns">
|
||||
<div class="column col-auto">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('word.name') }}</label>
|
||||
<label class="form-label">{{ t('general.name') }}</label>
|
||||
<input
|
||||
v-model="localView.name"
|
||||
class="form-input"
|
||||
@@ -43,11 +43,11 @@
|
||||
</div>
|
||||
<div class="column col-auto">
|
||||
<div v-if="workspace.customizations.definer" class="form-group">
|
||||
<label class="form-label">{{ t('word.definer') }}</label>
|
||||
<label class="form-label">{{ t('database.definer') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.definer"
|
||||
:options="users"
|
||||
:option-label="(user: any) => user.value === '' ? t('message.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-label="(user: any) => user.value === '' ? t('database.currentUser') : `${user.name}@${user.host}`"
|
||||
:option-track-by="(user: any) => user.value === '' ? '' : `\`${user.name}\`@\`${user.host}\``"
|
||||
class="form-select"
|
||||
/>
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
<div class="column col-auto mr-2">
|
||||
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
|
||||
<label class="form-label">{{ t('message.sqlSecurity') }}</label>
|
||||
<label class="form-label">{{ t('database.sqlSecurity') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.security"
|
||||
:options="['DEFINER', 'INVOKER']"
|
||||
@@ -65,7 +65,7 @@
|
||||
</div>
|
||||
<div class="column col-auto mr-2">
|
||||
<div v-if="workspace.customizations.viewAlgorithm" class="form-group">
|
||||
<label class="form-label">{{ t('word.algorithm') }}</label>
|
||||
<label class="form-label">{{ t('database.algorithm') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.algorithm"
|
||||
:options="['UNDEFINED', 'MERGE', 'TEMPTABLE']"
|
||||
@@ -75,7 +75,7 @@
|
||||
</div>
|
||||
<div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ t('message.updateOption') }}</label>
|
||||
<label class="form-label">{{ t('database.updateOption') }}</label>
|
||||
<BaseSelect
|
||||
v-model="localView.updateOption"
|
||||
:option-track-by="(user: any) => user.value"
|
||||
@@ -88,7 +88,7 @@
|
||||
</div>
|
||||
<div class="workspace-query-results column col-12 mt-2 p-relative">
|
||||
<BaseLoader v-if="isLoading" />
|
||||
<label class="form-label ml-2">{{ t('message.selectStatement') }}</label>
|
||||
<label class="form-label ml-2">{{ t('database.selectStatement') }}</label>
|
||||
<QueryEditor
|
||||
v-show="isSelected"
|
||||
ref="queryEditor"
|
||||
|
@@ -24,11 +24,11 @@
|
||||
v-if="showCancel && isQuering"
|
||||
class="btn btn-primary btn-sm cancellable"
|
||||
:disabled="!query"
|
||||
:title="t('word.cancel')"
|
||||
:title="t('general.cancel')"
|
||||
@click="killTabQuery()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-window-close" />
|
||||
<span class="d-invisible pr-1">{{ t('word.run') }}</span>
|
||||
<span class="d-invisible pr-1">{{ t('general.run') }}</span>
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
@@ -38,7 +38,7 @@
|
||||
@click="runQuery(query)"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-play pr-1" />
|
||||
<span>{{ t('word.run') }}</span>
|
||||
<span>{{ t('general.run') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
@@ -48,7 +48,7 @@
|
||||
@click="commitTab()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-cube-send pr-1" />
|
||||
<span>{{ t('word.commit') }}</span>
|
||||
<span>{{ t('database.commit') }}</span>
|
||||
</button>
|
||||
<button
|
||||
v-if="!autocommit"
|
||||
@@ -57,7 +57,7 @@
|
||||
@click="rollbackTab()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-undo-variant pr-1" />
|
||||
<span>{{ t('word.rollback') }}</span>
|
||||
<span>{{ t('database.rollback') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-link btn-sm mr-0"
|
||||
@@ -65,7 +65,7 @@
|
||||
@click="clear()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-delete-sweep pr-1" />
|
||||
<span>{{ t('word.clear') }}</span>
|
||||
<span>{{ t('general.clear') }}</span>
|
||||
</button>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
@@ -76,7 +76,7 @@
|
||||
@click="beautify()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-brush pr-1" />
|
||||
<span>{{ t('word.format') }}</span>
|
||||
<span>{{ t('general.format') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-dark btn-sm"
|
||||
@@ -84,7 +84,7 @@
|
||||
@click="openHistoryModal()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-history pr-1" />
|
||||
<span>{{ t('word.history') }}</span>
|
||||
<span>{{ t('general.history') }}</span>
|
||||
</button>
|
||||
<div class="dropdown table-dropdown pr-2">
|
||||
<button
|
||||
@@ -93,7 +93,7 @@
|
||||
tabindex="0"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||
<span>{{ t('word.export') }}</span>
|
||||
<span>{{ t('database.export') }}</span>
|
||||
<i class="mdi mdi-24px mdi-menu-down" />
|
||||
</button>
|
||||
<ul class="menu text-left">
|
||||
@@ -104,18 +104,18 @@
|
||||
<a class="c-hand" @click="downloadTable('csv')">CSV</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="c-hand" @click="downloadTable('php')">{{ t('message.phpArray') }}</a>
|
||||
<a class="c-hand" @click="downloadTable('php')">{{ t('application.phpArray') }}</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="c-hand" @click="downloadTable('sql')">SQL INSERT</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="input-group pr-2" :title="t('message.commitMode')">
|
||||
<div class="input-group pr-2" :title="t('database.commitMode')">
|
||||
<i class="input-group-addon addon-sm mdi mdi-24px mdi-source-commit p-0" />
|
||||
<BaseSelect
|
||||
v-model="autocommit"
|
||||
:options="[{value: true, label: t('message.autoCommit')}, {value: false, label: t('message.manualCommit')}]"
|
||||
:options="[{value: true, label: t('database.autoCommit')}, {value: false, label: t('database.manualCommit')}]"
|
||||
:option-label="(opt: any) => opt.label"
|
||||
:option-track-by="(opt: any) => opt.value"
|
||||
class="form-select select-sm text-bold"
|
||||
@@ -126,30 +126,30 @@
|
||||
<div
|
||||
v-if="results.length"
|
||||
class="d-flex"
|
||||
:title="t('message.queryDuration')"
|
||||
:title="t('database.queryDuration')"
|
||||
>
|
||||
<i class="mdi mdi-timer-sand mdi-rotate-180 pr-1" /> <b>{{ durationsCount / 1000 }}s</b>
|
||||
</div>
|
||||
<div
|
||||
v-if="resultsCount"
|
||||
class="d-flex"
|
||||
:title="t('word.results')"
|
||||
:title="t('general.results')"
|
||||
>
|
||||
<i class="mdi mdi-equal pr-1" /> <b>{{ resultsCount.toLocaleString() }}</b>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasAffected"
|
||||
class="d-flex"
|
||||
:title="t('message.affectedRows')"
|
||||
:title="t('database.affectedRows')"
|
||||
>
|
||||
<i class="mdi mdi-target pr-1" /> <b>{{ affectedCount }}</b>
|
||||
</div>
|
||||
<div class="input-group" :title="t('word.schema')">
|
||||
<div class="input-group" :title="t('database.schema')">
|
||||
<i class="input-group-addon addon-sm mdi mdi-24px mdi-database" />
|
||||
|
||||
<BaseSelect
|
||||
v-model="selectedSchema"
|
||||
:options="[{value: null, label: t('message.noSchema')}, ...databaseSchemas.map(el => ({label: el, value: el}))]"
|
||||
:options="[{value: null, label: t('database.noSchema')}, ...databaseSchemas.map(el => ({label: el, value: el}))]"
|
||||
class="form-select select-sm text-bold"
|
||||
/>
|
||||
</div>
|
||||
@@ -291,6 +291,11 @@ watch(selectedSchema, () => {
|
||||
changeBreadcrumbs({ schema: selectedSchema.value, query: `Query #${props.tab.index}` });
|
||||
});
|
||||
|
||||
watch(databaseSchemas, () => {
|
||||
if (!databaseSchemas.value.includes(selectedSchema.value))
|
||||
selectedSchema.value = null;
|
||||
}, { deep: true });
|
||||
|
||||
const runQuery = async (query: string) => {
|
||||
if (!query || isQuering.value) return;
|
||||
isQuering.value = true;
|
||||
@@ -463,7 +468,7 @@ const commitTab = async () => {
|
||||
|
||||
await Schema.commitTab(params);
|
||||
setUnsavedChanges({ uid: props.connection.uid, tUid: props.tabUid, isChanged: false });
|
||||
addNotification({ status: 'success', message: t('message.actionSuccessful', { action: 'COMMIT' }) });
|
||||
addNotification({ status: 'success', message: t('general.actionSuccessful', { action: 'COMMIT' }) });
|
||||
}
|
||||
catch (err) {
|
||||
addNotification({ status: 'error', message: err.stack });
|
||||
@@ -482,7 +487,7 @@ const rollbackTab = async () => {
|
||||
|
||||
await Schema.rollbackTab(params);
|
||||
setUnsavedChanges({ uid: props.connection.uid, tUid: props.tabUid, isChanged: false });
|
||||
addNotification({ status: 'success', message: t('message.actionSuccessful', { action: 'ROLLBACK' }) });
|
||||
addNotification({ status: 'success', message: t('general.actionSuccessful', { action: 'ROLLBACK' }) });
|
||||
}
|
||||
catch (err) {
|
||||
addNotification({ status: 'error', message: err.stack });
|
||||
@@ -496,9 +501,6 @@ defineExpose({ resizeResults });
|
||||
query.value = props.tab.content as string;
|
||||
selectedSchema.value = props.tab.schema || breadcrumbsSchema.value;
|
||||
|
||||
if (!databaseSchemas.value.includes(selectedSchema.value))
|
||||
selectedSchema.value = null;
|
||||
|
||||
window.addEventListener('resize', onWindowResize);
|
||||
|
||||
const reloadListener = () => {
|
||||
|
@@ -102,12 +102,12 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-delete mr-1" />
|
||||
<span class="cut-text">{{ t('message.deleteRows', selectedRows.length) }}</span>
|
||||
<span class="cut-text">{{ t('database.deleteRows', selectedRows.length) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="mb-2">
|
||||
{{ t('message.confirmToDeleteRows', selectedRows.length) }}
|
||||
{{ t('database.confirmToDeleteRows', selectedRows.length) }}
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
@@ -120,12 +120,12 @@
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||
<span class="cut-text">{{ t('message.sqlExportOptions') }}</span>
|
||||
<span class="cut-text">{{ t('database.sqlExportOptions') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="columns">
|
||||
<label class="column col-12 h6 mb-2 cut-text">{{ t('message.targetTable') }}</label>
|
||||
<label class="column col-12 h6 mb-2 cut-text">{{ t('database.targetTable') }}</label>
|
||||
<div class="column col-12">
|
||||
<input
|
||||
v-model.number="sqlExportOptions.targetTable"
|
||||
@@ -134,7 +134,7 @@
|
||||
:placeholder="chunkModalRequest"
|
||||
>
|
||||
</div>
|
||||
<label class="column col-12 h6 mb-2 mt-4 cut-text">{{ t('message.newInserStmtEvery') }}:</label>
|
||||
<label class="column col-12 h6 mb-2 mt-4 cut-text">{{ t('database.newInsertStmtEvery') }}:</label>
|
||||
<div class="column col-6">
|
||||
<input
|
||||
v-model.number="sqlExportOptions.sqlInsertAfter"
|
||||
@@ -146,12 +146,83 @@
|
||||
<BaseSelect
|
||||
v-model="sqlExportOptions.sqlInsertDivider"
|
||||
class="form-select"
|
||||
:options="[{value: 'bytes', label: 'KiB'}, {value: 'rows', label: t('word.row', 2)}]"
|
||||
:options="[{value: 'bytes', label: 'KiB'}, {value: 'rows', label: t('database.row', 2)}]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
|
||||
<ConfirmModal
|
||||
v-if="csvModalRequest"
|
||||
@confirm="downloadTable('csv', csvModalRequest as string, true)"
|
||||
@hide="csvModalRequest = false"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||
<span class="cut-text">{{ t('application.csvExportOptions') }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
<div class="columns">
|
||||
<div class="form-group column col-12 columns col-gapless">
|
||||
<div class="column col-5">
|
||||
<label class="form-label cut-text">{{ t('application.csvFieldDelimiter') }}:</label>
|
||||
</div>
|
||||
<div class="column col-7">
|
||||
<input
|
||||
v-model.number="csvExportOptions.fieldDelimiter"
|
||||
type="string"
|
||||
class="form-input"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group column col-12 columns col-gapless">
|
||||
<div class="column col-5">
|
||||
<label class="form-label cut-text">{{ t('application.csvStringDelimiter') }}:</label>
|
||||
</div>
|
||||
<div class="column col-7">
|
||||
<BaseSelect
|
||||
v-model="csvExportOptions.stringDelimiter"
|
||||
class="form-select"
|
||||
:options="[
|
||||
{value: '', label: t('general.none')},
|
||||
{value: 'single', label: t('general.singleQuote')},
|
||||
{value: 'double', label: t('general.doubleQuote')}
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group column col-12 columns col-gapless">
|
||||
<div class="column col-5">
|
||||
<label class="form-label cut-text">{{ t('application.csvLinesTerminator') }}:</label>
|
||||
</div>
|
||||
<div class="column col-7">
|
||||
<textarea
|
||||
v-model.number="csvExportOptions.linesTerminator"
|
||||
class="form-input"
|
||||
:style="'resize: none'"
|
||||
rows="1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group column col-12 columns col-gapless">
|
||||
<div class="column col-5">
|
||||
<label class="form-label">
|
||||
{{ t('application.csvIncludeHeader') }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="column col-7">
|
||||
<label class="form-switch d-inline-block" @click.prevent="csvExportOptions.header = !csvExportOptions.header">
|
||||
<input type="checkbox" :checked="csvExportOptions.header">
|
||||
<i class="form-icon" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</ConfirmModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -223,11 +294,18 @@ const rowHeight = ref(23);
|
||||
const selectedField = ref(null);
|
||||
const isEditingRow = ref(false);
|
||||
const chunkModalRequest: Ref<false | string> = ref(false);
|
||||
const csvModalRequest: Ref<false | string> = ref(false);
|
||||
const sqlExportOptions = ref({
|
||||
sqlInsertAfter: 250,
|
||||
sqlInsertDivider: 'bytes' as 'bytes' | 'rows',
|
||||
targetTable: ''
|
||||
});
|
||||
const csvExportOptions = ref({
|
||||
header: true,
|
||||
fieldDelimiter: ';',
|
||||
linesTerminator: '\n',
|
||||
stringDelimiter: 'double'
|
||||
});
|
||||
|
||||
const workspaceSchema = computed(() => getWorkspace(props.connUid).breadcrumbs.schema);
|
||||
const workspaceClient = computed(() => getWorkspace(props.connUid).client);
|
||||
@@ -718,10 +796,10 @@ const selectResultset = (index: number) => {
|
||||
resultsetIndex.value = index;
|
||||
};
|
||||
|
||||
const downloadTable = (format: 'csv' | 'json' | 'sql' | 'php', table: string, chunks = false) => {
|
||||
const downloadTable = (format: 'csv' | 'json' | 'sql' | 'php', table: string, popup = false) => {
|
||||
if (!sortedResults.value) return;
|
||||
|
||||
if (format === 'sql' && !chunks && customizations.value.exportByChunks) {
|
||||
if (format === 'sql' && !popup && customizations.value.exportByChunks) {
|
||||
sqlExportOptions.value = {
|
||||
sqlInsertAfter: 250,
|
||||
sqlInsertDivider: 'bytes' as 'bytes' | 'rows',
|
||||
@@ -730,8 +808,20 @@ const downloadTable = (format: 'csv' | 'json' | 'sql' | 'php', table: string, ch
|
||||
chunkModalRequest.value = table;
|
||||
return;
|
||||
}
|
||||
else
|
||||
else if (format === 'csv' && !popup) {
|
||||
csvExportOptions.value = {
|
||||
header: true,
|
||||
fieldDelimiter: ';',
|
||||
linesTerminator: '\\n',
|
||||
stringDelimiter: 'double'
|
||||
};
|
||||
csvModalRequest.value = table;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
chunkModalRequest.value = false;
|
||||
csvModalRequest.value = false;
|
||||
}
|
||||
|
||||
const rows = sortedResults.value.map((row: any) => {
|
||||
const clonedRow = { ...row };
|
||||
@@ -747,7 +837,8 @@ const downloadTable = (format: 'csv' | 'json' | 'sql' | 'php', table: string, ch
|
||||
},
|
||||
client: workspaceClient.value,
|
||||
table,
|
||||
sqlOptions: chunks ? { ...sqlExportOptions.value }: null
|
||||
sqlOptions: popup ? { ...sqlExportOptions.value }: null,
|
||||
csvOptions: popup ? { ...csvExportOptions.value }: null
|
||||
});
|
||||
};
|
||||
|
||||
|
@@ -4,7 +4,7 @@
|
||||
@close-context="closeContext"
|
||||
>
|
||||
<div class="context-element">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-content-copy text-light pr-1" /> {{ t('word.copy') }}</span>
|
||||
<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" />
|
||||
<div class="context-submenu">
|
||||
<div
|
||||
@@ -13,32 +13,32 @@
|
||||
@click="copyCell"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-numeric-0 mdi-rotate-90 text-light pr-1" /> {{ t('word.cell', 1) }}
|
||||
<i class="mdi mdi-18px mdi-numeric-0 mdi-rotate-90 text-light pr-1" /> {{ t('database.cell', 1) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="context-element" @click="copyRow('html')">
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('word.row', selectedRows.length) }} ({{ t('word.table') }})
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('database.row', selectedRows.length) }} ({{ t('database.table') }})
|
||||
</span>
|
||||
</div>
|
||||
<div class="context-element" @click="copyRow('json')">
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('word.row', selectedRows.length) }} (JSON)
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('database.row', selectedRows.length) }} (JSON)
|
||||
</span>
|
||||
</div>
|
||||
<div class="context-element" @click="copyRow('csv')">
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('word.row', selectedRows.length) }} (CSV)
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('database.row', selectedRows.length) }} (CSV)
|
||||
</span>
|
||||
</div>
|
||||
<div class="context-element" @click="copyRow('php')">
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('word.row', selectedRows.length) }} (PHP)
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('database.row', selectedRows.length) }} (PHP)
|
||||
</span>
|
||||
</div>
|
||||
<div class="context-element" @click="copyRow('sql')">
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('word.row', selectedRows.length) }} (SQL INSERT)
|
||||
<i class="mdi mdi-18px mdi-table-row text-light pr-1" /> {{ t('database.row', selectedRows.length) }} (SQL INSERT)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@
|
||||
@click="duplicateRow"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ t('word.duplicate') }}
|
||||
<i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ t('general.duplicate') }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -57,7 +57,7 @@
|
||||
class="context-element"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-auto-fix text-light pr-1" /> {{ t('message.fillCell') }}
|
||||
<i class="mdi mdi-18px mdi-auto-fix text-light pr-1" /> {{ t('database.fillCell') }}
|
||||
</span>
|
||||
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
|
||||
<div class="context-submenu">
|
||||
@@ -79,7 +79,7 @@
|
||||
@click="setNull"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-null text-light pr-1" /> {{ t('message.setNull') }}
|
||||
<i class="mdi mdi-18px mdi-null text-light pr-1" /> {{ t('database.setNull') }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -88,7 +88,7 @@
|
||||
@click="showConfirmModal"
|
||||
>
|
||||
<span class="d-flex">
|
||||
<i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ t('message.deleteRows', selectedRows.length) }}
|
||||
<i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ t('database.deleteRows', selectedRows.length) }}
|
||||
</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
|
@@ -73,7 +73,7 @@
|
||||
</div>
|
||||
<ConfirmModal
|
||||
v-if="isTextareaEditor"
|
||||
:confirm-text="t('word.update')"
|
||||
:confirm-text="t('application.update')"
|
||||
size="medium"
|
||||
:disable-autofocus="true"
|
||||
@confirm="editOFF"
|
||||
@@ -81,7 +81,7 @@
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-playlist-edit mr-1" /> <span class="cut-text">{{ t('word.edit') }} "{{ editingField }}"</span>
|
||||
<i class="mdi mdi-24px mdi-playlist-edit mr-1" /> <span class="cut-text">{{ t('general.edit') }} "{{ editingField }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -96,7 +96,7 @@
|
||||
<div class="editor-field-info p-vcentered">
|
||||
<div class="d-flex p-vcentered">
|
||||
<label for="editorMode" class="form-label mr-2">
|
||||
<b>{{ t('word.content') }}</b>:
|
||||
<b>{{ t('general.content') }}</b>:
|
||||
</label>
|
||||
<BaseSelect
|
||||
id="editorMode"
|
||||
@@ -110,10 +110,10 @@
|
||||
<div class="d-flex">
|
||||
<div class="p-vcentered">
|
||||
<div class="mr-4">
|
||||
<b>{{ t('word.size') }}</b>: {{ editingContent ? editingContent.length : 0 }}
|
||||
<b>{{ t('general.size') }}</b>: {{ editingContent ? editingContent.length : 0 }}
|
||||
</div>
|
||||
<div v-if="editingType">
|
||||
<b>{{ t('word.type') }}</b>: {{ editingType.toUpperCase() }}
|
||||
<b>{{ t('database.type') }}</b>: {{ editingType.toUpperCase() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -138,14 +138,14 @@
|
||||
</ConfirmModal>
|
||||
<ConfirmModal
|
||||
v-if="isBlobEditor"
|
||||
:confirm-text="t('word.update')"
|
||||
:confirm-text="t('application.update')"
|
||||
@confirm="editOFF"
|
||||
@hide="hideEditorModal"
|
||||
>
|
||||
<template #header>
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-playlist-edit mr-1" />
|
||||
<span class="cut-text">{{ t('word.edit') }} "{{ editingField }}"</span>
|
||||
<span class="cut-text">{{ t('general.edit') }} "{{ editingField }}"</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #body>
|
||||
@@ -162,11 +162,11 @@
|
||||
</div>
|
||||
<div class="editor-buttons mt-2">
|
||||
<button class="btn btn-link btn-sm" @click="downloadFile">
|
||||
<span>{{ t('word.download') }}</span>
|
||||
<span>{{ t('general.download') }}</span>
|
||||
<i class="mdi mdi-24px mdi-download ml-1" />
|
||||
</button>
|
||||
<button class="btn btn-link btn-sm" @click="prepareToDelete">
|
||||
<span>{{ t('word.delete') }}</span>
|
||||
<span>{{ t('general.delete') }}</span>
|
||||
<i class="mdi mdi-24px mdi-delete-forever ml-1" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -174,15 +174,15 @@
|
||||
</Transition>
|
||||
<div class="editor-field-info">
|
||||
<div>
|
||||
<b>{{ t('word.size') }}</b>: {{ formatBytes(editingContent.length) }}<br>
|
||||
<b>{{ t('word.mimeType') }}</b>: {{ contentInfo.mime }}
|
||||
<b>{{ t('general.size') }}</b>: {{ formatBytes(editingContent.length) }}<br>
|
||||
<b>{{ t('general.mimeType') }}</b>: {{ contentInfo.mime }}
|
||||
</div>
|
||||
<div v-if="editingType">
|
||||
<b>{{ t('word.type') }}</b>: {{ editingType.toUpperCase() }}
|
||||
<b>{{ t('database.type') }}</b>: {{ editingType.toUpperCase() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<label>{{ t('message.uploadFile') }}</label>
|
||||
<label>{{ t('general.uploadFile') }}</label>
|
||||
<input
|
||||
class="form-input"
|
||||
type="file"
|
||||
@@ -293,7 +293,7 @@ const inputProps = computed(() => {
|
||||
let timeMask = '##:##:##';
|
||||
const precision = props.fields[editingField.value].length;
|
||||
|
||||
for (let i = 0; i < precision; i++)
|
||||
for (let i = 0; i < Number(precision); i++)
|
||||
timeMask += i === 0 ? '.#' : '#';
|
||||
|
||||
if (HAS_TIMEZONE.includes(editingType.value))
|
||||
@@ -309,7 +309,7 @@ const inputProps = computed(() => {
|
||||
let datetimeMask = '####-##-## ##:##:##';
|
||||
const precision = props.fields[editingField.value].length;
|
||||
|
||||
for (let i = 0; i < precision; i++)
|
||||
for (let i = 0; i < Number(precision); i++)
|
||||
datetimeMask += i === 0 ? '.#' : '#';
|
||||
|
||||
if (HAS_TIMEZONE.includes(editingType.value))
|
||||
@@ -582,14 +582,16 @@ const typeFormat = (val: string | number | Date | number[], type: string, precis
|
||||
return val;
|
||||
|
||||
let datePrecision = '';
|
||||
for (let i = 0; i < precision; i++)
|
||||
for (let i = 0; i < Number(precision); i++)
|
||||
datePrecision += i === 0 ? '.S' : 'S';
|
||||
|
||||
return moment(val).isValid() ? moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`) : val;
|
||||
}
|
||||
|
||||
if (BLOB.includes(type)) {
|
||||
const buff = Buffer.from(val as string);
|
||||
if (typeof val === 'string') return val;
|
||||
|
||||
const buff = Buffer.from(val as unknown as ArrayBuffer);
|
||||
if (!buff.length) return '';
|
||||
|
||||
const hex = buff.toString('hex').substring(0, 8).toUpperCase();
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<button
|
||||
class="btn btn-dark btn-sm mr-0 pr-1"
|
||||
:class="{'loading':isQuering}"
|
||||
:title="`${t('word.refresh')}`"
|
||||
:title="`${t('general.refresh')}`"
|
||||
@click="reloadTable"
|
||||
>
|
||||
<i v-if="!+autorefreshTimer" class="mdi mdi-24px mdi-refresh mr-1" />
|
||||
@@ -18,7 +18,7 @@
|
||||
<i class="mdi mdi-24px mdi-menu-down" />
|
||||
</div>
|
||||
<div class="menu px-3">
|
||||
<span>{{ t('word.autoRefresh') }}: <b>{{ +autorefreshTimer ? `${autorefreshTimer}s` : 'OFF' }}</b></span>
|
||||
<span>{{ t('general.autoRefresh') }}: <b>{{ +autorefreshTimer ? `${autorefreshTimer}s` : 'OFF' }}</b></span>
|
||||
<input
|
||||
v-model="autorefreshTimer"
|
||||
class="slider no-border"
|
||||
@@ -35,7 +35,7 @@
|
||||
<button
|
||||
class="btn btn-dark btn-sm mr-0"
|
||||
:disabled="isQuering || page === 1"
|
||||
:title="t('message.previousResultsPage')"
|
||||
:title="t('application.previousResultsPage')"
|
||||
@click="pageChange('prev')"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-skip-previous" />
|
||||
@@ -46,7 +46,7 @@
|
||||
{{ page }}
|
||||
</div>
|
||||
<div class="menu px-3">
|
||||
<span>{{ t('message.pageNumber') }}</span>
|
||||
<span>{{ t('general.pageNumber') }}</span>
|
||||
<input
|
||||
ref="pageSelect"
|
||||
v-model="pageProxy"
|
||||
@@ -61,7 +61,7 @@
|
||||
<button
|
||||
class="btn btn-dark btn-sm mr-0"
|
||||
:disabled="isQuering || (results.length && results[0].rows.length < limit)"
|
||||
:title="t('message.nextResultsPage')"
|
||||
:title="t('application.nextResultsPage')"
|
||||
@click="pageChange('next')"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-skip-next" />
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
<button
|
||||
class="btn btn-sm"
|
||||
:title="t('word.filter')"
|
||||
:title="t('general.filter')"
|
||||
:disabled="isQuering"
|
||||
:class="{'btn-primary': isSearch, 'btn-dark': !isSearch}"
|
||||
@click="isSearch = !isSearch"
|
||||
@@ -86,17 +86,17 @@
|
||||
@click="showFakerModal()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-playlist-plus mr-1" />
|
||||
<span>{{ t('message.insertRow', 2) }}</span>
|
||||
<span>{{ t('database.insertRow', 2) }}</span>
|
||||
</button>
|
||||
|
||||
<div class="dropdown table-dropdown pr-2">
|
||||
<div class="dropdown table-dropdown">
|
||||
<button
|
||||
:disabled="isQuering"
|
||||
class="btn btn-dark btn-sm dropdown-toggle mr-0 pr-0"
|
||||
tabindex="0"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||
<span>{{ t('word.export') }}</span>
|
||||
<span>{{ t('database.export') }}</span>
|
||||
<i class="mdi mdi-24px mdi-menu-down" />
|
||||
</button>
|
||||
<ul class="menu text-left">
|
||||
@@ -107,34 +107,46 @@
|
||||
<a class="c-hand" @click="downloadTable('csv')">CSV</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="c-hand" @click="downloadTable('php')">{{ t('message.phpArray') }}</a>
|
||||
<a class="c-hand" @click="downloadTable('php')">{{ t('application.phpArray') }}</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a class="c-hand" @click="downloadTable('sql')">SQL INSERT</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="divider-vert py-3" />
|
||||
|
||||
<button
|
||||
class="btn btn-dark btn-sm"
|
||||
:disabled="isQuering"
|
||||
:title="t('application.settings')"
|
||||
@click="openTableSettingTab()"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-cog" />
|
||||
<!-- <span>{{ t('application.settings') }}</span> -->
|
||||
</button>
|
||||
</div>
|
||||
<div class="workspace-query-info">
|
||||
<div
|
||||
v-if="results.length"
|
||||
class="d-flex"
|
||||
:title="t('message.queryDuration')"
|
||||
:title="t('database.queryDuration')"
|
||||
>
|
||||
<i class="mdi mdi-timer-sand mdi-rotate-180 pr-1" /> <b>{{ results[0].duration / 1000 }}s</b>
|
||||
</div>
|
||||
<div v-if="results.length && results[0].rows">
|
||||
{{ t('word.results') }}: <b>{{ localeString(results[0].rows.length) }}</b>
|
||||
{{ t('general.results') }}: <b>{{ localeString(results[0].rows.length) }}</b>
|
||||
</div>
|
||||
<div v-if="hasApproximately || (page > 1 && approximateCount)">
|
||||
{{ t('word.total') }}: <b
|
||||
:title="!customizations.tableRealCount ? t('word.approximately') : ''"
|
||||
{{ t('database.total') }}: <b
|
||||
:title="!customizations.tableRealCount ? t('database.approximately') : ''"
|
||||
>
|
||||
<span v-if="!customizations.tableRealCount">≈</span>
|
||||
{{ localeString(approximateCount) }}
|
||||
</b>
|
||||
</div>
|
||||
<div class="d-flex" :title="t('word.schema')">
|
||||
<div class="d-flex" :title="t('database.schema')">
|
||||
<i class="mdi mdi-18px mdi-database mr-1" /><b>{{ schema }}</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,7 +166,7 @@
|
||||
<i class="mdi mdi-48px mdi-island" />
|
||||
</div>
|
||||
<p class="h4 empty-subtitle">
|
||||
{{ t('message.noResultsPresent') }}
|
||||
{{ t('database.noResultsPresent') }}
|
||||
</p>
|
||||
</div>
|
||||
<WorkspaceTabQueryTable
|
||||
@@ -231,7 +243,7 @@ const workspacesStore = useWorkspacesStore();
|
||||
|
||||
const { dataTabLimit: limit } = storeToRefs(settingsStore);
|
||||
|
||||
const { changeBreadcrumbs, getWorkspace } = workspacesStore;
|
||||
const { changeBreadcrumbs, getWorkspace, newTab } = workspacesStore;
|
||||
|
||||
const pageSelect: Ref<HTMLInputElement> = ref(null);
|
||||
const tabUid = ref('data');
|
||||
@@ -428,6 +440,22 @@ const hasApproximately = computed(() => {
|
||||
results.value[0].rows.length < approximateCount.value;
|
||||
});
|
||||
|
||||
const openTableSettingTab = () => {
|
||||
newTab({
|
||||
uid: workspace.value.uid,
|
||||
elementName: props.table,
|
||||
schema: props.schema,
|
||||
type: isTable.value ? 'table-props' : 'view-props',
|
||||
elementType: isTable.value ? 'table' : 'view'
|
||||
});
|
||||
|
||||
changeBreadcrumbs({
|
||||
schema: props.schema,
|
||||
table: isTable.value ? props.table : null,
|
||||
view: !isTable.value ? props.table : null
|
||||
});
|
||||
};
|
||||
|
||||
watch(() => props.schema, () => {
|
||||
if (props.isSelected) {
|
||||
page.value = 1;
|
||||
|
@@ -51,7 +51,7 @@
|
||||
class="btn btn-sm btn-primary mr-0 ml-2"
|
||||
type="submit"
|
||||
>
|
||||
{{ t('word.filter') }}
|
||||
{{ t('general.filter') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-dark mr-0 ml-2"
|
||||
|
@@ -4,19 +4,19 @@
|
||||
@close-context="closeContext"
|
||||
>
|
||||
<div class="context-element" @click.stop="closeAllTabs">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-asterisk text-light pr-1" /> {{ t('message.closeAllTabs') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-asterisk text-light pr-1" /> {{ t('application.closeAllTabs') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="context-element" @click.stop="closeOtherTabs">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-not-equal text-light pr-1" /> {{ t('message.closeOtherTabs') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-not-equal text-light pr-1" /> {{ t('application.closeOtherTabs') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="context-element" @click.stop="closeLeftTabs">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-less-than text-light pr-1" /> {{ t('message.closeTabsToLeft') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-less-than text-light pr-1" /> {{ t('application.closeTabsToLeft') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="context-element" @click.stop="closeRightTabs">
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-greater-than text-light pr-1" /> {{ t('message.closeTabsToRight') }}</span>
|
||||
<span class="d-flex"><i class="mdi mdi-18px mdi-greater-than text-light pr-1" /> {{ t('application.closeTabsToRight') }}</span>
|
||||
</div>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
export const arSA = {
|
||||
word: {
|
||||
general: {
|
||||
edit: 'تعديل',
|
||||
save: 'حفظ',
|
||||
close: 'إغلاق',
|
||||
@@ -7,6 +7,23 @@ export const arSA = {
|
||||
confirm: 'تأكيد',
|
||||
cancel: 'إلغاء',
|
||||
send: 'إرسال',
|
||||
refresh: 'تحديث',
|
||||
version: 'النسخة',
|
||||
donate: 'إدعم',
|
||||
run: 'شغل',
|
||||
results: 'النتائج',
|
||||
size: 'الحجم',
|
||||
mimeType: 'نوع الميديا',
|
||||
download: 'تحميل',
|
||||
add: 'أضف',
|
||||
data: 'بيانات',
|
||||
properties: 'خصائص',
|
||||
insert: 'أدرج',
|
||||
seconds: 'ثواني',
|
||||
deleteConfirm: 'هل أنت متأكد من حذف الإتصال؟',
|
||||
uploadFile: 'رفع ملف'
|
||||
},
|
||||
connection: {
|
||||
connectionName: 'إسم الإتصال',
|
||||
client: 'العميل',
|
||||
hostName: 'إسم المستضيف',
|
||||
@@ -18,31 +35,6 @@ export const arSA = {
|
||||
connected: 'متصل',
|
||||
disconnect: 'إلغاء الإتصال',
|
||||
disconnected: 'غير متصل',
|
||||
refresh: 'تحديث',
|
||||
settings: 'الإعدادات',
|
||||
general: 'عام',
|
||||
themes: 'الأنماط',
|
||||
update: 'تحديث',
|
||||
about: 'حول',
|
||||
language: 'اللغة',
|
||||
version: 'النسخة',
|
||||
donate: 'إدعم',
|
||||
run: 'شغل',
|
||||
schema: 'Schema',
|
||||
results: 'النتائج',
|
||||
size: 'الحجم',
|
||||
seconds: 'ثواني',
|
||||
type: 'نوع',
|
||||
mimeType: 'نوع الميديا',
|
||||
download: 'تحميل',
|
||||
add: 'أضف',
|
||||
data: 'بيانات',
|
||||
properties: 'خصائص',
|
||||
insert: 'أدرج'
|
||||
},
|
||||
message: {
|
||||
appWelcome: 'مرحبا بك في عميل الSQL انتاريس!',
|
||||
appFirstStep: 'خطوتك الأولى قم بإنشاء إتصال جديد بقاعدة بيانات.',
|
||||
addConnection: 'إضافة إتصال',
|
||||
createConnection: 'إنشاء إتصال',
|
||||
createNewConnection: 'إنشاء إتصال جديد',
|
||||
@@ -50,8 +42,25 @@ export const arSA = {
|
||||
testConnection: 'إختبر الإتصال',
|
||||
editConnection: 'عدل الإتصال',
|
||||
deleteConnection: 'إحذف الإتصال',
|
||||
deleteCorfirm: 'هل أنت متأكد من حذف الإتصال؟',
|
||||
connectionSuccessfullyMade: 'تم الإتصال بنجاح!',
|
||||
connectionSuccessfullyMade: 'تم الإتصال بنجاح!'
|
||||
},
|
||||
database: {
|
||||
schema: 'Schema',
|
||||
type: 'نوع',
|
||||
unableEditFieldWithoutPrimary: 'لا يمكن تعديل الخانة بدون وجود مفتاح رئيسي في النتائج',
|
||||
editCell: 'تعديل الخلية',
|
||||
deleteRows: 'حذف صف | حذف {count} صفوف',
|
||||
confirmToDeleteRows: 'هل أنت متأكد من حذف صف واحد؟? | هل أنت متأكد من حذف {count} صف?',
|
||||
addNewRow: 'إضافة صف جديد',
|
||||
numberOfInserts: 'عدد الإدراجات'
|
||||
},
|
||||
application: {
|
||||
settings: 'الإعدادات',
|
||||
general: 'عام',
|
||||
themes: 'الأنماط',
|
||||
update: 'تحديث',
|
||||
about: 'حول',
|
||||
language: 'اللغة',
|
||||
madeWithJS: 'بني بـ 💛 و جافاسكربت!',
|
||||
checkForUpdates: 'تأكد من التحديثات',
|
||||
noUpdatesAvailable: 'لا توجد تحديثات',
|
||||
@@ -61,13 +70,6 @@ export const arSA = {
|
||||
downloadingUpdate: 'جاري تحميل التحديث',
|
||||
updateDownloaded: 'تم تحميل التحديث',
|
||||
restartToInstall: 'قم بإعادة تشغيل انتاريس للتحديث',
|
||||
unableEditFieldWithoutPrimary: 'لا يمكن تعديل الخانة بدون وجود مفتاح رئيسي في النتائج',
|
||||
editCell: 'تعديل الخلية',
|
||||
deleteRows: 'حذف صف | حذف {count} صفوف',
|
||||
confirmToDeleteRows: 'هل أنت متأكد من حذف صف واحد؟? | هل أنت متأكد من حذف {count} صف?',
|
||||
notificationsTimeout: 'إنتهاء التنبيهات',
|
||||
uploadFile: 'رفع ملف',
|
||||
addNewRow: 'إضافة صف جديد',
|
||||
numberOfInserts: 'عدد الإدراجات'
|
||||
notificationsTimeout: 'إنتهاء التنبيهات'
|
||||
}
|
||||
};
|
||||
|
522
src/renderer/i18n/ca-ES.ts
Normal file
522
src/renderer/i18n/ca-ES.ts
Normal file
@@ -0,0 +1,522 @@
|
||||
export const caES = {
|
||||
general: {
|
||||
edit: 'Editar',
|
||||
save: 'Desar',
|
||||
close: 'Tancar',
|
||||
delete: 'Esborrar',
|
||||
confirm: 'Confirmar',
|
||||
cancel: 'Cancel·lar',
|
||||
send: 'Enviar',
|
||||
refresh: 'Actualitzar',
|
||||
autoRefresh: 'Actualització automàtica',
|
||||
version: 'Versió',
|
||||
donate: 'Donar',
|
||||
run: 'Executar',
|
||||
results: 'Resultats',
|
||||
size: 'Mida',
|
||||
mimeType: 'Tipus MIME',
|
||||
download: 'Descarregar',
|
||||
add: 'Afegir',
|
||||
data: 'Dades',
|
||||
properties: 'Propietats',
|
||||
insert: 'Inserir',
|
||||
name: 'Nom',
|
||||
clear: 'Netejar',
|
||||
seconds: 'Segons',
|
||||
options: 'Opcions',
|
||||
discard: 'Descartar',
|
||||
stay: 'Quedar-se',
|
||||
author: 'Autor',
|
||||
upload: 'Pujar',
|
||||
browse: 'Navegar',
|
||||
content: 'Contingut',
|
||||
cut: 'Tallar',
|
||||
copy: 'Copiar',
|
||||
paste: 'Enganxar',
|
||||
tools: 'Eines',
|
||||
format: 'Format',
|
||||
all: 'Tot',
|
||||
duplicate: 'Duplicar',
|
||||
new: 'Nou',
|
||||
history: 'Històric',
|
||||
select: 'Seleccionar',
|
||||
filter: 'Filtre',
|
||||
change: 'Canviar',
|
||||
includes: 'Inclou',
|
||||
completed: 'Completat',
|
||||
aborted: 'Avortat',
|
||||
disabled: 'Deshabilitat',
|
||||
enable: 'Habilitar',
|
||||
disable: 'Deshabilitar',
|
||||
contributors: 'Contribuïdors',
|
||||
pin: 'Fixar',
|
||||
unpin: 'Desfixar',
|
||||
folder: 'Carpeta | Carpetes',
|
||||
none: 'Cap',
|
||||
singleQuote: 'Cometa simple',
|
||||
doubleQuote: 'Cometa doble',
|
||||
deleteConfirm: 'Confirmes la cancel·lació de',
|
||||
uploadFile: 'Puja fitxer',
|
||||
manualValue: 'Valor manual',
|
||||
selectAll: 'Selecciona tot',
|
||||
pageNumber: 'Número de pàgina',
|
||||
directoryPath: 'Ruta del directori',
|
||||
actionSuccessful: '{action} realitzat amb èxit',
|
||||
outputFormat: 'Format de sortida',
|
||||
singleFile: 'Arxiu {ext} únic',
|
||||
zipCompressedFile: 'Arxiu {ext} comprimit en ZIP'
|
||||
},
|
||||
connection: {
|
||||
connectionName: 'Nom de la connexió',
|
||||
client: 'Client',
|
||||
hostName: 'Nom de l\'amfitrió',
|
||||
port: 'Port',
|
||||
user: 'Usuari',
|
||||
password: 'Contrasenya',
|
||||
credentials: 'Credencials',
|
||||
connect: 'Connectar',
|
||||
connected: 'Connectat',
|
||||
disconnect: 'Desconnectar',
|
||||
disconnected: 'Desconnectat',
|
||||
ssl: 'SSL',
|
||||
privateKey: 'Clau privada',
|
||||
certificate: 'Certificat',
|
||||
caCertificate: 'Certificat CA',
|
||||
ciphers: 'Xifrats',
|
||||
sshTunnel: 'Túnel SSH',
|
||||
passphrase: 'Frase de contrasenya',
|
||||
connectionString: 'Cadena de connexió',
|
||||
addConnection: 'Afegeix connexió',
|
||||
createConnection: 'Crea connexió',
|
||||
createNewConnection: 'Crea una nova connexió',
|
||||
askCredentials: 'Demana credencials',
|
||||
testConnection: 'Prova la connexió',
|
||||
editConnection: 'Edita la connexió',
|
||||
deleteConnection: 'Esborra la connexió',
|
||||
connectionSuccessfullyMade: 'Connexió realitzada amb èxit!',
|
||||
enableSsl: 'Activa SSL',
|
||||
enableSsh: 'Activa SSH',
|
||||
readOnlyMode: 'Mode de lectura',
|
||||
untrustedConnection: 'Connexió no confiable',
|
||||
allConnections: 'Totes les connexions',
|
||||
searchForConnections: 'Cerca connexions'
|
||||
},
|
||||
database: {
|
||||
schema: 'Esquema',
|
||||
type: 'Tipus',
|
||||
foreignKeys: 'Claus foranes',
|
||||
length: 'Longitud',
|
||||
unsigned: 'Sense signe',
|
||||
default: 'Per defecte',
|
||||
comment: 'Comentari',
|
||||
collation: 'Ordenació',
|
||||
key: 'Clau | Claus',
|
||||
order: 'Ordre',
|
||||
expression: 'Expressió',
|
||||
autoIncrement: 'Autoincrement',
|
||||
engine: 'Motor',
|
||||
field: 'Camp | Camps',
|
||||
approximately: 'Aproximadament',
|
||||
total: 'Total',
|
||||
table: 'Taula',
|
||||
view: 'Vista',
|
||||
indexes: 'Índexs',
|
||||
definer: 'Definidor',
|
||||
algorithm: 'Algorisme',
|
||||
trigger: 'Desencadenador | Desencadenadors',
|
||||
storedRoutine: 'Rutina emmagatzemada | Rutines emmagatzemades',
|
||||
scheduler: 'Planificador | Planificadors',
|
||||
event: 'Esdeveniment',
|
||||
parameters: 'Paràmetres',
|
||||
function: 'Funció | Funcions',
|
||||
deterministic: 'Determinista',
|
||||
context: 'Context',
|
||||
export: 'Exportar',
|
||||
import: 'Importar',
|
||||
returns: 'Retorna',
|
||||
timing: 'Temporització',
|
||||
state: 'Estat',
|
||||
execution: 'Execució',
|
||||
starts: 'Comença',
|
||||
ends: 'Acaba',
|
||||
variables: 'Variables',
|
||||
processes: 'Processos',
|
||||
database: 'Base de dades',
|
||||
array: 'Matriu',
|
||||
structure: 'Estructura',
|
||||
row: 'Fila | Files',
|
||||
cell: 'Cel·la | Cel·les',
|
||||
triggerFunction: 'Funció de desencadenador | Funcions de desencadenador',
|
||||
routine: 'Rutina',
|
||||
commit: 'Validar',
|
||||
rollback: 'Desfer',
|
||||
resultsTable: 'Taula de resultats',
|
||||
ddl: 'DDL',
|
||||
drop: 'Descartar',
|
||||
unableEditFieldWithoutPrimary: 'No es pot editar un camp sense una clau primària en el conjunt de resultats',
|
||||
editCell: 'Edita la cel·la',
|
||||
deleteRows: 'Esborra fila | Esborra {count} files',
|
||||
confirmToDeleteRows: 'Confirmes esborrar una fila? | Confirmes esborrar {count} files?',
|
||||
addNewRow: 'Afegeix una nova fila',
|
||||
numberOfInserts: 'Nombre d\'insercions',
|
||||
affectedRows: 'Files afectades',
|
||||
createNewDatabase: 'Crea una nova base de dades',
|
||||
databaseName: 'Nom de la base de dades',
|
||||
serverDefault: 'Per defecte del servidor',
|
||||
deleteDatabase: 'Esborra la base de dades',
|
||||
editDatabase: 'Edita la base de dades',
|
||||
clearChanges: 'Neteja els canvis',
|
||||
addNewField: 'Afegeix un nou camp',
|
||||
manageIndexes: 'Gestiona els índexs',
|
||||
manageForeignKeys: 'Gestiona les claus foranes',
|
||||
allowNull: 'Permet NULL',
|
||||
zeroFill: 'Omplir amb zeros',
|
||||
customValue: 'Valor personalitzat',
|
||||
onUpdate: 'A l\'actualitzar',
|
||||
deleteField: 'Esborra camp',
|
||||
createNewIndex: 'Crea un nou índex',
|
||||
addToIndex: 'Afegeix a l\'índex',
|
||||
createNewTable: 'Crea una nova taula',
|
||||
emptyTable: 'Taula buida',
|
||||
deleteTable: 'Esborra la taula',
|
||||
emptyConfirm: 'Confirmes buidar',
|
||||
thereAreNoIndexes: 'No hi ha índexs',
|
||||
thereAreNoForeign: 'No hi ha claus foranes',
|
||||
createNewForeign: 'Crea una nova clau forana',
|
||||
referenceTable: 'Taula de referència',
|
||||
referenceField: 'Camp de referència',
|
||||
foreignFields: 'Camps foranis',
|
||||
invalidDefault: 'Valor per defecte no vàlid',
|
||||
onDelete: 'Al esborrar',
|
||||
selectStatement: 'Sentència SELECT',
|
||||
triggerStatement: 'Sentència TRIGGER',
|
||||
sqlSecurity: 'Seguretat SQL',
|
||||
updateOption: 'Opció d\'actualització',
|
||||
deleteView: 'Esborra vista',
|
||||
createNewView: 'Crea una nova vista',
|
||||
deleteTrigger: 'Esborra disparador',
|
||||
createNewTrigger: 'Crea un nou disparador',
|
||||
currentUser: 'Usuari actual',
|
||||
routineBody: 'Cos de la rutina',
|
||||
dataAccess: 'Accés a dades',
|
||||
thereAreNoParameters: 'No hi ha paràmetres',
|
||||
createNewParameter: 'Crea un nou paràmetre',
|
||||
createNewRoutine: 'Crea una nova rutina emmagatzemada',
|
||||
deleteRoutine: 'Esborra rutina emmagatzemada',
|
||||
functionBody: 'Cos de la funció',
|
||||
createNewFunction: 'Crea una nova funció',
|
||||
deleteFunction: 'Esborra funció',
|
||||
schedulerBody: 'Cos del planificador',
|
||||
createNewScheduler: 'Crea un nou planificador',
|
||||
deleteScheduler: 'Esborra planificador',
|
||||
preserveOnCompletion: 'Conserva en finalitzar',
|
||||
tableFiller: 'Ompletaula',
|
||||
fakeDataLanguage: 'Idioma de dades fictícies',
|
||||
queryDuration: 'Durada de la consulta',
|
||||
setNull: 'Estableix NULL',
|
||||
processesList: 'Llista de processos',
|
||||
processInfo: 'Informació del procés',
|
||||
manageUsers: 'Gestiona usuaris',
|
||||
createNewSchema: 'Crea un nou esquema',
|
||||
schemaName: 'Nom de l\'esquema',
|
||||
editSchema: 'Edita l\'esquema',
|
||||
deleteSchema: 'Esborra l\'esquema',
|
||||
duplicateTable: 'Duplica taula',
|
||||
noSchema: 'No hi ha esquema',
|
||||
runQuery: 'Executa consulta',
|
||||
thereAreNoTableFields: 'No hi ha camps a la taula',
|
||||
newTable: 'Nova taula',
|
||||
newView: 'Nova vista',
|
||||
newTrigger: 'Nou disparador',
|
||||
newRoutine: 'Nova rutina',
|
||||
newFunction: 'Nova funció',
|
||||
newScheduler: 'Nou planificador',
|
||||
newTriggerFunction: 'Nova funció de disparador',
|
||||
thereIsNoQueriesYet: 'Encara no hi ha consultes',
|
||||
searchForQueries: 'Cerca consultes',
|
||||
killProcess: 'Mata procés',
|
||||
exportSchema: 'Exporta esquema',
|
||||
importSchema: 'Importa esquema',
|
||||
newInsertStmtEvery: 'Nova sentència INSERT cada',
|
||||
processingTableExport: 'Processant {table}',
|
||||
fetchingTableExport: 'Obtenint dades de {table}',
|
||||
writingTableExport: 'Escrivint dades de {table}',
|
||||
checkAllTables: 'Marca totes les taules',
|
||||
uncheckAllTables: 'Desmarca totes les taules',
|
||||
killQuery: 'Mata consulta',
|
||||
insertRow: 'Insereix fila | Insereix files',
|
||||
commitMode: 'Mode de validació',
|
||||
autoCommit: 'Validació automàtica',
|
||||
manualCommit: 'Validació manual',
|
||||
disableFKChecks: 'Desactiva les comprovacions de claus foranes',
|
||||
formatQuery: 'Formata consulta',
|
||||
queryHistory: 'Històric de consultes',
|
||||
clearQuery: 'Neteja consulta',
|
||||
fillCell: 'Omplir cel·la',
|
||||
executeSelectedQuery: 'Executa la consulta seleccionada',
|
||||
noResultsPresent: 'No hi ha resultats',
|
||||
sqlExportOptions: 'Opcions d\'exportació SQL',
|
||||
targetTable: 'Taula objectiu',
|
||||
switchDatabase: 'Canvia la base de dades',
|
||||
importQueryErrors: 'Avís: ha ocorregut {n} error | Avís: han ocorregut {n} errors',
|
||||
executedQueries: '{n} consulta executada | {n} consultes executades'
|
||||
},
|
||||
application: {
|
||||
settings: 'Configuració',
|
||||
general: 'General',
|
||||
themes: 'Temes',
|
||||
update: 'Actualitzar',
|
||||
about: 'Sobre',
|
||||
language: 'Idioma',
|
||||
light: 'Clar',
|
||||
dark: 'Fosc',
|
||||
autoCompletion: 'Autocompletat',
|
||||
application: 'Aplicació',
|
||||
editor: 'Editor',
|
||||
scratchpad: 'Bloc de notes',
|
||||
changelog: 'Registre de canvis',
|
||||
small: 'Petit',
|
||||
medium: 'Mitjà',
|
||||
large: 'Gran',
|
||||
console: 'Consola',
|
||||
shortcuts: 'Dreceres',
|
||||
appearance: 'Aparença',
|
||||
color: 'Color',
|
||||
label: 'Etiqueta',
|
||||
icon: 'Icona',
|
||||
madeWithJS: 'Fet amb 💛 i JavaScript!',
|
||||
checkForUpdates: 'Comprova actualitzacions',
|
||||
noUpdatesAvailable: 'No hi ha actualitzacions disponibles',
|
||||
checkingForUpdate: 'Comprovant actualitzacions',
|
||||
checkFailure: 'La comprovació ha fallat, si us plau, torna-ho a intentar més tard',
|
||||
updateAvailable: 'Actualització disponible',
|
||||
downloadingUpdate: 'Descarregant actualització',
|
||||
updateDownloaded: 'Actualització descarregada',
|
||||
restartToInstall: 'Reinicia Antares per instal·lar',
|
||||
notificationsTimeout: 'Temps d\'espera de notificacions',
|
||||
openNewTab: 'Obre una nova pestanya',
|
||||
unsavedChanges: 'Canvis no desats',
|
||||
discardUnsavedChanges: 'Tens alguns canvis no desats. Tancant aquesta pestanya aquests canvis es descartaran.',
|
||||
applicationTheme: 'Tema de l\'aplicació',
|
||||
editorTheme: 'Tema de l\'editor',
|
||||
wrapLongLines: 'Ajusta línies llargues',
|
||||
includeBetaUpdates: 'Inclou actualitzacions beta',
|
||||
markdownSupported: 'Suporta markdown',
|
||||
plantATree: 'Planta un arbre',
|
||||
dataTabPageSize: 'Mida de pàgina de la pestanya DATA',
|
||||
noOpenTabs: 'No hi ha pestanyes obertes, navega per la barra de l\'esquerra o:',
|
||||
restorePreviousSession: 'Restaura la sessió anterior',
|
||||
closeTab: 'Tanca pestanya',
|
||||
goToDownloadPage: 'Ves a la pàgina de descàrrega',
|
||||
disableBlur: 'Desactiva el desenfoc',
|
||||
missingOrIncompleteTranslation: 'Traducció absent o incompleta?',
|
||||
findOutHowToContribute: 'Descobreix com contribuir',
|
||||
disableScratchpad: 'Desactiva el bloc de notes',
|
||||
reportABug: 'Informa d\'un error',
|
||||
nextTab: 'Pestanya següent',
|
||||
previousTab: 'Pestanya anterior',
|
||||
selectTabNumber: 'Selecciona el número de pestanya {param}',
|
||||
toggleConsole: 'Commuta la consola',
|
||||
addShortcut: 'Afegeix drecera',
|
||||
editShortcut: 'Edita drecera',
|
||||
deleteShortcut: 'Esborra drecera',
|
||||
restoreDefaults: 'Restaura els valors per defecte',
|
||||
restoreDefaultsQuestion: 'Confirmes restaurar els valors per defecte?',
|
||||
registerAShortcut: 'Registra una drecera',
|
||||
invalidShortcutMessage: 'Combinació no vàlida, continua escrivint',
|
||||
shortcutAlreadyExists: 'La drecera ja existeix',
|
||||
saveContent: 'Desa el contingut',
|
||||
openAllConnections: 'Obre totes les connexions',
|
||||
openSettings: 'Obre configuració',
|
||||
openScratchpad: 'Obre el bloc de notes',
|
||||
runOrReload: 'Executa o recarrega',
|
||||
openFilter: 'Obre filtre',
|
||||
nextResultsPage: 'Pàgina de resultats següent',
|
||||
previousResultsPage: 'Pàgina de resultats anterior',
|
||||
editFolder: 'Edita carpeta',
|
||||
folderName: 'Nom de la carpeta',
|
||||
deleteFolder: 'Esborra carpeta',
|
||||
editConnectionAppearance: 'Edita l\'aparença de la connexió',
|
||||
defaultCopyType: 'Tipus de còpia per defecte',
|
||||
showTableSize: 'Mostra la mida de la taula a la barra lateral',
|
||||
showTableSizeDescription: 'Només MySQL/MariaDB. Activar aquesta opció pot afectar el rendiment en esquemes amb moltes taules.',
|
||||
searchForSchemas: 'Cerca esquemes',
|
||||
searchForElements: 'Cerca elements',
|
||||
switchSearchMethod: 'Canvia el mètode de cerca',
|
||||
closeAllTabs: 'Tanca totes les pestanyes',
|
||||
closeOtherTabs: 'Tanca altres pestanyes',
|
||||
closeTabsToLeft: 'Tanca pestanyes a l\'esquerra',
|
||||
closeTabsToRight: 'Tanca pestanyes a la dreta',
|
||||
csvFieldDelimiter: 'Delimitador de camp',
|
||||
csvLinesTerminator: 'Terminador de línia',
|
||||
csvStringDelimiter: 'Delimitador de cadena',
|
||||
csvIncludeHeader: 'Inclou capçalera',
|
||||
csvExportOptions: 'Opcions d\'exportació CSV',
|
||||
phpArray: 'Matriu PHP'
|
||||
},
|
||||
faker: {
|
||||
address: 'Adreça',
|
||||
commerce: 'Comerç',
|
||||
company: 'Empresa',
|
||||
database: 'Base de dades',
|
||||
date: 'Data',
|
||||
finance: 'Finances',
|
||||
git: 'Git',
|
||||
hacker: 'Hacker',
|
||||
internet: 'Internet',
|
||||
lorem: 'Lorem',
|
||||
name: 'Nom',
|
||||
music: 'Música',
|
||||
phone: 'Telèfon',
|
||||
random: 'Aleatori',
|
||||
system: 'Sistema',
|
||||
time: 'Hora',
|
||||
vehicle: 'Vehicle',
|
||||
zipCode: 'Codi postal',
|
||||
zipCodeByState: 'Codi postal per estat',
|
||||
city: 'Ciutat',
|
||||
cityPrefix: 'Prefix de ciutat',
|
||||
citySuffix: 'Sufix de ciutat',
|
||||
streetName: 'Nom del carrer',
|
||||
streetAddress: 'Adreça del carrer',
|
||||
streetSuffix: 'Sufix del carrer',
|
||||
streetPrefix: 'Prefix del carrer',
|
||||
secondaryAddress: 'Adreça secundària',
|
||||
county: 'Comtat',
|
||||
country: 'País',
|
||||
countryCode: 'Codi de país',
|
||||
state: 'Estat',
|
||||
stateAbbr: 'Abreviatura de l\'estat',
|
||||
latitude: 'Latitud',
|
||||
longitude: 'Longitud',
|
||||
direction: 'Direcció',
|
||||
cardinalDirection: 'Direcció cardinal',
|
||||
ordinalDirection: 'Direcció ordinal',
|
||||
nearbyGPSCoordinate: 'Coordenada GPS propera',
|
||||
timeZone: 'Zona horària',
|
||||
color: 'Color',
|
||||
department: 'Departament',
|
||||
productName: 'Nom del producte',
|
||||
price: 'Preu',
|
||||
productAdjective: 'Adjectiu del producte',
|
||||
productMaterial: 'Material del producte',
|
||||
product: 'Producte',
|
||||
productDescription: 'Descripció del producte',
|
||||
suffixes: 'Sufixos',
|
||||
companyName: 'Nom de l\'empresa',
|
||||
companySuffix: 'Sufix de l\'empresa',
|
||||
catchPhrase: 'Frase feta',
|
||||
bs: 'BS',
|
||||
catchPhraseAdjective: 'Adjectiu de la frase feta',
|
||||
catchPhraseDescriptor: 'Descriptor de la frase feta',
|
||||
catchPhraseNoun: 'Substantiu de la frase feta',
|
||||
bsAdjective: 'Adjectiu BS',
|
||||
bsBuzz: 'Buzz BS',
|
||||
bsNoun: 'Substantiu BS',
|
||||
column: 'Columna',
|
||||
type: 'Tipus',
|
||||
collation: 'Ordenació',
|
||||
engine: 'Motor',
|
||||
past: 'Passat',
|
||||
now: 'Ara',
|
||||
future: 'Futur',
|
||||
between: 'Entre',
|
||||
recent: 'Recent',
|
||||
soon: 'Aviat',
|
||||
month: 'Mes',
|
||||
weekday: 'Dia de la setmana',
|
||||
account: 'Compte',
|
||||
accountName: 'Nom del compte',
|
||||
routingNumber: 'Número de ruta',
|
||||
mask: 'Màscara',
|
||||
amount: 'Quantitat',
|
||||
transactionType: 'Tipus de transacció',
|
||||
currencyCode: 'Codi de moneda',
|
||||
currencyName: 'Nom de la moneda',
|
||||
currencySymbol: 'Símbol de moneda',
|
||||
bitcoinAddress: 'Adreça Bitcoin',
|
||||
litecoinAddress: 'Adreça Litecoin',
|
||||
creditCardNumber: 'Número de targeta de crèdit',
|
||||
creditCardCVV: 'CVV de la targeta de crèdit',
|
||||
ethereumAddress: 'Adreça Ethereum',
|
||||
iban: 'Iban',
|
||||
bic: 'Bic',
|
||||
transactionDescription: 'Descripció de la transacció',
|
||||
branch: 'Branca',
|
||||
commitEntry: 'Entrada de commit',
|
||||
commitMessage: 'Missatge de commit',
|
||||
commitSha: 'SHA de commit',
|
||||
shortSha: 'SHA curt',
|
||||
abbreviation: 'Abreviació',
|
||||
adjective: 'Adjectiu',
|
||||
noun: 'Substantiu',
|
||||
verb: 'Verb',
|
||||
ingverb: 'Gerundi',
|
||||
phrase: 'Frase',
|
||||
avatar: 'Avatar',
|
||||
email: 'Correu electrònic',
|
||||
exampleEmail: 'Correu electrònic d\'exemple',
|
||||
userName: 'Nom d\'usuari',
|
||||
protocol: 'Protocol',
|
||||
url: 'Url',
|
||||
domainName: 'Nom de domini',
|
||||
domainSuffix: 'Sufix de domini',
|
||||
domainWord: 'Paraula de domini',
|
||||
ip: 'Ip',
|
||||
ipv6: 'Ipv6',
|
||||
userAgent: 'Agent d\'usuari',
|
||||
mac: 'Mac',
|
||||
password: 'Contrasenya',
|
||||
word: 'Paraula',
|
||||
words: 'Paraules',
|
||||
sentence: 'Frase',
|
||||
slug: 'Slug',
|
||||
sentences: 'Frases',
|
||||
paragraph: 'Paràgraf',
|
||||
paragraphs: 'Paràgrafs',
|
||||
text: 'Text',
|
||||
lines: 'Línies',
|
||||
genre: 'Gènere',
|
||||
firstName: 'Nom',
|
||||
lastName: 'Cognom',
|
||||
middleName: 'Segon nom',
|
||||
findName: 'Nom complet',
|
||||
jobTitle: 'Títol del treball',
|
||||
gender: 'Gènere',
|
||||
prefix: 'Prefix',
|
||||
suffix: 'Sufix',
|
||||
title: 'Títol',
|
||||
jobDescriptor: 'Descriptor de treball',
|
||||
jobArea: 'Àrea de treball',
|
||||
jobType: 'Tipus de treball',
|
||||
phoneNumber: 'Número de telèfon',
|
||||
phoneNumberFormat: 'Format de número de telèfon',
|
||||
phoneFormats: 'Formats de telèfon',
|
||||
number: 'Número',
|
||||
float: 'Decimal',
|
||||
arrayElement: 'Element de matriu',
|
||||
arrayElements: 'Elements de matriu',
|
||||
objectElement: 'Element d\'objecte',
|
||||
uuid: 'Uuid',
|
||||
boolean: 'Booleà',
|
||||
image: 'Imatge',
|
||||
locale: 'Localització',
|
||||
alpha: 'Alfa',
|
||||
alphaNumeric: 'Alfanumèric',
|
||||
hexaDecimal: 'Hexadecimal',
|
||||
fileName: 'Nom del fitxer',
|
||||
commonFileName: 'Nom de fitxer comú',
|
||||
mimeType: 'Tipus de mime',
|
||||
commonFileType: 'Tipus de fitxer comú',
|
||||
commonFileExt: 'Extensió de fitxer comú',
|
||||
fileType: 'Tipus de fitxer',
|
||||
fileExt: 'Extensió de fitxer',
|
||||
directoryPath: 'Ruta del directori',
|
||||
filePath: 'Ruta del fitxer',
|
||||
semver: 'Semver',
|
||||
manufacturer: 'Fabricant',
|
||||
model: 'Model',
|
||||
fuel: 'Combustible',
|
||||
vin: 'Vin'
|
||||
}
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user