mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
45 Commits
v0.0.1-alp
...
v0.0.3-alp
Author | SHA1 | Date | |
---|---|---|---|
4a83ae7e75 | |||
60132c94a1 | |||
fdf5bef5ad | |||
67f55fbeb9 | |||
|
fd5a8548c7 | ||
425ecf838d | |||
1a8a49eceb | |||
|
e9fffcc37e | ||
bba7c4af6f | |||
|
376d74c7dc | ||
307a32aff6 | |||
d1aaad276b | |||
|
b23b4f18b9 | ||
334cfa9047 | |||
|
2f6d16c730 | ||
b8e09e7003 | |||
9caf424331 | |||
|
9e5e545478 | ||
|
c9ab731bb4 | ||
57832c43aa | |||
|
184363369b | ||
b221dd12ff | |||
|
1324464aa3 | ||
187b4f50f9 | |||
262a476f50 | |||
|
f00c2600e5 | ||
75a7db9c05 | |||
50cd852d01 | |||
bb8cfa533b | |||
|
1ddc8b5dca | ||
8a4c628128 | |||
0076f146fa | |||
098d12f462 | |||
b619285d94 | |||
|
a5fed1bb64 | ||
55ec03bd8e | |||
|
d1977fbd75 | ||
3c20c0733c | |||
1d4a353d5c | |||
db71777cbc | |||
f350fe8203 | |||
28c3f87dd8 | |||
cc8dbb8df7 | |||
85ac1bc85f | |||
baea5c26e2 |
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: fabio286
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ['https://paypal.me/fabiodistasio']
|
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,6 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## [0.0.1-alpha]() - Coming Soon
|
||||
## [0.0.2-alpha](https://github.com/Fabio286/antares/releases/tag/v0.0.2-alpha) - 2020-06-26
|
||||
|
||||
### Added
|
||||
|
||||
- **Edit table fields:** You can edit fields from tables by double click. For now is available only on numeric and textual values.
|
||||
- Various improvements under the hood.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Connection test.
|
||||
|
||||
## [0.0.1-alpha](https://github.com/Fabio286/antares/releases/tag/v0.0.1-alpha) - 2020-06-19
|
||||
|
||||
### Features
|
||||
|
||||
|
28
README.md
28
README.md
@@ -1,7 +1,29 @@
|
||||
<p align="center">
|
||||
<img width="256" src="https://raw.githubusercontent.com/Fabio286/antares/master/docs/logo.png">
|
||||
<img width="800" src="https://raw.githubusercontent.com/Fabio286/antares/master/docs/screen-alpha.png">
|
||||
</p>
|
||||
|
||||
# Antares
|
||||
# Antares SQL Client
|
||||
|
||||
🚧 Work in progress! 🚧
|
||||
Antares is an SQL client based on Electron.js and Vue.js that aims to become a useful tool, especially for developers.
|
||||
My target is to support as many databases as possible, and all major operating systems, including the ARM versions.
|
||||
|
||||
At the moment this application is in a development state, it lacks many features, and is'nt ready as a main SQL client. However i'm actively working on it, hoping to provide all all minimum features as soon as possible.
|
||||
|
||||
If you are curious to try this early state of Antares you can download and install the [latest release](https://github.com/EStarium/antares/releases), and stay tuned for updates. At moment is only available for Windows.
|
||||
|
||||
## Currently supported
|
||||
|
||||
### Databases
|
||||
|
||||
- [x] MySQL/MariaDB
|
||||
- [ ] PostrgreSQL
|
||||
- [ ] MSSQL
|
||||
- [ ] SQLite
|
||||
- [ ] OracleDB
|
||||
- [ ] More...
|
||||
|
||||
### Operating Systems
|
||||
|
||||
- [x] Windows
|
||||
- [ ] Linux
|
||||
- [ ] MacOS
|
||||
|
BIN
docs/screen-alpha.png
Normal file
BIN
docs/screen-alpha.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 224 KiB |
246
package-lock.json
generated
246
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"version": "0.0.0-alpha",
|
||||
"version": "0.0.2-alpha",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -1146,6 +1146,12 @@
|
||||
"integrity": "sha512-q95SP4FdkmF0CwO0F2q0H6ZgudsApaY/yCtAQNRn1gduef5fGpyEphzy0YCq/N0UFvDSnLg5V8jFK/YGXlDiCw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
|
||||
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json5": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
@@ -1164,9 +1170,9 @@
|
||||
"integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg=="
|
||||
},
|
||||
"@types/readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-oAbOdOKhx5nu1+pBPiwEHh6gqA3ojgwwNwNIjNd67TqwEjvVePqe21mnYc6RrnGZ8aVPFBe6sci3cU2pKKwuug==",
|
||||
"version": "2.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.9.tgz",
|
||||
"integrity": "sha512-sqsgQqFT7HmQz/V5jH1O0fvQQnXAJO46Gg9LRO/JPfjmVmGUlcx831TZZO3Y3HtWhIkzf3kTsNT0Z0kzIhIvZw==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"safe-buffer": "*"
|
||||
@@ -3020,17 +3026,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"clone-deep": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
|
||||
"integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4",
|
||||
"kind-of": "^6.0.2",
|
||||
"shallow-clone": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"clone-response": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
|
||||
@@ -3047,9 +3042,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"codemirror": {
|
||||
"version": "5.54.0",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.54.0.tgz",
|
||||
"integrity": "sha512-Pgf3surv4zvw+KaW3doUU7pGjF0BPU8/sj7eglWJjzni46U/DDW8pu3nZY0QgQKUcICDXRkq8jZmq0y6KhxM3Q=="
|
||||
"version": "5.56.0",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.56.0.tgz",
|
||||
"integrity": "sha512-MfKVmYgifXjQpLSgpETuih7A7WTTIsxvKfSLGseTY5+qt0E1UD1wblZGM6WLenORo8sgmf+3X+WTe2WF7mufyw=="
|
||||
},
|
||||
"collection-visit": {
|
||||
"version": "1.0.0",
|
||||
@@ -4034,9 +4029,9 @@
|
||||
}
|
||||
},
|
||||
"electron": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-8.3.0.tgz",
|
||||
"integrity": "sha512-XRjiIJICZCgUr2vKSUI2PTkfP0gPFqCtqJUaTJSfCTuE3nTrxBKOUNeRMuCzEqspKkpFQU3SB3MdbMSHmZARlQ==",
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-8.4.0.tgz",
|
||||
"integrity": "sha512-SpgyccM5rjDJSGcpQjiviUBT44fZlSyhcjy8RpKSnAad+co4xY1vYj6T25U1CfSk0PH/dhvcp63P2sdXHCwq/Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^1.0.1",
|
||||
@@ -4116,14 +4111,14 @@
|
||||
}
|
||||
},
|
||||
"electron-devtools-installer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.0.0.tgz",
|
||||
"integrity": "sha512-zll3w/8PvnPiGmL5tBtgSSoSjWnUljsOjJYsYYU12PKLljzWyfD6S75LKTZFn21VYxVbae2OwmjM5uFStLp6nQ==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.1.1.tgz",
|
||||
"integrity": "sha512-g2D4J6APbpsiIcnLkFMyKZ6bOpEJ0Ltcc2m66F7oKUymyGAt628OWeU9nRZoh1cNmUs/a6Cls2UfOmsZtE496Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.2.1",
|
||||
"unzip-crx": "^0.2.0"
|
||||
"unzip-crx-3": "^0.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"rimraf": {
|
||||
@@ -4138,9 +4133,9 @@
|
||||
}
|
||||
},
|
||||
"electron-log": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.2.1.tgz",
|
||||
"integrity": "sha512-tUI9w3kUP3qhwXJ92RDUPFVZfwtBwKCy/1TsSHndXYLlNCB/7+vkiQG0uxv9D2Leuxc/DJKfYyrdEBpzi/vyZg=="
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.2.2.tgz",
|
||||
"integrity": "sha512-lBpLh1Q8qayrTxFIrTPcNjSHsosvUfOYyZ8glhiLcx7zCNPDGuj8+nXlEaaSS6LRiQQbLgLG+wKpuvztNzBIrA=="
|
||||
},
|
||||
"electron-publish": {
|
||||
"version": "22.7.0",
|
||||
@@ -4560,9 +4555,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
|
||||
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
@@ -4706,9 +4701,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"eslint-import-resolver-node": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz",
|
||||
"integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==",
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
|
||||
"integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^2.6.9",
|
||||
@@ -4845,9 +4840,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-plugin-import": {
|
||||
"version": "2.21.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.21.1.tgz",
|
||||
"integrity": "sha512-qYOOsgUv63vHof7BqbzuD+Ud34bXHxFJxntuAC1ZappFZXYbRIek3aJ7jc9i2dHDGDyZ/0zlO0cpioES265Lsw==",
|
||||
"version": "2.22.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz",
|
||||
"integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-includes": "^3.1.1",
|
||||
@@ -6442,19 +6437,19 @@
|
||||
}
|
||||
},
|
||||
"global-agent": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz",
|
||||
"integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==",
|
||||
"version": "2.1.12",
|
||||
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz",
|
||||
"integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"boolean": "^3.0.0",
|
||||
"core-js": "^3.6.4",
|
||||
"boolean": "^3.0.1",
|
||||
"core-js": "^3.6.5",
|
||||
"es6-error": "^4.1.1",
|
||||
"matcher": "^2.1.0",
|
||||
"roarr": "^2.15.2",
|
||||
"semver": "^7.1.2",
|
||||
"serialize-error": "^5.0.0"
|
||||
"matcher": "^3.0.0",
|
||||
"roarr": "^2.15.3",
|
||||
"semver": "^7.3.2",
|
||||
"serialize-error": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"global-dirs": {
|
||||
@@ -7767,9 +7762,9 @@
|
||||
}
|
||||
},
|
||||
"jszip": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.4.0.tgz",
|
||||
"integrity": "sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg==",
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz",
|
||||
"integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lie": "~3.3.0",
|
||||
@@ -7818,6 +7813,12 @@
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true
|
||||
},
|
||||
"klona": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/klona/-/klona-1.1.2.tgz",
|
||||
"integrity": "sha512-xf88rTeHiXk+XE2Vhi6yj8Wm3gMZrygGdKjJqN8HkV+PwF/t50/LdAKHoHpPcxFAlmQszTZ1CugrK25S7qDRLA==",
|
||||
"dev": true
|
||||
},
|
||||
"latest-version": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
|
||||
@@ -7939,9 +7940,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
"version": "4.17.19",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
@@ -8073,13 +8074,13 @@
|
||||
}
|
||||
},
|
||||
"matcher": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz",
|
||||
"integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
||||
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "^2.0.0"
|
||||
"escape-string-regexp": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"material-design-icons": {
|
||||
@@ -8476,9 +8477,9 @@
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
|
||||
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
|
||||
"version": "2.27.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz",
|
||||
"integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ=="
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
@@ -8500,9 +8501,9 @@
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"mssql": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mssql/-/mssql-6.2.0.tgz",
|
||||
"integrity": "sha512-C1WcvpiyGGoNyA+rNae/87V4O47S1P75zqmITutxzamocccY8BsZA+cljXJvpnYbbGlmMB5eoSaVUSqR9NyLCg==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/mssql/-/mssql-6.2.1.tgz",
|
||||
"integrity": "sha512-erINJ9EUPvPuWXifZfhum0CVEVrdvnFYlpgU6WKkQW69W4W7DWqJS2FHdedHnuJWlJ8x1WW1NcD8GFfF15O2aA==",
|
||||
"requires": {
|
||||
"debug": "^4",
|
||||
"tarn": "^1.1.5",
|
||||
@@ -9419,25 +9420,20 @@
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||
},
|
||||
"pg": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.2.1.tgz",
|
||||
"integrity": "sha512-DKzffhpkWRr9jx7vKxA+ur79KG+SKw+PdjMb1IRhMiKI9zqYUGczwFprqy+5Veh/DCcFs1Y6V8lRLN5I1DlleQ==",
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.3.0.tgz",
|
||||
"integrity": "sha512-jQPKWHWxbI09s/Z9aUvoTbvGgoj98AU7FDCcQ7kdejupn/TcNpx56v2gaOTzXkzOajmOEJEdi9eTh9cA2RVAjQ==",
|
||||
"requires": {
|
||||
"buffer-writer": "2.0.0",
|
||||
"packet-reader": "1.0.0",
|
||||
"pg-connection-string": "^2.2.3",
|
||||
"pg-connection-string": "^2.3.0",
|
||||
"pg-pool": "^3.2.1",
|
||||
"pg-protocol": "^1.2.4",
|
||||
"pg-protocol": "^1.2.5",
|
||||
"pg-types": "^2.1.0",
|
||||
"pgpass": "1.x",
|
||||
"semver": "4.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"pg-connection-string": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.2.3.tgz",
|
||||
"integrity": "sha512-I/KCSQGmOrZx6sMHXkOs2MjddrYcqpza3Dtsy0AjIgBr/bZiPJRK9WhABXN1Uy1UDazRbi9gZEzO2sAhL5EqiQ=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz",
|
||||
@@ -9445,6 +9441,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"pg-connection-string": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.3.0.tgz",
|
||||
"integrity": "sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w=="
|
||||
},
|
||||
"pg-int8": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||
@@ -9456,9 +9457,9 @@
|
||||
"integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA=="
|
||||
},
|
||||
"pg-protocol": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.4.tgz",
|
||||
"integrity": "sha512-/8L/G+vW/VhWjTGXpGh8XVkXOFx1ZDY+Yuz//Ab8CfjInzFkreI+fDG3WjCeSra7fIZwAFxzbGptNbm8xSXenw=="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.5.tgz",
|
||||
"integrity": "sha512-1uYCckkuTfzz/FCefvavRywkowa6M5FohNMF5OjKrqo9PSR8gYc8poVmwwYQaBxhmQdBjhtP514eXy9/Us2xKg=="
|
||||
},
|
||||
"pg-types": {
|
||||
"version": "2.2.0",
|
||||
@@ -10811,23 +10812,39 @@
|
||||
}
|
||||
},
|
||||
"sass-loader": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz",
|
||||
"integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==",
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-9.0.2.tgz",
|
||||
"integrity": "sha512-nphcum3jNI442njnrZ5wJgSNX5lfEOHOKHCLf+PrTIaleploKqAMUuT9CVKjf+lyi6c2MCGPHh1vb9nGsjnZJA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone-deep": "^4.0.1",
|
||||
"loader-utils": "^1.2.3",
|
||||
"klona": "^1.1.1",
|
||||
"loader-utils": "^2.0.0",
|
||||
"neo-async": "^2.6.1",
|
||||
"schema-utils": "^2.6.1",
|
||||
"semver": "^6.3.0"
|
||||
"schema-utils": "^2.7.0",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"dev": true
|
||||
"loader-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"schema-utils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
|
||||
"integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.4",
|
||||
"ajv": "^6.12.2",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -10991,13 +11008,22 @@
|
||||
}
|
||||
},
|
||||
"serialize-error": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz",
|
||||
"integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
|
||||
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.8.0"
|
||||
"type-fest": "^0.13.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
|
||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"serialize-javascript": {
|
||||
@@ -11131,15 +11157,6 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"shallow-clone": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
|
||||
"integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.2"
|
||||
}
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
@@ -11512,9 +11529,9 @@
|
||||
}
|
||||
},
|
||||
"spectre.css": {
|
||||
"version": "0.5.8",
|
||||
"resolved": "https://registry.npmjs.org/spectre.css/-/spectre.css-0.5.8.tgz",
|
||||
"integrity": "sha512-3N4WocWY+Dl6b3e5v3nsZYyp+VSDcBfGDzyyHw/H78ie9BoAhHkxmrhLxo9y8RadxYzVrPjfPdlev3hXEUzR2w=="
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/spectre.css/-/spectre.css-0.5.9.tgz",
|
||||
"integrity": "sha512-9jUqwZmCnvflrxFGcK+ize43TvjwDjqMwZPVubEtSIHzvinH0TBUESm1LcOJx3Ur7bdPaeOHQIjOqBl1Y5kLFw=="
|
||||
},
|
||||
"split": {
|
||||
"version": "1.0.1",
|
||||
@@ -12451,10 +12468,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"unzip-crx": {
|
||||
"unzip-crx-3": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/unzip-crx/-/unzip-crx-0.2.0.tgz",
|
||||
"integrity": "sha1-TAuqi9rHViVnVL7KeEPBPXuFjBg=",
|
||||
"resolved": "https://registry.npmjs.org/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz",
|
||||
"integrity": "sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jszip": "^3.1.0",
|
||||
@@ -12784,18 +12801,23 @@
|
||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||
"dev": true
|
||||
},
|
||||
"vue-the-mask": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz",
|
||||
"integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ=="
|
||||
},
|
||||
"vuedraggable": {
|
||||
"version": "2.23.2",
|
||||
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.23.2.tgz",
|
||||
"integrity": "sha512-PgHCjUpxEAEZJq36ys49HfQmXglattf/7ofOzUrW2/rRdG7tu6fK84ir14t1jYv4kdXewTEa2ieKEAhhEMdwkQ==",
|
||||
"version": "2.24.0",
|
||||
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.0.tgz",
|
||||
"integrity": "sha512-IlslPpc+iZ2zPNSJbydFZIDrE+don5u+Nc/bjT2YaF+Azidc+wxxJKfKT0NwE68AKk0syb0YbZneAcnynqREZQ==",
|
||||
"requires": {
|
||||
"sortablejs": "^1.10.1"
|
||||
}
|
||||
},
|
||||
"vuex": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.4.0.tgz",
|
||||
"integrity": "sha512-ajtqwEW/QhnrBZQsZxCLHThZZaa+Db45c92Asf46ZDXu6uHXgbfVuBaJ4gzD2r4UX0oMJHstFwd2r2HM4l8umg=="
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
|
||||
"integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw=="
|
||||
},
|
||||
"vuex-persist": {
|
||||
"version": "2.2.0",
|
||||
|
33
package.json
33
package.json
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.0.1-alpha",
|
||||
"version": "0.0.2-alpha",
|
||||
"description": "A cross-platform easy to use SQL client.",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/Fabio286/antares.git",
|
||||
"repository": "https://github.com/EStarium/antares.git",
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_ENV=development electron-webpack dev",
|
||||
"compile": "electron-webpack",
|
||||
"dist": "cross-env NODE_ENV=production npm run compile && electron-builder",
|
||||
"dist:dir": "cross-env NODE_ENV=production npm run dist --dir -c.compression=store -c.mac.identity=null",
|
||||
"publish": "build -p always"
|
||||
"publish": "electron-builder -p always"
|
||||
},
|
||||
"author": "Fabio Di Stasio <fabio286@gmail.com>",
|
||||
"build": {
|
||||
@@ -29,40 +29,41 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"codemirror": "^5.54.0",
|
||||
"electron-log": "^4.2.1",
|
||||
"codemirror": "^5.56.0",
|
||||
"electron-log": "^4.2.2",
|
||||
"electron-updater": "^4.3.1",
|
||||
"lodash": "^4.17.15",
|
||||
"lodash": "^4.17.19",
|
||||
"material-design-icons": "^3.0.1",
|
||||
"moment": "^2.26.0",
|
||||
"mssql": "^6.2.0",
|
||||
"moment": "^2.27.0",
|
||||
"mssql": "^6.2.1",
|
||||
"mysql": "^2.18.1",
|
||||
"pg": "^8.2.1",
|
||||
"pg": "^8.3.0",
|
||||
"source-map-support": "^0.5.16",
|
||||
"spectre.css": "^0.5.8",
|
||||
"spectre.css": "^0.5.9",
|
||||
"vue-click-outside": "^1.1.0",
|
||||
"vue-i18n": "^8.18.2",
|
||||
"vuedraggable": "^2.23.2",
|
||||
"vuex": "^3.4.0",
|
||||
"vue-the-mask": "^0.11.1",
|
||||
"vuedraggable": "^2.24.0",
|
||||
"vuex": "^3.5.1",
|
||||
"vuex-persist": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.1.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"electron": "^8.3.0",
|
||||
"electron": "^8.4.0",
|
||||
"electron-builder": "^22.7.0",
|
||||
"electron-devtools-installer": "^3.0.0",
|
||||
"electron-devtools-installer": "^3.1.1",
|
||||
"electron-webpack": "^2.8.2",
|
||||
"electron-webpack-vue": "^2.4.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.21.1",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"node-sass": "^4.14.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"sass-loader": "^9.0.2",
|
||||
"vue": "^2.6.11",
|
||||
"webpack": "^4.43.0"
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import connection from './connection';
|
||||
import structure from './structure';
|
||||
import tables from './tables';
|
||||
import updates from './updates';
|
||||
|
||||
const connections = {};
|
||||
|
||||
export default () => {
|
||||
connection(connections);
|
||||
structure(connections);
|
||||
tables(connections);
|
||||
updates();
|
||||
};
|
||||
|
@@ -1,27 +0,0 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import InformationSchema from '../models/InformationSchema';
|
||||
import Generic from '../models/Generic';
|
||||
|
||||
// TODO: remap objects based on client
|
||||
|
||||
export default (connections) => {
|
||||
ipcMain.handle('getTableColumns', async (event, { uid, schema, table }) => {
|
||||
try {
|
||||
const result = await InformationSchema.getTableColumns(connections[uid], schema, table);
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('getTableData', async (event, { uid, schema, table }) => {
|
||||
try {
|
||||
const result = await Generic.getTableData(connections[uid], schema, table);
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
};
|
47
src/main/ipc-handlers/tables.js
Normal file
47
src/main/ipc-handlers/tables.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import InformationSchema from '../models/InformationSchema';
|
||||
import Tables from '../models/Tables';
|
||||
|
||||
// TODO: remap objects based on client
|
||||
|
||||
export default (connections) => {
|
||||
ipcMain.handle('getTableColumns', async (event, { uid, schema, table }) => {
|
||||
try {
|
||||
const result = await InformationSchema.getTableColumns(connections[uid], schema, table);// TODO: uniform column properties
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('getTableData', async (event, { uid, schema, table }) => {
|
||||
try {
|
||||
const result = await Tables.getTableData(connections[uid], schema, table);
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('updateTableCell', async (event, params) => {
|
||||
try {
|
||||
const result = await Tables.updateTableCell(connections[params.uid], params);
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('deleteTableRows', async (event, params) => {
|
||||
try {
|
||||
const result = await Tables.deleteTableRows(connections[params.uid], params);
|
||||
return { status: 'success', response: result };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
};
|
@@ -32,7 +32,7 @@ export class AntaresConnector {
|
||||
join: [],
|
||||
update: [],
|
||||
insert: [],
|
||||
delete: []
|
||||
delete: false
|
||||
};
|
||||
this._query = Object.assign({}, this._queryDefaults);
|
||||
}
|
||||
@@ -73,14 +73,10 @@ export class AntaresConnector {
|
||||
switch (this._client) {
|
||||
case 'maria':
|
||||
case 'mysql':
|
||||
if (!this._poolSize) {
|
||||
const connection = mysql.createConnection(this._params);
|
||||
this._connection = connection.promise();
|
||||
}
|
||||
if (!this._poolSize)
|
||||
this._connection = mysql.createConnection(this._params);
|
||||
else
|
||||
this._connection = mysql.createPool({ ...this._params, connectionLimit: this._poolSize });
|
||||
// this._connection = pool.promise();
|
||||
|
||||
break;
|
||||
case 'mssql': {
|
||||
const mssqlParams = {
|
||||
@@ -111,6 +107,12 @@ export class AntaresConnector {
|
||||
return this;
|
||||
}
|
||||
|
||||
delete (table) {
|
||||
this._query.delete = true;
|
||||
this.from(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
where (...args) {
|
||||
this._query.where = [...this._query.where, ...args];
|
||||
return this;
|
||||
@@ -149,6 +151,16 @@ export class AntaresConnector {
|
||||
return this.raw(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String | Array} args field = value
|
||||
* @returns
|
||||
* @memberof AntaresConnector
|
||||
*/
|
||||
update (...args) {
|
||||
this._query.update = [...this._query.update, ...args];
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} SQL string
|
||||
* @memberof AntaresConnector
|
||||
@@ -156,30 +168,35 @@ export class AntaresConnector {
|
||||
getSQL () {
|
||||
// SELECT
|
||||
const selectArray = this._query.select.reduce(this._reducer, []);
|
||||
let selectRaw;
|
||||
switch (this._client) {
|
||||
case 'maria':
|
||||
case 'mysql':
|
||||
selectRaw = selectArray.length ? `SELECT ${selectArray.join(', ')} ` : 'SELECT * ';
|
||||
break;
|
||||
case 'mssql': {
|
||||
const topRaw = this._query.limit.length ? ` TOP (${this._query.limit[0]}) ` : '';
|
||||
selectRaw = selectArray.length ? `SELECT${topRaw} ${selectArray.join(', ')} ` : 'SELECT * ';
|
||||
let selectRaw = '';
|
||||
if (selectArray.length) {
|
||||
switch (this._client) {
|
||||
case 'maria':
|
||||
case 'mysql':
|
||||
selectRaw = selectArray.length ? `SELECT ${selectArray.join(', ')} ` : 'SELECT * ';
|
||||
break;
|
||||
case 'mssql': {
|
||||
const topRaw = this._query.limit.length ? ` TOP (${this._query.limit[0]}) ` : '';
|
||||
selectRaw = selectArray.length ? `SELECT${topRaw} ${selectArray.join(', ')} ` : 'SELECT * ';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// FROM
|
||||
let fromRaw;
|
||||
let fromRaw = '';
|
||||
if (!this._query.update.length && !!this._query.from)
|
||||
fromRaw = 'FROM';
|
||||
|
||||
switch (this._client) {
|
||||
case 'maria':
|
||||
case 'mysql':
|
||||
fromRaw = this._query.from ? `FROM ${this._query.schema ? `\`${this._query.schema}\`.` : ''}\`${this._query.from}\` ` : '';
|
||||
fromRaw += this._query.from ? ` ${this._query.schema ? `\`${this._query.schema}\`.` : ''}\`${this._query.from}\` ` : '';
|
||||
break;
|
||||
case 'mssql':
|
||||
fromRaw = this._query.from ? `FROM ${this._query.schema ? `${this._query.schema}.` : ''}${this._query.from} ` : '';
|
||||
fromRaw += this._query.from ? ` ${this._query.schema ? `${this._query.schema}.` : ''}${this._query.from} ` : '';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -187,8 +204,13 @@ export class AntaresConnector {
|
||||
|
||||
const whereArray = this._query.where.reduce(this._reducer, []);
|
||||
const whereRaw = whereArray.length ? `WHERE ${whereArray.join(' AND ')} ` : '';
|
||||
|
||||
const updateArray = this._query.update.reduce(this._reducer, []);
|
||||
const updateRaw = updateArray.length ? `SET ${updateArray.join(', ')} ` : '';
|
||||
|
||||
const groupByArray = this._query.groupBy.reduce(this._reducer, []);
|
||||
const groupByRaw = groupByArray.length ? `GROUP BY ${groupByArray.join(', ')} ` : '';
|
||||
|
||||
const orderByArray = this._query.orderBy.reduce(this._reducer, []);
|
||||
const orderByRaw = orderByArray.length ? `ORDER BY ${orderByArray.join(', ')} ` : '';
|
||||
|
||||
@@ -206,7 +228,7 @@ export class AntaresConnector {
|
||||
break;
|
||||
}
|
||||
|
||||
return `${selectRaw}${fromRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}`;
|
||||
return `${selectRaw}${updateRaw ? 'UPDATE' : ''}${this._query.delete ? 'DELETE ' : ''}${fromRaw}${updateRaw}${whereRaw}${groupByRaw}${orderByRaw}${limitRaw}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,7 +249,7 @@ export class AntaresConnector {
|
||||
async raw (sql) {
|
||||
if (process.env.NODE_ENV === 'development') console.log(sql);
|
||||
|
||||
switch (this._client) {
|
||||
switch (this._client) { // TODO: uniform fields with every client type, needed table name and fields array
|
||||
case 'maria':
|
||||
case 'mysql': {
|
||||
const { rows, fields } = await new Promise((resolve, reject) => {
|
||||
|
@@ -11,13 +11,4 @@ export default class {
|
||||
}
|
||||
return connection.raw(query);
|
||||
}
|
||||
|
||||
static async getTableData (connection, schema, table) {
|
||||
return connection
|
||||
.select('*')
|
||||
.schema(schema)
|
||||
.from(table)
|
||||
.limit(1000)
|
||||
.run();
|
||||
}
|
||||
}
|
||||
|
28
src/main/models/Tables.js
Normal file
28
src/main/models/Tables.js
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
export default class {
|
||||
static async getTableData (connection, schema, table) {
|
||||
return connection
|
||||
.select('*')
|
||||
.schema(schema)
|
||||
.from(table)
|
||||
.limit(1000)
|
||||
.run();
|
||||
}
|
||||
|
||||
static async updateTableCell (connection, params) { // TODO: Handle different field types
|
||||
return connection
|
||||
.update({ [params.field]: `= "${params.content}"` })
|
||||
.schema(params.schema)
|
||||
.from(params.table)
|
||||
.where({ [params.primary]: `= ${params.id}` })
|
||||
.run();
|
||||
}
|
||||
|
||||
static async deleteTableRows (connection, params) {
|
||||
return connection
|
||||
.schema(params.schema)
|
||||
.delete(params.table)
|
||||
.where({ [params.primary]: `IN (${params.rows.join(',')})` })
|
||||
.run();
|
||||
}
|
||||
}
|
@@ -41,6 +41,8 @@ export default {
|
||||
.context{
|
||||
display: flex;
|
||||
position: absolute;
|
||||
color: $body-font-color;
|
||||
font-size: 16px;
|
||||
z-index: 400;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@@ -74,7 +74,9 @@
|
||||
</div>
|
||||
|
||||
<div v-if="selectedTab === 'themes'" class="panel-body py-4">
|
||||
<!-- -->
|
||||
<div class="text-center">
|
||||
<p>In future releases</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="selectedTab === 'update'" class="panel-body py-4">
|
||||
@@ -87,7 +89,7 @@
|
||||
<h4>{{ appName }}</h4>
|
||||
<p>
|
||||
{{ $t('word.version') }}: {{ appVersion }}<br>
|
||||
<a class="c-hand" @click="openOutside('https://github.com/Fabio286/antares')">GitHub</a><br>
|
||||
<a class="c-hand" @click="openOutside('https://github.com/EStarium/antares')">GitHub</a><br>
|
||||
<small>{{ $t('message.madeWithJS') }}</small>
|
||||
</p>
|
||||
</div>
|
||||
|
@@ -11,11 +11,11 @@
|
||||
|
||||
<div class="footer-right-elements">
|
||||
<ul class="footer-elements">
|
||||
<li class="footer-element footer-link">
|
||||
<li class="footer-element footer-link" @click="openOutside('https://www.patreon.com/fabio286')">
|
||||
<i class="material-icons md-18 mr-1">favorite</i>
|
||||
<small>{{ $t('word.donate') }}</small>
|
||||
</li>
|
||||
<li class="footer-element footer-link">
|
||||
<li class="footer-element footer-link" @click="openOutside('https://github.com/EStarium/antares/issues')">
|
||||
<i class="material-icons md-18">bug_report</i>
|
||||
</li>
|
||||
<li class="footer-element footer-link" @click="showSettingModal('about')">
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex';
|
||||
const { shell } = require('electron');
|
||||
|
||||
export default {
|
||||
name: 'TheFooter',
|
||||
@@ -40,7 +41,10 @@ export default {
|
||||
methods: {
|
||||
...mapActions({
|
||||
showSettingModal: 'application/showSettingModal'
|
||||
})
|
||||
}),
|
||||
openOutside (link) {
|
||||
shell.openExternal(link);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@@ -82,7 +82,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
addNotification: 'notifications/addNotification',
|
||||
addWorkspace: 'workspaces/addWorkspace',
|
||||
connectWorkspace: 'workspaces/connectWorkspace',
|
||||
removeConnected: 'workspaces/removeConnected',
|
||||
@@ -153,9 +152,14 @@ export default {
|
||||
border-left: none;
|
||||
border-bottom-width: 2px;
|
||||
border-color: $bg-color-light;
|
||||
padding: .1rem .4rem;
|
||||
padding: 0;
|
||||
font-weight: 700;
|
||||
font-size: .7rem;
|
||||
|
||||
> div {
|
||||
padding: .1rem .4rem;
|
||||
min-width: -webkit-fill-available;
|
||||
}
|
||||
}
|
||||
|
||||
.td{
|
||||
|
@@ -45,7 +45,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
addNotification: 'notifications/addNotification',
|
||||
connectWorkspace: 'workspaces/connectWorkspace'
|
||||
}),
|
||||
async startConnection () {
|
||||
|
@@ -31,8 +31,11 @@
|
||||
<div class="workspace-query-results column col-12">
|
||||
<WorkspaceQueryTable
|
||||
v-if="results"
|
||||
ref="queryTable"
|
||||
:results="results"
|
||||
:fields="resultsFields"
|
||||
@updateField="updateField"
|
||||
@deleteSelected="deleteSelected"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,9 +43,11 @@
|
||||
|
||||
<script>
|
||||
import Connection from '@/ipc-api/Connection';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import QueryEditor from '@/components/QueryEditor';
|
||||
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import tableTabs from '@/mixins/tableTabs';
|
||||
|
||||
export default {
|
||||
name: 'WorkspaceQueryTab',
|
||||
@@ -50,6 +55,7 @@ export default {
|
||||
QueryEditor,
|
||||
WorkspaceQueryTable
|
||||
},
|
||||
mixins: [tableTabs],
|
||||
props: {
|
||||
connection: Object
|
||||
},
|
||||
@@ -57,7 +63,8 @@ export default {
|
||||
return {
|
||||
query: '',
|
||||
isQuering: false,
|
||||
results: {}
|
||||
results: {},
|
||||
fields: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -68,9 +75,28 @@ export default {
|
||||
return this.getWorkspace(this.connection.uid);
|
||||
},
|
||||
resultsFields () {
|
||||
return this.results.rows && this.results.rows.length ? Object.keys(this.results.rows[0]).map(field => {
|
||||
return { name: field, key: '', type: '' }; // TODO: extract getting table name from query
|
||||
}) : [];
|
||||
if (this.results) {
|
||||
return this.fields.map(field => { // TODO: move to main process
|
||||
return {
|
||||
name: field.COLUMN_NAME,
|
||||
key: field.COLUMN_KEY.toLowerCase(),
|
||||
type: field.DATA_TYPE,
|
||||
precision: field.DATETIME_PRECISION
|
||||
};
|
||||
}).filter(field => {
|
||||
if (this.results.fields) {
|
||||
const queryFields = this.results.fields.map(field => field.name);
|
||||
if (queryFields.includes(field.name)) return field;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
return [];
|
||||
},
|
||||
table () {
|
||||
if (this.results.fields.length)
|
||||
return this.results.fields[0].orgTable;
|
||||
return '';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -99,6 +125,23 @@ export default {
|
||||
this.addNotification({ status: 'error', message: err.stack });
|
||||
}
|
||||
|
||||
try {
|
||||
const params = {
|
||||
uid: this.connection.uid,
|
||||
schema: this.workspace.breadcrumbs.schema,
|
||||
table: this.table
|
||||
};
|
||||
|
||||
const { status, response } = await Tables.getTableColumns(params);
|
||||
if (status === 'success')
|
||||
this.fields = response.rows;
|
||||
else
|
||||
this.addNotification({ status: 'error', message: response });
|
||||
}
|
||||
catch (err) {
|
||||
this.addNotification({ status: 'error', message: err.stack });
|
||||
}
|
||||
|
||||
this.isQuering = false;
|
||||
}
|
||||
}
|
||||
|
@@ -1,99 +1,83 @@
|
||||
<template>
|
||||
<BaseVirtualScroll
|
||||
v-if="results.rows"
|
||||
ref="resultTable"
|
||||
:items="localResults"
|
||||
:item-height="25"
|
||||
class="vscroll"
|
||||
:style="{'height': resultsSize+'px'}"
|
||||
>
|
||||
<template slot-scope="{ items }">
|
||||
<div class="table table-hover">
|
||||
<div class="thead">
|
||||
<div class="tr">
|
||||
<div
|
||||
v-for="field in fields"
|
||||
:key="field.name"
|
||||
class="th"
|
||||
>
|
||||
<div class="table-column-title">
|
||||
<i
|
||||
v-if="field.key"
|
||||
class="material-icons column-key c-help"
|
||||
:class="`key-${field.key}`"
|
||||
:title="keyName(field.key)"
|
||||
>vpn_key</i>
|
||||
<span>{{ field.name }}</span>
|
||||
<div>
|
||||
<TableContext
|
||||
v-if="isContext"
|
||||
:context-event="contextEvent"
|
||||
:selected-rows="selectedRows"
|
||||
@deleteSelected="deleteSelected"
|
||||
@closeContext="isContext = false"
|
||||
/>
|
||||
<BaseVirtualScroll
|
||||
v-if="results.rows"
|
||||
ref="resultTable"
|
||||
:items="sortedResults"
|
||||
:item-height="25"
|
||||
class="vscroll"
|
||||
:style="{'height': resultsSize+'px'}"
|
||||
>
|
||||
<template slot-scope="{ items }">
|
||||
<div class="table table-hover">
|
||||
<div class="thead">
|
||||
<div class="tr">
|
||||
<div
|
||||
v-for="field in fields"
|
||||
:key="field.name"
|
||||
class="th c-hand"
|
||||
>
|
||||
<div ref="columnResize" class="column-resizable">
|
||||
<div class="table-column-title" @click="sort(field.name)">
|
||||
<i
|
||||
v-if="field.key"
|
||||
class="material-icons column-key c-help"
|
||||
:class="`key-${field.key}`"
|
||||
:title="keyName(field.key)"
|
||||
>vpn_key</i>
|
||||
<span>{{ field.name }}</span>
|
||||
<i v-if="currentSort === field.name" class="material-icons sort-icon">{{ currentSortDir === 'asc' ? 'arrow_upward':'arrow_downward' }}</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tbody">
|
||||
<div
|
||||
v-for="row in items"
|
||||
:key="row._id"
|
||||
class="tr"
|
||||
>
|
||||
<div class="tbody">
|
||||
<div
|
||||
v-for="(col, cKey) in row"
|
||||
:key="cKey"
|
||||
class="td"
|
||||
:class="`type-${fieldType(cKey)}${isNull(col)}`"
|
||||
:style="{'display': cKey === '_id' ? 'none' : ''}"
|
||||
tabindex="0"
|
||||
v-for="row in items"
|
||||
:key="row._id"
|
||||
class="tr"
|
||||
:class="{'selected': selectedRows.includes(row._id)}"
|
||||
@click="selectRow($event, row._id)"
|
||||
>
|
||||
{{ col | typeFormat(fieldType(cKey)) }}
|
||||
<WorkspaceQueryTableCell
|
||||
v-for="(col, cKey) in row"
|
||||
:key="cKey"
|
||||
:content="col"
|
||||
:field="cKey"
|
||||
:precision="fieldPrecision(cKey)"
|
||||
:type="fieldType(cKey)"
|
||||
@updateField="updateField($event, row[primaryField.name])"
|
||||
@contextmenu="contextMenu($event, {id: row._id, field: cKey})"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</BaseVirtualScroll>
|
||||
</template>
|
||||
</BaseVirtualScroll>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { uidGen, mimeFromHex, formatBytes } from 'common/libs/utilities';
|
||||
import hexToBinary from 'common/libs/hexToBinary';
|
||||
import moment from 'moment';
|
||||
import { uidGen } from 'common/libs/utilities';
|
||||
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
|
||||
import WorkspaceQueryTableCell from '@/components/WorkspaceQueryTableCell';
|
||||
import TableContext from '@/components/WorkspaceQueryTableContext';
|
||||
import { mapActions } from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'WorkspaceQueryTable',
|
||||
components: {
|
||||
BaseVirtualScroll
|
||||
},
|
||||
filters: {
|
||||
typeFormat (val, type) {
|
||||
if (!val) return val;
|
||||
|
||||
switch (type) {
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
case 'text':
|
||||
case 'mediumtext':
|
||||
return val.substring(0, 128);
|
||||
case 'date':
|
||||
return moment(val).format('YYYY-MM-DD');
|
||||
case 'datetime':
|
||||
case 'timestamp':
|
||||
return moment(val).format('YYYY-MM-DD HH:mm:ss.SSS');
|
||||
case 'blob':
|
||||
case 'mediumblob':
|
||||
case 'longblob': {
|
||||
const buff = Buffer.from(val);
|
||||
if (!buff.length) return '';
|
||||
|
||||
const hex = buff.toString('hex').substring(0, 8).toUpperCase();
|
||||
return `${mimeFromHex(hex).mime} (${formatBytes(buff.length)})`;
|
||||
}
|
||||
case 'bit': {
|
||||
const hex = Buffer.from(val).toString('hex');
|
||||
return hexToBinary(hex);
|
||||
}
|
||||
default:
|
||||
return val;
|
||||
}
|
||||
}
|
||||
BaseVirtualScroll,
|
||||
WorkspaceQueryTableCell,
|
||||
TableContext
|
||||
},
|
||||
props: {
|
||||
results: Object,
|
||||
@@ -102,11 +86,38 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
resultsSize: 1000,
|
||||
localResults: []
|
||||
localResults: [],
|
||||
isContext: false,
|
||||
contextEvent: null,
|
||||
selectedCell: null,
|
||||
selectedRows: [],
|
||||
currentSort: '',
|
||||
currentSortDir: 'asc'
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
primaryField () {
|
||||
return this.fields.filter(field => field.key === 'pri')[0] || false;
|
||||
},
|
||||
sortedResults () {
|
||||
if (this.currentSort) {
|
||||
return [...this.localResults].sort((a, b) => {
|
||||
let modifier = 1;
|
||||
const valA = typeof a[this.currentSort] === 'string' ? a[this.currentSort].toLowerCase() : a[this.currentSort];
|
||||
const valB = typeof b[this.currentSort] === 'string' ? b[this.currentSort].toLowerCase() : b[this.currentSort];
|
||||
if (this.currentSortDir === 'desc') modifier = -1;
|
||||
if (valA < valB) return -1 * modifier;
|
||||
if (valA > valB) return 1 * modifier;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
else
|
||||
return this.localResults;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
results () {
|
||||
this.resetSort();
|
||||
this.localResults = this.results.rows ? this.results.rows.map(item => {
|
||||
return { ...item, _id: uidGen() };
|
||||
}) : [];
|
||||
@@ -114,7 +125,7 @@ export default {
|
||||
},
|
||||
updated () {
|
||||
if (this.$refs.resultTable)
|
||||
this.resizeResults();
|
||||
this.refreshScroller();
|
||||
},
|
||||
mounted () {
|
||||
window.addEventListener('resize', this.resizeResults);
|
||||
@@ -123,6 +134,9 @@ export default {
|
||||
window.removeEventListener('resize', this.resizeResults);
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
addNotification: 'notifications/addNotification'
|
||||
}),
|
||||
fieldType (cKey) {
|
||||
let type = 'unknown';
|
||||
const field = this.fields.filter(field => field.name === cKey)[0];
|
||||
@@ -131,8 +145,13 @@ export default {
|
||||
|
||||
return type;
|
||||
},
|
||||
isNull (col) {
|
||||
return col === null ? ' is-null' : '';
|
||||
fieldPrecision (cKey) {
|
||||
let length = 0;
|
||||
const field = this.fields.filter(field => field.name === cKey)[0];
|
||||
if (field)
|
||||
length = field.precision;
|
||||
|
||||
return length;
|
||||
},
|
||||
keyName (key) {
|
||||
switch (key) {
|
||||
@@ -146,7 +165,7 @@ export default {
|
||||
return 'UNKNOWN ' + key;
|
||||
}
|
||||
},
|
||||
resizeResults (e) {
|
||||
resizeResults () {
|
||||
if (this.$refs.resultTable) {
|
||||
const el = this.$refs.resultTable.$el;
|
||||
const footer = document.getElementById('footer');
|
||||
@@ -155,7 +174,94 @@ export default {
|
||||
const size = window.innerHeight - el.getBoundingClientRect().top - footer.offsetHeight;
|
||||
this.resultsSize = size;
|
||||
}
|
||||
this.$refs.resultTable.updateWindow();
|
||||
}
|
||||
},
|
||||
refreshScroller () {
|
||||
this.resizeResults();
|
||||
},
|
||||
updateField (payload, id) {
|
||||
if (!this.primaryField)
|
||||
this.addNotification({ status: 'warning', message: this.$t('message.unableEditFieldWithoutPrimary') });
|
||||
else {
|
||||
const params = {
|
||||
primary: this.primaryField.name,
|
||||
id,
|
||||
...payload
|
||||
};
|
||||
this.$emit('updateField', params);
|
||||
}
|
||||
},
|
||||
deleteSelected () {
|
||||
if (!this.primaryField)
|
||||
this.addNotification({ status: 'warning', message: this.$t('message.unableEditFieldWithoutPrimary') });
|
||||
else {
|
||||
const rowIDs = this.localResults.filter(row => this.selectedRows.includes(row._id)).map(row => row[this.primaryField.name]);
|
||||
const params = {
|
||||
primary: this.primaryField.name,
|
||||
rows: rowIDs
|
||||
};
|
||||
this.$emit('deleteSelected', params);
|
||||
}
|
||||
},
|
||||
applyUpdate (params) {
|
||||
const { primary, id, field, content } = params;
|
||||
this.localResults = this.localResults.map(row => {
|
||||
if (row[primary] === id)
|
||||
row[field] = content;
|
||||
|
||||
return row;
|
||||
});
|
||||
},
|
||||
selectRow (event, row) {
|
||||
if (event.ctrlKey) {
|
||||
if (this.selectedRows.includes(row))
|
||||
this.selectedRows = this.selectedRows.filter(el => el !== row);
|
||||
else
|
||||
this.selectedRows.push(row);
|
||||
}
|
||||
else if (event.shiftKey) {
|
||||
if (!this.selectedRows.length)
|
||||
this.selectedRows.push(row);
|
||||
else {
|
||||
const lastID = this.selectedRows.slice(-1)[0];
|
||||
const lastIndex = this.localResults.findIndex(el => el._id === lastID);
|
||||
const clickedIndex = this.localResults.findIndex(el => el._id === row);
|
||||
if (lastIndex > clickedIndex) {
|
||||
for (let i = clickedIndex; i < lastIndex; i++)
|
||||
this.selectedRows.push(this.localResults[i]._id);
|
||||
}
|
||||
else if (lastIndex < clickedIndex) {
|
||||
for (let i = clickedIndex; i > lastIndex; i--)
|
||||
this.selectedRows.push(this.localResults[i]._id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this.selectedRows = [row];
|
||||
},
|
||||
contextMenu (event, cell) {
|
||||
this.selectedCell = cell;
|
||||
if (!this.selectedRows.includes(cell.id))
|
||||
this.selectedRows = [cell.id];
|
||||
this.contextEvent = event;
|
||||
this.isContext = true;
|
||||
},
|
||||
sort (field) {
|
||||
if (field === this.currentSort) {
|
||||
if (this.currentSortDir === 'asc')
|
||||
this.currentSortDir = 'desc';
|
||||
else
|
||||
this.resetSort();
|
||||
}
|
||||
else {
|
||||
this.currentSortDir = 'asc';
|
||||
this.currentSort = field;
|
||||
}
|
||||
},
|
||||
resetSort () {
|
||||
this.currentSort = '';
|
||||
this.currentSortDir = 'asc';
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -168,11 +274,25 @@ export default {
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
.column-resizable{
|
||||
&:hover,
|
||||
&:active{
|
||||
resize: horizontal;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.table-column-title{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.sort-icon{
|
||||
font-size: .7rem;
|
||||
line-height: 1;
|
||||
margin-left: .2rem;
|
||||
}
|
||||
|
||||
.column-key{
|
||||
transform: rotate(90deg);
|
||||
font-size: .7rem;
|
||||
|
179
src/renderer/components/WorkspaceQueryTableCell.vue
Normal file
179
src/renderer/components/WorkspaceQueryTableCell.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="field !== '_id'"
|
||||
ref="cell"
|
||||
class="td"
|
||||
:class="`type-${type} p-0`"
|
||||
tabindex="0"
|
||||
@contextmenu.prevent="$emit('contextmenu', $event)"
|
||||
>
|
||||
<span
|
||||
v-if="!isEditing"
|
||||
class="cell-content px-2"
|
||||
:class="isNull(content)"
|
||||
@dblclick="editON"
|
||||
>{{ content | typeFormat(type, precision) | cutText }}</span>
|
||||
<template v-else>
|
||||
<input
|
||||
v-if="inputProps.mask"
|
||||
ref="editField"
|
||||
v-model="localContent"
|
||||
v-mask="inputProps.mask"
|
||||
:type="inputProps.type"
|
||||
autofocus
|
||||
class="editable-field px-2"
|
||||
@blur="editOFF"
|
||||
>
|
||||
<input
|
||||
v-else
|
||||
ref="editField"
|
||||
v-model="localContent"
|
||||
:type="inputProps.type"
|
||||
autofocus
|
||||
class="editable-field px-2"
|
||||
@blur="editOFF"
|
||||
>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import { mimeFromHex, formatBytes } from 'common/libs/utilities';
|
||||
import hexToBinary from 'common/libs/hexToBinary';
|
||||
import { mask } from 'vue-the-mask';
|
||||
|
||||
export default {
|
||||
name: 'WorkspaceQueryTableCell',
|
||||
filters: {
|
||||
cutText (val) {
|
||||
if (typeof val !== 'string') return val;
|
||||
return val.length > 128 ? `${val.substring(0, 128)}[...]` : val;
|
||||
},
|
||||
typeFormat (val, type, precision) {
|
||||
if (!val) return val;
|
||||
|
||||
switch (type) {
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
case 'text':
|
||||
case 'mediumtext':
|
||||
return val;
|
||||
case 'date': {
|
||||
return moment(val).isValid() ? moment(val).format('YYYY-MM-DD') : val;
|
||||
}
|
||||
case 'datetime':
|
||||
case 'timestamp': {
|
||||
let datePrecision = '';
|
||||
for (let i = 0; i < precision; i++)
|
||||
datePrecision += i === 0 ? '.S' : 'S';
|
||||
|
||||
return moment(val).isValid() ? moment(val).format(`YYYY-MM-DD HH:mm:ss${datePrecision}`) : val;
|
||||
}
|
||||
case 'blob':
|
||||
case 'mediumblob':
|
||||
case 'longblob': {
|
||||
const buff = Buffer.from(val);
|
||||
if (!buff.length) return '';
|
||||
|
||||
const hex = buff.toString('hex').substring(0, 8).toUpperCase();
|
||||
return `${mimeFromHex(hex).mime} (${formatBytes(buff.length)})`;
|
||||
}
|
||||
case 'bit': {
|
||||
const hex = Buffer.from(val).toString('hex');
|
||||
return hexToBinary(hex);
|
||||
}
|
||||
default:
|
||||
return val;
|
||||
}
|
||||
}
|
||||
},
|
||||
directives: {
|
||||
mask
|
||||
},
|
||||
props: {
|
||||
type: String,
|
||||
field: String,
|
||||
precision: [Number, null],
|
||||
content: [String, Number, Object, Date, Uint8Array]
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
isEditing: false,
|
||||
localContent: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
inputProps () {
|
||||
switch (this.type) {
|
||||
case 'char':
|
||||
case 'varchar':
|
||||
case 'text':
|
||||
case 'mediumtext':
|
||||
return { type: 'text', mask: false };
|
||||
case 'int':
|
||||
case 'tinyint':
|
||||
case 'smallint':
|
||||
case 'mediumint':
|
||||
return { type: 'number', mask: false };
|
||||
case 'date':
|
||||
return { type: 'text', mask: '####-##-##' };
|
||||
case 'datetime':
|
||||
case 'timestamp': {
|
||||
let datetimeMask = '####-##-## ##:##:##';
|
||||
for (let i = 0; i < this.precision; i++)
|
||||
datetimeMask += i === 0 ? '.#' : '#';
|
||||
return { type: 'text', mask: datetimeMask };
|
||||
}
|
||||
case 'blob':
|
||||
case 'mediumblob':
|
||||
case 'longblob':
|
||||
case 'bit':
|
||||
return { type: 'file', mask: false };
|
||||
default:
|
||||
return 'hidden';
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isNull (value) {
|
||||
return value === null ? ' is-null' : '';
|
||||
},
|
||||
editON () {
|
||||
if (['file'].includes(this.inputProps.type)) return;// TODO: remove temporary file block
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.cell.blur();
|
||||
|
||||
this.$nextTick(() => this.$refs.editField.focus());
|
||||
});
|
||||
this.localContent = this.$options.filters.typeFormat(this.content, this.type);
|
||||
this.isEditing = true;
|
||||
},
|
||||
editOFF () {
|
||||
this.isEditing = false;
|
||||
if (this.localContent === this.$options.filters.typeFormat(this.content, this.type)) return;
|
||||
|
||||
const { field, type, localContent: content } = this;
|
||||
this.$emit('updateField', { field, type, content });
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.editable-field{
|
||||
margin: 0;
|
||||
border: none;
|
||||
line-height: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cell-content{
|
||||
display: block;
|
||||
min-height: .8rem;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
73
src/renderer/components/WorkspaceQueryTableContext.vue
Normal file
73
src/renderer/components/WorkspaceQueryTableContext.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<BaseContextMenu
|
||||
:context-event="contextEvent"
|
||||
@closeContext="closeContext"
|
||||
>
|
||||
<div class="context-element" @click="showConfirmModal">
|
||||
<i class="material-icons md-18 text-light pr-1">delete</i> {{ $tc('message.deleteRows', selectedRows.length) }}
|
||||
</div>
|
||||
|
||||
<ConfirmModal
|
||||
v-if="isConfirmModal"
|
||||
@confirm="deleteRows()"
|
||||
@hide="hideConfirmModal"
|
||||
>
|
||||
<template :slot="'header'">
|
||||
{{ $tc('message.deleteRows', selectedRows.length) }}
|
||||
</template>
|
||||
<div :slot="'body'">
|
||||
<div class="mb-2">
|
||||
{{ $tc('message.confirmToDeleteRows', selectedRows.length) }}
|
||||
</div>
|
||||
</div>
|
||||
</ConfirmModal>
|
||||
</BaseContextMenu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex';
|
||||
import BaseContextMenu from '@/components/BaseContextMenu';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||
|
||||
export default {
|
||||
name: 'WorkspaceQueryTableContext',
|
||||
components: {
|
||||
BaseContextMenu,
|
||||
ConfirmModal
|
||||
},
|
||||
props: {
|
||||
contextEvent: MouseEvent,
|
||||
selectedRows: Array
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
isConfirmModal: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
deleteConnection: 'connections/deleteConnection',
|
||||
showEditModal: 'application/showEditConnModal'
|
||||
}),
|
||||
showConfirmModal () {
|
||||
this.isConfirmModal = true;
|
||||
},
|
||||
hideConfirmModal () {
|
||||
this.isConfirmModal = false;
|
||||
},
|
||||
closeContext () {
|
||||
this.$emit('closeContext');
|
||||
},
|
||||
deleteRows () {
|
||||
this.$emit('deleteSelected');
|
||||
this.closeContext();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
@@ -29,23 +29,28 @@
|
||||
<div class="workspace-query-results column col-12">
|
||||
<WorkspaceQueryTable
|
||||
v-if="results"
|
||||
ref="queryTable"
|
||||
:results="results"
|
||||
:fields="resultsFields"
|
||||
@updateField="updateField"
|
||||
@deleteSelected="deleteSelected"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Structure from '@/ipc-api/Structure';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import tableTabs from '@/mixins/tableTabs';
|
||||
|
||||
export default {
|
||||
name: 'WorkspaceTableTab',
|
||||
components: {
|
||||
WorkspaceQueryTable
|
||||
},
|
||||
mixins: [tableTabs],
|
||||
props: {
|
||||
connection: Object,
|
||||
table: String
|
||||
@@ -73,19 +78,20 @@ export default {
|
||||
return {
|
||||
name: field.COLUMN_NAME,
|
||||
key: field.COLUMN_KEY.toLowerCase(),
|
||||
type: field.DATA_TYPE
|
||||
type: field.DATA_TYPE,
|
||||
precision: field.DATETIME_PRECISION
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
table: function () {
|
||||
table () {
|
||||
if (this.isSelected) {
|
||||
this.getTableData();
|
||||
this.lastTable = this.table;
|
||||
}
|
||||
},
|
||||
isSelected: function (val) {
|
||||
isSelected (val) {
|
||||
if (val && this.lastTable !== this.table) {
|
||||
this.getTableData();
|
||||
this.lastTable = this.table;
|
||||
@@ -111,7 +117,7 @@ export default {
|
||||
};
|
||||
|
||||
try {
|
||||
const { status, response } = await Structure.getTableColumns(params);
|
||||
const { status, response } = await Tables.getTableColumns(params);
|
||||
if (status === 'success')
|
||||
this.fields = response.rows;
|
||||
else
|
||||
@@ -122,7 +128,7 @@ export default {
|
||||
}
|
||||
|
||||
try {
|
||||
const { status, response } = await Structure.getTableData(params);
|
||||
const { status, response } = await Tables.getTableData(params);
|
||||
|
||||
if (status === 'success')
|
||||
this.results = response;
|
||||
|
@@ -51,7 +51,11 @@ module.exports = {
|
||||
updateAvailable: 'Update available',
|
||||
downloadingUpdate: 'Downloading update',
|
||||
updateDownloaded: 'Update downloaded',
|
||||
restartToInstall: 'Restart Antares to install'
|
||||
restartToInstall: 'Restart Antares to install',
|
||||
unableEditFieldWithoutPrimary: 'Unable to edit a field without a primary key in resultset',
|
||||
editCell: 'Edit cell',
|
||||
deleteRows: 'Delete row | Delete {count} rows',
|
||||
confirmToDeleteRows: 'Do you confirm to delete one row? | Do you confirm to delete {count} rows?'
|
||||
},
|
||||
// Date and Time
|
||||
short: {
|
||||
|
@@ -9,4 +9,12 @@ export default class {
|
||||
static getTableData (params) {
|
||||
return ipcRenderer.invoke('getTableData', params);
|
||||
}
|
||||
|
||||
static updateTableCell (params) {
|
||||
return ipcRenderer.invoke('updateTableCell', params);
|
||||
}
|
||||
|
||||
static deleteTableRows (params) {
|
||||
return ipcRenderer.invoke('deleteTableRows', params);
|
||||
}
|
||||
}
|
47
src/renderer/mixins/tableTabs.js
Normal file
47
src/renderer/mixins/tableTabs.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
async updateField (payload) {
|
||||
const params = {
|
||||
uid: this.connection.uid,
|
||||
schema: this.workspace.breadcrumbs.schema,
|
||||
table: this.table,
|
||||
...payload
|
||||
};
|
||||
|
||||
try {
|
||||
const { status, response } = await Tables.updateTableCell(params);
|
||||
if (status === 'success')
|
||||
this.$refs.queryTable.applyUpdate(payload);
|
||||
else
|
||||
this.addNotification({ status: 'error', message: response });
|
||||
}
|
||||
catch (err) {
|
||||
this.addNotification({ status: 'error', message: err.stack });
|
||||
}
|
||||
},
|
||||
async deleteSelected (payload) {
|
||||
const params = {
|
||||
uid: this.connection.uid,
|
||||
schema: this.workspace.breadcrumbs.schema,
|
||||
table: this.workspace.breadcrumbs.table,
|
||||
...payload
|
||||
};
|
||||
|
||||
try {
|
||||
const { status, response } = await Tables.deleteTableRows(params);
|
||||
if (status === 'success') {
|
||||
const { primary, rows } = params;
|
||||
this.results = { ...this.results, rows: this.results.rows.filter(row => !rows.includes(row[primary])) };
|
||||
this.$refs.queryTable.refreshScroller();// Necessary to re-render virtual scroller
|
||||
}
|
||||
else
|
||||
this.addNotification({ status: 'error', message: response });
|
||||
}
|
||||
catch (err) {
|
||||
this.addNotification({ status: 'error', message: err.stack });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@@ -3,42 +3,41 @@
|
||||
.type-#{$type} {
|
||||
color: $color;
|
||||
|
||||
@if $type == 'number'{
|
||||
@if $type == "number" {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include type-colors((
|
||||
"char": seagreen,
|
||||
"varchar": seagreen,
|
||||
"text": seagreen,
|
||||
"mediumtext": seagreen,
|
||||
@include type-colors(
|
||||
(
|
||||
"char": seagreen,
|
||||
"varchar": seagreen,
|
||||
"text": seagreen,
|
||||
"mediumtext": seagreen,
|
||||
"longtext": seagreen,
|
||||
"int": cornflowerblue,
|
||||
"tinyint": cornflowerblue,
|
||||
"smallint": cornflowerblue,
|
||||
"mediumint": cornflowerblue,
|
||||
"bigint": cornflowerblue,
|
||||
"datetime": coral,
|
||||
"date": coral,
|
||||
"time": coral,
|
||||
"timestamp": coral,
|
||||
"bit": lightskyblue,
|
||||
"blob": darkorchid,
|
||||
"mediumblob": darkorchid,
|
||||
"longblob": darkorchid,
|
||||
"unknown": gray,
|
||||
)
|
||||
);
|
||||
|
||||
"int": cornflowerblue,
|
||||
"tinyint": cornflowerblue,
|
||||
"smallint": cornflowerblue,
|
||||
"mediumint": cornflowerblue,
|
||||
|
||||
"datetime": coral,
|
||||
"date": coral,
|
||||
"time": coral,
|
||||
"timestamp": coral,
|
||||
|
||||
"bit": lightskyblue,
|
||||
|
||||
"blob": darkorchid,
|
||||
"mediumblob": darkorchid,
|
||||
"longblob": darkorchid,
|
||||
|
||||
"unknown": gray,
|
||||
));
|
||||
|
||||
.is-null{
|
||||
.is-null {
|
||||
color: gray;
|
||||
|
||||
&::after{
|
||||
content: 'NULL';
|
||||
&::after {
|
||||
content: "NULL";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,26 +1,26 @@
|
||||
.dbi{
|
||||
.dbi {
|
||||
display: inline-block;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
background-size: cover;
|
||||
|
||||
&.dbi-mysql{
|
||||
background-image: url('../images/svg/mysql.svg');
|
||||
&.dbi-mysql {
|
||||
background-image: url("../images/svg/mysql.svg");
|
||||
}
|
||||
|
||||
&.dbi-maria{
|
||||
background-image: url('../images/svg/mariadb.svg');
|
||||
&.dbi-maria {
|
||||
background-image: url("../images/svg/mariadb.svg");
|
||||
}
|
||||
|
||||
&.dbi-mssql{
|
||||
background-image: url('../images/svg/mssql.svg');
|
||||
&.dbi-mssql {
|
||||
background-image: url("../images/svg/mssql.svg");
|
||||
}
|
||||
|
||||
&.dbi-pg{
|
||||
background-image: url('../images/svg/pg.svg');
|
||||
&.dbi-pg {
|
||||
background-image: url("../images/svg/pg.svg");
|
||||
}
|
||||
|
||||
&.dbi-oracledb{
|
||||
background-image: url('../images/svg/oracledb.svg');
|
||||
&.dbi-oracledb {
|
||||
background-image: url("../images/svg/oracledb.svg");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,65 +1,69 @@
|
||||
.table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
display: table;
|
||||
|
||||
&.table-striped {
|
||||
.tbody {
|
||||
.tr:nth-of-type(odd) {
|
||||
background: $bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&,
|
||||
&.table-striped {
|
||||
.tbody {
|
||||
.tr {
|
||||
&.active {
|
||||
background: $bg-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.table-hover {
|
||||
.tbody {
|
||||
.tr {
|
||||
&:hover {
|
||||
background: $bg-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scollable tables
|
||||
&.table-scroll {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding-bottom: .75rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
|
||||
.thead{
|
||||
&.table-striped {
|
||||
.tbody {
|
||||
.tr:nth-of-type(odd) {
|
||||
background: $bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&,
|
||||
&.table-striped {
|
||||
.tbody {
|
||||
.tr {
|
||||
&.selected {
|
||||
background: #333 !important;
|
||||
}
|
||||
&.active {
|
||||
background: $bg-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.table-hover {
|
||||
.tbody {
|
||||
.tr {
|
||||
&:hover {
|
||||
background: $bg-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scollable tables
|
||||
&.table-scroll {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 0.75rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.thead {
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
.tbody{
|
||||
}
|
||||
|
||||
.tbody {
|
||||
display: table-row-group;
|
||||
}
|
||||
}
|
||||
|
||||
.tr{
|
||||
.tr {
|
||||
display: table-row;
|
||||
}
|
||||
}
|
||||
|
||||
.td,
|
||||
.th {
|
||||
border-bottom: $border-width solid $border-color;
|
||||
padding: $unit-3 $unit-2;
|
||||
display: table-cell;
|
||||
}
|
||||
.th {
|
||||
border-bottom-width: $border-width-lg;
|
||||
}
|
||||
}
|
||||
.td,
|
||||
.th {
|
||||
border-bottom: $border-width solid $border-color;
|
||||
padding: $unit-3 $unit-2;
|
||||
display: table-cell;
|
||||
}
|
||||
.th {
|
||||
border-bottom-width: $border-width-lg;
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,11 @@
|
||||
.slide-fade-enter-active {
|
||||
transition: all .3s ease;
|
||||
}
|
||||
.slide-fade-leave-active {
|
||||
transition: all .3s cubic-bezier(1.0, 0.5, 0.8, 1.0);
|
||||
}
|
||||
.slide-fade-enter, .slide-fade-leave-to {
|
||||
transform: translateX(10px);
|
||||
opacity: 0;
|
||||
}
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.slide-fade-leave-active {
|
||||
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
|
||||
}
|
||||
.slide-fade-enter,
|
||||
.slide-fade-leave-to {
|
||||
transform: translateX(10px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ $bg-color-gray: #272727;
|
||||
$primary-color: #e36929;
|
||||
$success-color: #32b643;
|
||||
$error-color: #de3b28;
|
||||
$warning-color: #e0a40c;
|
||||
|
||||
/*Sizes*/
|
||||
$titlebar-height: 1.5rem;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
|
||||
@import "~spectre.css/src/variables";
|
||||
@import "variables";
|
||||
@import "transitions";
|
||||
@@ -9,7 +8,7 @@
|
||||
@import "~spectre.css/src/spectre";
|
||||
@import "~spectre.css/src/spectre-exp";
|
||||
|
||||
body{
|
||||
body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -19,21 +18,21 @@ body{
|
||||
@include padding-variant(3, $unit-3);
|
||||
@include padding-variant(4, $unit-4);
|
||||
|
||||
.btn.btn-gray{
|
||||
.btn.btn-gray {
|
||||
color: #fff;
|
||||
background: $bg-color-gray;
|
||||
|
||||
&:hover{
|
||||
&:hover {
|
||||
background: $bg-color;
|
||||
}
|
||||
}
|
||||
|
||||
.p-vcentered{
|
||||
display: flex!important;
|
||||
.p-vcentered {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c-help{
|
||||
.c-help {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
@@ -42,109 +41,108 @@ body{
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: $bg-color-light;
|
||||
background: $bg-color-light;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba($color: #FFF, $alpha: .5);
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba($color: #fff, $alpha: 0.5);
|
||||
|
||||
&:hover {
|
||||
background: rgba($color: #FFF, $alpha: 1);
|
||||
background: rgba($color: #fff, $alpha: 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Animations
|
||||
@keyframes rotation {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(359deg);
|
||||
transform: rotate(359deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rotate {
|
||||
animation: rotation .8s infinite linear;
|
||||
animation: rotation 0.8s infinite linear;
|
||||
}
|
||||
|
||||
/*Override*/
|
||||
.modal{
|
||||
.modal {
|
||||
.modal-overlay,
|
||||
&.active .modal-overlay{
|
||||
&.active .modal-overlay {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
|
||||
.modal-sm .modal-container,
|
||||
.modal-container{
|
||||
.modal-container {
|
||||
box-shadow: 0 0 1px 0px #000;
|
||||
padding: 0;
|
||||
background: $bg-color;
|
||||
|
||||
.modal-header{
|
||||
padding: .4rem .8rem;
|
||||
|
||||
.modal-header {
|
||||
padding: 0.4rem 0.8rem;
|
||||
text-transform: uppercase;
|
||||
background: $bg-color-gray;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #FFF;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab{
|
||||
.tab {
|
||||
border-color: #272727;
|
||||
}
|
||||
|
||||
.panel{
|
||||
.panel {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.badge{
|
||||
.badge {
|
||||
&[data-badge],
|
||||
&:not([data-badge]){
|
||||
&:not([data-badge]) {
|
||||
&::after {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-select{
|
||||
.form-select {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.form-select,
|
||||
.form-select:not([multiple]):not([size]),
|
||||
.form-input,
|
||||
.form-checkbox .form-icon,
|
||||
.form-radio .form-icon{
|
||||
.form-checkbox .form-icon,
|
||||
.form-radio .form-icon {
|
||||
border-color: $bg-color-light;
|
||||
background: $bg-color-gray;
|
||||
}
|
||||
|
||||
.form-select:not([multiple]):not([size]):focus{
|
||||
.form-select:not([multiple]):not([size]):focus {
|
||||
border-color: $primary-color;
|
||||
}
|
||||
|
||||
.menu{
|
||||
font-size: .7rem;
|
||||
.menu {
|
||||
font-size: 0.7rem;
|
||||
.menu-item {
|
||||
+ .menu-item{
|
||||
+ .menu-item {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.accordion-body {
|
||||
max-height: 500rem!important;
|
||||
max-height: 500rem !important;
|
||||
}
|
||||
|
||||
.btn.loading {
|
||||
> .material-icons,
|
||||
> span{
|
||||
> span {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ export default {
|
||||
isSettingModal: state => state.is_setting_modal,
|
||||
selectedSettingTab: state => state.selected_setting_tab,
|
||||
getUpdateStatus: state => state.update_status,
|
||||
getDownloadProgress: state => state.download_progress
|
||||
getDownloadProgress: state => Number(state.download_progress.toFixed(1))
|
||||
},
|
||||
mutations: {
|
||||
SET_LOADING_STATUS (state, payload) {
|
||||
|
@@ -17,7 +17,7 @@ module.exports = {
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
prependData: '@import "@/scss/_variables.scss";'
|
||||
additionalData: '@import "@/scss/_variables.scss";'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
Reference in New Issue
Block a user