mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
dea5ec7513 | |||
be816e8588 | |||
1e938adc5d | |||
8735a0c5f9 | |||
3dde1c109e | |||
d0b3e1b1b8 | |||
c20bff7bcb | |||
9f5ec0276c | |||
55932fe115 | |||
d374372e20 | |||
bb5f44681f | |||
49a4e1cb7b | |||
c2f76e490a | |||
e349dd5eab | |||
280697698e | |||
0783f8b57e | |||
c981244d7a | |||
dcb135dd01 | |||
99f7511c4d | |||
fe4c8e12b3 | |||
21728a663d | |||
9ca03f4625 | |||
affb7288b0 | |||
614e0d3275 | |||
feef5e30ee | |||
82c25711b6 | |||
2ca2988832 | |||
e3f259c6e8 | |||
e7401cc96e | |||
13b9840f3d | |||
d20414b692 | |||
22a8c25717 | |||
db47b4040a | |||
e89911b185 | |||
fccfe92453 | |||
d465e18dba | |||
ffb1712a59 | |||
9f6a183d9b | |||
1f80a64fe1 | |||
fc651149b9 | |||
964570247f | |||
8a6c59f7ce | |||
4d844fe2c9 | |||
d892fa6fb3 | |||
8c9e4f6e96 | |||
966ca60c89 | |||
9bbe218f90 | |||
a1c6be372b |
9
.github/ISSUE_TEMPLATE/bug_report.md
vendored
9
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -3,7 +3,7 @@ name: Bug report
|
|||||||
about: Create a report to help us improve
|
about: Create a report to help us improve
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: ''
|
||||||
assignees: ''
|
assignees: Fabio286
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -25,13 +25,6 @@ If applicable, add screenshots to help explain your problem.
|
|||||||
|
|
||||||
**Desktop (please complete the following information):**
|
**Desktop (please complete the following information):**
|
||||||
- OS: [e.g. iOS]
|
- OS: [e.g. iOS]
|
||||||
- Browser [e.g. chrome, safari]
|
|
||||||
- Version [e.g. 22]
|
|
||||||
|
|
||||||
**Smartphone (please complete the following information):**
|
|
||||||
- Device: [e.g. iPhone6]
|
|
||||||
- OS: [e.g. iOS8.1]
|
|
||||||
- Browser [e.g. stock browser, safari]
|
|
||||||
- Version [e.g. 22]
|
- Version [e.g. 22]
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -3,7 +3,7 @@ name: Feature request
|
|||||||
about: Suggest an idea for this project
|
about: Suggest an idea for this project
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: ''
|
||||||
assignees: ''
|
assignees: Fabio286
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
26
.github/workflows/build.yml
vendored
Normal file
26
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: Build/release
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out Git repository
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Install Node.js, NPM and Yarn
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: 10
|
||||||
|
|
||||||
|
- name: Build/release Electron app
|
||||||
|
uses: samuelmeuli/action-electron-builder@v1
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.github_token }}
|
||||||
|
release: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
@@ -8,7 +8,8 @@
|
|||||||
"stylelint-scss"
|
"stylelint-scss"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"at-rule-no-unknown": null
|
"at-rule-no-unknown": null,
|
||||||
|
"no-descending-specificity": null
|
||||||
},
|
},
|
||||||
"syntax": "scss"
|
"syntax": "scss"
|
||||||
}
|
}
|
69
CHANGELOG.md
69
CHANGELOG.md
@@ -2,6 +2,75 @@
|
|||||||
|
|
||||||
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.
|
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.1.2](https://github.com/Fabio286/antares/compare/v0.1.1...v0.1.2) (2021-04-11)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* in-app last release changelog ([1e938ad](https://github.com/Fabio286/antares/commit/1e938adc5d8eb5ad16ab16342375eecd88f68d20))
|
||||||
|
* **PostgreSQL:** edit timezone in cell editor ([8735a0c](https://github.com/Fabio286/antares/commit/8735a0c5f9e5b6b3bcaadf37ce158aa7beae2c48))
|
||||||
|
* **PostgreSQL:** procedures management ([3dde1c1](https://github.com/Fabio286/antares/commit/3dde1c109e23342d94362626ef7350dc123ea859))
|
||||||
|
* **PostgreSQL:** support of arrays in table settings ([d0b3e1b](https://github.com/Fabio286/antares/commit/d0b3e1b1b8be9d2c038d70e16d4478671315de8f))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* cell edit doesn't properly use primary or unique index to update if both present, closes [#51](https://github.com/Fabio286/antares/issues/51) ([55932fe](https://github.com/Fabio286/antares/commit/55932fe11583bd5ff48f82b8408965adba4f5071))
|
||||||
|
* deletion of rows from query results ([c20bff7](https://github.com/Fabio286/antares/commit/c20bff7bcbe340ac99ebcacaba3359edd61c068a))
|
||||||
|
* no foreign key select when cell value is NULL, closes [#50](https://github.com/Fabio286/antares/issues/50) ([9f5ec02](https://github.com/Fabio286/antares/commit/9f5ec0276c92904975fdaea34b4c845c92bfe8d4))
|
||||||
|
* wrong datetime conversion when updating a row without an unique key ([d374372](https://github.com/Fabio286/antares/commit/d374372e208318d7e50b258a8041145bdf7992c5))
|
||||||
|
* **PostgreSQL:** issue with selected schema different than public ([49a4e1c](https://github.com/Fabio286/antares/commit/49a4e1cb7b24642641265d5830d3fee370cceeb4))
|
||||||
|
* **UI:** white readonly inputs with dark theme ([bb5f446](https://github.com/Fabio286/antares/commit/bb5f44681f87aacf2cd2f60a6d958c5732289790))
|
||||||
|
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
* **UI:** improved setting modal rendering ([be816e8](https://github.com/Fabio286/antares/commit/be816e85888b4f3d26cbb9caac0adbc4dde0ea94))
|
||||||
|
|
||||||
|
### [0.1.1](https://github.com/Fabio286/antares/compare/v0.1.0...v0.1.1) (2021-04-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* scratchpad to save persistent notes ([e349dd5](https://github.com/Fabio286/antares/commit/e349dd5eaba608591257f2799b830805e4936c27))
|
||||||
|
* **PostgreSQL:** foreign keys management ([fe4c8e1](https://github.com/Fabio286/antares/commit/fe4c8e12b39dd3cdfc233f07e3fe2ff0676252b0))
|
||||||
|
* **PostgreSQL:** indexes management ([9ca03f4](https://github.com/Fabio286/antares/commit/9ca03f462560b634970a19d3d97b878d60509acc))
|
||||||
|
* **PostgreSQL:** table fields edit ([e3f259c](https://github.com/Fabio286/antares/commit/e3f259c6e8327d71bd7dd0a9c33d957dc6ca1fb8))
|
||||||
|
* **PostgreSQL:** tables addition ([feef5e3](https://github.com/Fabio286/antares/commit/feef5e30eec915cbb219223cc428bd4e98d2e9c5))
|
||||||
|
* **PostgreSQL:** unique keys management ([614e0d3](https://github.com/Fabio286/antares/commit/614e0d32758c13b59139d349d4682a5bafc3ca88))
|
||||||
|
* **PostgreSQL:** views management ([99f7511](https://github.com/Fabio286/antares/commit/99f7511c4d5fab4030b30d5134cd03248167faea))
|
||||||
|
* **UI:** light theme ([2806976](https://github.com/Fabio286/antares/commit/280697698ea5fae6d54326970c823878888c196c))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **UI:** editor theme preview not properly loaded in some cases ([c981244](https://github.com/Fabio286/antares/commit/c981244d7aa93ca18ca2de44bf8df06f253b9d20))
|
||||||
|
* fields of ref. table not automatically loaded in foreign keys modal ([e7401cc](https://github.com/Fabio286/antares/commit/e7401cc96e76e00100a88eea9f40541fd8027adb))
|
||||||
|
* hide update tab for Windows Store distributions ([dcb135d](https://github.com/Fabio286/antares/commit/dcb135dd015b8f8c6cfb44021211bb8cf3089192))
|
||||||
|
|
||||||
|
## [0.1.0](https://github.com/Fabio286/antares/compare/v0.0.20...v0.1.0) (2021-03-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **PostgreSQL:** database in connection parameters ([9645702](https://github.com/Fabio286/antares/commit/964570247ff5b7b8317419730eec5bed4f0f0580))
|
||||||
|
* **PostgreSQL:** edit array and text search fields ([fc65114](https://github.com/Fabio286/antares/commit/fc651149b95399c52d2d63e946731e9c1b0303a9))
|
||||||
|
* **PostgreSQL:** insert and edit blob fields ([1f80a64](https://github.com/Fabio286/antares/commit/1f80a64fe1400baacca26f1a762c5aeb4ef6350d))
|
||||||
|
* **PostgreSQL:** partial postgre implementation ([d892fa6](https://github.com/Fabio286/antares/commit/d892fa6fb3e86fbb96887d8eb67319ae855260a1))
|
||||||
|
* **PostgreSQL:** support to microseconds ([d465e18](https://github.com/Fabio286/antares/commit/d465e18dba8ea3aa00726e33f9b1f70ca4c0683c))
|
||||||
|
* **UI:** support to boolean fields ([ffb1712](https://github.com/Fabio286/antares/commit/ffb1712a593d1421793011e48a17369b884ea3c0))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* update or delete rows with more than one primary key ([22a8c25](https://github.com/Fabio286/antares/commit/22a8c25717a4d4b285855426098a3a2846ce7448))
|
||||||
|
* **MySQL:** handle NEWDECIMAL data type ([a1c6be3](https://github.com/Fabio286/antares/commit/a1c6be372b570cf13e89ef7ecf9b7a7c033a9293))
|
||||||
|
* **PostgreSQL:** issue getting foreign keys informations ([db47b40](https://github.com/Fabio286/antares/commit/db47b4040a5282a6ac0711b1926c4c2ac867999e))
|
||||||
|
* remove last char from datetime and time if is a dot ([e89911b](https://github.com/Fabio286/antares/commit/e89911b1851c19813d4acf2c79adfbc2ac7c1112))
|
||||||
|
* **PostgreSQL:** single quote escape ([9f6a183](https://github.com/Fabio286/antares/commit/9f6a183d9b293dfe9ad9f3759f2375f05f37db8e))
|
||||||
|
* **PostgreSQL:** various issues in query results ([fccfe92](https://github.com/Fabio286/antares/commit/fccfe92453325cd54c0331cc5670af0a56822c5b))
|
||||||
|
* schema content not loaded if selected with right click ([8a6c59f](https://github.com/Fabio286/antares/commit/8a6c59f7ce7d051315b04cea38a96e4739b5b9d3))
|
||||||
|
|
||||||
### [0.0.20](https://github.com/Fabio286/antares/compare/v0.0.19...v0.0.20) (2021-03-13)
|
### [0.0.20](https://github.com/Fabio286/antares/compare/v0.0.19...v0.0.20) (2021-03-13)
|
||||||
|
|
||||||
|
|
||||||
|
29
README.md
29
README.md
@@ -1,19 +1,19 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img width="800" src="https://raw.githubusercontent.com/Fabio286/antares/master/docs/screen-alpha.png">
|
<img width="800" src="https://raw.githubusercontent.com/Fabio286/antares/master/docs/gh-logo.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# Antares SQL Client
|
# Antares SQL Client
|
||||||
|
|
||||||
 [](https://travis-ci.com/Fabio286/antares)  
|
 [](https://travis-ci.com/Fabio286/antares)   [](https://snapcraft.io/antares) [](https://snapcraft.io/antares)
|
||||||
|
|
||||||
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.
|
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.
|
||||||
My target is to support as many databases as possible, and all major operating systems, including the ARM versions.
|
My target is to support as many databases as possible, and all major operating systems, including the ARM versions.
|
||||||
|
|
||||||
**At the moment this application is an alpha, it lacks many features** and supports only MySQL.
|
**At the moment this application is in development state, many features will come in future updates**, and supports only MySQL/MariaDB and PostgreSQL (partially).
|
||||||
Most of its current features might be enough for basic MySQL use, so give it a chance and send me your feedback, I would really appreciate it.
|
Many of its current features are enough to have a pleasant user experience with MySQL/MariaDB, and basic functionalites with PostgreSQL, so give it a chance and send me your feedback, I would really appreciate it.
|
||||||
I'm actively working on it (yes, i'm a lone dev), hoping to provide cool features and fixes as soon as possible.
|
I'm actively working on it, hoping to provide cool features and fixes as soon as possible.
|
||||||
|
|
||||||
🔗 If you are curious to try this early state of Antares you can download and install the [latest release](https://github.com/Fabio286/antares/releases).
|
🔗 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 watch this repo on **Release only** channel.
|
👁 To stay tuned for new releases watch this repo on **Release only** channel.
|
||||||
🌟 Don't forget to **leave a star** if you appreciate this project.
|
🌟 Don't forget to **leave a star** if you appreciate this project.
|
||||||
|
|
||||||
@@ -21,7 +21,12 @@ I'm actively working on it (yes, i'm a lone dev), hoping to provide cool feature
|
|||||||
|
|
||||||
Why am I developing an SQL client when there are a lot of them on the market?
|
Why am I developing an SQL client when there are a lot of them on the market?
|
||||||
The main goal is to develop a totally free, full featured, cross platform and open source alternative, empowered by JavaScript's ecosystem.
|
The main goal is to develop a totally free, full featured, cross platform and open source alternative, empowered by JavaScript's ecosystem.
|
||||||
An application created with minimalism and semplicity in mind, with features in the right places, not hundreds of tiny buttons or submenu.
|
A modern application created with minimalism and semplicity in mind, with features in the right places, not hundreds of tiny buttons, tabs or submenu.
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
[](https://snapcraft.io/antares) [](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)**
|
||||||
|
|
||||||
## How to contribute
|
## How to contribute
|
||||||
|
|
||||||
@@ -36,7 +41,8 @@ An application created with minimalism and semplicity in mind, with features in
|
|||||||
- Fake table data filler.
|
- Fake table data filler.
|
||||||
- Run queries on multiple tabs.
|
- Run queries on multiple tabs.
|
||||||
- Query suggestions and auto complete.
|
- Query suggestions and auto complete.
|
||||||
- Native dark theme.
|
- Dark and light theme.
|
||||||
|
- Scratchpad.
|
||||||
- Multi language.
|
- Multi language.
|
||||||
- Secure password storage.
|
- Secure password storage.
|
||||||
- Auto updates.
|
- Auto updates.
|
||||||
@@ -46,7 +52,7 @@ An application created with minimalism and semplicity in mind, with features in
|
|||||||
This is a roadmap with major features will come in near future.
|
This is a roadmap with major features will come in near future.
|
||||||
|
|
||||||
- Support for other databases.
|
- Support for other databases.
|
||||||
- Database tools (variables, process list...).
|
- Database tools.
|
||||||
- SSH tunnel support.
|
- SSH tunnel support.
|
||||||
- Users management (add/edit/delete).
|
- Users management (add/edit/delete).
|
||||||
- UI/UX improvements.
|
- UI/UX improvements.
|
||||||
@@ -55,7 +61,6 @@ This is a roadmap with major features will come in near future.
|
|||||||
- More keyboard shortcuts.
|
- More keyboard shortcuts.
|
||||||
- Query logs console.
|
- Query logs console.
|
||||||
- Import/export and migration.
|
- Import/export and migration.
|
||||||
- Light theme.
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
@@ -73,7 +78,7 @@ Depending on your distribution, you will need to run the following command:
|
|||||||
### Databases
|
### Databases
|
||||||
|
|
||||||
- [x] MySQL/MariaDB
|
- [x] MySQL/MariaDB
|
||||||
- [ ] PostgreSQL
|
- [x] PostgreSQL (partially, work in progress)
|
||||||
- [ ] SQLite
|
- [ ] SQLite
|
||||||
- [ ] MSSQL
|
- [ ] MSSQL
|
||||||
- [ ] OracleDB
|
- [ ] OracleDB
|
||||||
@@ -85,7 +90,7 @@ Depending on your distribution, you will need to run the following command:
|
|||||||
|
|
||||||
- [x] Windows
|
- [x] Windows
|
||||||
- [x] Linux
|
- [x] Linux
|
||||||
- [x] MacOS (i need feedbacks)
|
- [x] MacOS (not tested due lack of hardware)
|
||||||
|
|
||||||
#### • ARM
|
#### • ARM
|
||||||
|
|
||||||
|
BIN
build/appx/Square150x150Logo.png
Normal file
BIN
build/appx/Square150x150Logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.4 KiB |
BIN
build/appx/Square44x44Logo.png
Normal file
BIN
build/appx/Square44x44Logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
BIN
build/appx/StoreLogo.png
Normal file
BIN
build/appx/StoreLogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
build/appx/Wide310x150Logo.png
Normal file
BIN
build/appx/Wide310x150Logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
BIN
docs/gh-logo.png
Normal file
BIN
docs/gh-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
13
package.json
13
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "antares",
|
"name": "antares",
|
||||||
"productName": "Antares",
|
"productName": "Antares",
|
||||||
"version": "0.0.20",
|
"version": "0.1.2",
|
||||||
"description": "A cross-platform easy to use SQL client.",
|
"description": "A cross-platform easy to use SQL client.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": "https://github.com/Fabio286/antares.git",
|
"repository": "https://github.com/Fabio286/antares.git",
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
"dev": "cross-env NODE_ENV=development electron-webpack dev",
|
"dev": "cross-env NODE_ENV=development electron-webpack dev",
|
||||||
"compile": "electron-webpack",
|
"compile": "electron-webpack",
|
||||||
"build": "cross-env NODE_ENV=production npm run compile && electron-builder",
|
"build": "cross-env NODE_ENV=production npm run compile && electron-builder",
|
||||||
|
"build:appx": "npm run build -- --win appx",
|
||||||
"release": "standard-version",
|
"release": "standard-version",
|
||||||
"release:pre": "npm run release -- --prerelease alpha",
|
"release:pre": "npm run release -- --prerelease alpha",
|
||||||
"release:snap": "npm run build -- --linux snap && snapcraft upload --release=edge ./dist/Antares-${npm_package_version}-linux_amd64.snap",
|
|
||||||
"test": "npm run lint",
|
"test": "npm run lint",
|
||||||
"lint": "eslint . --ext .js,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"",
|
"lint": "eslint . --ext .js,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"",
|
||||||
"lint:fix": "eslint . --ext .js,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix"
|
"lint:fix": "eslint . --ext .js,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix"
|
||||||
@@ -53,6 +53,12 @@
|
|||||||
},
|
},
|
||||||
"portable": {
|
"portable": {
|
||||||
"artifactName": "${productName}-${version}-portable.exe"
|
"artifactName": "${productName}-${version}-portable.exe"
|
||||||
|
},
|
||||||
|
"appx": {
|
||||||
|
"displayName": "Antares SQL Client",
|
||||||
|
"identityName": "62514FabioDiStasio.AntaresSQLClient",
|
||||||
|
"publisher": "CN=1A2729ED-865C-41D2-9038-39AE2A63AA52",
|
||||||
|
"applicationId": "FabioDiStasio.AntaresSQLClient"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electronWebpack": {
|
"electronWebpack": {
|
||||||
@@ -68,10 +74,13 @@
|
|||||||
"electron-updater": "^4.3.5",
|
"electron-updater": "^4.3.5",
|
||||||
"faker": "^5.3.1",
|
"faker": "^5.3.1",
|
||||||
"keytar": "^7.3.0",
|
"keytar": "^7.3.0",
|
||||||
|
"marked": "^2.0.2",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"mssql": "^6.2.3",
|
"mssql": "^6.2.3",
|
||||||
"mysql2": "^2.2.5",
|
"mysql2": "^2.2.5",
|
||||||
|
"node-sql-parser": "^3.1.0",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
|
"pgsql-ast-parser": "^7.0.2",
|
||||||
"source-map-support": "^0.5.16",
|
"source-map-support": "^0.5.16",
|
||||||
"spectre.css": "^0.5.9",
|
"spectre.css": "^0.5.9",
|
||||||
"v-mask": "^2.2.4",
|
"v-mask": "^2.2.4",
|
||||||
|
56
src/common/customizations/defaults.js
Normal file
56
src/common/customizations/defaults.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
module.exports = {
|
||||||
|
// Defaults
|
||||||
|
defaultPort: null,
|
||||||
|
defaultUser: null,
|
||||||
|
defaultDatabase: null,
|
||||||
|
// Core
|
||||||
|
database: false,
|
||||||
|
collations: false,
|
||||||
|
engines: false,
|
||||||
|
// Tools
|
||||||
|
processesList: false,
|
||||||
|
usersManagement: false,
|
||||||
|
variables: false,
|
||||||
|
// Structure
|
||||||
|
schemas: false,
|
||||||
|
tables: false,
|
||||||
|
views: false,
|
||||||
|
triggers: false,
|
||||||
|
routines: false,
|
||||||
|
functions: false,
|
||||||
|
schedulers: false,
|
||||||
|
// Settings
|
||||||
|
tableAdd: false,
|
||||||
|
viewAdd: false,
|
||||||
|
triggerAdd: false,
|
||||||
|
routineAdd: false,
|
||||||
|
functionAdd: false,
|
||||||
|
schedulerAdd: false,
|
||||||
|
databaseEdit: false,
|
||||||
|
schemaEdit: false,
|
||||||
|
tableSettings: false,
|
||||||
|
viewSettings: false,
|
||||||
|
triggerSettings: false,
|
||||||
|
routineSettings: false,
|
||||||
|
functionSettings: false,
|
||||||
|
schedulerSettings: false,
|
||||||
|
indexes: false,
|
||||||
|
foreigns: false,
|
||||||
|
sortableFields: false,
|
||||||
|
unsigned: false,
|
||||||
|
nullable: false,
|
||||||
|
zerofill: false,
|
||||||
|
autoIncrement: false,
|
||||||
|
comment: false,
|
||||||
|
collation: false,
|
||||||
|
definer: false,
|
||||||
|
onUpdate: false,
|
||||||
|
tableArray: false,
|
||||||
|
viewAlgorithm: false,
|
||||||
|
viewSqlSecurity: false,
|
||||||
|
viewUpdateOption: false,
|
||||||
|
procedureDeterministic: false,
|
||||||
|
procedureDataAccess: false,
|
||||||
|
procedureSql: false,
|
||||||
|
parametersLength: false
|
||||||
|
};
|
5
src/common/customizations/index.js
Normal file
5
src/common/customizations/index.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
maria: require('./mysql'),
|
||||||
|
mysql: require('./mysql'),
|
||||||
|
pg: require('./postgresql')
|
||||||
|
};
|
54
src/common/customizations/mysql.js
Normal file
54
src/common/customizations/mysql.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
const defaults = require('./defaults');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
...defaults,
|
||||||
|
// Defaults
|
||||||
|
defaultPort: 3306,
|
||||||
|
defaultUser: 'root',
|
||||||
|
defaultDatabase: null,
|
||||||
|
// Core
|
||||||
|
collations: true,
|
||||||
|
engines: true,
|
||||||
|
// Tools
|
||||||
|
processesList: true,
|
||||||
|
// Structure
|
||||||
|
schemas: true,
|
||||||
|
tables: true,
|
||||||
|
views: true,
|
||||||
|
triggers: true,
|
||||||
|
routines: true,
|
||||||
|
functions: true,
|
||||||
|
schedulers: true,
|
||||||
|
// Settings
|
||||||
|
tableAdd: true,
|
||||||
|
viewAdd: true,
|
||||||
|
triggerAdd: true,
|
||||||
|
routineAdd: true,
|
||||||
|
functionAdd: true,
|
||||||
|
schedulerAdd: true,
|
||||||
|
schemaEdit: true,
|
||||||
|
tableSettings: true,
|
||||||
|
viewSettings: true,
|
||||||
|
triggerSettings: true,
|
||||||
|
routineSettings: true,
|
||||||
|
functionSettings: true,
|
||||||
|
schedulerSettings: true,
|
||||||
|
indexes: true,
|
||||||
|
foreigns: true,
|
||||||
|
sortableFields: true,
|
||||||
|
unsigned: true,
|
||||||
|
nullable: true,
|
||||||
|
zerofill: true,
|
||||||
|
autoIncrement: true,
|
||||||
|
comment: true,
|
||||||
|
collation: true,
|
||||||
|
definer: true,
|
||||||
|
onUpdate: true,
|
||||||
|
viewAlgorithm: true,
|
||||||
|
viewSqlSecurity: true,
|
||||||
|
viewUpdateOption: true,
|
||||||
|
procedureDeterministic: true,
|
||||||
|
procedureDataAccess: true,
|
||||||
|
procedureSql: 'BEGIN\r\n\r\nEND',
|
||||||
|
parametersLength: true
|
||||||
|
};
|
39
src/common/customizations/postgresql.js
Normal file
39
src/common/customizations/postgresql.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
const defaults = require('./defaults');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
...defaults,
|
||||||
|
// Defaults
|
||||||
|
defaultPort: 5432,
|
||||||
|
defaultUser: 'postgres',
|
||||||
|
defaultDatabase: 'postgres',
|
||||||
|
// Core
|
||||||
|
database: true,
|
||||||
|
// Tools
|
||||||
|
processesList: true,
|
||||||
|
// Structure
|
||||||
|
tables: true,
|
||||||
|
views: true,
|
||||||
|
triggers: false,
|
||||||
|
routines: true,
|
||||||
|
functions: false,
|
||||||
|
schedulers: false,
|
||||||
|
// Settings
|
||||||
|
tableAdd: true,
|
||||||
|
viewAdd: true,
|
||||||
|
triggerAdd: false,
|
||||||
|
routineAdd: true,
|
||||||
|
functionAdd: false,
|
||||||
|
databaseEdit: false,
|
||||||
|
tableSettings: true,
|
||||||
|
viewSettings: true,
|
||||||
|
triggerSettings: false,
|
||||||
|
routineSettings: true,
|
||||||
|
functionSettings: false,
|
||||||
|
schedulerSettings: false,
|
||||||
|
indexes: true,
|
||||||
|
foreigns: true,
|
||||||
|
sortableFields: false,
|
||||||
|
nullable: true,
|
||||||
|
tableArray: true,
|
||||||
|
procedureSql: '$BODY$\r\n\r\n$BODY$'
|
||||||
|
};
|
@@ -4,7 +4,7 @@ module.exports = [
|
|||||||
types: [
|
types: [
|
||||||
{
|
{
|
||||||
name: 'TINYINT',
|
name: 'TINYINT',
|
||||||
length: true,
|
length: 4,
|
||||||
collation: false,
|
collation: false,
|
||||||
unsigned: true,
|
unsigned: true,
|
||||||
zerofill: true
|
zerofill: true
|
||||||
|
292
src/common/data-types/postgresql.js
Normal file
292
src/common/data-types/postgresql.js
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
group: 'integer',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'SMALLINT',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'INTEGER',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BIGINT',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'DECIMAL',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'NUMERIC',
|
||||||
|
length: true,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SMALLSERIAL',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SERIAL',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BIGSERIAL',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'float',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'REAL',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'DOUBLE PRECISION',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'monetary',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'money',
|
||||||
|
length: false,
|
||||||
|
unsigned: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'string',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'CHARACTER VARYING',
|
||||||
|
length: true,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CHARACTER',
|
||||||
|
length: true,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TEXT',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '"CHAR"',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'NAME',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'binary',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'BYTEA',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'time',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'TIMESTAMP WITHOUT TIME ZONE',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TIMESTAMP WITH TIME ZONE',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'DATE',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TIME WITHOUT TIME ZONE',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TIME WITH TIME ZONE',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'INTERVAL',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'boolean',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'BOOLEAN',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'geometric',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'POINT',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'LINE',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'LSEG',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BOX',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PATH',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'POLYGON',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CIRCLE',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'network',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'CIDR',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'INET',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'MACADDR',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'MACADDR8',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'bit',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'BIT',
|
||||||
|
length: true,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'BIT VARYING',
|
||||||
|
length: true,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'text search',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'TSVECTOR',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'TSQUERY',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'uuid',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'UUID',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'xml',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'XML',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: 'json',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
name: 'JSON',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'JSONB',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'JSONPATH',
|
||||||
|
length: false,
|
||||||
|
unsigned: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
@@ -1 +0,0 @@
|
|||||||
module.exports = [];
|
|
@@ -1,13 +1,82 @@
|
|||||||
export const TEXT = ['CHAR', 'VARCHAR'];
|
export const TEXT = [
|
||||||
export const LONG_TEXT = ['TEXT', 'MEDIUMTEXT', 'LONGTEXT'];
|
'CHAR',
|
||||||
|
'VARCHAR',
|
||||||
|
'CHARACTER',
|
||||||
|
'CHARACTER VARYING'
|
||||||
|
];
|
||||||
|
export const LONG_TEXT = [
|
||||||
|
'TEXT',
|
||||||
|
'MEDIUMTEXT',
|
||||||
|
'LONGTEXT'
|
||||||
|
];
|
||||||
|
|
||||||
export const NUMBER = ['INT', 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'BIGINT', 'DECIMAL', 'BOOL'];
|
export const ARRAY = [
|
||||||
export const FLOAT = ['FLOAT', 'DOUBLE'];
|
'ARRAY',
|
||||||
|
'ANYARRAY'
|
||||||
|
];
|
||||||
|
|
||||||
|
export const TEXT_SEARCH = [
|
||||||
|
'TSVECTOR',
|
||||||
|
'TSQUERY'
|
||||||
|
];
|
||||||
|
|
||||||
|
export const NUMBER = [
|
||||||
|
'INT',
|
||||||
|
'TINYINT',
|
||||||
|
'SMALLINT',
|
||||||
|
'MEDIUMINT',
|
||||||
|
'BIGINT',
|
||||||
|
'DECIMAL',
|
||||||
|
'NUMERIC',
|
||||||
|
'INTEGER',
|
||||||
|
'SMALLSERIAL',
|
||||||
|
'SERIAL',
|
||||||
|
'BIGSERIAL',
|
||||||
|
'OID',
|
||||||
|
'XID'
|
||||||
|
];
|
||||||
|
|
||||||
|
export const FLOAT = [
|
||||||
|
'FLOAT',
|
||||||
|
'DOUBLE',
|
||||||
|
'REAL',
|
||||||
|
'DOUBLE PRECISION',
|
||||||
|
'MONEY'
|
||||||
|
];
|
||||||
|
|
||||||
|
export const BOOLEAN = [
|
||||||
|
'BOOL',
|
||||||
|
'BOOLEAN'
|
||||||
|
];
|
||||||
|
|
||||||
export const DATE = ['DATE'];
|
export const DATE = ['DATE'];
|
||||||
export const TIME = ['TIME'];
|
export const TIME = [
|
||||||
export const DATETIME = ['DATETIME', 'TIMESTAMP'];
|
'TIME',
|
||||||
|
'TIME WITH TIME ZONE'
|
||||||
|
];
|
||||||
|
|
||||||
export const BLOB = ['BLOB', 'TINYBLOB', 'MEDIUMBLOB', 'LONGBLOB'];
|
export const DATETIME = [
|
||||||
|
'DATETIME',
|
||||||
|
'TIMESTAMP',
|
||||||
|
'TIMESTAMP WITHOUT TIME ZONE',
|
||||||
|
'TIMESTAMP WITH TIME ZONE'
|
||||||
|
];
|
||||||
|
|
||||||
export const BIT = ['BIT'];
|
// Used to check datetime fields only
|
||||||
|
export const HAS_TIMEZONE = [
|
||||||
|
'TIMESTAMP WITH TIME ZONE',
|
||||||
|
'TIME WITH TIME ZONE'
|
||||||
|
];
|
||||||
|
|
||||||
|
export const BLOB = [
|
||||||
|
'BLOB',
|
||||||
|
'TINYBLOB',
|
||||||
|
'MEDIUMBLOB',
|
||||||
|
'LONGBLOB',
|
||||||
|
'BYTEA'
|
||||||
|
];
|
||||||
|
|
||||||
|
export const BIT = [
|
||||||
|
'BIT',
|
||||||
|
'BIT VARYING'
|
||||||
|
];
|
||||||
|
5
src/common/index-types/postgresql.js
Normal file
5
src/common/index-types/postgresql.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = [
|
||||||
|
'PRIMARY',
|
||||||
|
'INDEX',
|
||||||
|
'UNIQUE'
|
||||||
|
];
|
@@ -8,9 +8,13 @@ export default connections => {
|
|||||||
host: conn.host,
|
host: conn.host,
|
||||||
port: +conn.port,
|
port: +conn.port,
|
||||||
user: conn.user,
|
user: conn.user,
|
||||||
password: conn.password
|
password: conn.password,
|
||||||
|
application_name: 'Antares SQL'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (conn.database)
|
||||||
|
params.database = conn.database;
|
||||||
|
|
||||||
if (conn.ssl) {
|
if (conn.ssl) {
|
||||||
params.ssl = {
|
params.ssl = {
|
||||||
key: conn.key ? fs.readFileSync(conn.key) : null,
|
key: conn.key ? fs.readFileSync(conn.key) : null,
|
||||||
@@ -47,9 +51,13 @@ export default connections => {
|
|||||||
host: conn.host,
|
host: conn.host,
|
||||||
port: +conn.port,
|
port: +conn.port,
|
||||||
user: conn.user,
|
user: conn.user,
|
||||||
password: conn.password
|
password: conn.password,
|
||||||
|
application_name: 'Antares SQL'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (conn.database)
|
||||||
|
params.database = conn.database;
|
||||||
|
|
||||||
if (conn.ssl) {
|
if (conn.ssl) {
|
||||||
params.ssl = {
|
params.ssl = {
|
||||||
key: conn.key ? fs.readFileSync(conn.key) : null,
|
key: conn.key ? fs.readFileSync(conn.key) : null,
|
||||||
@@ -59,13 +67,13 @@ export default connections => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const connection = ClientsFactory.getConnection({
|
|
||||||
client: conn.client,
|
|
||||||
params,
|
|
||||||
poolSize: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const connection = ClientsFactory.getConnection({
|
||||||
|
client: conn.client,
|
||||||
|
params,
|
||||||
|
poolSize: 1
|
||||||
|
});
|
||||||
|
|
||||||
await connection.connect();
|
await connection.connect();
|
||||||
|
|
||||||
const structure = await connection.getStructure(new Set());
|
const structure = await connection.getStructure(new Set());
|
||||||
|
@@ -7,7 +7,7 @@ import functions from './functions';
|
|||||||
import schedulers from './schedulers';
|
import schedulers from './schedulers';
|
||||||
import updates from './updates';
|
import updates from './updates';
|
||||||
import application from './application';
|
import application from './application';
|
||||||
import database from './database';
|
import schema from './schema';
|
||||||
import users from './users';
|
import users from './users';
|
||||||
|
|
||||||
const connections = {};
|
const connections = {};
|
||||||
@@ -20,7 +20,7 @@ export default () => {
|
|||||||
routines(connections);
|
routines(connections);
|
||||||
functions(connections);
|
functions(connections);
|
||||||
schedulers(connections);
|
schedulers(connections);
|
||||||
database(connections);
|
schema(connections);
|
||||||
users(connections);
|
users(connections);
|
||||||
updates();
|
updates();
|
||||||
application();
|
application();
|
||||||
|
@@ -2,10 +2,9 @@
|
|||||||
import { ipcMain } from 'electron';
|
import { ipcMain } from 'electron';
|
||||||
|
|
||||||
export default connections => {
|
export default connections => {
|
||||||
ipcMain.handle('create-database', async (event, params) => {
|
ipcMain.handle('create-schema', async (event, params) => {
|
||||||
try {
|
try {
|
||||||
const query = `CREATE DATABASE \`${params.name}\` COLLATE ${params.collation}`;
|
await connections[params.uid].createSchema(params);
|
||||||
await connections[params.uid].raw(query);
|
|
||||||
|
|
||||||
return { status: 'success' };
|
return { status: 'success' };
|
||||||
}
|
}
|
||||||
@@ -14,10 +13,9 @@ export default connections => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('update-database', async (event, params) => {
|
ipcMain.handle('update-schema', async (event, params) => {
|
||||||
try {
|
try {
|
||||||
const query = `ALTER DATABASE \`${params.name}\` COLLATE ${params.collation}`;
|
await connections[params.uid].alterSchema(params);
|
||||||
await connections[params.uid].raw(query);
|
|
||||||
|
|
||||||
return { status: 'success' };
|
return { status: 'success' };
|
||||||
}
|
}
|
||||||
@@ -26,10 +24,9 @@ export default connections => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('delete-database', async (event, params) => {
|
ipcMain.handle('delete-schema', async (event, params) => {
|
||||||
try {
|
try {
|
||||||
const query = `DROP DATABASE \`${params.database}\``;
|
await connections[params.uid].dropSchema(params);
|
||||||
await connections[params.uid].raw(query);
|
|
||||||
|
|
||||||
return { status: 'success' };
|
return { status: 'success' };
|
||||||
}
|
}
|
||||||
@@ -38,10 +35,9 @@ export default connections => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('get-database-collation', async (event, params) => { // TODO: move to mysql class
|
ipcMain.handle('get-schema-collation', async (event, params) => {
|
||||||
try {
|
try {
|
||||||
const query = `SELECT \`DEFAULT_COLLATION_NAME\` FROM \`information_schema\`.\`SCHEMATA\` WHERE \`SCHEMA_NAME\`='${params.database}'`;
|
const collation = await connections[params.uid].getDatabaseCollation(params);
|
||||||
const collation = await connections[params.uid].raw(query);
|
|
||||||
|
|
||||||
return { status: 'success', response: collation.rows.length ? collation.rows[0].DEFAULT_COLLATION_NAME : '' };
|
return { status: 'success', response: collation.rows.length ? collation.rows[0].DEFAULT_COLLATION_NAME : '' };
|
||||||
}
|
}
|
@@ -2,7 +2,7 @@ import { ipcMain } from 'electron';
|
|||||||
import faker from 'faker';
|
import faker from 'faker';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { sqlEscaper } from 'common/libs/sqlEscaper';
|
import { sqlEscaper } from 'common/libs/sqlEscaper';
|
||||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, BLOB, BIT, DATE, DATETIME } from 'common/fieldTypes';
|
import { TEXT, LONG_TEXT, ARRAY, TEXT_SEARCH, NUMBER, FLOAT, BLOB, BIT, DATE, DATETIME } from 'common/fieldTypes';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
export default (connections) => {
|
export default (connections) => {
|
||||||
@@ -59,23 +59,56 @@ export default (connections) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('update-table-cell', async (event, params) => {
|
ipcMain.handle('update-table-cell', async (event, params) => {
|
||||||
try {
|
try { // TODO: move to client classes
|
||||||
let escapedParam;
|
let escapedParam;
|
||||||
let reload = false;
|
let reload = false;
|
||||||
const id = typeof params.id === 'number' ? params.id : `"${params.id}"`;
|
const id = typeof params.id === 'number' ? params.id : `"${params.id}"`;
|
||||||
|
|
||||||
if ([...NUMBER, ...FLOAT].includes(params.type))
|
if ([...NUMBER, ...FLOAT].includes(params.type))
|
||||||
escapedParam = params.content;
|
escapedParam = params.content;
|
||||||
else if ([...TEXT, ...LONG_TEXT].includes(params.type))
|
else if ([...TEXT, ...LONG_TEXT].includes(params.type)) {
|
||||||
escapedParam = `"${sqlEscaper(params.content)}"`;
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
escapedParam = `"${sqlEscaper(params.content)}"`;
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ARRAY.includes(params.type))
|
||||||
|
escapedParam = `'${params.content}'`;
|
||||||
|
else if (TEXT_SEARCH.includes(params.type))
|
||||||
|
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||||
else if (BLOB.includes(params.type)) {
|
else if (BLOB.includes(params.type)) {
|
||||||
if (params.content) {
|
if (params.content) {
|
||||||
const fileBlob = fs.readFileSync(params.content);
|
let fileBlob;
|
||||||
escapedParam = `0x${fileBlob.toString('hex')}`;
|
|
||||||
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
fileBlob = fs.readFileSync(params.content);
|
||||||
|
escapedParam = `0x${fileBlob.toString('hex')}`;
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
fileBlob = fs.readFileSync(params.content);
|
||||||
|
escapedParam = `decode('${fileBlob.toString('hex')}', 'hex')`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
reload = true;
|
reload = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
escapedParam = '""';
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
escapedParam = '\'\'';
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
escapedParam = 'decode(\'\', \'hex\')';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ([...BIT].includes(params.type)) {
|
else if ([...BIT].includes(params.type)) {
|
||||||
escapedParam = `b'${sqlEscaper(params.content)}'`;
|
escapedParam = `b'${sqlEscaper(params.content)}'`;
|
||||||
@@ -84,32 +117,33 @@ export default (connections) => {
|
|||||||
else if (params.content === null)
|
else if (params.content === null)
|
||||||
escapedParam = 'NULL';
|
escapedParam = 'NULL';
|
||||||
else
|
else
|
||||||
escapedParam = `"${sqlEscaper(params.content)}"`;
|
escapedParam = `'${sqlEscaper(params.content)}'`;
|
||||||
|
|
||||||
if (params.primary) {
|
if (params.primary) { // TODO: handle multiple primary
|
||||||
await connections[params.uid]
|
await connections[params.uid]
|
||||||
.update({ [params.field]: `= ${escapedParam}` })
|
.update({ [params.field]: `= ${escapedParam}` })
|
||||||
.schema(params.schema)
|
.schema(params.schema)
|
||||||
.from(params.table)
|
.from(params.table)
|
||||||
.where({ [params.primary]: `= ${id}` })
|
.where({ [params.primary]: `= ${id}` })
|
||||||
|
.limit(1)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const { row } = params;
|
const { orgRow } = params;
|
||||||
reload = true;
|
reload = true;
|
||||||
|
|
||||||
for (const key in row) {
|
for (const key in orgRow) {
|
||||||
if (typeof row[key] === 'string')
|
if (typeof orgRow[key] === 'string')
|
||||||
row[key] = `'${row[key]}'`;
|
orgRow[key] = `'${orgRow[key]}'`;
|
||||||
|
|
||||||
row[key] = `= ${row[key]}`;
|
orgRow[key] = `= ${orgRow[key]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
await connections[params.uid]
|
await connections[params.uid]
|
||||||
.schema(params.schema)
|
.schema(params.schema)
|
||||||
.update({ [params.field]: `= ${escapedParam}` })
|
.update({ [params.field]: `= ${escapedParam}` })
|
||||||
.from(params.table)
|
.from(params.table)
|
||||||
.where(row)
|
.where(orgRow)
|
||||||
.limit(1)
|
.limit(1)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@@ -123,9 +157,13 @@ export default (connections) => {
|
|||||||
|
|
||||||
ipcMain.handle('delete-table-rows', async (event, params) => {
|
ipcMain.handle('delete-table-rows', async (event, params) => {
|
||||||
if (params.primary) {
|
if (params.primary) {
|
||||||
const idString = params.rows.map(row => typeof row[params.primary] === 'string'
|
const idString = params.rows.map(row => {
|
||||||
? `"${row[params.primary]}"`
|
const fieldName = Object.keys(row)[0].includes('.') ? `${params.table}.${params.primary}` : params.primary;
|
||||||
: row[params.primary]).join(',');
|
|
||||||
|
return typeof row[fieldName] === 'string'
|
||||||
|
? `"${row[fieldName]}"`
|
||||||
|
: row[fieldName];
|
||||||
|
}).join(',');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await connections[params.uid]
|
const result = await connections[params.uid]
|
||||||
@@ -167,7 +205,7 @@ export default (connections) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('insert-table-rows', async (event, params) => {
|
ipcMain.handle('insert-table-rows', async (event, params) => {
|
||||||
try {
|
try { // TODO: move to client classes
|
||||||
const insertObj = {};
|
const insertObj = {};
|
||||||
for (const key in params.row) {
|
for (const key in params.row) {
|
||||||
const type = params.fields[key];
|
const type = params.fields[key];
|
||||||
@@ -176,19 +214,46 @@ export default (connections) => {
|
|||||||
if (params.row[key] === null)
|
if (params.row[key] === null)
|
||||||
escapedParam = 'NULL';
|
escapedParam = 'NULL';
|
||||||
else if ([...NUMBER, ...FLOAT].includes(type))
|
else if ([...NUMBER, ...FLOAT].includes(type))
|
||||||
escapedParam = params.row[key];
|
escapedParam = +params.row[key];
|
||||||
else if ([...TEXT, ...LONG_TEXT].includes(type))
|
else if ([...TEXT, ...LONG_TEXT].includes(type)) {
|
||||||
escapedParam = `"${sqlEscaper(params.row[key])}"`;
|
switch (connections[params.uid]._client) {
|
||||||
else if (BLOB.includes(type)) {
|
case 'mysql':
|
||||||
if (params.row[key]) {
|
case 'maria':
|
||||||
const fileBlob = fs.readFileSync(params.row[key]);
|
escapedParam = `"${sqlEscaper(params.row[key].value)}"`;
|
||||||
escapedParam = `0x${fileBlob.toString('hex')}`;
|
break;
|
||||||
|
case 'pg':
|
||||||
|
escapedParam = `'${params.row[key].value.replaceAll('\'', '\'\'')}'`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (BLOB.includes(type)) {
|
||||||
|
if (params.row[key].value) {
|
||||||
|
let fileBlob;
|
||||||
|
|
||||||
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
fileBlob = fs.readFileSync(params.row[key].value);
|
||||||
|
escapedParam = `0x${fileBlob.toString('hex')}`;
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
fileBlob = fs.readFileSync(params.row[key].value);
|
||||||
|
escapedParam = `decode('${fileBlob.toString('hex')}', 'hex')`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
escapedParam = '""';
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
escapedParam = 'decode(\'\', \'hex\')';
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
escapedParam = '""';
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
escapedParam = `"${sqlEscaper(params.row[key])}"`;
|
|
||||||
|
|
||||||
insertObj[key] = escapedParam;
|
insertObj[key] = escapedParam;
|
||||||
}
|
}
|
||||||
@@ -209,7 +274,7 @@ export default (connections) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('insert-table-fake-rows', async (event, params) => {
|
ipcMain.handle('insert-table-fake-rows', async (event, params) => {
|
||||||
try {
|
try { // TODO: move to client classes
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
|
||||||
for (let i = 0; i < +params.repeat; i++) {
|
for (let i = 0; i < +params.repeat; i++) {
|
||||||
@@ -224,20 +289,49 @@ export default (connections) => {
|
|||||||
escapedParam = 'NULL';
|
escapedParam = 'NULL';
|
||||||
else if ([...NUMBER, ...FLOAT].includes(type))
|
else if ([...NUMBER, ...FLOAT].includes(type))
|
||||||
escapedParam = params.row[key].value;
|
escapedParam = params.row[key].value;
|
||||||
else if ([...TEXT, ...LONG_TEXT].includes(type))
|
else if ([...TEXT, ...LONG_TEXT].includes(type)) {
|
||||||
escapedParam = `"${sqlEscaper(params.row[key].value)}"`;
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
escapedParam = `"${sqlEscaper(params.row[key].value)}"`;
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
escapedParam = `'${params.row[key].value.replaceAll('\'', '\'\'')}'`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (BLOB.includes(type)) {
|
else if (BLOB.includes(type)) {
|
||||||
if (params.row[key].value) {
|
if (params.row[key].value) {
|
||||||
const fileBlob = fs.readFileSync(params.row[key].value);
|
let fileBlob;
|
||||||
escapedParam = `0x${fileBlob.toString('hex')}`;
|
|
||||||
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
fileBlob = fs.readFileSync(params.row[key].value);
|
||||||
|
escapedParam = `0x${fileBlob.toString('hex')}`;
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
fileBlob = fs.readFileSync(params.row[key].value);
|
||||||
|
escapedParam = `decode('${fileBlob.toString('hex')}', 'hex')`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (connections[params.uid]._client) {
|
||||||
|
case 'mysql':
|
||||||
|
case 'maria':
|
||||||
|
escapedParam = '""';
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
escapedParam = 'decode(\'\', \'hex\')';
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
escapedParam = '""';
|
|
||||||
}
|
}
|
||||||
else if (BIT.includes(type))
|
else if (BIT.includes(type))
|
||||||
escapedParam = `b'${sqlEscaper(params.row[key].value)}'`;
|
escapedParam = `b'${sqlEscaper(params.row[key].value)}'`;
|
||||||
else
|
else
|
||||||
escapedParam = `"${sqlEscaper(params.row[key].value)}"`;
|
escapedParam = `'${sqlEscaper(params.row[key].value)}'`;
|
||||||
|
|
||||||
insertObj[key] = escapedParam;
|
insertObj[key] = escapedParam;
|
||||||
}
|
}
|
||||||
@@ -261,10 +355,10 @@ export default (connections) => {
|
|||||||
if (typeof fakeValue === 'string') {
|
if (typeof fakeValue === 'string') {
|
||||||
if (params.row[key].length)
|
if (params.row[key].length)
|
||||||
fakeValue = fakeValue.substr(0, params.row[key].length);
|
fakeValue = fakeValue.substr(0, params.row[key].length);
|
||||||
fakeValue = `"${sqlEscaper(fakeValue)}"`;
|
fakeValue = `'${sqlEscaper(fakeValue)}'`;
|
||||||
}
|
}
|
||||||
else if ([...DATE, ...DATETIME].includes(type))
|
else if ([...DATE, ...DATETIME].includes(type))
|
||||||
fakeValue = `"${moment(fakeValue).format('YYYY-MM-DD HH:mm:ss.SSSSSS')}"`;
|
fakeValue = `'${moment(fakeValue).format('YYYY-MM-DD HH:mm:ss.SSSSSS')}'`;
|
||||||
|
|
||||||
insertObj[key] = fakeValue;
|
insertObj[key] = fakeValue;
|
||||||
}
|
}
|
||||||
@@ -289,13 +383,13 @@ export default (connections) => {
|
|||||||
ipcMain.handle('get-foreign-list', async (event, { uid, schema, table, column, description }) => {
|
ipcMain.handle('get-foreign-list', async (event, { uid, schema, table, column, description }) => {
|
||||||
try {
|
try {
|
||||||
const query = connections[uid]
|
const query = connections[uid]
|
||||||
.select(`${column} AS foreignColumn`)
|
.select(`${column} AS foreign_column`)
|
||||||
.schema(schema)
|
.schema(schema)
|
||||||
.from(table)
|
.from(table)
|
||||||
.orderBy('foreignColumn ASC');
|
.orderBy('foreign_column ASC');
|
||||||
|
|
||||||
if (description)
|
if (description)
|
||||||
query.select(`LEFT(${description}, 20) AS foreignDescription`);
|
query.select(`LEFT(${description}, 20) AS foreign_description`);
|
||||||
|
|
||||||
const results = await query.run();
|
const results = await query.run();
|
||||||
|
|
||||||
|
@@ -9,10 +9,13 @@ autoUpdater.allowPrerelease = persistentStore.get('allow_prerelease', true);
|
|||||||
export default () => {
|
export default () => {
|
||||||
ipcMain.on('check-for-updates', event => {
|
ipcMain.on('check-for-updates', event => {
|
||||||
mainWindow = event;
|
mainWindow = event;
|
||||||
|
if (process.windowsStore)
|
||||||
autoUpdater.checkForUpdatesAndNotify().catch(() => {
|
mainWindow.reply('no-auto-update');
|
||||||
mainWindow.reply('check-failed');
|
else {
|
||||||
});
|
autoUpdater.checkForUpdatesAndNotify().catch(() => {
|
||||||
|
mainWindow.reply('check-failed');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('restart-to-update', () => {
|
ipcMain.on('restart-to-update', () => {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import { MySQLClient } from './clients/MySQLClient';
|
import { MySQLClient } from './clients/MySQLClient';
|
||||||
|
import { PostgreSQLClient } from './clients/PostgreSQLClient';
|
||||||
|
|
||||||
export class ClientsFactory {
|
export class ClientsFactory {
|
||||||
/**
|
/**
|
||||||
@@ -20,8 +21,10 @@ export class ClientsFactory {
|
|||||||
case 'mysql':
|
case 'mysql':
|
||||||
case 'maria':
|
case 'maria':
|
||||||
return new MySQLClient(args);
|
return new MySQLClient(args);
|
||||||
|
case 'pg':
|
||||||
|
return new PostgreSQLClient(args);
|
||||||
default:
|
default:
|
||||||
return new Error(`Unknown database client: ${args.client}`);
|
throw new Error(`Unknown database client: ${args.client}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,8 @@ export class MySQLClient extends AntaresCore {
|
|||||||
constructor (args) {
|
constructor (args) {
|
||||||
super(args);
|
super(args);
|
||||||
|
|
||||||
|
this._schema = null;
|
||||||
|
|
||||||
this.types = {
|
this.types = {
|
||||||
0: 'DECIMAL',
|
0: 'DECIMAL',
|
||||||
1: 'TINYINT',
|
1: 'TINYINT',
|
||||||
@@ -120,6 +122,7 @@ export class MySQLClient extends AntaresCore {
|
|||||||
* @memberof MySQLClient
|
* @memberof MySQLClient
|
||||||
*/
|
*/
|
||||||
use (schema) {
|
use (schema) {
|
||||||
|
this._schema = schema;
|
||||||
return this.raw(`USE \`${schema}\``);
|
return this.raw(`USE \`${schema}\``);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +407,44 @@ export class MySQLClient extends AntaresCore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CREATE DATABASE
|
||||||
|
*
|
||||||
|
* @returns {Array.<Object>} parameters
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
async createSchema (params) {
|
||||||
|
return await this.raw(`CREATE DATABASE \`${params.name}\` COLLATE ${params.collation}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ALTER DATABASE
|
||||||
|
*
|
||||||
|
* @returns {Array.<Object>} parameters
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
async alterSchema (params) {
|
||||||
|
return await this.raw(`ALTER DATABASE \`${params.name}\` COLLATE ${params.collation}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DROP DATABASE
|
||||||
|
*
|
||||||
|
* @returns {Array.<Object>} parameters
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
async dropSchema (params) {
|
||||||
|
return await this.raw(`DROP DATABASE \`${params.database}\``);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Array.<Object>} parameters
|
||||||
|
* @memberof MySQLClient
|
||||||
|
*/
|
||||||
|
async getDatabaseCollation (params) {
|
||||||
|
return await this.raw(`SELECT \`DEFAULT_COLLATION_NAME\` FROM \`information_schema\`.\`SCHEMATA\` WHERE \`SCHEMA_NAME\`='${params.database}'`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SHOW CREATE VIEW
|
* SHOW CREATE VIEW
|
||||||
*
|
*
|
||||||
@@ -1011,7 +1052,7 @@ export class MySQLClient extends AntaresCore {
|
|||||||
options
|
options
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
let sql = `ALTER TABLE \`${table}\` `;
|
let sql = `ALTER TABLE \`${this._schema}\`.\`${table}\` `;
|
||||||
const alterColumns = [];
|
const alterColumns = [];
|
||||||
|
|
||||||
// OPTIONS
|
// OPTIONS
|
||||||
@@ -1281,7 +1322,7 @@ export class MySQLClient extends AntaresCore {
|
|||||||
const response = await this.getTableColumns(paramObj);
|
const response = await this.getTableColumns(paramObj);
|
||||||
remappedFields = remappedFields.map(field => {
|
remappedFields = remappedFields.map(field => {
|
||||||
const detailedField = response.find(f => f.name === field.name);
|
const detailedField = response.find(f => f.name === field.name);
|
||||||
if (detailedField && field.orgTable === paramObj.table && field.schema === paramObj.schema && detailedField.name === field.orgName)
|
if (detailedField && field.orgTable === paramObj.table && field.schema === paramObj.schema)
|
||||||
field = { ...detailedField, ...field };
|
field = { ...detailedField, ...field };
|
||||||
return field;
|
return field;
|
||||||
});
|
});
|
||||||
|
1378
src/main/libs/clients/PostgreSQLClient.js
Normal file
1378
src/main/libs/clients/PostgreSQLClient.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="wrapper">
|
<div id="wrapper" :class="`theme-${applicationTheme}`">
|
||||||
<TheTitleBar />
|
<TheTitleBar />
|
||||||
<div id="window-content">
|
<div id="window-content">
|
||||||
<TheSettingBar />
|
<TheSettingBar />
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
<TheFooter />
|
<TheFooter />
|
||||||
<TheNotificationsBoard />
|
<TheNotificationsBoard />
|
||||||
<ModalNewConnection v-if="isNewConnModal" />
|
<ModalNewConnection v-if="isNewConnModal" />
|
||||||
|
<TheScratchpad v-if="isScratchpad" />
|
||||||
<ModalSettings v-if="isSettingModal" />
|
<ModalSettings v-if="isSettingModal" />
|
||||||
<ModalDiscardChanges v-if="isUnsavedDiscardModal" />
|
<ModalDiscardChanges v-if="isUnsavedDiscardModal" />
|
||||||
</div>
|
</div>
|
||||||
@@ -37,6 +38,7 @@ export default {
|
|||||||
Workspace: () => import(/* webpackChunkName: "Workspace" */'@/components/Workspace'),
|
Workspace: () => import(/* webpackChunkName: "Workspace" */'@/components/Workspace'),
|
||||||
ModalNewConnection: () => import(/* webpackChunkName: "ModalNewConnection" */'@/components/ModalNewConnection'),
|
ModalNewConnection: () => import(/* webpackChunkName: "ModalNewConnection" */'@/components/ModalNewConnection'),
|
||||||
ModalSettings: () => import(/* webpackChunkName: "ModalSettings" */'@/components/ModalSettings'),
|
ModalSettings: () => import(/* webpackChunkName: "ModalSettings" */'@/components/ModalSettings'),
|
||||||
|
TheScratchpad: () => import(/* webpackChunkName: "TheScratchpad" */'@/components/TheScratchpad'),
|
||||||
ModalDiscardChanges: () => import(/* webpackChunkName: "ModalDiscardChanges" */'@/components/ModalDiscardChanges')
|
ModalDiscardChanges: () => import(/* webpackChunkName: "ModalDiscardChanges" */'@/components/ModalDiscardChanges')
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -48,12 +50,15 @@ export default {
|
|||||||
isNewConnModal: 'application/isNewModal',
|
isNewConnModal: 'application/isNewModal',
|
||||||
isEditModal: 'application/isEditModal',
|
isEditModal: 'application/isEditModal',
|
||||||
isSettingModal: 'application/isSettingModal',
|
isSettingModal: 'application/isSettingModal',
|
||||||
|
isScratchpad: 'application/isScratchpad',
|
||||||
connections: 'connections/getConnections',
|
connections: 'connections/getConnections',
|
||||||
|
applicationTheme: 'settings/getApplicationTheme',
|
||||||
isUnsavedDiscardModal: 'workspaces/isUnsavedDiscardModal'
|
isUnsavedDiscardModal: 'workspaces/isUnsavedDiscardModal'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
ipcRenderer.send('check-for-updates');
|
ipcRenderer.send('check-for-updates');
|
||||||
|
this.checkVersionUpdate();
|
||||||
|
|
||||||
const Menu = remote.Menu;
|
const Menu = remote.Menu;
|
||||||
|
|
||||||
@@ -96,7 +101,8 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
...mapActions({
|
||||||
showNewConnModal: 'application/showNewConnModal'
|
showNewConnModal: 'application/showNewConnModal',
|
||||||
|
checkVersionUpdate: 'application/checkVersionUpdate'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -71,7 +71,6 @@ export default {
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.context {
|
.context {
|
||||||
display: flex;
|
display: flex;
|
||||||
color: $body-font-color;
|
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
z-index: 400;
|
z-index: 400;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -87,7 +86,6 @@ export default {
|
|||||||
.context-container {
|
.context-container {
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
box-shadow: 0 0 2px 0 #000;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: #1d1d1d;
|
background: #1d1d1d;
|
||||||
border-radius: 0.1rem;
|
border-radius: 0.1rem;
|
||||||
@@ -111,14 +109,10 @@ export default {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 100%;
|
left: 100%;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: #1d1d1d;
|
|
||||||
box-shadow: 0 0 2px 0 #000;
|
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $primary-color;
|
|
||||||
|
|
||||||
.context-submenu {
|
.context-submenu {
|
||||||
display: block;
|
display: block;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
|
@@ -22,6 +22,7 @@ export default {
|
|||||||
editorClass: { type: String, default: '' },
|
editorClass: { type: String, default: '' },
|
||||||
autoFocus: { type: Boolean, default: false },
|
autoFocus: { type: Boolean, default: false },
|
||||||
readOnly: { type: Boolean, default: false },
|
readOnly: { type: Boolean, default: false },
|
||||||
|
showLineNumbers: { type: Boolean, default: true },
|
||||||
height: { type: Number, default: 200 }
|
height: { type: Number, default: 200 }
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -68,10 +69,12 @@ export default {
|
|||||||
this.editor = ace.edit(`editor-${this.id}`, {
|
this.editor = ace.edit(`editor-${this.id}`, {
|
||||||
mode: `ace/mode/${this.mode}`,
|
mode: `ace/mode/${this.mode}`,
|
||||||
theme: `ace/theme/${this.editorTheme}`,
|
theme: `ace/theme/${this.editorTheme}`,
|
||||||
value: this.value,
|
value: this.value || '',
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
printMargin: false,
|
printMargin: false,
|
||||||
readOnly: this.readOnly
|
readOnly: this.readOnly,
|
||||||
|
showLineNumbers: this.showLineNumbers,
|
||||||
|
showGutter: this.showLineNumbers
|
||||||
});
|
});
|
||||||
|
|
||||||
this.editor.setOptions({
|
this.editor.setOptions({
|
||||||
@@ -102,8 +105,6 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.editor-wrapper {
|
.editor-wrapper {
|
||||||
border-bottom: 1px solid #444;
|
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@@ -113,17 +114,4 @@ export default {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 17px;
|
width: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {
|
|
||||||
background-color: #c9561a99;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_line-hover {
|
|
||||||
background-color: #c9571a33;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight {
|
|
||||||
color: #e0d00c;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@@ -63,13 +63,11 @@ export default {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.file-uploader {
|
.file-uploader {
|
||||||
border: 0.05rem solid $bg-color-light;
|
|
||||||
border-radius: 0.1rem;
|
border-radius: 0.1rem;
|
||||||
height: 1.8rem;
|
height: 1.8rem;
|
||||||
line-height: 1.2rem;
|
line-height: 1.2rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-color: $bg-color-gray;
|
|
||||||
transition: background 0.2s, border 0.2s, box-shadow 0.2s, color 0.2s;
|
transition: background 0.2s, border 0.2s, box-shadow 0.2s, color 0.2s;
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
@@ -80,8 +78,6 @@ export default {
|
|||||||
|
|
||||||
.file-uploader-message {
|
.file-uploader-message {
|
||||||
display: flex;
|
display: flex;
|
||||||
border-right: 0.05rem solid $bg-color-light;
|
|
||||||
background-color: $bg-color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-uploader-input {
|
.file-uploader-input {
|
||||||
@@ -105,7 +101,6 @@ export default {
|
|||||||
:disabled {
|
:disabled {
|
||||||
.file-uploader {
|
.file-uploader {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
background-color: #151515;
|
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,11 +11,11 @@
|
|||||||
</option>
|
</option>
|
||||||
<option
|
<option
|
||||||
v-for="row in foreignList"
|
v-for="row in foreignList"
|
||||||
:key="row.foreignColumn"
|
:key="row.foreign_column"
|
||||||
:value="row.foreignColumn"
|
:value="row.foreign_column"
|
||||||
:selected="row.foreignColumn === value"
|
:selected="row.foreign_column === value"
|
||||||
>
|
>
|
||||||
{{ row.foreignColumn }} {{ 'foreignDescription' in row ? ` - ${row.foreignDescription}` : '' | cutText }}
|
{{ row.foreign_column }} {{ 'foreign_description' in row ? ` - ${row.foreign_description}` : '' | cutText }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</template>
|
</template>
|
||||||
@@ -51,11 +51,11 @@ export default {
|
|||||||
}),
|
}),
|
||||||
isValidDefault () {
|
isValidDefault () {
|
||||||
if (!this.foreignList.length) return true;
|
if (!this.foreignList.length) return true;
|
||||||
return this.foreignList.some(foreign => foreign.foreignColumn.toString() === this.value.toString());
|
return this.value === null || this.foreignList.some(foreign => foreign.foreign_column.toString() === this.value.toString());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created () {
|
async created () {
|
||||||
let firstTextField;
|
let foreignDesc;
|
||||||
const params = {
|
const params = {
|
||||||
uid: this.selectedWorkspace,
|
uid: this.selectedWorkspace,
|
||||||
schema: this.keyUsage.refSchema,
|
schema: this.keyUsage.refSchema,
|
||||||
@@ -64,8 +64,10 @@ export default {
|
|||||||
|
|
||||||
try { // Field data
|
try { // Field data
|
||||||
const { status, response } = await Tables.getTableColumns(params);
|
const { status, response } = await Tables.getTableColumns(params);
|
||||||
if (status === 'success')
|
if (status === 'success') {
|
||||||
firstTextField = response.find(field => [...TEXT, ...LONG_TEXT].includes(field.type)).name || false;
|
const textField = response.find(field => [...TEXT, ...LONG_TEXT].includes(field.type));
|
||||||
|
foreignDesc = textField ? textField.name : false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
this.addNotification({ status: 'error', message: response });
|
this.addNotification({ status: 'error', message: response });
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,7 @@ export default {
|
|||||||
const { status, response } = await Tables.getForeignList({
|
const { status, response } = await Tables.getForeignList({
|
||||||
...params,
|
...params,
|
||||||
column: this.keyUsage.refField,
|
column: this.keyUsage.refField,
|
||||||
description: firstTextField
|
description: foreignDesc
|
||||||
});
|
});
|
||||||
|
|
||||||
if (status === 'success')
|
if (status === 'success')
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
class="form-input"
|
class="form-input"
|
||||||
type="text"
|
type="text"
|
||||||
>
|
>
|
||||||
<span class="input-group-addon field-type" :class="`type-${parameter.type.toLowerCase()}`">
|
<span class="input-group-addon field-type" :class="typeClass(parameter.type)">
|
||||||
{{ parameter.type }} {{ parameter.length | wrapNumber }}
|
{{ parameter.type }} {{ parameter.length | wrapNumber }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { NUMBER, FLOAT } from 'common/fieldTypes';
|
||||||
import ConfirmModal from '@/components/BaseConfirmModal';
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -57,7 +58,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
localRoutine: Object
|
localRoutine: Object,
|
||||||
|
client: String
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -75,9 +77,29 @@ export default {
|
|||||||
window.removeEventListener('keydown', this.onKey);
|
window.removeEventListener('keydown', this.onKey);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
typeClass (type) {
|
||||||
|
if (type)
|
||||||
|
return `type-${type.toLowerCase().replaceAll(' ', '_').replaceAll('"', '')}`;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
runRoutine () {
|
runRoutine () {
|
||||||
const valArr = Object.keys(this.values).reduce((acc, curr) => {
|
const valArr = Object.keys(this.values).reduce((acc, curr) => {
|
||||||
const value = isNaN(this.values[curr]) ? `"${this.values[curr]}"` : this.values[curr];
|
let qc;
|
||||||
|
switch (this.client) {
|
||||||
|
case 'maria':
|
||||||
|
case 'mysql':
|
||||||
|
qc = '"';
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
qc = '\'';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qc = '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
const param = this.localRoutine.parameters.find(param => param.name === curr);
|
||||||
|
|
||||||
|
const value = [...NUMBER, ...FLOAT].includes(param.type) ? this.values[curr] : `${qc}${this.values[curr]}${qc}`;
|
||||||
acc.push(value);
|
acc.push(value);
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
@@ -59,15 +59,15 @@
|
|||||||
<option value="maria">
|
<option value="maria">
|
||||||
MariaDB
|
MariaDB
|
||||||
</option>
|
</option>
|
||||||
|
<option value="pg">
|
||||||
|
PostgreSQL
|
||||||
|
</option>
|
||||||
<!-- <option value="mssql">
|
<!-- <option value="mssql">
|
||||||
Microsoft SQL
|
Microsoft SQL
|
||||||
</option>
|
</option>
|
||||||
<option value="pg">
|
<option value="oracledb">
|
||||||
PostgreSQL
|
Oracle DB
|
||||||
</option>
|
</option> -->
|
||||||
<option value="oracledb">
|
|
||||||
Oracle DB
|
|
||||||
</option> -->
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -97,6 +97,18 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="customizations.database" class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.database') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.database"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-4 col-sm-12">
|
<div class="col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.user') }}</label>
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
@@ -247,6 +259,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions } from 'vuex';
|
||||||
|
import customizations from 'common/customizations';
|
||||||
import Connection from '@/ipc-api/Connection';
|
import Connection from '@/ipc-api/Connection';
|
||||||
import ModalAskCredentials from '@/components/ModalAskCredentials';
|
import ModalAskCredentials from '@/components/ModalAskCredentials';
|
||||||
import BaseToast from '@/components/BaseToast';
|
import BaseToast from '@/components/BaseToast';
|
||||||
@@ -274,6 +287,11 @@ export default {
|
|||||||
selectedTab: 'general'
|
selectedTab: 'general'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
customizations () {
|
||||||
|
return customizations[this.connection.client];
|
||||||
|
}
|
||||||
|
},
|
||||||
created () {
|
created () {
|
||||||
this.localConnection = Object.assign({}, this.connection);
|
this.localConnection = Object.assign({}, this.connection);
|
||||||
window.addEventListener('keydown', this.onKey);
|
window.addEventListener('keydown', this.onKey);
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
<div class="modal-header pl-2">
|
<div class="modal-header pl-2">
|
||||||
<div class="modal-title h6">
|
<div class="modal-title h6">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<i class="mdi mdi-24px mdi-database-edit mr-1" /> {{ $t('message.editDatabase') }}
|
<i class="mdi mdi-24px mdi-database-edit mr-1" /> {{ $t('message.editSchema') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
class="form-input"
|
class="form-input"
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
:placeholder="$t('message.databaseName')"
|
:placeholder="$t('message.schemaName')"
|
||||||
readonly
|
readonly
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer text-light">
|
<div class="modal-footer text-light">
|
||||||
<button class="btn btn-primary mr-2" @click.stop="updateDatabase">
|
<button class="btn btn-primary mr-2" @click.stop="updateSchema">
|
||||||
{{ $t('word.update') }}
|
{{ $t('word.update') }}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-link" @click.stop="closeModal">
|
<button class="btn btn-link" @click.stop="closeModal">
|
||||||
@@ -66,10 +66,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import Database from '@/ipc-api/Database';
|
import Schema from '@/ipc-api/Schema';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ModalEditDatabase',
|
name: 'ModalEditSchema',
|
||||||
props: {
|
props: {
|
||||||
selectedDatabase: String
|
selectedDatabase: String
|
||||||
},
|
},
|
||||||
@@ -98,7 +98,7 @@ export default {
|
|||||||
async created () {
|
async created () {
|
||||||
let actualCollation;
|
let actualCollation;
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.getDatabaseCollation({ uid: this.selectedWorkspace, database: this.selectedDatabase });
|
const { status, response } = await Schema.getDatabaseCollation({ uid: this.selectedWorkspace, database: this.selectedDatabase });
|
||||||
|
|
||||||
if (status === 'success')
|
if (status === 'success')
|
||||||
actualCollation = response;
|
actualCollation = response;
|
||||||
@@ -130,10 +130,10 @@ export default {
|
|||||||
...mapActions({
|
...mapActions({
|
||||||
addNotification: 'notifications/addNotification'
|
addNotification: 'notifications/addNotification'
|
||||||
}),
|
}),
|
||||||
async updateDatabase () {
|
async updateSchema () {
|
||||||
if (this.database.collation !== this.database.prevCollation) {
|
if (this.database.collation !== this.database.prevCollation) {
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.updateDatabase({
|
const { status, response } = await Schema.updateSchema({
|
||||||
uid: this.selectedWorkspace,
|
uid: this.selectedWorkspace,
|
||||||
...this.database
|
...this.database
|
||||||
});
|
});
|
@@ -34,7 +34,7 @@
|
|||||||
:field-obj="localRow[field.name]"
|
:field-obj="localRow[field.name]"
|
||||||
:value.sync="localRow[field.name]"
|
:value.sync="localRow[field.name]"
|
||||||
>
|
>
|
||||||
<span class="input-group-addon field-type" :class="`type-${field.type.toLowerCase()}`">
|
<span class="input-group-addon field-type" :class="typeClass(field.type)">
|
||||||
{{ field.type }} {{ fieldLength(field) | wrapNumber }}
|
{{ field.type }} {{ fieldLength(field) | wrapNumber }}
|
||||||
</span>
|
</span>
|
||||||
<label class="form-checkbox ml-3" :title="$t('word.insert')">
|
<label class="form-checkbox ml-3" :title="$t('word.insert')">
|
||||||
@@ -286,6 +286,11 @@ export default {
|
|||||||
...mapActions({
|
...mapActions({
|
||||||
addNotification: 'notifications/addNotification'
|
addNotification: 'notifications/addNotification'
|
||||||
}),
|
}),
|
||||||
|
typeClass (type) {
|
||||||
|
if (type)
|
||||||
|
return `type-${type.toLowerCase().replaceAll(' ', '_').replaceAll('"', '')}`;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
async insertRows () {
|
async insertRows () {
|
||||||
this.isInserting = true;
|
this.isInserting = true;
|
||||||
const rowToInsert = this.localRow;
|
const rowToInsert = this.localRow;
|
||||||
|
@@ -63,12 +63,12 @@
|
|||||||
<option value="maria">
|
<option value="maria">
|
||||||
MariaDB
|
MariaDB
|
||||||
</option>
|
</option>
|
||||||
|
<option value="pg">
|
||||||
|
PostgreSQL
|
||||||
|
</option>
|
||||||
<!-- <option value="mssql">
|
<!-- <option value="mssql">
|
||||||
Microsoft SQL
|
Microsoft SQL
|
||||||
</option>
|
</option>
|
||||||
<option value="pg">
|
|
||||||
PostgreSQL
|
|
||||||
</option>
|
|
||||||
<option value="oracledb">
|
<option value="oracledb">
|
||||||
Oracle DB
|
Oracle DB
|
||||||
</option> -->
|
</option> -->
|
||||||
@@ -101,6 +101,18 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="customizations.database" class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.database') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.database"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-4 col-sm-12">
|
<div class="col-4 col-sm-12">
|
||||||
<label class="form-label">{{ $t('word.user') }}</label>
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
@@ -251,6 +263,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions } from 'vuex';
|
import { mapActions } from 'vuex';
|
||||||
|
import customizations from 'common/customizations';
|
||||||
import Connection from '@/ipc-api/Connection';
|
import Connection from '@/ipc-api/Connection';
|
||||||
import { uidGen } from 'common/libs/uidGen';
|
import { uidGen } from 'common/libs/uidGen';
|
||||||
import ModalAskCredentials from '@/components/ModalAskCredentials';
|
import ModalAskCredentials from '@/components/ModalAskCredentials';
|
||||||
@@ -270,8 +283,9 @@ export default {
|
|||||||
name: '',
|
name: '',
|
||||||
client: 'mysql',
|
client: 'mysql',
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: '3306',
|
database: null,
|
||||||
user: 'root',
|
port: null,
|
||||||
|
user: null,
|
||||||
password: '',
|
password: '',
|
||||||
ask: false,
|
ask: false,
|
||||||
uid: uidGen('C'),
|
uid: uidGen('C'),
|
||||||
@@ -291,7 +305,13 @@ export default {
|
|||||||
selectedTab: 'general'
|
selectedTab: 'general'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
customizations () {
|
||||||
|
return customizations[this.connection.client];
|
||||||
|
}
|
||||||
|
},
|
||||||
created () {
|
created () {
|
||||||
|
this.setDefaults();
|
||||||
window.addEventListener('keydown', this.onKey);
|
window.addEventListener('keydown', this.onKey);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -307,20 +327,9 @@ export default {
|
|||||||
addConnection: 'connections/addConnection'
|
addConnection: 'connections/addConnection'
|
||||||
}),
|
}),
|
||||||
setDefaults () {
|
setDefaults () {
|
||||||
switch (this.connection.client) {
|
this.connection.user = this.customizations.defaultUser;
|
||||||
case 'mysql':
|
this.connection.port = this.customizations.defaultPort;
|
||||||
this.connection.port = '3306';
|
this.connection.database = this.customizations.defaultDatabase;
|
||||||
break;
|
|
||||||
case 'mssql':
|
|
||||||
this.connection.port = '1433';
|
|
||||||
break;
|
|
||||||
case 'pg':
|
|
||||||
this.connection.port = '5432';
|
|
||||||
break;
|
|
||||||
case 'oracledb':
|
|
||||||
this.connection.port = '1521';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
async startTest () {
|
async startTest () {
|
||||||
this.isTesting = true;
|
this.isTesting = true;
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.definer" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.definer') }}
|
{{ $t('word.definer') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.comment" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.comment') }}
|
{{ $t('word.comment') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.comment" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('message.dataAccess') }}
|
{{ $t('message.dataAccess') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.procedureDeterministic" class="form-group">
|
||||||
<div class="col-4" />
|
<div class="col-4" />
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<label class="form-checkbox form-inline">
|
<label class="form-checkbox form-inline">
|
||||||
@@ -117,7 +117,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
localRoutine: {
|
localRoutine: {
|
||||||
definer: '',
|
definer: '',
|
||||||
sql: 'BEGIN\r\n\r\nEND',
|
sql: '',
|
||||||
parameters: [],
|
parameters: [],
|
||||||
name: '',
|
name: '',
|
||||||
comment: '',
|
comment: '',
|
||||||
@@ -131,9 +131,14 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
schema () {
|
schema () {
|
||||||
return this.workspace.breadcrumbs.schema;
|
return this.workspace.breadcrumbs.schema;
|
||||||
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.workspace.customizations;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
if (this.customizations.procedureSql)
|
||||||
|
this.localRoutine.sql = this.customizations.procedureSql;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$refs.firstInput.focus();
|
this.$refs.firstInput.focus();
|
||||||
}, 20);
|
}, 20);
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
<div class="modal-header pl-2">
|
<div class="modal-header pl-2">
|
||||||
<div class="modal-title h6">
|
<div class="modal-title h6">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<i class="mdi mdi-24px mdi-database-plus mr-1" /> {{ $t('message.createNewDatabase') }}
|
<i class="mdi mdi-24px mdi-database-plus mr-1" /> {{ $t('message.createNewSchema') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||||
@@ -24,11 +24,11 @@
|
|||||||
class="form-input"
|
class="form-input"
|
||||||
type="text"
|
type="text"
|
||||||
required
|
required
|
||||||
:placeholder="$t('message.databaseName')"
|
:placeholder="$t('message.schemaName')"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.collations" class="form-group">
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<label class="form-label">{{ $t('word.collation') }}</label>
|
<label class="form-label">{{ $t('word.collation') }}</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -49,7 +49,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer text-light">
|
<div class="modal-footer text-light">
|
||||||
<button class="btn btn-primary mr-2" @click.stop="createDatabase">
|
<button
|
||||||
|
class="btn btn-primary mr-2"
|
||||||
|
:class="{'loading': isLoading}"
|
||||||
|
@click.stop="createSchema"
|
||||||
|
>
|
||||||
{{ $t('word.add') }}
|
{{ $t('word.add') }}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-link" @click.stop="closeModal">
|
<button class="btn btn-link" @click.stop="closeModal">
|
||||||
@@ -62,12 +66,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import Database from '@/ipc-api/Database';
|
import Schema from '@/ipc-api/Schema';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ModalNewDatabase',
|
name: 'ModalNewSchema',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
isLoading: false,
|
||||||
database: {
|
database: {
|
||||||
name: '',
|
name: '',
|
||||||
collation: ''
|
collation: ''
|
||||||
@@ -83,8 +88,11 @@ export default {
|
|||||||
collations () {
|
collations () {
|
||||||
return this.getWorkspace(this.selectedWorkspace).collations;
|
return this.getWorkspace(this.selectedWorkspace).collations;
|
||||||
},
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.getWorkspace(this.selectedWorkspace).customizations;
|
||||||
|
},
|
||||||
defaultCollation () {
|
defaultCollation () {
|
||||||
return this.getDatabaseVariable(this.selectedWorkspace, 'collation_server').value || '';
|
return this.getDatabaseVariable(this.selectedWorkspace, 'collation_server') ? this.getDatabaseVariable(this.selectedWorkspace, 'collation_server').value : '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
@@ -101,9 +109,10 @@ export default {
|
|||||||
...mapActions({
|
...mapActions({
|
||||||
addNotification: 'notifications/addNotification'
|
addNotification: 'notifications/addNotification'
|
||||||
}),
|
}),
|
||||||
async createDatabase () {
|
async createSchema () {
|
||||||
|
this.isLoading = true;
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.createDatabase({
|
const { status, response } = await Schema.createSchema({
|
||||||
uid: this.selectedWorkspace,
|
uid: this.selectedWorkspace,
|
||||||
...this.database
|
...this.database
|
||||||
});
|
});
|
||||||
@@ -118,6 +127,7 @@ export default {
|
|||||||
catch (err) {
|
catch (err) {
|
||||||
this.addNotification({ status: 'error', message: err.stack });
|
this.addNotification({ status: 'error', message: err.stack });
|
||||||
}
|
}
|
||||||
|
this.isLoading = false;
|
||||||
},
|
},
|
||||||
closeModal () {
|
closeModal () {
|
||||||
this.$emit('close');
|
this.$emit('close');
|
@@ -25,7 +25,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.comment" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.comment') }}
|
{{ $t('word.comment') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.collations" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.collation') }}
|
{{ $t('word.collation') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.engines" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.engine') }}
|
{{ $t('word.engine') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -103,10 +103,14 @@ export default {
|
|||||||
getDatabaseVariable: 'workspaces/getDatabaseVariable'
|
getDatabaseVariable: 'workspaces/getDatabaseVariable'
|
||||||
}),
|
}),
|
||||||
defaultCollation () {
|
defaultCollation () {
|
||||||
return this.getDatabaseVariable(this.selectedWorkspace, 'collation_server').value || '';
|
if (this.workspace.customizations.collations)
|
||||||
|
return this.getDatabaseVariable(this.selectedWorkspace, 'collation_server').value || '';
|
||||||
|
return '';
|
||||||
},
|
},
|
||||||
defaultEngine () {
|
defaultEngine () {
|
||||||
return this.workspace.engines.find(engine => engine.isDefault).name;
|
if (this.workspace.customizations.engines)
|
||||||
|
return this.workspace.engines.find(engine => engine.isDefault).name;
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
@@ -69,7 +69,7 @@
|
|||||||
:disabled="fieldsToExclude.includes(field.name)"
|
:disabled="fieldsToExclude.includes(field.name)"
|
||||||
:tabindex="key+1"
|
:tabindex="key+1"
|
||||||
>
|
>
|
||||||
<span class="input-group-addon" :class="`type-${field.type.toLowerCase()}`">
|
<span class="input-group-addon" :class="typeCLass(field.type)">
|
||||||
{{ field.type }} {{ fieldLength(field) | wrapNumber }}
|
{{ field.type }} {{ fieldLength(field) | wrapNumber }}
|
||||||
</span>
|
</span>
|
||||||
<label class="form-checkbox ml-3" :title="$t('word.insert')">
|
<label class="form-checkbox ml-3" :title="$t('word.insert')">
|
||||||
@@ -222,6 +222,11 @@ export default {
|
|||||||
...mapActions({
|
...mapActions({
|
||||||
addNotification: 'notifications/addNotification'
|
addNotification: 'notifications/addNotification'
|
||||||
}),
|
}),
|
||||||
|
typeClass (type) {
|
||||||
|
if (type)
|
||||||
|
return `type-${type.toLowerCase().replaceAll(' ', '_').replaceAll('"', '')}`;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
async insertRows () {
|
async insertRows () {
|
||||||
this.isInserting = true;
|
this.isInserting = true;
|
||||||
const rowToInsert = this.localRow;
|
const rowToInsert = this.localRow;
|
||||||
|
@@ -25,7 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-6">
|
<div class="column col-6">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.definer" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.definer') }}</label>
|
<label class="form-label">{{ $t('word.definer') }}</label>
|
||||||
<select v-model="localView.definer" class="form-select">
|
<select v-model="localView.definer" class="form-select">
|
||||||
<option value="">
|
<option value="">
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column col-4">
|
<div class="column col-4">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
|
||||||
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-4">
|
<div class="column col-4">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewAlgorithm" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-4">
|
<div class="column col-4">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewUpdateOption" class="form-group">
|
||||||
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
|
@@ -101,7 +101,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import Database from '@/ipc-api/Database';
|
import Schema from '@/ipc-api/Schema';
|
||||||
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
|
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
|
||||||
import ProcessesListRow from '@/components/ProcessesListRow';
|
import ProcessesListRow from '@/components/ProcessesListRow';
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ export default {
|
|||||||
this.results = [];
|
this.results = [];
|
||||||
|
|
||||||
try { // Table data
|
try { // Table data
|
||||||
const { status, response } = await Database.getProcesses(this.connection.uid);
|
const { status, response } = await Schema.getProcesses(this.connection.uid);
|
||||||
|
|
||||||
if (status === 'success') {
|
if (status === 'success') {
|
||||||
this.results = response;
|
this.results = response;
|
||||||
|
@@ -30,12 +30,21 @@
|
|||||||
<a class="c-hand">{{ $t('word.themes') }}</a>
|
<a class="c-hand">{{ $t('word.themes') }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
|
v-if="updateStatus !== 'disabled'"
|
||||||
class="tab-item"
|
class="tab-item"
|
||||||
:class="{'active': selectedTab === 'update'}"
|
:class="{'active': selectedTab === 'update'}"
|
||||||
@click="selectTab('update')"
|
@click="selectTab('update')"
|
||||||
>
|
>
|
||||||
<a class="c-hand" :class="{'badge badge-update': hasUpdates}">{{ $t('word.update') }}</a>
|
<a class="c-hand" :class="{'badge badge-update': hasUpdates}">{{ $t('word.update') }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li
|
||||||
|
v-if="updateStatus !== 'disabled'"
|
||||||
|
class="tab-item"
|
||||||
|
:class="{'active': selectedTab === 'changelog'}"
|
||||||
|
@click="selectTab('changelog')"
|
||||||
|
>
|
||||||
|
<a class="c-hand">{{ $t('word.changelog') }}</a>
|
||||||
|
</li>
|
||||||
<li
|
<li
|
||||||
class="tab-item"
|
class="tab-item"
|
||||||
:class="{'active': selectedTab === 'about'}"
|
:class="{'active': selectedTab === 'about'}"
|
||||||
@@ -45,7 +54,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="selectedTab === 'general'" class="panel-body py-4">
|
<div v-show="selectedTab === 'general'" class="panel-body py-4">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<form class="form-horizontal columns">
|
<form class="form-horizontal columns">
|
||||||
<div class="column col-12 h6 text-uppercase mb-1">
|
<div class="column col-12 h6 text-uppercase mb-1">
|
||||||
@@ -133,26 +142,35 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="selectedTab === 'themes'" class="panel-body py-4">
|
<div v-show="selectedTab === 'themes'" class="panel-body py-4">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column col-12 h6 text-uppercase mb-2">
|
<div class="column col-12 h6 text-uppercase mb-2">
|
||||||
{{ $t('message.applicationTheme') }}
|
{{ $t('message.applicationTheme') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-6 c-hand theme-block" :class="{'selected': applicationTheme === 'dark'}">
|
<div
|
||||||
|
class="column col-6 c-hand theme-block"
|
||||||
|
:class="{'selected': applicationTheme === 'dark'}"
|
||||||
|
@click="changeApplicationTheme('dark')"
|
||||||
|
>
|
||||||
<img :src="require('@/images/dark.png').default" class="img-responsive img-fit-cover s-rounded">
|
<img :src="require('@/images/dark.png').default" class="img-responsive img-fit-cover s-rounded">
|
||||||
<div class="theme-name">
|
<div class="theme-name text-light">
|
||||||
<i class="mdi mdi-moon-waning-crescent mdi-48px" />
|
<i class="mdi mdi-moon-waning-crescent mdi-48px" />
|
||||||
<div class="h6 mt-4">
|
<div class="h6 mt-4">
|
||||||
{{ $t('word.dark') }}
|
{{ $t('word.dark') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-6 theme-block disabled" :class="{'selected': applicationTheme === 'light'}">
|
<div
|
||||||
<div class="theme-name">
|
class="column col-6 c-hand theme-block"
|
||||||
|
:class="{'selected': applicationTheme === 'light'}"
|
||||||
|
@click="changeApplicationTheme('light')"
|
||||||
|
>
|
||||||
|
<img :src="require('@/images/light.png').default" class="img-responsive img-fit-cover s-rounded">
|
||||||
|
<div class="theme-name text-dark">
|
||||||
<i class="mdi mdi-white-balance-sunny mdi-48px" />
|
<i class="mdi mdi-white-balance-sunny mdi-48px" />
|
||||||
<div class="h6 mt-4">
|
<div class="h6 mt-4">
|
||||||
{{ $t('word.light') }} (Coming)
|
{{ $t('word.light') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -185,8 +203,9 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-12">
|
<div class="column col-12">
|
||||||
<QueryEditor
|
<BaseTextEditor
|
||||||
:value="exampleQuery"
|
:value="exampleQuery"
|
||||||
|
mode="sql"
|
||||||
:workspace="workspace"
|
:workspace="workspace"
|
||||||
:read-only="true"
|
:read-only="true"
|
||||||
:height="270"
|
:height="270"
|
||||||
@@ -196,11 +215,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="selectedTab === 'update'" class="panel-body py-4">
|
<div v-show="selectedTab === 'update'" class="panel-body py-4">
|
||||||
<ModalSettingsUpdate />
|
<ModalSettingsUpdate />
|
||||||
</div>
|
</div>
|
||||||
|
<div v-show="selectedTab === 'changelog'" class="panel-body py-4">
|
||||||
|
<ModalSettingsChangelog />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="selectedTab === 'about'" class="panel-body py-4">
|
<div v-show="selectedTab === 'about'" class="panel-body py-4">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<img :src="require('@/images/logo.svg').default" width="128">
|
<img :src="require('@/images/logo.svg').default" width="128">
|
||||||
<h4>{{ appName }}</h4>
|
<h4>{{ appName }}</h4>
|
||||||
@@ -222,14 +244,16 @@
|
|||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
import localesNames from '@/i18n/supported-locales';
|
import localesNames from '@/i18n/supported-locales';
|
||||||
import ModalSettingsUpdate from '@/components/ModalSettingsUpdate';
|
import ModalSettingsUpdate from '@/components/ModalSettingsUpdate';
|
||||||
import QueryEditor from '@/components/QueryEditor';
|
import ModalSettingsChangelog from '@/components/ModalSettingsChangelog';
|
||||||
|
import BaseTextEditor from '@/components/BaseTextEditor';
|
||||||
const { shell } = require('electron');
|
const { shell } = require('electron');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ModalSettings',
|
name: 'ModalSettings',
|
||||||
components: {
|
components: {
|
||||||
ModalSettingsUpdate,
|
ModalSettingsUpdate,
|
||||||
QueryEditor
|
ModalSettingsChangelog,
|
||||||
|
BaseTextEditor
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -350,6 +374,7 @@ ORDER BY
|
|||||||
changeLocale: 'settings/changeLocale',
|
changeLocale: 'settings/changeLocale',
|
||||||
changeAutoComplete: 'settings/changeAutoComplete',
|
changeAutoComplete: 'settings/changeAutoComplete',
|
||||||
changeLineWrap: 'settings/changeLineWrap',
|
changeLineWrap: 'settings/changeLineWrap',
|
||||||
|
changeApplicationTheme: 'settings/changeApplicationTheme',
|
||||||
changeEditorTheme: 'settings/changeEditorTheme',
|
changeEditorTheme: 'settings/changeEditorTheme',
|
||||||
updateNotificationsTimeout: 'settings/updateNotificationsTimeout'
|
updateNotificationsTimeout: 'settings/updateNotificationsTimeout'
|
||||||
}),
|
}),
|
||||||
@@ -382,54 +407,58 @@ ORDER BY
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
#settings {
|
#settings {
|
||||||
.modal-body {
|
.modal-container {
|
||||||
overflow: hidden;
|
position: absolute;
|
||||||
|
top: 17.5vh;
|
||||||
|
|
||||||
.panel-body {
|
.modal-body {
|
||||||
height: calc(70vh - 70px);
|
overflow: hidden;
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
.theme-block {
|
.panel-body {
|
||||||
position: relative;
|
min-height: calc(25vh - 70px);
|
||||||
text-align: center;
|
overflow: auto;
|
||||||
|
|
||||||
&.selected {
|
.theme-block {
|
||||||
img {
|
position: relative;
|
||||||
box-shadow: 0 0 0 3px $primary-color;
|
text-align: center;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
img {
|
||||||
|
box-shadow: 0 0 0 3px $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-name {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-name {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
top: 0;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
text-shadow: 0 0 8px #000;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.badge::after {
|
.badge::after {
|
||||||
background: #32b643;
|
background: #32b643;
|
||||||
}
|
}
|
||||||
|
|
||||||
.badge-update::after {
|
.badge-update::after {
|
||||||
bottom: initial;
|
bottom: initial;
|
||||||
background: $primary-color;
|
background: $primary-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-label {
|
.form-label {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
78
src/renderer/components/ModalSettingsChangelog.vue
Normal file
78
src/renderer/components/ModalSettingsChangelog.vue
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-relative">
|
||||||
|
<BaseLoader v-if="isLoading" />
|
||||||
|
<div
|
||||||
|
id="changelog"
|
||||||
|
class="container"
|
||||||
|
v-html="changelog"
|
||||||
|
/>
|
||||||
|
<div v-if="isError" class="empty">
|
||||||
|
<div class="empty-icon">
|
||||||
|
<i class="mdi mdi-48px mdi-alert-outline" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import marked from 'marked';
|
||||||
|
import BaseLoader from '@/components/BaseLoader';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ModalSettingsChangelog',
|
||||||
|
components: {
|
||||||
|
BaseLoader
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
changelog: '',
|
||||||
|
isLoading: true,
|
||||||
|
error: '',
|
||||||
|
isError: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.getChangelog();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getChangelog () {
|
||||||
|
try {
|
||||||
|
const apiRes = await fetch('https://api.github.com/repos/Fabio286/antares/releases/latest', {
|
||||||
|
method: 'GET'
|
||||||
|
});
|
||||||
|
|
||||||
|
const { body } = await apiRes.json();
|
||||||
|
const markdown = body.substr(0, body.indexOf('### Download'));
|
||||||
|
const renderer = {
|
||||||
|
link (href, title, text) {
|
||||||
|
return text;
|
||||||
|
},
|
||||||
|
listitem (text) {
|
||||||
|
return `<li>${text.replace(/ *\([^)]*\) */g, '')}</li>`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
marked.use({ renderer });
|
||||||
|
|
||||||
|
this.changelog = marked(markdown);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.error = err.message;
|
||||||
|
this.isError = true;
|
||||||
|
}
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
#changelog {
|
||||||
|
h3 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -92,9 +92,3 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.empty {
|
|
||||||
color: $body-font-color;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@@ -312,19 +312,6 @@ export default {
|
|||||||
width: 17px;
|
width: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {
|
|
||||||
background-color: #c9561a99;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_line-hover {
|
|
||||||
background-color: #c9571a33;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight {
|
|
||||||
color: #e0d00c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ace_gutter-cell.ace_breakpoint {
|
.ace_gutter-cell.ace_breakpoint {
|
||||||
&::before {
|
&::before {
|
||||||
content: '\F0403';
|
content: '\F0403';
|
||||||
|
@@ -64,13 +64,11 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: $primary-color;
|
|
||||||
padding: 0 0.2rem;
|
padding: 0 0.2rem;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
box-shadow: 0 0 1px 0 #000;
|
|
||||||
|
|
||||||
.footer-elements {
|
.footer-elements {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@@ -88,10 +86,6 @@ export default {
|
|||||||
&.footer-link {
|
&.footer-link {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba($color: #fff, $alpha: 0.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
75
src/renderer/components/TheScratchpad.vue
Normal file
75
src/renderer/components/TheScratchpad.vue
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<ConfirmModal
|
||||||
|
:confirm-text="$t('word.update')"
|
||||||
|
:cancel-text="$t('word.close')"
|
||||||
|
size="large"
|
||||||
|
:hide-footer="true"
|
||||||
|
@hide="hideScratchpad"
|
||||||
|
>
|
||||||
|
<template :slot="'header'">
|
||||||
|
<div class="d-flex">
|
||||||
|
<i class="mdi mdi-24px mdi-notebook-edit-outline mr-1" /> {{ $t('word.scratchpad') }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div :slot="'body'">
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<TextEditor
|
||||||
|
:value.sync="localNotes"
|
||||||
|
editor-class="textarea-editor"
|
||||||
|
mode="markdown"
|
||||||
|
:auto-focus="true"
|
||||||
|
:show-line-numbers="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<small class="text-gray">{{ $t('message.markdownSupported') }}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ConfirmModal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||||
|
import TextEditor from '@/components/BaseTextEditor';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'TheScratchpad',
|
||||||
|
components: {
|
||||||
|
ConfirmModal,
|
||||||
|
TextEditor
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
localNotes: '',
|
||||||
|
debounceTimeout: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
notes: 'scratchpad/getNotes'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
localNotes () {
|
||||||
|
clearTimeout(this.debounceTimeout);
|
||||||
|
|
||||||
|
this.debounceTimeout = setTimeout(() => {
|
||||||
|
this.changeNotes(this.localNotes);
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.localNotes = this.notes;
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions({
|
||||||
|
hideScratchpad: 'application/hideScratchpad',
|
||||||
|
changeNotes: 'scratchpad/changeNotes'
|
||||||
|
}),
|
||||||
|
hideModal () {
|
||||||
|
this.$emit('hide');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@@ -36,6 +36,10 @@
|
|||||||
|
|
||||||
<div class="settingbar-bottom-elements">
|
<div class="settingbar-bottom-elements">
|
||||||
<ul class="settingbar-elements">
|
<ul class="settingbar-elements">
|
||||||
|
<li class="settingbar-element btn btn-link ex-tooltip" @click="showScratchpad">
|
||||||
|
<i class="settingbar-element-icon mdi mdi-24px mdi-notebook-edit-outline text-light" />
|
||||||
|
<span class="ex-tooltip-content">{{ $t('word.scratchpad') }}</span>
|
||||||
|
</li>
|
||||||
<li class="settingbar-element btn btn-link ex-tooltip" @click="showSettingModal('general')">
|
<li class="settingbar-element btn btn-link ex-tooltip" @click="showSettingModal('general')">
|
||||||
<i class="settingbar-element-icon mdi mdi-24px mdi-cog text-light" :class="{' badge badge-update': hasUpdates}" />
|
<i class="settingbar-element-icon mdi mdi-24px mdi-cog text-light" :class="{' badge badge-update': hasUpdates}" />
|
||||||
<span class="ex-tooltip-content">{{ $t('word.settings') }}</span>
|
<span class="ex-tooltip-content">{{ $t('word.settings') }}</span>
|
||||||
@@ -90,6 +94,7 @@ export default {
|
|||||||
updateConnections: 'connections/updateConnections',
|
updateConnections: 'connections/updateConnections',
|
||||||
showNewConnModal: 'application/showNewConnModal',
|
showNewConnModal: 'application/showNewConnModal',
|
||||||
showSettingModal: 'application/showSettingModal',
|
showSettingModal: 'application/showSettingModal',
|
||||||
|
showScratchpad: 'application/showScratchpad',
|
||||||
selectWorkspace: 'workspaces/selectWorkspace'
|
selectWorkspace: 'workspaces/selectWorkspace'
|
||||||
}),
|
}),
|
||||||
contextMenu (event, connection) {
|
contextMenu (event, connection) {
|
||||||
@@ -117,9 +122,7 @@ export default {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: $bg-color-light;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-shadow: 0 0 1px 0 #000;
|
|
||||||
z-index: 9;
|
z-index: 9;
|
||||||
|
|
||||||
.settingbar-top-elements {
|
.settingbar-top-elements {
|
||||||
@@ -134,7 +137,6 @@ export default {
|
|||||||
|
|
||||||
.settingbar-bottom-elements {
|
.settingbar-bottom-elements {
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
background: $bg-color-light;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +164,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.selected {
|
&.selected {
|
||||||
border-left-color: $body-font-color;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,12 +172,10 @@ export default {
|
|||||||
bottom: -10px;
|
bottom: -10px;
|
||||||
right: 0;
|
right: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: $success-color;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.badge-update::after {
|
&.badge-update::after {
|
||||||
bottom: initial;
|
bottom: initial;
|
||||||
background: $primary-color;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -102,12 +102,10 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background: $bg-color-light;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: $titlebar-height;
|
height: $titlebar-height;
|
||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
box-shadow: 0 0 1px 0 #000;
|
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
|
|
||||||
.titlebar-resizer {
|
.titlebar-resizer {
|
||||||
@@ -149,11 +147,6 @@ export default {
|
|||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
background: rgba($color: #fff, $alpha: 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.close-button:hover {
|
|
||||||
background: red;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,19 +16,27 @@
|
|||||||
<i class="mdi mdi-24px mdi-tools" />
|
<i class="mdi mdi-24px mdi-tools" />
|
||||||
</a>
|
</a>
|
||||||
<ul class="menu text-left text-uppercase">
|
<ul class="menu text-left text-uppercase">
|
||||||
<li class="menu-item">
|
<li v-if="workspace.customizations.processesList" class="menu-item">
|
||||||
<a class="c-hand p-vcentered" @click="showProcessesModal">
|
<a class="c-hand p-vcentered" @click="showProcessesModal">
|
||||||
<i class="mdi mdi-memory mr-1 tool-icon" />
|
<i class="mdi mdi-memory mr-1 tool-icon" />
|
||||||
<span>{{ $t('message.processesList') }}</span>
|
<span>{{ $t('message.processesList') }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-item" title="Coming...">
|
<li
|
||||||
|
v-if="workspace.customizations.variables"
|
||||||
|
class="menu-item"
|
||||||
|
title="Coming..."
|
||||||
|
>
|
||||||
<a class="c-hand p-vcentered disabled">
|
<a class="c-hand p-vcentered disabled">
|
||||||
<i class="mdi mdi-shape mr-1 tool-icon" />
|
<i class="mdi mdi-shape mr-1 tool-icon" />
|
||||||
<span>{{ $t('word.variables') }}</span>
|
<span>{{ $t('word.variables') }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu-item" title="Coming...">
|
<li
|
||||||
|
v-if="workspace.customizations.usersManagement"
|
||||||
|
class="menu-item"
|
||||||
|
title="Coming..."
|
||||||
|
>
|
||||||
<a class="c-hand p-vcentered disabled">
|
<a class="c-hand p-vcentered disabled">
|
||||||
<i class="mdi mdi-account-group mr-1 tool-icon" />
|
<i class="mdi mdi-account-group mr-1 tool-icon" />
|
||||||
<span>{{ $t('message.manageUsers') }}</span>
|
<span>{{ $t('message.manageUsers') }}</span>
|
||||||
@@ -37,7 +45,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
v-if="schemaChild"
|
v-if="schemaChild && isSettingSupported"
|
||||||
class="tab-item"
|
class="tab-item"
|
||||||
:class="{'active': selectedTab === 'prop'}"
|
:class="{'active': selectedTab === 'prop'}"
|
||||||
@click="selectTab({uid: workspace.uid, tab: 'prop'})"
|
@click="selectTab({uid: workspace.uid, tab: 'prop'})"
|
||||||
@@ -194,6 +202,15 @@ export default {
|
|||||||
isSelected () {
|
isSelected () {
|
||||||
return this.selectedWorkspace === this.connection.uid;
|
return this.selectedWorkspace === this.connection.uid;
|
||||||
},
|
},
|
||||||
|
isSettingSupported () {
|
||||||
|
if (this.workspace.breadcrumbs.table && this.workspace.customizations.tableSettings) return true;
|
||||||
|
if (this.workspace.breadcrumbs.view && this.workspace.customizations.viewSettings) return true;
|
||||||
|
if (this.workspace.breadcrumbs.trigger && this.workspace.customizations.triggerSettings) return true;
|
||||||
|
if (this.workspace.breadcrumbs.procedure && this.workspace.customizations.routineSettings) return true;
|
||||||
|
if (this.workspace.breadcrumbs.function && this.workspace.customizations.functionSettings) return true;
|
||||||
|
if (this.workspace.breadcrumbs.scheduler && this.workspace.customizations.schedulerSettings) return true;
|
||||||
|
return false;
|
||||||
|
},
|
||||||
selectedTab () {
|
selectedTab () {
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
@@ -287,7 +304,6 @@ export default {
|
|||||||
height: calc(100vh - #{$excluding-size});
|
height: calc(100vh - #{$excluding-size});
|
||||||
|
|
||||||
.tab-block {
|
.tab-block {
|
||||||
background: $bg-color-light;
|
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -307,7 +323,6 @@ export default {
|
|||||||
|
|
||||||
> a {
|
> a {
|
||||||
padding: 0.2rem 0.8rem;
|
padding: 0.2rem 0.8rem;
|
||||||
color: $body-font-color;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -338,7 +353,6 @@ export default {
|
|||||||
|
|
||||||
&.tools-dropdown {
|
&.tools-dropdown {
|
||||||
.tab-link:focus {
|
.tab-link:focus {
|
||||||
color: $primary-color;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
@@ -357,11 +371,6 @@ export default {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $primary-color;
|
|
||||||
background: $bg-color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-icon {
|
.tool-icon {
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -397,11 +406,9 @@ export default {
|
|||||||
.th {
|
.th {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: $bg-color;
|
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-bottom-width: 2px;
|
border-bottom-width: 2px;
|
||||||
border-color: $bg-color-light;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
@@ -416,7 +423,6 @@ export default {
|
|||||||
.td {
|
.td {
|
||||||
border-right: 1px solid;
|
border-right: 1px solid;
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
border-color: $bg-color-light;
|
|
||||||
padding: 0 0.4rem;
|
padding: 0 0.4rem;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
@@ -426,8 +432,6 @@ export default {
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: inset 0 0 0 1px $body-font-color;
|
|
||||||
background: rgba($color: #000, $alpha: 0.3);
|
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column col-12 empty text-light">
|
<div class="column col-12 empty">
|
||||||
<div class="empty-icon">
|
<div class="empty-icon">
|
||||||
<i class="mdi mdi-48px mdi-power-plug-off" />
|
<i class="mdi mdi-48px mdi-power-plug-off" />
|
||||||
</div>
|
</div>
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
<span v-if="workspace.connected" class="workspace-explorebar-tools">
|
<span v-if="workspace.connected" class="workspace-explorebar-tools">
|
||||||
<i
|
<i
|
||||||
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
|
class="mdi mdi-18px mdi-database-plus c-hand mr-2"
|
||||||
:title="$t('message.createNewDatabase')"
|
:title="$t('message.createNewSchema')"
|
||||||
@click="showNewDBModal"
|
@click="showNewDBModal"
|
||||||
/>
|
/>
|
||||||
<i
|
<i
|
||||||
@@ -44,18 +44,18 @@
|
|||||||
:connection="connection"
|
:connection="connection"
|
||||||
/>
|
/>
|
||||||
<div v-else class="workspace-explorebar-body">
|
<div v-else class="workspace-explorebar-body">
|
||||||
<WorkspaceExploreBarDatabase
|
<WorkspaceExploreBarSchema
|
||||||
v-for="db of workspace.structure"
|
v-for="db of workspace.structure"
|
||||||
:key="db.name"
|
:key="db.name"
|
||||||
:database="db"
|
:database="db"
|
||||||
:connection="connection"
|
:connection="connection"
|
||||||
@show-database-context="openDatabaseContext"
|
@show-schema-context="openSchemaContext"
|
||||||
@show-table-context="openTableContext"
|
@show-table-context="openTableContext"
|
||||||
@show-misc-context="openMiscContext"
|
@show-misc-context="openMiscContext"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ModalNewDatabase
|
<ModalNewSchema
|
||||||
v-if="isNewDBModal"
|
v-if="isNewDBModal"
|
||||||
@close="hideNewDBModal"
|
@close="hideNewDBModal"
|
||||||
@reload="refresh"
|
@reload="refresh"
|
||||||
@@ -137,11 +137,11 @@ import Functions from '@/ipc-api/Functions';
|
|||||||
import Schedulers from '@/ipc-api/Schedulers';
|
import Schedulers from '@/ipc-api/Schedulers';
|
||||||
|
|
||||||
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
||||||
import WorkspaceExploreBarDatabase from '@/components/WorkspaceExploreBarDatabase';
|
import WorkspaceExploreBarSchema from '@/components/WorkspaceExploreBarSchema';
|
||||||
import DatabaseContext from '@/components/WorkspaceExploreBarDatabaseContext';
|
import DatabaseContext from '@/components/WorkspaceExploreBarSchemaContext';
|
||||||
import TableContext from '@/components/WorkspaceExploreBarTableContext';
|
import TableContext from '@/components/WorkspaceExploreBarTableContext';
|
||||||
import MiscContext from '@/components/WorkspaceExploreBarMiscContext';
|
import MiscContext from '@/components/WorkspaceExploreBarMiscContext';
|
||||||
import ModalNewDatabase from '@/components/ModalNewDatabase';
|
import ModalNewSchema from '@/components/ModalNewSchema';
|
||||||
import ModalNewTable from '@/components/ModalNewTable';
|
import ModalNewTable from '@/components/ModalNewTable';
|
||||||
import ModalNewView from '@/components/ModalNewView';
|
import ModalNewView from '@/components/ModalNewView';
|
||||||
import ModalNewTrigger from '@/components/ModalNewTrigger';
|
import ModalNewTrigger from '@/components/ModalNewTrigger';
|
||||||
@@ -153,11 +153,11 @@ export default {
|
|||||||
name: 'WorkspaceExploreBar',
|
name: 'WorkspaceExploreBar',
|
||||||
components: {
|
components: {
|
||||||
WorkspaceConnectPanel,
|
WorkspaceConnectPanel,
|
||||||
WorkspaceExploreBarDatabase,
|
WorkspaceExploreBarSchema,
|
||||||
DatabaseContext,
|
DatabaseContext,
|
||||||
TableContext,
|
TableContext,
|
||||||
MiscContext,
|
MiscContext,
|
||||||
ModalNewDatabase,
|
ModalNewSchema,
|
||||||
ModalNewTable,
|
ModalNewTable,
|
||||||
ModalNewView,
|
ModalNewView,
|
||||||
ModalNewTrigger,
|
ModalNewTrigger,
|
||||||
@@ -299,8 +299,8 @@ export default {
|
|||||||
else
|
else
|
||||||
this.addNotification({ status: 'error', message: response });
|
this.addNotification({ status: 'error', message: response });
|
||||||
},
|
},
|
||||||
openDatabaseContext (payload) {
|
openSchemaContext (payload) {
|
||||||
this.selectedDatabase = payload.database;
|
this.selectedDatabase = payload.schema;
|
||||||
this.databaseContextEvent = payload.event;
|
this.databaseContextEvent = payload.event;
|
||||||
this.isDatabaseContext = true;
|
this.isDatabaseContext = true;
|
||||||
},
|
},
|
||||||
@@ -460,8 +460,6 @@ export default {
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background: $bg-color-gray;
|
|
||||||
box-shadow: 0 0 1px 0 #000;
|
|
||||||
z-index: 8;
|
z-index: 8;
|
||||||
flex: initial;
|
flex: initial;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
<ModalAskParameters
|
<ModalAskParameters
|
||||||
v-if="isAskingParameters"
|
v-if="isAskingParameters"
|
||||||
:local-routine="localElement"
|
:local-routine="localElement"
|
||||||
|
:client="workspace.client"
|
||||||
@confirm="runElement"
|
@confirm="runElement"
|
||||||
@close="hideAskParamsModal"
|
@close="hideAskParamsModal"
|
||||||
/>
|
/>
|
||||||
@@ -205,13 +206,13 @@ export default {
|
|||||||
case 'maria':
|
case 'maria':
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
case 'pg':
|
case 'pg':
|
||||||
sql = `CALL \`${this.localElement.name}\` (${params.join(',')})`;
|
sql = `CALL ${this.localElement.name}(${params.join(',')})`;
|
||||||
break;
|
break;
|
||||||
case 'mssql':
|
case 'mssql':
|
||||||
sql = `EXEC ${this.localElement.name} ${params.join(',')}`;
|
sql = `EXEC ${this.localElement.name} ${params.join(',')}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sql = `CALL \`${this.localElement.name}\` (${params.join(',')})`;
|
sql = `CALL \`${this.localElement.name}\`(${params.join(',')})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.newTab({ uid: this.workspace.uid, content: sql, autorun: true });
|
this.newTab({ uid: this.workspace.uid, content: sql, autorun: true });
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
class="accordion-header database-name"
|
class="accordion-header database-name"
|
||||||
:class="{'text-bold': breadcrumbs.schema === database.name}"
|
:class="{'text-bold': breadcrumbs.schema === database.name}"
|
||||||
@click="selectSchema(database.name)"
|
@click="selectSchema(database.name)"
|
||||||
@contextmenu.prevent="showDatabaseContext($event, database.name)"
|
@contextmenu.prevent="showSchemaContext($event, database.name)"
|
||||||
>
|
>
|
||||||
<div v-if="isLoading" class="icon loading" />
|
<div v-if="isLoading" class="icon loading" />
|
||||||
<i v-else class="icon mdi mdi-18px mdi-chevron-right" />
|
<i v-else class="icon mdi mdi-18px mdi-chevron-right" />
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="filteredTriggers.length" class="database-misc">
|
<div v-if="filteredTriggers.length && customizations.triggers" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger}">
|
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger}">
|
||||||
<i class="misc-icon mdi mdi-18px mdi-folder-cog mr-1" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-cog mr-1" />
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="filteredProcedures.length" class="database-misc">
|
<div v-if="filteredProcedures.length && customizations.routines" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.procedure}">
|
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.procedure}">
|
||||||
<i class="misc-icon mdi mdi-18px mdi-folder-sync mr-1" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-sync mr-1" />
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="filteredFunctions.length" class="database-misc">
|
<div v-if="filteredFunctions.length && customizations.functions" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.function}">
|
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.function}">
|
||||||
<i class="misc-icon mdi mdi-18px mdi-folder-move mr-1" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-move mr-1" />
|
||||||
@@ -121,7 +121,7 @@
|
|||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="filteredSchedulers.length" class="database-misc">
|
<div v-if="filteredSchedulers.length && customizations.schedulers" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.scheduler}">
|
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.scheduler}">
|
||||||
<i class="misc-icon mdi mdi-18px mdi-folder-clock mr-1" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-clock mr-1" />
|
||||||
@@ -157,7 +157,7 @@ import { mapActions, mapGetters } from 'vuex';
|
|||||||
import { formatBytes } from 'common/libs/formatBytes';
|
import { formatBytes } from 'common/libs/formatBytes';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WorkspaceExploreBarDatabase',
|
name: 'WorkspaceExploreBarSchema',
|
||||||
props: {
|
props: {
|
||||||
database: Object,
|
database: Object,
|
||||||
connection: Object
|
connection: Object
|
||||||
@@ -171,7 +171,8 @@ export default {
|
|||||||
...mapGetters({
|
...mapGetters({
|
||||||
getLoadedSchemas: 'workspaces/getLoadedSchemas',
|
getLoadedSchemas: 'workspaces/getLoadedSchemas',
|
||||||
getWorkspace: 'workspaces/getWorkspace',
|
getWorkspace: 'workspaces/getWorkspace',
|
||||||
getSearchTerm: 'workspaces/getSearchTerm'
|
getSearchTerm: 'workspaces/getSearchTerm',
|
||||||
|
applicationTheme: 'settings/getApplicationTheme'
|
||||||
}),
|
}),
|
||||||
searchTerm () {
|
searchTerm () {
|
||||||
return this.getSearchTerm(this.connection.uid);
|
return this.getSearchTerm(this.connection.uid);
|
||||||
@@ -194,6 +195,9 @@ export default {
|
|||||||
breadcrumbs () {
|
breadcrumbs () {
|
||||||
return this.getWorkspace(this.connection.uid).breadcrumbs;
|
return this.getWorkspace(this.connection.uid).breadcrumbs;
|
||||||
},
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.getWorkspace(this.connection.uid).customizations;
|
||||||
|
},
|
||||||
loadedSchemas () {
|
loadedSchemas () {
|
||||||
return this.getLoadedSchemas(this.connection.uid);
|
return this.getLoadedSchemas(this.connection.uid);
|
||||||
},
|
},
|
||||||
@@ -222,9 +226,9 @@ export default {
|
|||||||
|
|
||||||
this.changeBreadcrumbs({ schema, table: null });
|
this.changeBreadcrumbs({ schema, table: null });
|
||||||
},
|
},
|
||||||
showDatabaseContext (event, database) {
|
showSchemaContext (event, schema) {
|
||||||
this.changeBreadcrumbs({ schema: database, table: null });
|
this.selectSchema(schema);
|
||||||
this.$emit('show-database-context', { event, database });
|
this.$emit('show-schema-context', { event, schema });
|
||||||
},
|
},
|
||||||
showTableContext (event, table) {
|
showTableContext (event, table) {
|
||||||
this.setBreadcrumbs({ schema: this.database.name, [table.type]: table.name });
|
this.setBreadcrumbs({ schema: this.database.name, [table.type]: table.name });
|
||||||
@@ -236,7 +240,10 @@ export default {
|
|||||||
},
|
},
|
||||||
piePercentage (val) {
|
piePercentage (val) {
|
||||||
const perc = val / this.maxSize * 100;
|
const perc = val / this.maxSize * 100;
|
||||||
return { background: `conic-gradient(lime ${perc}%, white 0)` };
|
if (this.applicationTheme === 'dark')
|
||||||
|
return { background: `conic-gradient(lime ${perc}%, white 0)` };
|
||||||
|
else
|
||||||
|
return { background: `conic-gradient(teal ${perc}%, silver 0)` };
|
||||||
},
|
},
|
||||||
setBreadcrumbs (payload) {
|
setBreadcrumbs (payload) {
|
||||||
if (this.breadcrumbs.schema === payload.schema && this.breadcrumbs.table === payload.table) return;
|
if (this.breadcrumbs.schema === payload.schema && this.breadcrumbs.table === payload.table) return;
|
||||||
@@ -259,7 +266,6 @@ export default {
|
|||||||
.database-name {
|
.database-name {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: $bg-color-gray;
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,26 +311,15 @@ export default {
|
|||||||
.database-name,
|
.database-name,
|
||||||
.misc-name {
|
.misc-name {
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $body-font-color;
|
|
||||||
background: $bg-color-light;
|
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a.table-name {
|
|
||||||
&:hover {
|
|
||||||
color: inherit;
|
|
||||||
background: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $body-font-color;
|
|
||||||
background: rgba($color: #fff, $alpha: 0.05);
|
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -7,27 +7,55 @@
|
|||||||
<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('word.add') }}</span>
|
||||||
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
|
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
|
||||||
<div class="context-submenu">
|
<div class="context-submenu">
|
||||||
<div class="context-element" @click="showCreateTableModal">
|
<div
|
||||||
|
v-if="workspace.customizations.tableAdd"
|
||||||
|
class="context-element"
|
||||||
|
@click="showCreateTableModal"
|
||||||
|
>
|
||||||
<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('word.table') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showCreateViewModal">
|
<div
|
||||||
|
v-if="workspace.customizations.viewAdd"
|
||||||
|
class="context-element"
|
||||||
|
@click="showCreateViewModal"
|
||||||
|
>
|
||||||
<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('word.view') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showCreateTriggerModal">
|
<div
|
||||||
|
v-if="workspace.customizations.triggerAdd"
|
||||||
|
class="context-element"
|
||||||
|
@click="showCreateTriggerModal"
|
||||||
|
>
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ $tc('word.trigger', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ $tc('word.trigger', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showCreateRoutineModal">
|
<div
|
||||||
|
v-if="workspace.customizations.routineAdd"
|
||||||
|
class="context-element"
|
||||||
|
@click="showCreateRoutineModal"
|
||||||
|
>
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle pr-1" /> {{ $tc('word.storedRoutine', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle pr-1" /> {{ $tc('word.storedRoutine', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showCreateFunctionModal">
|
<div
|
||||||
|
v-if="workspace.customizations.functionAdd"
|
||||||
|
class="context-element"
|
||||||
|
@click="showCreateFunctionModal"
|
||||||
|
>
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box pr-1" /> {{ $tc('word.function', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box pr-1" /> {{ $tc('word.function', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showCreateSchedulerModal">
|
<div
|
||||||
|
v-if="workspace.customizations.schedulerAdd"
|
||||||
|
class="context-element"
|
||||||
|
@click="showCreateSchedulerModal"
|
||||||
|
>
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ $tc('word.scheduler', 1) }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ $tc('word.scheduler', 1) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showEditModal">
|
<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('word.edit') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showDeleteModal">
|
<div class="context-element" @click="showDeleteModal">
|
||||||
@@ -36,12 +64,12 @@
|
|||||||
|
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
v-if="isDeleteModal"
|
v-if="isDeleteModal"
|
||||||
@confirm="deleteDatabase"
|
@confirm="deleteSchema"
|
||||||
@hide="hideDeleteModal"
|
@hide="hideDeleteModal"
|
||||||
>
|
>
|
||||||
<template slot="header">
|
<template slot="header">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<i class="mdi mdi-24px mdi-database-remove mr-1" /> {{ $t('message.deleteDatabase') }}
|
<i class="mdi mdi-24px mdi-database-remove mr-1" /> {{ $t('message.deleteSchema') }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div slot="body">
|
<div slot="body">
|
||||||
@@ -50,7 +78,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ConfirmModal>
|
</ConfirmModal>
|
||||||
<ModalEditDatabase
|
<ModalEditSchema
|
||||||
v-if="isEditModal"
|
v-if="isEditModal"
|
||||||
:selected-database="selectedDatabase"
|
:selected-database="selectedDatabase"
|
||||||
@close="hideEditModal"
|
@close="hideEditModal"
|
||||||
@@ -62,15 +90,15 @@
|
|||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import BaseContextMenu from '@/components/BaseContextMenu';
|
import BaseContextMenu from '@/components/BaseContextMenu';
|
||||||
import ConfirmModal from '@/components/BaseConfirmModal';
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||||
import ModalEditDatabase from '@/components/ModalEditDatabase';
|
import ModalEditSchema from '@/components/ModalEditSchema';
|
||||||
import Database from '@/ipc-api/Database';
|
import Schema from '@/ipc-api/Schema';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WorkspaceExploreBarDatabaseContext',
|
name: 'WorkspaceExploreBarSchemaContext',
|
||||||
components: {
|
components: {
|
||||||
BaseContextMenu,
|
BaseContextMenu,
|
||||||
ConfirmModal,
|
ConfirmModal,
|
||||||
ModalEditDatabase
|
ModalEditSchema
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
contextEvent: MouseEvent,
|
contextEvent: MouseEvent,
|
||||||
@@ -130,9 +158,9 @@ export default {
|
|||||||
closeContext () {
|
closeContext () {
|
||||||
this.$emit('close-context');
|
this.$emit('close-context');
|
||||||
},
|
},
|
||||||
async deleteDatabase () {
|
async deleteSchema () {
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.deleteDatabase({
|
const { status, response } = await Schema.deleteSchema({
|
||||||
uid: this.selectedWorkspace,
|
uid: this.selectedWorkspace,
|
||||||
database: this.selectedDatabase
|
database: this.selectedDatabase
|
||||||
});
|
});
|
@@ -2,6 +2,7 @@
|
|||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
:confirm-text="$t('word.confirm')"
|
:confirm-text="$t('word.confirm')"
|
||||||
size="medium"
|
size="medium"
|
||||||
|
class="options-modal"
|
||||||
@confirm="confirmForeignsChange"
|
@confirm="confirmForeignsChange"
|
||||||
@hide="$emit('hide')"
|
@hide="$emit('hide')"
|
||||||
>
|
>
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
v-for="foreign in foreignProxy"
|
v-for="foreign in foreignProxy"
|
||||||
:key="foreign._id"
|
:key="foreign._id"
|
||||||
class="tile tile-centered c-hand mb-1 p-1"
|
class="tile tile-centered c-hand mb-1 p-1"
|
||||||
:class="{'selected-foreign': selectedForeignID === foreign._id}"
|
:class="{'selected-element': selectedForeignID === foreign._id}"
|
||||||
@click="selectForeign($event, foreign._id)"
|
@click="selectForeign($event, foreign._id)"
|
||||||
>
|
>
|
||||||
<div class="tile-icon">
|
<div class="tile-icon">
|
||||||
@@ -268,8 +269,10 @@ export default {
|
|||||||
this.$emit('foreigns-update', this.foreignProxy);
|
this.$emit('foreigns-update', this.foreignProxy);
|
||||||
},
|
},
|
||||||
selectForeign (event, id) {
|
selectForeign (event, id) {
|
||||||
if (this.selectedForeignID !== id && !event.target.classList.contains('remove-field'))
|
if (this.selectedForeignID !== id && !event.target.classList.contains('remove-field')) {
|
||||||
this.selectedForeignID = id;
|
this.selectedForeignID = id;
|
||||||
|
this.getRefFields();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
getModalInnerHeight () {
|
getModalInnerHeight () {
|
||||||
const modalBody = document.querySelector('.modal-body');
|
const modalBody = document.querySelector('.modal-body');
|
||||||
@@ -369,23 +372,16 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $bg-color-light;
|
|
||||||
|
|
||||||
.tile-action {
|
.tile-action {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected-foreign {
|
&.selected-element {
|
||||||
background: $bg-color-light;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-col {
|
|
||||||
border-left: 2px solid $bg-color-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fields-list {
|
.fields-list {
|
||||||
max-height: 80px;
|
max-height: 80px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
:confirm-text="$t('word.confirm')"
|
:confirm-text="$t('word.confirm')"
|
||||||
size="medium"
|
size="medium"
|
||||||
|
class="options-modal"
|
||||||
@confirm="confirmParametersChange"
|
@confirm="confirmParametersChange"
|
||||||
@hide="$emit('hide')"
|
@hide="$emit('hide')"
|
||||||
>
|
>
|
||||||
@@ -36,12 +37,12 @@
|
|||||||
v-for="param in parametersProxy"
|
v-for="param in parametersProxy"
|
||||||
:key="param._id"
|
:key="param._id"
|
||||||
class="tile tile-centered c-hand mb-1 p-1"
|
class="tile tile-centered c-hand mb-1 p-1"
|
||||||
:class="{'selected-param': selectedParam === param._id}"
|
:class="{'selected-element': selectedParam === param._id}"
|
||||||
@click="selectParameter($event, param._id)"
|
@click="selectParameter($event, param._id)"
|
||||||
>
|
>
|
||||||
<div class="tile-icon">
|
<div class="tile-icon">
|
||||||
<div>
|
<div>
|
||||||
<i class="mdi mdi-hexagon mdi-24px" :class="`type-${param.type.toLowerCase()}`" />
|
<i class="mdi mdi-hexagon mdi-24px" :class="typeClass(param.type)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile-content">
|
<div class="tile-content">
|
||||||
@@ -183,6 +184,11 @@ export default {
|
|||||||
window.removeEventListener('resize', this.getModalInnerHeight);
|
window.removeEventListener('resize', this.getModalInnerHeight);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
typeClass (type) {
|
||||||
|
if (type)
|
||||||
|
return `type-${type.toLowerCase().replaceAll(' ', '_').replaceAll('"', '')}`;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
confirmParametersChange () {
|
confirmParametersChange () {
|
||||||
this.$emit('parameters-update', this.parametersProxy);
|
this.$emit('parameters-update', this.parametersProxy);
|
||||||
},
|
},
|
||||||
@@ -244,23 +250,16 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $bg-color-light;
|
|
||||||
|
|
||||||
.tile-action {
|
.tile-action {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected-param {
|
&.selected-element {
|
||||||
background: $bg-color-light;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-col {
|
|
||||||
border-left: 2px solid $bg-color-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fields-list {
|
.fields-list {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
:confirm-text="$t('word.confirm')"
|
:confirm-text="$t('word.confirm')"
|
||||||
size="medium"
|
size="medium"
|
||||||
|
class="options-modal"
|
||||||
@confirm="confirmIndexesChange"
|
@confirm="confirmIndexesChange"
|
||||||
@hide="$emit('hide')"
|
@hide="$emit('hide')"
|
||||||
>
|
>
|
||||||
@@ -36,7 +37,7 @@
|
|||||||
v-for="index in indexesProxy"
|
v-for="index in indexesProxy"
|
||||||
:key="index._id"
|
:key="index._id"
|
||||||
class="tile tile-centered c-hand mb-1 p-1"
|
class="tile tile-centered c-hand mb-1 p-1"
|
||||||
:class="{'selected-index': selectedIndexID === index._id}"
|
:class="{'selected-element': selectedIndexID === index._id}"
|
||||||
@click="selectIndex($event, index._id)"
|
@click="selectIndex($event, index._id)"
|
||||||
>
|
>
|
||||||
<div class="tile-icon">
|
<div class="tile-icon">
|
||||||
@@ -256,23 +257,16 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $bg-color-light;
|
|
||||||
|
|
||||||
.tile-action {
|
.tile-action {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected-index {
|
&.selected-element {
|
||||||
background: $bg-color-light;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-col {
|
|
||||||
border-left: 2px solid $bg-color-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fields-list {
|
.fields-list {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.comment" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.comment') }}
|
{{ $t('word.comment') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.autoIncrement" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.autoIncrement') }}
|
{{ $t('word.autoIncrement') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.collations" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.collation') }}
|
{{ $t('word.collation') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.engines" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.engine') }}
|
{{ $t('word.engine') }}
|
||||||
</label>
|
</label>
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.definer" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.definer') }}
|
{{ $t('word.definer') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.comment" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('word.comment') }}
|
{{ $t('word.comment') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.procedureDataAccess" class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('message.dataAccess') }}
|
{{ $t('message.dataAccess') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.procedureDeterministic" class="form-group">
|
||||||
<div class="col-4" />
|
<div class="col-4" />
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<label class="form-checkbox form-inline">
|
<label class="form-checkbox form-inline">
|
||||||
@@ -124,6 +124,9 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
isTableNameValid () {
|
isTableNameValid () {
|
||||||
return this.optionsProxy.name !== '';
|
return this.optionsProxy.name !== '';
|
||||||
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.workspace.customizations;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
:confirm-text="$t('word.confirm')"
|
:confirm-text="$t('word.confirm')"
|
||||||
size="medium"
|
size="medium"
|
||||||
|
class="options-modal"
|
||||||
@confirm="confirmParametersChange"
|
@confirm="confirmParametersChange"
|
||||||
@hide="$emit('hide')"
|
@hide="$emit('hide')"
|
||||||
>
|
>
|
||||||
@@ -36,12 +37,12 @@
|
|||||||
v-for="param in parametersProxy"
|
v-for="param in parametersProxy"
|
||||||
:key="param._id"
|
:key="param._id"
|
||||||
class="tile tile-centered c-hand mb-1 p-1"
|
class="tile tile-centered c-hand mb-1 p-1"
|
||||||
:class="{'selected-param': selectedParam === param._id}"
|
:class="{'selected-element': selectedParam === param._id}"
|
||||||
@click="selectParameter($event, param._id)"
|
@click="selectParameter($event, param._id)"
|
||||||
>
|
>
|
||||||
<div class="tile-icon">
|
<div class="tile-icon">
|
||||||
<div>
|
<div>
|
||||||
<i class="mdi mdi-hexagon mdi-24px" :class="`type-${param.type.toLowerCase()}`" />
|
<i class="mdi mdi-hexagon mdi-24px" :class="typeClass(param.type)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile-content">
|
<div class="tile-content">
|
||||||
@@ -105,7 +106,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div v-if="customizations.parametersLength" class="form-group">
|
||||||
<label class="form-label col-3">
|
<label class="form-label col-3">
|
||||||
{{ $t('word.length') }}
|
{{ $t('word.length') }}
|
||||||
</label>
|
</label>
|
||||||
@@ -198,6 +199,9 @@ export default {
|
|||||||
},
|
},
|
||||||
isChanged () {
|
isChanged () {
|
||||||
return JSON.stringify(this.localParameters) !== JSON.stringify(this.parametersProxy);
|
return JSON.stringify(this.localParameters) !== JSON.stringify(this.parametersProxy);
|
||||||
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.workspace.customizations;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -214,6 +218,11 @@ export default {
|
|||||||
window.removeEventListener('resize', this.getModalInnerHeight);
|
window.removeEventListener('resize', this.getModalInnerHeight);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
typeClass (type) {
|
||||||
|
if (type)
|
||||||
|
return `type-${type.toLowerCase().replaceAll(' ', '_').replaceAll('"', '')}`;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
confirmParametersChange () {
|
confirmParametersChange () {
|
||||||
this.$emit('parameters-update', this.parametersProxy);
|
this.$emit('parameters-update', this.parametersProxy);
|
||||||
},
|
},
|
||||||
@@ -229,10 +238,10 @@ export default {
|
|||||||
addParameter () {
|
addParameter () {
|
||||||
this.parametersProxy = [...this.parametersProxy, {
|
this.parametersProxy = [...this.parametersProxy, {
|
||||||
_id: uidGen(),
|
_id: uidGen(),
|
||||||
name: `Param${this.i++}`,
|
name: `param${this.i++}`,
|
||||||
type: 'INT',
|
type: this.workspace.dataTypes[0].types[0].name,
|
||||||
context: 'IN',
|
context: 'IN',
|
||||||
length: 10
|
length: ''
|
||||||
}];
|
}];
|
||||||
|
|
||||||
if (this.parametersProxy.length === 1)
|
if (this.parametersProxy.length === 1)
|
||||||
@@ -275,23 +284,16 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: $bg-color-light;
|
|
||||||
|
|
||||||
.tile-action {
|
.tile-action {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.selected-param {
|
&.selected-element {
|
||||||
background: $bg-color-light;
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-col {
|
|
||||||
border-left: 2px solid $bg-color-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fields-list {
|
.fields-list {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@@ -433,11 +433,11 @@ export default {
|
|||||||
_id: uidGen(),
|
_id: uidGen(),
|
||||||
name: `${this.$tc('word.field', 1)}_${++this.newFieldsCounter}`,
|
name: `${this.$tc('word.field', 1)}_${++this.newFieldsCounter}`,
|
||||||
key: '',
|
key: '',
|
||||||
type: 'int',
|
type: this.workspace.dataTypes[0].types[0].name,
|
||||||
schema: this.schema,
|
schema: this.schema,
|
||||||
table: this.table,
|
table: this.table,
|
||||||
numPrecision: null,
|
numPrecision: null,
|
||||||
numLength: 11,
|
numLength: this.workspace.dataTypes[0].types[0].length,
|
||||||
datePrecision: null,
|
datePrecision: null,
|
||||||
charLength: null,
|
charLength: null,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
|
@@ -73,6 +73,7 @@
|
|||||||
<ModalAskParameters
|
<ModalAskParameters
|
||||||
v-if="isAskingParameters"
|
v-if="isAskingParameters"
|
||||||
:local-routine="localFunction"
|
:local-routine="localFunction"
|
||||||
|
:client="workspace.client"
|
||||||
@confirm="runFunction"
|
@confirm="runFunction"
|
||||||
@close="hideAskParamsModal"
|
@close="hideAskParamsModal"
|
||||||
/>
|
/>
|
||||||
|
@@ -74,6 +74,7 @@
|
|||||||
<ModalAskParameters
|
<ModalAskParameters
|
||||||
v-if="isAskingParameters"
|
v-if="isAskingParameters"
|
||||||
:local-routine="localRoutine"
|
:local-routine="localRoutine"
|
||||||
|
:client="workspace.client"
|
||||||
@confirm="runRoutine"
|
@confirm="runRoutine"
|
||||||
@close="hideAskParamsModal"
|
@close="hideAskParamsModal"
|
||||||
/>
|
/>
|
||||||
@@ -281,13 +282,13 @@ export default {
|
|||||||
case 'maria':
|
case 'maria':
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
case 'pg':
|
case 'pg':
|
||||||
sql = `CALL \`${this.originalRoutine.name}\` (${params.join(',')})`;
|
sql = `CALL ${this.originalRoutine.name}(${params.join(',')})`;
|
||||||
break;
|
break;
|
||||||
case 'mssql':
|
case 'mssql':
|
||||||
sql = `EXEC ${this.originalRoutine.name} ${params.join(',')}`;
|
sql = `EXEC ${this.originalRoutine.name} ${params.join(',')}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sql = `CALL \`${this.originalRoutine.name}\` (${params.join(',')})`;
|
sql = `CALL \`${this.originalRoutine.name}\`(${params.join(',')})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.newTab({ uid: this.connection.uid, content: sql, autorun: true });
|
this.newTab({ uid: this.connection.uid, content: sql, autorun: true });
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-auto">
|
<div class="column col-auto">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.definer" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.definer') }}</label>
|
<label class="form-label">{{ $t('word.definer') }}</label>
|
||||||
<select
|
<select
|
||||||
v-if="workspace.users.length"
|
v-if="workspace.users.length"
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column col-auto mr-2">
|
<div class="column col-auto mr-2">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewSqlSecurity" class="form-group">
|
||||||
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
<label class="form-label">{{ $t('message.sqlSecurity') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-auto mr-2">
|
<div class="column col-auto mr-2">
|
||||||
<div class="form-group">
|
<div v-if="workspace.customizations.viewAlgorithm" class="form-group">
|
||||||
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
<label class="form-label">{{ $t('word.algorithm') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
<input
|
<input
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-auto mr-2">
|
<div v-if="workspace.customizations.viewUpdateOption" class="column col-auto mr-2">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
<label class="form-label">{{ $t('message.updateOption') }}</label>
|
||||||
<label class="form-radio">
|
<label class="form-radio">
|
||||||
|
@@ -42,6 +42,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="customizations.tableArray" class="th">
|
||||||
|
<div class="column-resizable">
|
||||||
|
<div class="table-column-title">
|
||||||
|
{{ $t('word.array') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="th">
|
<div class="th">
|
||||||
<div class="column-resizable">
|
<div class="column-resizable">
|
||||||
<div class="table-column-title">
|
<div class="table-column-title">
|
||||||
@@ -49,21 +56,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="th">
|
<div v-if="customizations.unsigned" class="th">
|
||||||
<div class="column-resizable">
|
<div class="column-resizable">
|
||||||
<div class="table-column-title">
|
<div class="table-column-title">
|
||||||
{{ $t('word.unsigned') }}
|
{{ $t('word.unsigned') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="th">
|
<div v-if="customizations.nullable" class="th">
|
||||||
<div class="column-resizable">
|
<div class="column-resizable">
|
||||||
<div class="table-column-title">
|
<div class="table-column-title">
|
||||||
{{ $t('message.allowNull') }}
|
{{ $t('message.allowNull') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="th">
|
<div v-if="customizations.zerofill" class="th">
|
||||||
<div class="column-resizable">
|
<div class="column-resizable">
|
||||||
<div class="table-column-title">
|
<div class="table-column-title">
|
||||||
{{ $t('message.zeroFill') }}
|
{{ $t('message.zeroFill') }}
|
||||||
@@ -77,14 +84,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="th">
|
<div v-if="customizations.comment" class="th">
|
||||||
<div class="column-resizable">
|
<div class="column-resizable">
|
||||||
<div class="table-column-title">
|
<div class="table-column-title">
|
||||||
{{ $t('word.comment') }}
|
{{ $t('word.comment') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="th">
|
<div v-if="customizations.collation" class="th">
|
||||||
<div class="column-resizable min-100">
|
<div class="column-resizable min-100">
|
||||||
<div class="table-column-title">
|
<div class="table-column-title">
|
||||||
{{ $t('word.collation') }}
|
{{ $t('word.collation') }}
|
||||||
@@ -106,6 +113,7 @@
|
|||||||
:indexes="getIndexes(row.name)"
|
:indexes="getIndexes(row.name)"
|
||||||
:foreigns="getForeigns(row.name)"
|
:foreigns="getForeigns(row.name)"
|
||||||
:data-types="dataTypes"
|
:data-types="dataTypes"
|
||||||
|
:customizations="customizations"
|
||||||
@contextmenu="contextMenu"
|
@contextmenu="contextMenu"
|
||||||
/>
|
/>
|
||||||
</draggable>
|
</draggable>
|
||||||
@@ -154,6 +162,9 @@ export default {
|
|||||||
workspaceSchema () {
|
workspaceSchema () {
|
||||||
return this.getWorkspace(this.connUid).breadcrumbs.schema;
|
return this.getWorkspace(this.connUid).breadcrumbs.schema;
|
||||||
},
|
},
|
||||||
|
customizations () {
|
||||||
|
return this.getWorkspace(this.connUid).customizations;
|
||||||
|
},
|
||||||
dataTypes () {
|
dataTypes () {
|
||||||
return this.getWorkspace(this.connUid).dataTypes;
|
return this.getWorkspace(this.connUid).dataTypes;
|
||||||
},
|
},
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="tr" @contextmenu.prevent="$emit('contextmenu', $event, localRow._id)">
|
<div class="tr" @contextmenu.prevent="$emit('contextmenu', $event, localRow._id)">
|
||||||
<div class="td" tabindex="0">
|
<div class="td" tabindex="0">
|
||||||
<div class="row-draggable">
|
<div :class="customizations.sortableFields ? 'row-draggable' : 'text-center'">
|
||||||
<i class="mdi mdi-drag-horizontal row-draggable-icon" />
|
<i v-if="customizations.sortableFields" class="mdi mdi-drag-horizontal row-draggable-icon" />
|
||||||
{{ localRow.order }}
|
{{ localRow.order }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<span
|
<span
|
||||||
v-if="!isInlineEditor.type"
|
v-if="!isInlineEditor.type"
|
||||||
class="cell-content text-left"
|
class="cell-content text-left"
|
||||||
:class="`type-${lowerCase(localRow.type)}`"
|
:class="typeClass(localRow.type)"
|
||||||
@click="editON($event, localRow.type.toUpperCase(), 'type')"
|
@click="editON($event, localRow.type.toUpperCase(), 'type')"
|
||||||
>
|
>
|
||||||
{{ localRow.type }}
|
{{ localRow.type }}
|
||||||
@@ -76,6 +76,16 @@
|
|||||||
</optgroup>
|
</optgroup>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="customizations.tableArray"
|
||||||
|
class="td"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<label class="form-checkbox">
|
||||||
|
<input v-model="localRow.isArray" type="checkbox">
|
||||||
|
<i class="form-icon" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="td type-int" tabindex="0">
|
<div class="td type-int" tabindex="0">
|
||||||
<template v-if="fieldType.length">
|
<template v-if="fieldType.length">
|
||||||
<span
|
<span
|
||||||
@@ -96,7 +106,11 @@
|
|||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="td" tabindex="0">
|
<div
|
||||||
|
v-if="customizations.unsigned"
|
||||||
|
class="td"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
<label class="form-checkbox">
|
<label class="form-checkbox">
|
||||||
<input
|
<input
|
||||||
v-model="localRow.unsigned"
|
v-model="localRow.unsigned"
|
||||||
@@ -106,7 +120,11 @@
|
|||||||
<i class="form-icon" />
|
<i class="form-icon" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="td" tabindex="0">
|
<div
|
||||||
|
v-if="customizations.nullable"
|
||||||
|
class="td"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
<label class="form-checkbox">
|
<label class="form-checkbox">
|
||||||
<input
|
<input
|
||||||
v-model="localRow.nullable"
|
v-model="localRow.nullable"
|
||||||
@@ -116,7 +134,11 @@
|
|||||||
<i class="form-icon" />
|
<i class="form-icon" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="td" tabindex="0">
|
<div
|
||||||
|
v-if="customizations.zerofill"
|
||||||
|
class="td"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
<label class="form-checkbox">
|
<label class="form-checkbox">
|
||||||
<input
|
<input
|
||||||
v-model="localRow.zerofill"
|
v-model="localRow.zerofill"
|
||||||
@@ -131,7 +153,11 @@
|
|||||||
{{ fieldDefault }}
|
{{ fieldDefault }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="td type-varchar" tabindex="0">
|
<div
|
||||||
|
v-if="customizations.comment"
|
||||||
|
class="td type-varchar"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="!isInlineEditor.comment"
|
v-if="!isInlineEditor.comment"
|
||||||
class="cell-content"
|
class="cell-content"
|
||||||
@@ -149,7 +175,11 @@
|
|||||||
@blur="editOFF"
|
@blur="editOFF"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="td" tabindex="0">
|
<div
|
||||||
|
v-if="customizations.collation"
|
||||||
|
class="td"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
<template v-if="fieldType.collation">
|
<template v-if="fieldType.collation">
|
||||||
<span
|
<span
|
||||||
v-if="!isInlineEditor.collation"
|
v-if="!isInlineEditor.collation"
|
||||||
@@ -220,7 +250,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2">
|
<div v-if="customizations.nullable" class="mb-2">
|
||||||
<label class="form-radio form-inline">
|
<label class="form-radio form-inline">
|
||||||
<input
|
<input
|
||||||
v-model="defaultValue.type"
|
v-model="defaultValue.type"
|
||||||
@@ -230,7 +260,7 @@
|
|||||||
><i class="form-icon" /> NULL
|
><i class="form-icon" /> NULL
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-2">
|
<div v-if="customizations.autoIncrement" class="mb-2">
|
||||||
<label class="form-radio form-inline">
|
<label class="form-radio form-inline">
|
||||||
<input
|
<input
|
||||||
v-model="defaultValue.type"
|
v-model="defaultValue.type"
|
||||||
@@ -261,7 +291,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-if="customizations.onUpdate">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label col-4">
|
<label class="form-label col-4">
|
||||||
{{ $t('message.onUpdate') }}
|
{{ $t('message.onUpdate') }}
|
||||||
@@ -294,7 +324,8 @@ export default {
|
|||||||
row: Object,
|
row: Object,
|
||||||
dataTypes: Array,
|
dataTypes: Array,
|
||||||
indexes: Array,
|
indexes: Array,
|
||||||
foreigns: Array
|
foreigns: Array,
|
||||||
|
customizations: Object
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -378,10 +409,10 @@ export default {
|
|||||||
return 'UNKNOWN ' + key;
|
return 'UNKNOWN ' + key;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lowerCase (val) {
|
typeClass (type) {
|
||||||
if (val)
|
if (type)
|
||||||
return val.toLowerCase();
|
return `type-${type.toLowerCase().replaceAll(' ', '_').replaceAll('"', '')}`;
|
||||||
return val;
|
return '';
|
||||||
},
|
},
|
||||||
initLocalRow () {
|
initLocalRow () {
|
||||||
Object.keys(this.localRow).forEach(key => {
|
Object.keys(this.localRow).forEach(key => {
|
||||||
|
@@ -68,7 +68,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Database from '@/ipc-api/Database';
|
import Schema from '@/ipc-api/Schema';
|
||||||
import QueryEditor from '@/components/QueryEditor';
|
import QueryEditor from '@/components/QueryEditor';
|
||||||
import BaseLoader from '@/components/BaseLoader';
|
import BaseLoader from '@/components/BaseLoader';
|
||||||
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
|
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
|
||||||
@@ -150,7 +150,7 @@ export default {
|
|||||||
query
|
query
|
||||||
};
|
};
|
||||||
|
|
||||||
const { status, response } = await Database.rawQuery(params);
|
const { status, response } = await Schema.rawQuery(params);
|
||||||
|
|
||||||
if (status === 'success') {
|
if (status === 'success') {
|
||||||
this.results = Array.isArray(response) ? response : [response];
|
this.results = Array.isArray(response) ? response : [response];
|
||||||
@@ -232,7 +232,6 @@ export default {
|
|||||||
.btn {
|
.btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
color: $body-font-color;
|
|
||||||
margin-right: 0.4rem;
|
margin-right: 0.4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -86,6 +86,7 @@ import BaseVirtualScroll from '@/components/BaseVirtualScroll';
|
|||||||
import WorkspaceQueryTableRow from '@/components/WorkspaceQueryTableRow';
|
import WorkspaceQueryTableRow from '@/components/WorkspaceQueryTableRow';
|
||||||
import TableContext from '@/components/WorkspaceQueryTableContext';
|
import TableContext from '@/components/WorkspaceQueryTableContext';
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WorkspaceQueryTable',
|
name: 'WorkspaceQueryTable',
|
||||||
@@ -122,7 +123,13 @@ export default {
|
|||||||
return this.getWorkspace(this.connUid).breadcrumbs.schema;
|
return this.getWorkspace(this.connUid).breadcrumbs.schema;
|
||||||
},
|
},
|
||||||
primaryField () {
|
primaryField () {
|
||||||
return this.fields.filter(field => ['pri', 'uni'].includes(field.key))[0] || false;
|
const primaryFields = this.fields.filter(field => field.key === 'pri');
|
||||||
|
const uniqueFields = this.fields.filter(field => field.key === 'uni');
|
||||||
|
|
||||||
|
if ((primaryFields.length > 1 || !primaryFields.length) && (uniqueFields.length > 1 || !uniqueFields.length))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return primaryFields[0] || uniqueFields[0];
|
||||||
},
|
},
|
||||||
isSortable () {
|
isSortable () {
|
||||||
return this.fields.every(field => field.name);
|
return this.fields.every(field => field.name);
|
||||||
@@ -289,15 +296,28 @@ export default {
|
|||||||
this.resizeResults();
|
this.resizeResults();
|
||||||
},
|
},
|
||||||
updateField (payload, row) {
|
updateField (payload, row) {
|
||||||
const localRow = Object.assign({}, row);
|
const orgRow = this.localResults.find(lr => lr._id === row._id);
|
||||||
delete localRow._id;
|
delete row._id;
|
||||||
|
delete orgRow._id;
|
||||||
|
|
||||||
|
Object.keys(orgRow).forEach(key => { // remap the row
|
||||||
|
if (orgRow[key] instanceof Date && moment(orgRow[key]).isValid()) { // if datetime
|
||||||
|
let datePrecision = '';
|
||||||
|
const precision = this.fields.find(field => field.name === key).datePrecision;
|
||||||
|
for (let i = 0; i < precision; i++)
|
||||||
|
datePrecision += i === 0 ? '.S' : 'S';
|
||||||
|
|
||||||
|
orgRow[key] = moment(orgRow[key]).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
primary: this.primaryField.name,
|
primary: this.primaryField.name,
|
||||||
schema: this.getSchema(this.resultsetIndex),
|
schema: this.getSchema(this.resultsetIndex),
|
||||||
table: this.getTable(this.resultsetIndex),
|
table: this.getTable(this.resultsetIndex),
|
||||||
id: this.getPrimaryValue(localRow),
|
id: this.getPrimaryValue(orgRow),
|
||||||
localRow,
|
row,
|
||||||
|
orgRow,
|
||||||
...payload
|
...payload
|
||||||
};
|
};
|
||||||
this.$emit('update-field', params);
|
this.$emit('update-field', params);
|
||||||
@@ -326,6 +346,7 @@ export default {
|
|||||||
table: this.getTable(this.resultsetIndex),
|
table: this.getTable(this.resultsetIndex),
|
||||||
id: this.getPrimaryValue(row),
|
id: this.getPrimaryValue(row),
|
||||||
row,
|
row,
|
||||||
|
orgRow: row,
|
||||||
field: this.selectedCell.field,
|
field: this.selectedCell.field,
|
||||||
content: null
|
content: null
|
||||||
};
|
};
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
<span
|
<span
|
||||||
v-if="!isInlineEditor[cKey]"
|
v-if="!isInlineEditor[cKey]"
|
||||||
class="cell-content px-2"
|
class="cell-content px-2"
|
||||||
:class="`${isNull(col)} type-${fields[cKey].type.toLowerCase()}`"
|
:class="`${isNull(col)} ${typeClass(fields[cKey].type)}`"
|
||||||
@dblclick="editON($event, col, cKey)"
|
@dblclick="editON($event, col, cKey)"
|
||||||
>{{ col | typeFormat(fields[cKey].type.toLowerCase(), fields[cKey].length) | cutText }}</span>
|
>{{ col | typeFormat(fields[cKey].type.toLowerCase(), fields[cKey].length) | cutText }}</span>
|
||||||
<ForeignKeySelect
|
<ForeignKeySelect
|
||||||
@@ -34,6 +34,15 @@
|
|||||||
class="editable-field px-2"
|
class="editable-field px-2"
|
||||||
@blur="editOFF"
|
@blur="editOFF"
|
||||||
>
|
>
|
||||||
|
<select
|
||||||
|
v-else-if="inputProps.type === 'boolean'"
|
||||||
|
v-model="editingContent"
|
||||||
|
class="form-select small-select editable-field"
|
||||||
|
@blur="editOFF"
|
||||||
|
>
|
||||||
|
<option>true</option>
|
||||||
|
<option>false</option>
|
||||||
|
</select>
|
||||||
<input
|
<input
|
||||||
v-else
|
v-else
|
||||||
ref="editField"
|
ref="editField"
|
||||||
@@ -173,7 +182,7 @@ import { mimeFromHex } from 'common/libs/mimeFromHex';
|
|||||||
import { formatBytes } from 'common/libs/formatBytes';
|
import { formatBytes } from 'common/libs/formatBytes';
|
||||||
import { bufferToBase64 } from 'common/libs/bufferToBase64';
|
import { bufferToBase64 } from 'common/libs/bufferToBase64';
|
||||||
import hexToBinary from 'common/libs/hexToBinary';
|
import hexToBinary from 'common/libs/hexToBinary';
|
||||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
import { TEXT, LONG_TEXT, ARRAY, TEXT_SEARCH, NUMBER, FLOAT, BOOLEAN, DATE, TIME, DATETIME, BLOB, BIT, HAS_TIMEZONE } from 'common/fieldTypes';
|
||||||
import { VueMaskDirective } from 'v-mask';
|
import { VueMaskDirective } from 'v-mask';
|
||||||
import ConfirmModal from '@/components/BaseConfirmModal';
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||||
import TextEditor from '@/components/BaseTextEditor';
|
import TextEditor from '@/components/BaseTextEditor';
|
||||||
@@ -204,6 +213,9 @@ export default {
|
|||||||
return moment(val).isValid() ? moment(val).format('YYYY-MM-DD') : val;
|
return moment(val).isValid() ? moment(val).format('YYYY-MM-DD') : val;
|
||||||
|
|
||||||
if (DATETIME.includes(type)) {
|
if (DATETIME.includes(type)) {
|
||||||
|
if (typeof val === 'string')
|
||||||
|
return val;
|
||||||
|
|
||||||
let datePrecision = '';
|
let datePrecision = '';
|
||||||
for (let i = 0; i < precision; i++)
|
for (let i = 0; i < precision; i++)
|
||||||
datePrecision += i === 0 ? '.S' : 'S';
|
datePrecision += i === 0 ? '.S' : 'S';
|
||||||
@@ -225,6 +237,12 @@ export default {
|
|||||||
return hexToBinary(hex);
|
return hexToBinary(hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ARRAY.includes(type)) {
|
||||||
|
if (Array.isArray(val))
|
||||||
|
return JSON.stringify(val).replaceAll('[', '{').replaceAll(']', '}');
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -268,6 +286,9 @@ export default {
|
|||||||
for (let i = 0; i < precision; i++)
|
for (let i = 0; i < precision; i++)
|
||||||
timeMask += i === 0 ? '.#' : '#';
|
timeMask += i === 0 ? '.#' : '#';
|
||||||
|
|
||||||
|
if (HAS_TIMEZONE.includes(this.editingType))
|
||||||
|
timeMask += 'X##';
|
||||||
|
|
||||||
return { type: 'text', mask: timeMask };
|
return { type: 'text', mask: timeMask };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,14 +302,17 @@ export default {
|
|||||||
for (let i = 0; i < precision; i++)
|
for (let i = 0; i < precision; i++)
|
||||||
datetimeMask += i === 0 ? '.#' : '#';
|
datetimeMask += i === 0 ? '.#' : '#';
|
||||||
|
|
||||||
|
if (HAS_TIMEZONE.includes(this.editingType))
|
||||||
|
datetimeMask += 'X##';
|
||||||
|
|
||||||
return { type: 'text', mask: datetimeMask };
|
return { type: 'text', mask: datetimeMask };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BLOB.includes(this.editingType))
|
if (BLOB.includes(this.editingType))
|
||||||
return { type: 'file', mask: false };
|
return { type: 'file', mask: false };
|
||||||
|
|
||||||
if (BIT.includes(this.editingType))
|
if (BOOLEAN.includes(this.editingType))
|
||||||
return { type: 'text', mask: false };
|
return { type: 'boolean', mask: false };
|
||||||
|
|
||||||
return { type: 'text', mask: false };
|
return { type: 'text', mask: false };
|
||||||
},
|
},
|
||||||
@@ -331,6 +355,11 @@ export default {
|
|||||||
isNull (value) {
|
isNull (value) {
|
||||||
return value === null ? ' is-null' : '';
|
return value === null ? ' is-null' : '';
|
||||||
},
|
},
|
||||||
|
typeClass (type) {
|
||||||
|
if (type)
|
||||||
|
return `type-${type.toLowerCase().replaceAll(' ', '_').replaceAll('"', '')}`;
|
||||||
|
return '';
|
||||||
|
},
|
||||||
bufferToBase64 (val) {
|
bufferToBase64 (val) {
|
||||||
return bufferToBase64(val);
|
return bufferToBase64(val);
|
||||||
},
|
},
|
||||||
@@ -345,7 +374,7 @@ export default {
|
|||||||
this.editingField = field;
|
this.editingField = field;
|
||||||
this.editingLength = this.fields[field].length;
|
this.editingLength = this.fields[field].length;
|
||||||
|
|
||||||
if (LONG_TEXT.includes(type)) {
|
if ([...LONG_TEXT, ...ARRAY, ...TEXT_SEARCH].includes(type)) {
|
||||||
this.isTextareaEditor = true;
|
this.isTextareaEditor = true;
|
||||||
this.editingContent = this.$options.filters.typeFormat(content, type);
|
this.editingContent = this.$options.filters.typeFormat(content, type);
|
||||||
return;
|
return;
|
||||||
@@ -389,7 +418,13 @@ export default {
|
|||||||
this.isInlineEditor[this.editingField] = false;
|
this.isInlineEditor[this.editingField] = false;
|
||||||
let content;
|
let content;
|
||||||
if (!BLOB.includes(this.editingType)) {
|
if (!BLOB.includes(this.editingType)) {
|
||||||
|
if ([...DATETIME, ...TIME].includes(this.editingType)) {
|
||||||
|
if (this.editingContent.substring(this.editingContent.length - 1) === '.')
|
||||||
|
this.editingContent = this.editingContent.slice(0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.editingContent === this.$options.filters.typeFormat(this.originalContent, this.editingType, this.editingLength)) return;// If not changed
|
if (this.editingContent === this.$options.filters.typeFormat(this.originalContent, this.editingType, this.editingLength)) return;// If not changed
|
||||||
|
|
||||||
content = this.editingContent;
|
content = this.editingContent;
|
||||||
}
|
}
|
||||||
else { // Handle file upload
|
else { // Handle file upload
|
||||||
|
@@ -289,10 +289,6 @@ export default {
|
|||||||
.export-dropdown {
|
.export-dropdown {
|
||||||
.menu {
|
.menu {
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
|
|
||||||
.menu-item a:hover {
|
|
||||||
background: $bg-color-gray;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -100,7 +100,11 @@ module.exports = {
|
|||||||
paste: 'Paste',
|
paste: 'Paste',
|
||||||
tools: 'Tools',
|
tools: 'Tools',
|
||||||
variables: 'Variables',
|
variables: 'Variables',
|
||||||
processes: 'Processes'
|
processes: 'Processes',
|
||||||
|
database: 'Database',
|
||||||
|
scratchpad: 'Scratchpad',
|
||||||
|
array: 'Array',
|
||||||
|
changelog: 'Changelog'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
appWelcome: 'Welcome to Antares SQL Client!',
|
appWelcome: 'Welcome to Antares SQL Client!',
|
||||||
@@ -199,7 +203,12 @@ module.exports = {
|
|||||||
setNull: 'Set NULL',
|
setNull: 'Set NULL',
|
||||||
processesList: 'Processes list',
|
processesList: 'Processes list',
|
||||||
processInfo: 'Process info',
|
processInfo: 'Process info',
|
||||||
manageUsers: 'Manage users'
|
manageUsers: 'Manage users',
|
||||||
|
createNewSchema: 'Create new schema',
|
||||||
|
schemaName: 'Schema name',
|
||||||
|
editSchema: 'Edit schema',
|
||||||
|
deleteSchema: 'Delete schema',
|
||||||
|
markdownSupported: 'Markdown supported'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Address',
|
address: 'Address',
|
||||||
|
BIN
src/renderer/images/light.png
Normal file
BIN
src/renderer/images/light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
@@ -2,20 +2,20 @@
|
|||||||
import { ipcRenderer } from 'electron';
|
import { ipcRenderer } from 'electron';
|
||||||
|
|
||||||
export default class {
|
export default class {
|
||||||
static createDatabase (params) {
|
static createSchema (params) {
|
||||||
return ipcRenderer.invoke('create-database', params);
|
return ipcRenderer.invoke('create-schema', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static updateDatabase (params) {
|
static updateSchema (params) {
|
||||||
return ipcRenderer.invoke('update-database', params);
|
return ipcRenderer.invoke('update-schema', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDatabaseCollation (params) {
|
static getDatabaseCollation (params) {
|
||||||
return ipcRenderer.invoke('get-database-collation', params);
|
return ipcRenderer.invoke('get-schema-collation', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static deleteDatabase (params) {
|
static deleteSchema (params) {
|
||||||
return ipcRenderer.invoke('delete-database', params);
|
return ipcRenderer.invoke('delete-schema', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getStructure (params) {
|
static getStructure (params) {
|
@@ -42,6 +42,7 @@ export default {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Tables.deleteTableRows(params);
|
const { status, response } = await Tables.deleteTableRows(params);
|
||||||
|
this.isQuering = false;
|
||||||
|
|
||||||
if (status === 'success')
|
if (status === 'success')
|
||||||
this.reloadTable();
|
this.reloadTable();
|
||||||
@@ -50,9 +51,8 @@ export default {
|
|||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.addNotification({ status: 'error', message: err.stack });
|
this.addNotification({ status: 'error', message: err.stack });
|
||||||
|
this.isQuering = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isQuering = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -22,6 +22,15 @@
|
|||||||
"mediumtext": $string-color,
|
"mediumtext": $string-color,
|
||||||
"longtext": $string-color,
|
"longtext": $string-color,
|
||||||
"json": $string-color,
|
"json": $string-color,
|
||||||
|
"name": $string-color,
|
||||||
|
"character": $string-color,
|
||||||
|
"character_varying": $string-color,
|
||||||
|
"cidr": $string-color,
|
||||||
|
"inet": $string-color,
|
||||||
|
"macaddr": $string-color,
|
||||||
|
"macaddr8": $string-color,
|
||||||
|
"uuid": $string-color,
|
||||||
|
"regproc": $string-color,
|
||||||
"int": $number-color,
|
"int": $number-color,
|
||||||
"tinyint": $number-color,
|
"tinyint": $number-color,
|
||||||
"smallint": $number-color,
|
"smallint": $number-color,
|
||||||
@@ -31,12 +40,26 @@
|
|||||||
"decimal": $number-color,
|
"decimal": $number-color,
|
||||||
"bigint": $number-color,
|
"bigint": $number-color,
|
||||||
"newdecimal": $number-color,
|
"newdecimal": $number-color,
|
||||||
|
"integer": $number-color,
|
||||||
|
"numeric": $number-color,
|
||||||
|
"smallserial": $number-color,
|
||||||
|
"serial": $number-color,
|
||||||
|
"bigserial": $number-color,
|
||||||
|
"real": $number-color,
|
||||||
|
"double_precision": $number-color,
|
||||||
|
"oid": $number-color,
|
||||||
|
"xid": $number-color,
|
||||||
|
"money": $number-color,
|
||||||
"datetime": $date-color,
|
"datetime": $date-color,
|
||||||
"date": $date-color,
|
"date": $date-color,
|
||||||
"time": $date-color,
|
"time": $date-color,
|
||||||
|
"time_with_time_zone": $date-color,
|
||||||
"year": $date-color,
|
"year": $date-color,
|
||||||
"timestamp": $date-color,
|
"timestamp": $date-color,
|
||||||
|
"timestamp_without_time_zone": $date-color,
|
||||||
|
"timestamp_with_time_zone": $date-color,
|
||||||
"bit": $bit-color,
|
"bit": $bit-color,
|
||||||
|
"bit_varying": $bit-color,
|
||||||
"binary": $blob-color,
|
"binary": $blob-color,
|
||||||
"varbinary": $blob-color,
|
"varbinary": $blob-color,
|
||||||
"blob": $blob-color,
|
"blob": $blob-color,
|
||||||
@@ -44,8 +67,17 @@
|
|||||||
"mediumblob": $blob-color,
|
"mediumblob": $blob-color,
|
||||||
"medium_blob": $blob-color,
|
"medium_blob": $blob-color,
|
||||||
"longblob": $blob-color,
|
"longblob": $blob-color,
|
||||||
|
"bytea": $blob-color,
|
||||||
"enum": $enum-color,
|
"enum": $enum-color,
|
||||||
"set": $enum-color,
|
"set": $enum-color,
|
||||||
|
"boolean": $enum-color,
|
||||||
|
"interval": $array-color,
|
||||||
|
"array": $array-color,
|
||||||
|
"anyarray": $array-color,
|
||||||
|
"tsvector": $array-color,
|
||||||
|
"tsquery": $array-color,
|
||||||
|
"pg_node_tree": $array-color,
|
||||||
|
"aclitem": $array-color,
|
||||||
"unknown": $unknown-color,
|
"unknown": $unknown-color,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
.td,
|
.td,
|
||||||
.th {
|
.th {
|
||||||
border-bottom: $border-width solid $border-color;
|
|
||||||
padding: $unit-3 $unit-2;
|
padding: $unit-3 $unit-2;
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
}
|
}
|
||||||
@@ -35,37 +34,4 @@
|
|||||||
.th {
|
.th {
|
||||||
border-bottom-width: $border-width-lg;
|
border-bottom-width: $border-width-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
&,
|
|
||||||
&.table-striped {
|
|
||||||
.tbody {
|
|
||||||
.tr {
|
|
||||||
&.selected {
|
|
||||||
background: #333 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
background: $bg-color-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.table-hover {
|
|
||||||
.tbody {
|
|
||||||
.tr {
|
|
||||||
&:hover {
|
|
||||||
background: $bg-color-dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.table-striped {
|
|
||||||
.tbody {
|
|
||||||
.tr:nth-of-type(odd) {
|
|
||||||
background: $bg-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.key-mul,
|
&.key-mul,
|
||||||
&.key-INDEX {
|
&.key-INDEX,
|
||||||
|
&.key-KEY {
|
||||||
color: palegreen;
|
color: palegreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
/* Colors */
|
/* Colors */
|
||||||
$body-bg: #1d1d1d;
|
$body-bg: #fdfdfd;
|
||||||
$body-font-color: #fff;
|
$body-bg-dark: #1d1d1d;
|
||||||
$bg-color: #1d1d1d;
|
$body-font-color-dark: #fff;
|
||||||
$bg-color-light: #3f3f3f;
|
$bg-color-dark: #1d1d1d;
|
||||||
|
$bg-color-light-dark: #3f3f3f;
|
||||||
$bg-color-gray: #272727;
|
$bg-color-gray: #272727;
|
||||||
|
$bg-color-light-gray: #f1f1f1;
|
||||||
|
$light-color: #fdfdfd;
|
||||||
$primary-color: #e36929;
|
$primary-color: #e36929;
|
||||||
$success-color: #32b643;
|
$success-color: #32b643;
|
||||||
$error-color: #de3b28;
|
$error-color: #de3b28;
|
||||||
@@ -14,7 +17,8 @@ $number-color: cornflowerblue;
|
|||||||
$date-color: coral;
|
$date-color: coral;
|
||||||
$bit-color: lightskyblue;
|
$bit-color: lightskyblue;
|
||||||
$blob-color: darkorchid;
|
$blob-color: darkorchid;
|
||||||
$enum-color: gold;
|
$array-color: yellowgreen;
|
||||||
|
$enum-color: goldenrod;
|
||||||
$unknown-color: gray;
|
$unknown-color: gray;
|
||||||
|
|
||||||
/* Sizes */
|
/* Sizes */
|
||||||
|
@@ -6,6 +6,8 @@
|
|||||||
@import "fake-tables";
|
@import "fake-tables";
|
||||||
@import "mdi-additions";
|
@import "mdi-additions";
|
||||||
@import "db-icons";
|
@import "db-icons";
|
||||||
|
@import "themes/dark-theme";
|
||||||
|
@import "themes/light-theme";
|
||||||
@import "~spectre.css/src/spectre";
|
@import "~spectre.css/src/spectre";
|
||||||
@import "~spectre.css/src/spectre-exp";
|
@import "~spectre.css/src/spectre-exp";
|
||||||
|
|
||||||
@@ -19,27 +21,6 @@ body {
|
|||||||
@include padding-variant(3, $unit-3);
|
@include padding-variant(3, $unit-3);
|
||||||
@include padding-variant(4, $unit-4);
|
@include padding-variant(4, $unit-4);
|
||||||
|
|
||||||
.btn {
|
|
||||||
&.btn-gray {
|
|
||||||
color: #fff;
|
|
||||||
background: $bg-color-gray;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $bg-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.btn-dark {
|
|
||||||
color: #fff;
|
|
||||||
background: $bg-color-light;
|
|
||||||
border-color: $bg-color-light;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $bg-color-gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-vcentered {
|
.p-vcentered {
|
||||||
display: flex !important;
|
display: flex !important;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -55,15 +36,6 @@ body {
|
|||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-checkered {
|
|
||||||
background-image:
|
|
||||||
linear-gradient(to right, rgba(192, 192, 192, 0.75), rgba(192, 192, 192, 0.75)),
|
|
||||||
linear-gradient(to right, black 50%, white 50%),
|
|
||||||
linear-gradient(to bottom, black 50%, white 50%);
|
|
||||||
background-blend-mode: normal, difference, normal;
|
|
||||||
background-size: 2em 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.workspace-tabs {
|
.workspace-tabs {
|
||||||
align-content: baseline;
|
align-content: baseline;
|
||||||
|
|
||||||
@@ -80,13 +52,14 @@ body {
|
|||||||
.btn {
|
.btn {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
color: $body-font-color;
|
|
||||||
margin-right: 0.4rem;
|
margin-right: 0.4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspace-query-info {
|
.workspace-query-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
> div + div {
|
> div + div {
|
||||||
padding-left: 0.6rem;
|
padding-left: 0.6rem;
|
||||||
@@ -106,18 +79,6 @@ body {
|
|||||||
height: 10px;
|
height: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: $bg-color-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: rgba($color: #fff, $alpha: 0.5);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: rgba($color: #fff, $alpha: 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Animations
|
// Animations
|
||||||
@keyframes rotation {
|
@keyframes rotation {
|
||||||
from {
|
from {
|
||||||
@@ -135,32 +96,21 @@ body {
|
|||||||
|
|
||||||
/* Override */
|
/* Override */
|
||||||
.modal {
|
.modal {
|
||||||
.modal-overlay,
|
|
||||||
&.active .modal-overlay {
|
|
||||||
background: rgba(255, 255, 255, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-container,
|
.modal-container,
|
||||||
.modal-sm .modal-container {
|
.modal-sm .modal-container {
|
||||||
box-shadow: 0 0 1px 0 #000;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: $bg-color;
|
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
padding: 0.4rem 0.8rem;
|
padding: 0.4rem 0.8rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
background: $bg-color-gray;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #fff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab {
|
.tab {
|
||||||
border-color: #272727;
|
|
||||||
|
|
||||||
.tab-item {
|
.tab-item {
|
||||||
.btn-clear {
|
.btn-clear {
|
||||||
margin-top: -0.1rem;
|
margin-top: -0.1rem;
|
||||||
@@ -192,34 +142,11 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-select,
|
|
||||||
.form-input,
|
|
||||||
.form-select:not([multiple]):not([size]),
|
|
||||||
.form-checkbox .form-icon,
|
|
||||||
.form-radio .form-icon {
|
|
||||||
border-color: $bg-color-light;
|
|
||||||
background-color: $bg-color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-input.is-error,
|
|
||||||
.form-select.is-error {
|
|
||||||
background-color: $bg-color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-input:not(:placeholder-shown):invalid:focus {
|
|
||||||
background: $bg-color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-select:not([multiple]):not([size]):focus {
|
|
||||||
border-color: $primary-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-input[type="file"] {
|
.form-input[type="file"] {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-group .input-group-addon {
|
.input-group .input-group-addon {
|
||||||
border-color: #3f3f3f;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +170,3 @@ body {
|
|||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty {
|
|
||||||
color: $body-font-color;
|
|
||||||
}
|
|
||||||
|
440
src/renderer/scss/themes/dark-theme.scss
Normal file
440
src/renderer/scss/themes/dark-theme.scss
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
.theme-dark {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
background: $body-bg-dark;
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba($color: #fff, $alpha: 0.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba($color: #fff, $alpha: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:disabled {
|
||||||
|
.file-uploader {
|
||||||
|
background-color: #151515;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override Spectre.css
|
||||||
|
.menu {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
|
||||||
|
.menu-item a {
|
||||||
|
&:hover {
|
||||||
|
color: $primary-color;
|
||||||
|
background: $bg-color-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
&.btn-link {
|
||||||
|
color: rgba($body-font-color-dark, 0.8);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-gray {
|
||||||
|
color: #fff;
|
||||||
|
background: $bg-color-gray;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-dark {
|
||||||
|
color: #fff;
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
border-color: $bg-color-light-dark;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
.modal-overlay,
|
||||||
|
&.active .modal-overlay {
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container,
|
||||||
|
.modal-sm .modal-container {
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
background: $bg-color-dark;
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
background: $bg-color-gray;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
border-color: #272727;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select,
|
||||||
|
.form-input,
|
||||||
|
.form-select:not([multiple]):not([size]),
|
||||||
|
.form-checkbox .form-icon,
|
||||||
|
.form-radio .form-icon {
|
||||||
|
border-color: $bg-color-light-dark;
|
||||||
|
background-color: $bg-color-gray;
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input.is-error,
|
||||||
|
.form-select.is-error {
|
||||||
|
background-color: $bg-color-gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:not(:placeholder-shown):invalid:focus {
|
||||||
|
background: $bg-color-gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select:not([multiple]):not([size]):focus {
|
||||||
|
border-color: $primary-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input[readonly] {
|
||||||
|
background-color: $bg-color-dark;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group .input-group-addon {
|
||||||
|
border-color: #3f3f3f;
|
||||||
|
background: $bg-color-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-switch .form-icon::before {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Antares
|
||||||
|
.workspace {
|
||||||
|
.workspace-explorebar {
|
||||||
|
background: $bg-color-gray;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
|
||||||
|
.workspace-explorebar-database {
|
||||||
|
.database-name {
|
||||||
|
background: $bg-color-gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-name,
|
||||||
|
.misc-name {
|
||||||
|
&:hover {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.table-name {
|
||||||
|
&:hover {
|
||||||
|
color: inherit;
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
&:hover {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
background: rgba($color: #fff, $alpha: 0.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-query-results {
|
||||||
|
.table {
|
||||||
|
.th {
|
||||||
|
background: $bg-color-dark;
|
||||||
|
border-color: $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.td {
|
||||||
|
border-color: $bg-color-light-dark;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
box-shadow: inset 0 0 0 1px $body-font-color-dark;
|
||||||
|
background: rgba($color: #000, $alpha: 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-tabs {
|
||||||
|
.tab-block {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
> a {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
& &.tools-dropdown {
|
||||||
|
.tab-link:focus {
|
||||||
|
color: $primary-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
.menu-item a {
|
||||||
|
&:hover {
|
||||||
|
color: $primary-color;
|
||||||
|
background: $bg-color-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-query-runner .workspace-query-runner-footer .workspace-query-buttons .btn {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-checkered {
|
||||||
|
background-image:
|
||||||
|
linear-gradient(to right, rgba(192, 192, 192, 0.75), rgba(192, 192, 192, 0.75)),
|
||||||
|
linear-gradient(to right, black 50%, white 50%),
|
||||||
|
linear-gradient(to bottom, black 50%, white 50%);
|
||||||
|
background-blend-mode: normal, difference, normal;
|
||||||
|
background-size: 2em 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
|
||||||
|
.context-container {
|
||||||
|
box-shadow: 0 0 2px 0 #000;
|
||||||
|
background: #1d1d1d;
|
||||||
|
|
||||||
|
.context-element {
|
||||||
|
.context-submenu {
|
||||||
|
background: #1d1d1d;
|
||||||
|
box-shadow: 0 0 2px 0 #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-wrapper {
|
||||||
|
border-bottom: 1px solid #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-uploader {
|
||||||
|
border: 0.05rem solid $bg-color-light-dark;
|
||||||
|
background-color: $bg-color-gray;
|
||||||
|
|
||||||
|
.file-uploader-message {
|
||||||
|
border-right: 0.05rem solid $bg-color-light-dark;
|
||||||
|
background-color: $bg-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tile {
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected-element {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-col {
|
||||||
|
border-left: 2px solid $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
.td,
|
||||||
|
.th {
|
||||||
|
border-bottom: $border-width solid $border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&,
|
||||||
|
&.table-striped {
|
||||||
|
.tbody {
|
||||||
|
.tr {
|
||||||
|
&.selected {
|
||||||
|
background: #333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: $bg-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-hover {
|
||||||
|
.tbody {
|
||||||
|
.tr {
|
||||||
|
&:hover {
|
||||||
|
background: #151515;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-striped {
|
||||||
|
.tbody {
|
||||||
|
.tr:nth-of-type(odd) {
|
||||||
|
background: $bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#titlebar {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
|
||||||
|
.titlebar-elements {
|
||||||
|
.titlebar-element {
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background: rgba($color: #fff, $alpha: 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.close-button:hover {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#settingbar {
|
||||||
|
width: $settingbar-width;
|
||||||
|
height: calc(100vh - #{$excluding-size});
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
z-index: 9;
|
||||||
|
|
||||||
|
.settingbar-top-elements {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: overlay;
|
||||||
|
max-height: calc((100vh - 3.5rem) - #{$excluding-size});
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingbar-bottom-elements {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingbar-elements {
|
||||||
|
list-style: none;
|
||||||
|
text-align: center;
|
||||||
|
width: $settingbar-width;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.settingbar-element {
|
||||||
|
height: $settingbar-width;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
border-left-color: $body-font-color-dark;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingbar-element-icon {
|
||||||
|
&.badge::after {
|
||||||
|
bottom: -10px;
|
||||||
|
right: 0;
|
||||||
|
position: absolute;
|
||||||
|
background: $success-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-update::after {
|
||||||
|
bottom: initial;
|
||||||
|
background: $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ex-tooltip {
|
||||||
|
.ex-tooltip-content {
|
||||||
|
background: rgba(48, 55, 66, 0.95);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .ex-tooltip-content {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
background: $primary-color;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
|
||||||
|
.footer-elements {
|
||||||
|
.footer-element {
|
||||||
|
&.footer-link {
|
||||||
|
&:hover {
|
||||||
|
background: rgba($color: #fff, $alpha: 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {
|
||||||
|
background-color: #c9561a99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_line-hover {
|
||||||
|
background-color: #c9571a33;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight {
|
||||||
|
color: #e0d00c;
|
||||||
|
}
|
299
src/renderer/scss/themes/light-theme.scss
Normal file
299
src/renderer/scss/themes/light-theme.scss
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
.theme-light {
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba($color: $bg-color-light-dark, $alpha: 0.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba($color: $bg-color-light-dark, $alpha: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:disabled,
|
||||||
|
.form-input.disabled,
|
||||||
|
.form-select:disabled,
|
||||||
|
.form-select.disabled {
|
||||||
|
background: #ababab;
|
||||||
|
}
|
||||||
|
|
||||||
|
#titlebar {
|
||||||
|
background: $bg-color-light;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
|
||||||
|
.titlebar-elements {
|
||||||
|
.titlebar-element {
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background: rgba($color: rgb(172, 172, 172), $alpha: 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.close-button:hover {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
&.btn-link {
|
||||||
|
color: rgba($body-font-color, 0.8);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $body-font-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-gray {
|
||||||
|
color: #fff;
|
||||||
|
background: $bg-color-gray;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.btn-dark {
|
||||||
|
color: #fff;
|
||||||
|
background: lighten($bg-color-light-dark, 20%);
|
||||||
|
border-color: lighten($bg-color-light-dark, 20%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
color: $body-font-color;
|
||||||
|
|
||||||
|
&:target .modal-overlay,
|
||||||
|
&.active .modal-overlay {
|
||||||
|
background: rgba($bg-color-dark, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container .modal-header {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tile {
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-light-gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected-element {
|
||||||
|
background: $bg-color-light-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-col {
|
||||||
|
border-left: 2px solid darken($bg-color-light-gray, 15%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-uploader {
|
||||||
|
border: 0.05rem solid $border-color-dark;
|
||||||
|
background-color: $bg-color-light;
|
||||||
|
|
||||||
|
.file-uploader-message {
|
||||||
|
border-right: 0.05rem solid $border-color-dark;
|
||||||
|
background-color: $bg-color-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#settingbar {
|
||||||
|
width: $settingbar-width;
|
||||||
|
height: calc(100vh - #{$excluding-size});
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
padding: 0;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
z-index: 9;
|
||||||
|
|
||||||
|
.settingbar-top-elements {
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: overlay;
|
||||||
|
max-height: calc((100vh - 3.5rem) - #{$excluding-size});
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingbar-bottom-elements {
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingbar-elements {
|
||||||
|
list-style: none;
|
||||||
|
text-align: center;
|
||||||
|
width: $settingbar-width;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.settingbar-element {
|
||||||
|
height: $settingbar-width;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-left: 3px solid transparent;
|
||||||
|
opacity: 0.5;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
border-left-color: $body-font-color-dark;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settingbar-element-icon {
|
||||||
|
&.badge::after {
|
||||||
|
bottom: -10px;
|
||||||
|
right: 0;
|
||||||
|
position: absolute;
|
||||||
|
background: $success-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.badge-update::after {
|
||||||
|
bottom: initial;
|
||||||
|
background: $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ex-tooltip {
|
||||||
|
.ex-tooltip-content {
|
||||||
|
background: rgba(48, 55, 66, 0.95);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .ex-tooltip-content {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace {
|
||||||
|
.workspace-explorebar {
|
||||||
|
background: $bg-color-light-gray;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
|
||||||
|
.workspace-explorebar-database {
|
||||||
|
.database-name {
|
||||||
|
background: $bg-color-light-gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-size {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-query-results {
|
||||||
|
.table {
|
||||||
|
.th {
|
||||||
|
background: $body-bg;
|
||||||
|
border-color: rgba($bg-color-light-dark, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.td {
|
||||||
|
border-color: rgba($bg-color-light-dark, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.context {
|
||||||
|
color: $body-font-color-dark;
|
||||||
|
|
||||||
|
.context-container {
|
||||||
|
box-shadow: 0 0 2px 0 #000;
|
||||||
|
background: #1d1d1d;
|
||||||
|
|
||||||
|
.context-element {
|
||||||
|
.context-submenu {
|
||||||
|
background: #1d1d1d;
|
||||||
|
box-shadow: 0 0 2px 0 #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
.td,
|
||||||
|
.th {
|
||||||
|
border-bottom: $border-width solid $border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&,
|
||||||
|
&.table-striped {
|
||||||
|
.tbody {
|
||||||
|
.tr {
|
||||||
|
&.selected {
|
||||||
|
background: rgba($bg-color-gray, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: $bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-hover {
|
||||||
|
.tbody {
|
||||||
|
.tr {
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-light-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-striped {
|
||||||
|
.tbody {
|
||||||
|
.tr:nth-of-type(odd) {
|
||||||
|
background: $bg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
background: $primary-color;
|
||||||
|
box-shadow: 0 0 1px 0 #000;
|
||||||
|
|
||||||
|
.footer-elements {
|
||||||
|
.footer-element {
|
||||||
|
&.footer-link {
|
||||||
|
&:hover {
|
||||||
|
background: rgba($color: #fff, $alpha: 0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -5,6 +5,7 @@ import Vuex from 'vuex';
|
|||||||
|
|
||||||
import application from './modules/application.store';
|
import application from './modules/application.store';
|
||||||
import settings from './modules/settings.store';
|
import settings from './modules/settings.store';
|
||||||
|
import scratchpad from './modules/scratchpad.store';
|
||||||
import connections from './modules/connections.store';
|
import connections from './modules/connections.store';
|
||||||
import workspaces from './modules/workspaces.store';
|
import workspaces from './modules/workspaces.store';
|
||||||
import notifications from './modules/notifications.store';
|
import notifications from './modules/notifications.store';
|
||||||
@@ -18,6 +19,7 @@ export default new Vuex.Store({
|
|||||||
modules: {
|
modules: {
|
||||||
application,
|
application,
|
||||||
settings,
|
settings,
|
||||||
|
scratchpad,
|
||||||
connections,
|
connections,
|
||||||
workspaces,
|
workspaces,
|
||||||
notifications
|
notifications
|
||||||
|
@@ -1,16 +1,21 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
import Store from 'electron-store';
|
||||||
|
const persistentStore = new Store({ name: 'settings' });
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
strict: true,
|
strict: true,
|
||||||
state: {
|
state: {
|
||||||
app_name: 'Antares - SQL Client',
|
app_name: 'Antares - SQL Client',
|
||||||
app_version: process.env.PACKAGE_VERSION || 0,
|
app_version: process.env.PACKAGE_VERSION || 0,
|
||||||
|
cached_version: persistentStore.get('cached_version', 0),
|
||||||
is_loading: false,
|
is_loading: false,
|
||||||
is_new_modal: false,
|
is_new_modal: false,
|
||||||
is_setting_modal: false,
|
is_setting_modal: false,
|
||||||
|
is_scratchpad: false,
|
||||||
selected_setting_tab: 'general',
|
selected_setting_tab: 'general',
|
||||||
selected_conection: {},
|
selected_conection: {},
|
||||||
update_status: 'noupdate', // noupdate, available, checking, nocheck, downloading, downloaded
|
update_status: 'noupdate', // noupdate, available, checking, nocheck, downloading, downloaded, disabled
|
||||||
download_progress: 0,
|
download_progress: 0,
|
||||||
base_completer: [] // Needed to reset ace editor, due global-only ace completer
|
base_completer: [] // Needed to reset ace editor, due global-only ace completer
|
||||||
},
|
},
|
||||||
@@ -18,10 +23,12 @@ export default {
|
|||||||
isLoading: state => state.is_loading,
|
isLoading: state => state.is_loading,
|
||||||
appName: state => state.app_name,
|
appName: state => state.app_name,
|
||||||
appVersion: state => state.app_version,
|
appVersion: state => state.app_version,
|
||||||
|
cachedVersion: state => state.cached_version,
|
||||||
getBaseCompleter: state => state.base_completer,
|
getBaseCompleter: state => state.base_completer,
|
||||||
getSelectedConnection: state => state.selected_conection,
|
getSelectedConnection: state => state.selected_conection,
|
||||||
isNewModal: state => state.is_new_modal,
|
isNewModal: state => state.is_new_modal,
|
||||||
isSettingModal: state => state.is_setting_modal,
|
isSettingModal: state => state.is_setting_modal,
|
||||||
|
isScratchpad: state => state.is_scratchpad,
|
||||||
selectedSettingTab: state => state.selected_setting_tab,
|
selectedSettingTab: state => state.selected_setting_tab,
|
||||||
getUpdateStatus: state => state.update_status,
|
getUpdateStatus: state => state.update_status,
|
||||||
getDownloadProgress: state => Number(state.download_progress.toFixed(1))
|
getDownloadProgress: state => Number(state.download_progress.toFixed(1))
|
||||||
@@ -46,6 +53,16 @@ export default {
|
|||||||
HIDE_SETTING_MODAL (state) {
|
HIDE_SETTING_MODAL (state) {
|
||||||
state.is_setting_modal = false;
|
state.is_setting_modal = false;
|
||||||
},
|
},
|
||||||
|
SHOW_SCRATCHPAD (state) {
|
||||||
|
state.is_scratchpad = true;
|
||||||
|
},
|
||||||
|
HIDE_SCRATCHPAD (state) {
|
||||||
|
state.is_scratchpad = false;
|
||||||
|
},
|
||||||
|
CHANGE_CACHED_VERSION (state) {
|
||||||
|
state.cached_version = state.app_version;
|
||||||
|
persistentStore.set('cached_version', state.cached_version);
|
||||||
|
},
|
||||||
CHANGE_UPDATE_STATUS (state, status) {
|
CHANGE_UPDATE_STATUS (state, status) {
|
||||||
state.update_status = status;
|
state.update_status = status;
|
||||||
},
|
},
|
||||||
@@ -54,6 +71,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
checkVersionUpdate ({ getters, commit, dispatch }) {
|
||||||
|
if (getters.appVersion !== getters.cachedVersion) {
|
||||||
|
dispatch('showSettingModal', 'changelog');
|
||||||
|
commit('CHANGE_CACHED_VERSION');
|
||||||
|
}
|
||||||
|
},
|
||||||
setLoadingStatus ({ commit }, payload) {
|
setLoadingStatus ({ commit }, payload) {
|
||||||
commit('SET_LOADING_STATUS', payload);
|
commit('SET_LOADING_STATUS', payload);
|
||||||
},
|
},
|
||||||
@@ -72,6 +95,12 @@ export default {
|
|||||||
},
|
},
|
||||||
hideSettingModal ({ commit }) {
|
hideSettingModal ({ commit }) {
|
||||||
commit('HIDE_SETTING_MODAL');
|
commit('HIDE_SETTING_MODAL');
|
||||||
|
},
|
||||||
|
showScratchpad ({ commit }) {
|
||||||
|
commit('SHOW_SCRATCHPAD');
|
||||||
|
},
|
||||||
|
hideScratchpad ({ commit }) {
|
||||||
|
commit('HIDE_SCRATCHPAD');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
25
src/renderer/store/modules/scratchpad.store.js
Normal file
25
src/renderer/store/modules/scratchpad.store.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
import Store from 'electron-store';
|
||||||
|
const persistentStore = new Store({ name: 'notes' });
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
strict: true,
|
||||||
|
state: {
|
||||||
|
notes: persistentStore.get('notes', '# HOW TO SUPPORT ANTARES\n\n- [ ] Leave a star to Antares [GitHub repo](https://github.com/Fabio286/antares)\n- [ ] Send feedbacks and advices\n- [ ] Report for bugs\n- [ ] If you enjoy, share Antares with friends\n\n# ABOUT SCRATCHPAD\n\nThis is a scratchpad where you can save your **personal notes**. It supports `markdown` format, but you are free to use plain text.\nThis content is just a placeholder, feel free to clear it to make space for your notes.\n')
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
getNotes: state => state.notes
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
SET_NOTES (state, notes) {
|
||||||
|
state.notes = notes;
|
||||||
|
persistentStore.set('notes', state.notes);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
changeNotes ({ commit }, notes) {
|
||||||
|
commit('SET_NOTES', notes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@@ -52,8 +52,13 @@ export default {
|
|||||||
state.explorebar_size = size;
|
state.explorebar_size = size;
|
||||||
persistentStore.set('explorebar_size', state.explorebar_size);
|
persistentStore.set('explorebar_size', state.explorebar_size);
|
||||||
},
|
},
|
||||||
|
SET_APPLICATION_THEME (state, theme) {
|
||||||
|
state.application_theme = theme;
|
||||||
|
persistentStore.set('application_theme', state.application_theme);
|
||||||
|
},
|
||||||
SET_EDITOR_THEME (state, theme) {
|
SET_EDITOR_THEME (state, theme) {
|
||||||
state.editor_theme = theme;
|
state.editor_theme = theme;
|
||||||
|
persistentStore.set('editor_theme', state.editor_theme);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -75,6 +80,9 @@ export default {
|
|||||||
changeLineWrap ({ commit }, val) {
|
changeLineWrap ({ commit }, val) {
|
||||||
commit('SET_LINE_WRAP', val);
|
commit('SET_LINE_WRAP', val);
|
||||||
},
|
},
|
||||||
|
changeApplicationTheme ({ commit }, theme) {
|
||||||
|
commit('SET_APPLICATION_THEME', theme);
|
||||||
|
},
|
||||||
changeEditorTheme ({ commit }, theme) {
|
changeEditorTheme ({ commit }, theme) {
|
||||||
commit('SET_EDITOR_THEME', theme);
|
commit('SET_EDITOR_THEME', theme);
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
import Connection from '@/ipc-api/Connection';
|
import Connection from '@/ipc-api/Connection';
|
||||||
import Database from '@/ipc-api/Database';
|
import Schema from '@/ipc-api/Schema';
|
||||||
import Users from '@/ipc-api/Users';
|
import Users from '@/ipc-api/Users';
|
||||||
import { uidGen } from 'common/libs/uidGen';
|
import { uidGen } from 'common/libs/uidGen';
|
||||||
const tabIndex = [];
|
const tabIndex = [];
|
||||||
@@ -55,7 +55,7 @@ export default {
|
|||||||
state.selected_workspace = uid;
|
state.selected_workspace = uid;
|
||||||
},
|
},
|
||||||
ADD_CONNECTED (state, payload) {
|
ADD_CONNECTED (state, payload) {
|
||||||
const { uid, client, dataTypes, indexTypes, structure, version } = payload;
|
const { uid, client, dataTypes, indexTypes, customizations, structure, version } = payload;
|
||||||
|
|
||||||
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid
|
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid
|
||||||
? {
|
? {
|
||||||
@@ -63,6 +63,7 @@ export default {
|
|||||||
client,
|
client,
|
||||||
dataTypes,
|
dataTypes,
|
||||||
indexTypes,
|
indexTypes,
|
||||||
|
customizations,
|
||||||
structure,
|
structure,
|
||||||
connected: true,
|
connected: true,
|
||||||
version
|
version
|
||||||
@@ -253,16 +254,23 @@ export default {
|
|||||||
else {
|
else {
|
||||||
let dataTypes = [];
|
let dataTypes = [];
|
||||||
let indexTypes = [];
|
let indexTypes = [];
|
||||||
|
let customizations = {};
|
||||||
|
|
||||||
switch (connection.client) {
|
switch (connection.client) {
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
case 'maria':
|
case 'maria':
|
||||||
dataTypes = require('common/data-types/mysql');
|
dataTypes = require('common/data-types/mysql');
|
||||||
indexTypes = require('common/index-types/mysql');
|
indexTypes = require('common/index-types/mysql');
|
||||||
|
customizations = require('common/customizations/mysql');
|
||||||
|
break;
|
||||||
|
case 'pg':
|
||||||
|
dataTypes = require('common/data-types/postgresql');
|
||||||
|
indexTypes = require('common/index-types/postgresql');
|
||||||
|
customizations = require('common/customizations/postgresql');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { status, response: version } = await Database.getVersion(connection.uid);
|
const { status, response: version } = await Schema.getVersion(connection.uid);
|
||||||
|
|
||||||
if (status === 'error')
|
if (status === 'error')
|
||||||
dispatch('notifications/addNotification', { status, message: version }, { root: true });
|
dispatch('notifications/addNotification', { status, message: version }, { root: true });
|
||||||
@@ -285,6 +293,7 @@ export default {
|
|||||||
client: connection.client,
|
client: connection.client,
|
||||||
dataTypes,
|
dataTypes,
|
||||||
indexTypes,
|
indexTypes,
|
||||||
|
customizations,
|
||||||
structure: response,
|
structure: response,
|
||||||
version
|
version
|
||||||
});
|
});
|
||||||
@@ -300,7 +309,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async refreshStructure ({ dispatch, commit, getters }, uid) {
|
async refreshStructure ({ dispatch, commit, getters }, uid) {
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.getStructure({ uid, schemas: getters.getLoadedSchemas(uid) });
|
const { status, response } = await Schema.getStructure({ uid, schemas: getters.getLoadedSchemas(uid) });
|
||||||
|
|
||||||
if (status === 'error')
|
if (status === 'error')
|
||||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||||
@@ -313,7 +322,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async refreshSchema ({ dispatch, commit }, { uid, schema }) {
|
async refreshSchema ({ dispatch, commit }, { uid, schema }) {
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.getStructure({ uid, schemas: new Set([schema]) });
|
const { status, response } = await Schema.getStructure({ uid, schemas: new Set([schema]) });
|
||||||
if (status === 'error')
|
if (status === 'error')
|
||||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||||
else
|
else
|
||||||
@@ -325,7 +334,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async refreshCollations ({ dispatch, commit }, uid) {
|
async refreshCollations ({ dispatch, commit }, uid) {
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.getCollations(uid);
|
const { status, response } = await Schema.getCollations(uid);
|
||||||
if (status === 'error')
|
if (status === 'error')
|
||||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||||
else
|
else
|
||||||
@@ -337,7 +346,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async refreshVariables ({ dispatch, commit }, uid) {
|
async refreshVariables ({ dispatch, commit }, uid) {
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.getVariables(uid);
|
const { status, response } = await Schema.getVariables(uid);
|
||||||
if (status === 'error')
|
if (status === 'error')
|
||||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||||
else
|
else
|
||||||
@@ -349,7 +358,7 @@ export default {
|
|||||||
},
|
},
|
||||||
async refreshEngines ({ dispatch, commit }, uid) {
|
async refreshEngines ({ dispatch, commit }, uid) {
|
||||||
try {
|
try {
|
||||||
const { status, response } = await Database.getEngines(uid);
|
const { status, response } = await Schema.getEngines(uid);
|
||||||
if (status === 'error')
|
if (status === 'error')
|
||||||
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
dispatch('notifications/addNotification', { status, message: response }, { root: true });
|
||||||
else
|
else
|
||||||
@@ -421,7 +430,7 @@ export default {
|
|||||||
if (lastBreadcrumbs.schema === payload.schema && hasLastChildren && !hasChildren) return;
|
if (lastBreadcrumbs.schema === payload.schema && hasLastChildren && !hasChildren) return;
|
||||||
|
|
||||||
if (lastBreadcrumbs.schema !== payload.schema)
|
if (lastBreadcrumbs.schema !== payload.schema)
|
||||||
Database.useSchema({ uid: getters.getSelected, schema: payload.schema });
|
Schema.useSchema({ uid: getters.getSelected, schema: payload.schema });
|
||||||
|
|
||||||
commit('CHANGE_BREADCRUMBS', { uid: getters.getSelected, breadcrumbs: { ...breadcrumbsObj, ...payload } });
|
commit('CHANGE_BREADCRUMBS', { uid: getters.getSelected, breadcrumbs: { ...breadcrumbsObj, ...payload } });
|
||||||
lastBreadcrumbs = { ...breadcrumbsObj, ...payload };
|
lastBreadcrumbs = { ...breadcrumbsObj, ...payload };
|
||||||
|
@@ -13,6 +13,9 @@ export default store => {
|
|||||||
ipcRenderer.on('check-failed', () => {
|
ipcRenderer.on('check-failed', () => {
|
||||||
store.commit('application/CHANGE_UPDATE_STATUS', 'nocheck');
|
store.commit('application/CHANGE_UPDATE_STATUS', 'nocheck');
|
||||||
});
|
});
|
||||||
|
ipcRenderer.on('no-auto-update', () => {
|
||||||
|
store.commit('application/CHANGE_UPDATE_STATUS', 'disabled');
|
||||||
|
});
|
||||||
ipcRenderer.on('download-progress', (event, data) => {
|
ipcRenderer.on('download-progress', (event, data) => {
|
||||||
store.commit('application/CHANGE_UPDATE_STATUS', 'downloading');
|
store.commit('application/CHANGE_UPDATE_STATUS', 'downloading');
|
||||||
store.commit('application/CHANGE_PROGRESS_PERCENTAGE', data.percent);
|
store.commit('application/CHANGE_PROGRESS_PERCENTAGE', data.percent);
|
||||||
|
Reference in New Issue
Block a user