mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
14d5842056 | |||
f19f9e23a2 | |||
0252a064d9 | |||
439356a019 | |||
c6897af22d | |||
7e40dbfba3 | |||
27a153ef43 | |||
56fcc2650b | |||
9622dbec6b | |||
a0ab63bdb5 | |||
8cd76e711c | |||
9af71a6e34 | |||
e7b3c28826 | |||
7570b0add8 | |||
|
1801bef019 | ||
0db5ebd7bf |
@@ -9,7 +9,8 @@
|
|||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"at-rule-no-unknown": null,
|
"at-rule-no-unknown": null,
|
||||||
"no-descending-specificity": null
|
"no-descending-specificity": null,
|
||||||
|
"declaration-colon-newline-after": "always-multi-line"
|
||||||
},
|
},
|
||||||
"syntax": "scss"
|
"syntax": "scss"
|
||||||
}
|
}
|
19
CHANGELOG.md
19
CHANGELOG.md
@@ -2,6 +2,25 @@
|
|||||||
|
|
||||||
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.2.1](https://github.com/Fabio286/antares/compare/v0.2.0...v0.2.1) (2021-07-09)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **UI:** contextual menu shortcuts to create new elements on folders ([0252a06](https://github.com/Fabio286/antares/commit/0252a064d99df09b01c020c7d10c76dd43d4ede8))
|
||||||
|
* context menu option to duplicate connections ([439356a](https://github.com/Fabio286/antares/commit/439356a01993a6a248f5a7d7df305ac5e0e63775))
|
||||||
|
* **MySQL:** possibility to set a default schema in connection parameters ([c6897af](https://github.com/Fabio286/antares/commit/c6897af22d04ed930289a55124b3e8d080fbae3a))
|
||||||
|
* **UI:** new connection add panel ([8cd76e7](https://github.com/Fabio286/antares/commit/8cd76e711c9328254d498b4f9afa221311f5a487))
|
||||||
|
* **UI:** new connection edit panel ([9af71a6](https://github.com/Fabio286/antares/commit/9af71a6e343deda1bf79d8410511cf861af3c304))
|
||||||
|
* SSH Tunnel functionality ([#81](https://github.com/Fabio286/antares/issues/81)) ([1801bef](https://github.com/Fabio286/antares/commit/1801bef019cee77a99df7e3822145ad952465abb))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* clear corrupted configurations to avoid exceptions ([56fcc26](https://github.com/Fabio286/antares/commit/56fcc2650b93ece398118f39f027dc9520dd8a6a))
|
||||||
|
* **UI:** connection tab indicator when scrolling ([a0ab63b](https://github.com/Fabio286/antares/commit/a0ab63bdb533aac9b2bdc2ee07a3b1f2b70ea227))
|
||||||
|
* avoid to trigger schema loading multiple times ([7570b0a](https://github.com/Fabio286/antares/commit/7570b0add8cb9130f15cf8cb807a96dbfd2837d0))
|
||||||
|
|
||||||
## [0.2.0](https://github.com/Fabio286/antares/compare/v0.1.13...v0.2.0) (2021-07-03)
|
## [0.2.0](https://github.com/Fabio286/antares/compare/v0.1.13...v0.2.0) (2021-07-03)
|
||||||
|
|
||||||
|
|
||||||
|
18
README.md
18
README.md
@@ -9,9 +9,9 @@
|
|||||||
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 in development state, many features will come in future updates**, and supports only MySQL/MariaDB and PostgreSQL (partially).
|
**At the moment this application is in development state, many features will come in future updates**, and supports only MySQL/MariaDB and PostgreSQL.
|
||||||
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.
|
At the moment, however, there are all the features necessary to have a pleasant database management experience, so give it a chance and send us your feedback, we would really appreciate it.
|
||||||
I'm actively working on it, hoping to provide cool features and fixes as soon as possible.
|
We are actively working on it, hoping to provide new cool features, improvements and fixes as soon as possible.
|
||||||
|
|
||||||
🔗 If you are curious to try Antares you can download and install the [latest release](https://github.com/Fabio286/antares/releases/latest).
|
🔗 If you are curious to try Antares you can download and install the [latest release](https://github.com/Fabio286/antares/releases/latest).
|
||||||
👁 To stay tuned for new releases [follow Antares SQL](https://twitter.com/AntaresSQL) on Twitter.
|
👁 To stay tuned for new releases [follow Antares SQL](https://twitter.com/AntaresSQL) on Twitter.
|
||||||
@@ -19,9 +19,9 @@ I'm actively working on it, hoping to provide cool features and fixes as soon as
|
|||||||
|
|
||||||
## Philosophy
|
## Philosophy
|
||||||
|
|
||||||
Why am I developing an SQL client when there are a lot of them on the market?
|
Why are we 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.
|
||||||
A modern application created with minimalism and semplicity in mind, with features in the right places, not hundreds of tiny buttons, tabs or submenu.
|
A modern application created with minimalism and semplicity in mind, with features in the right places, not hundreds of tiny buttons, nested tabs or submenu; productivity comes first.
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
@@ -43,6 +43,7 @@ A modern application created with minimalism and semplicity in mind, with featur
|
|||||||
- 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.
|
||||||
|
- SSH tunnel support.
|
||||||
- Dark and light theme.
|
- Dark and light theme.
|
||||||
- Scratchpad.
|
- Scratchpad.
|
||||||
- Multi language.
|
- Multi language.
|
||||||
@@ -54,13 +55,10 @@ This is a roadmap with major features will come in near future.
|
|||||||
|
|
||||||
- Support for other databases.
|
- Support for other databases.
|
||||||
- Database tools.
|
- Database tools.
|
||||||
- SSH tunnel support.
|
|
||||||
- Users management (add/edit/delete).
|
- Users management (add/edit/delete).
|
||||||
- UI/UX improvements.
|
- Query history and bookmarks.
|
||||||
- Query history.
|
|
||||||
- More context menu shortcuts.
|
- More context menu shortcuts.
|
||||||
- More keyboard shortcuts.
|
- More keyboard shortcuts.
|
||||||
- Query logs console.
|
|
||||||
- Import/export and migration.
|
- Import/export and migration.
|
||||||
|
|
||||||
## Currently supported
|
## Currently supported
|
||||||
@@ -68,7 +66,7 @@ This is a roadmap with major features will come in near future.
|
|||||||
### Databases
|
### Databases
|
||||||
|
|
||||||
- [x] MySQL/MariaDB
|
- [x] MySQL/MariaDB
|
||||||
- [x] PostgreSQL (partially, work in progress)
|
- [x] PostgreSQL
|
||||||
- [ ] SQLite
|
- [ ] SQLite
|
||||||
- [ ] MSSQL
|
- [ ] MSSQL
|
||||||
- [ ] OracleDB
|
- [ ] OracleDB
|
||||||
|
BIN
docs/gh-logo-2.png
Normal file
BIN
docs/gh-logo-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
docs/gh-logo.png
BIN
docs/gh-logo.png
Binary file not shown.
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 304 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "antares",
|
"name": "antares",
|
||||||
"productName": "Antares",
|
"productName": "Antares",
|
||||||
"version": "0.2.0",
|
"version": "0.2.1",
|
||||||
"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",
|
||||||
@@ -102,6 +102,7 @@
|
|||||||
"source-map-support": "^0.5.16",
|
"source-map-support": "^0.5.16",
|
||||||
"spectre.css": "^0.5.9",
|
"spectre.css": "^0.5.9",
|
||||||
"sql-formatter": "^4.0.2",
|
"sql-formatter": "^4.0.2",
|
||||||
|
"ssh2-promise": "^0.1.7",
|
||||||
"v-mask": "^2.2.4",
|
"v-mask": "^2.2.4",
|
||||||
"vue-i18n": "^8.24.4",
|
"vue-i18n": "^8.24.4",
|
||||||
"vuedraggable": "^2.24.3",
|
"vuedraggable": "^2.24.3",
|
||||||
|
@@ -7,6 +7,7 @@ module.exports = {
|
|||||||
database: false,
|
database: false,
|
||||||
collations: false,
|
collations: false,
|
||||||
engines: false,
|
engines: false,
|
||||||
|
connectionSchema: false,
|
||||||
// Tools
|
// Tools
|
||||||
processesList: false,
|
processesList: false,
|
||||||
usersManagement: false,
|
usersManagement: false,
|
||||||
|
@@ -7,6 +7,7 @@ module.exports = {
|
|||||||
defaultUser: 'root',
|
defaultUser: 'root',
|
||||||
defaultDatabase: null,
|
defaultDatabase: null,
|
||||||
// Core
|
// Core
|
||||||
|
connectionSchema: true,
|
||||||
collations: true,
|
collations: true,
|
||||||
engines: true,
|
engines: true,
|
||||||
// Tools
|
// Tools
|
||||||
|
@@ -24,13 +24,23 @@ export default connections => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const connection = ClientsFactory.getConnection({
|
if (conn.ssh) {
|
||||||
client: conn.client,
|
params.ssh = {
|
||||||
params
|
host: conn.sshHost,
|
||||||
});
|
username: conn.sshUser,
|
||||||
|
password: conn.sshPass,
|
||||||
|
port: conn.sshPort ? conn.sshPort : 22,
|
||||||
|
identity: conn.sshKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const connection = await ClientsFactory.getConnection({
|
||||||
|
client: conn.client,
|
||||||
|
params
|
||||||
|
});
|
||||||
await connection.connect();
|
await connection.connect();
|
||||||
|
|
||||||
await connection.select('1+1').run();
|
await connection.select('1+1').run();
|
||||||
connection.destroy();
|
connection.destroy();
|
||||||
|
|
||||||
@@ -57,6 +67,9 @@ export default connections => {
|
|||||||
if (conn.database)
|
if (conn.database)
|
||||||
params.database = conn.database;
|
params.database = conn.database;
|
||||||
|
|
||||||
|
if (conn.schema)
|
||||||
|
params.schema = conn.schema;
|
||||||
|
|
||||||
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,
|
||||||
@@ -66,6 +79,16 @@ export default connections => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conn.ssh) {
|
||||||
|
params.ssh = {
|
||||||
|
host: conn.sshHost,
|
||||||
|
username: conn.sshUser,
|
||||||
|
password: conn.sshPass,
|
||||||
|
port: conn.sshPort ? conn.sshPort : 22,
|
||||||
|
identity: conn.sshKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const connection = ClientsFactory.getConnection({
|
const connection = ClientsFactory.getConnection({
|
||||||
client: conn.client,
|
client: conn.client,
|
||||||
|
@@ -12,6 +12,12 @@ export class ClientsFactory {
|
|||||||
* @param {String} args.params.host
|
* @param {String} args.params.host
|
||||||
* @param {Number} args.params.port
|
* @param {Number} args.params.port
|
||||||
* @param {String} args.params.password
|
* @param {String} args.params.password
|
||||||
|
* @param {String=} args.params.database
|
||||||
|
* @param {String=} args.params.schema
|
||||||
|
* @param {String} args.params.ssh.host
|
||||||
|
* @param {String} args.params.ssh.username
|
||||||
|
* @param {String} args.params.ssh.password
|
||||||
|
* @param {Number} args.params.ssh.port
|
||||||
* @param {Number=} args.poolSize
|
* @param {Number=} args.poolSize
|
||||||
* @returns Database Connection
|
* @returns Database Connection
|
||||||
* @memberof ClientsFactory
|
* @memberof ClientsFactory
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
import mysql from 'mysql2/promise';
|
import mysql from 'mysql2/promise';
|
||||||
import { AntaresCore } from '../AntaresCore';
|
import { AntaresCore } from '../AntaresCore';
|
||||||
import dataTypes from 'common/data-types/mysql';
|
import dataTypes from 'common/data-types/mysql';
|
||||||
|
import * as SSH2Promise from 'ssh2-promise';
|
||||||
|
|
||||||
export class MySQLClient extends AntaresCore {
|
export class MySQLClient extends AntaresCore {
|
||||||
constructor (args) {
|
constructor (args) {
|
||||||
@@ -104,11 +105,33 @@ export class MySQLClient extends AntaresCore {
|
|||||||
async connect () {
|
async connect () {
|
||||||
delete this._params.application_name;
|
delete this._params.application_name;
|
||||||
|
|
||||||
|
const dbConfig = {
|
||||||
|
host: this._params.host,
|
||||||
|
port: this._params.port,
|
||||||
|
user: this._params.user,
|
||||||
|
password: this._params.password,
|
||||||
|
ssl: null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this._params.schema?.length) dbConfig.database = this._params.schema;
|
||||||
|
|
||||||
|
if (this._params.ssl) dbConfig.ssl = { ...this._params.ssl };
|
||||||
|
|
||||||
|
if (this._params.ssh) {
|
||||||
|
this._ssh = new SSH2Promise({ ...this._params.ssh });
|
||||||
|
|
||||||
|
this._tunnel = await this._ssh.addTunnel({
|
||||||
|
remoteAddr: this._params.host,
|
||||||
|
remotePort: this._params.port
|
||||||
|
});
|
||||||
|
dbConfig.port = this._tunnel.localPort;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._poolSize)
|
if (!this._poolSize)
|
||||||
this._connection = await mysql.createConnection(this._params);
|
this._connection = await mysql.createConnection(dbConfig);
|
||||||
else {
|
else {
|
||||||
this._connection = mysql.createPool({
|
this._connection = mysql.createPool({
|
||||||
...this._params,
|
...dbConfig,
|
||||||
connectionLimit: this._poolSize,
|
connectionLimit: this._poolSize,
|
||||||
typeCast: (field, next) => {
|
typeCast: (field, next) => {
|
||||||
if (field.type === 'DATETIME')
|
if (field.type === 'DATETIME')
|
||||||
@@ -125,6 +148,7 @@ export class MySQLClient extends AntaresCore {
|
|||||||
*/
|
*/
|
||||||
destroy () {
|
destroy () {
|
||||||
this._connection.end();
|
this._connection.end();
|
||||||
|
if (this._ssh) this._ssh.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,6 +169,12 @@ export class MySQLClient extends AntaresCore {
|
|||||||
*/
|
*/
|
||||||
async getStructure (schemas) {
|
async getStructure (schemas) {
|
||||||
const { rows: databases } = await this.raw('SHOW DATABASES');
|
const { rows: databases } = await this.raw('SHOW DATABASES');
|
||||||
|
|
||||||
|
let filteredDatabases = databases;
|
||||||
|
|
||||||
|
if (this._params.schema)
|
||||||
|
filteredDatabases = filteredDatabases.filter(db => db.Database === this._params.schema);
|
||||||
|
|
||||||
const { rows: functions } = await this.raw('SHOW FUNCTION STATUS');
|
const { rows: functions } = await this.raw('SHOW FUNCTION STATUS');
|
||||||
const { rows: procedures } = await this.raw('SHOW PROCEDURE STATUS');
|
const { rows: procedures } = await this.raw('SHOW PROCEDURE STATUS');
|
||||||
const { rows: schedulers } = await this.raw('SELECT *, EVENT_SCHEMA AS `Db`, EVENT_NAME AS `Name` FROM information_schema.`EVENTS`');
|
const { rows: schedulers } = await this.raw('SELECT *, EVENT_SCHEMA AS `Db`, EVENT_NAME AS `Name` FROM information_schema.`EVENTS`');
|
||||||
@@ -152,7 +182,7 @@ export class MySQLClient extends AntaresCore {
|
|||||||
const tablesArr = [];
|
const tablesArr = [];
|
||||||
const triggersArr = [];
|
const triggersArr = [];
|
||||||
|
|
||||||
for (const db of databases) {
|
for (const db of filteredDatabases) {
|
||||||
if (!schemas.has(db.Database)) continue;
|
if (!schemas.has(db.Database)) continue;
|
||||||
|
|
||||||
let { rows: tables } = await this.raw(`SHOW TABLE STATUS FROM \`${db.Database}\``);
|
let { rows: tables } = await this.raw(`SHOW TABLE STATUS FROM \`${db.Database}\``);
|
||||||
@@ -174,7 +204,7 @@ export class MySQLClient extends AntaresCore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return databases.map(db => {
|
return filteredDatabases.map(db => {
|
||||||
if (schemas.has(db.Database)) {
|
if (schemas.has(db.Database)) {
|
||||||
// TABLES
|
// TABLES
|
||||||
const remappedTables = tablesArr.filter(table => table.Db === db.Database).map(table => {
|
const remappedTables = tablesArr.filter(table => table.Db === db.Database).map(table => {
|
||||||
|
@@ -3,6 +3,7 @@ import { Pool, Client, types } from 'pg';
|
|||||||
import { parse } from 'pgsql-ast-parser';
|
import { parse } from 'pgsql-ast-parser';
|
||||||
import { AntaresCore } from '../AntaresCore';
|
import { AntaresCore } from '../AntaresCore';
|
||||||
import dataTypes from 'common/data-types/postgresql';
|
import dataTypes from 'common/data-types/postgresql';
|
||||||
|
import * as SSH2Promise from 'ssh2-promise';
|
||||||
|
|
||||||
function pgToString (value) {
|
function pgToString (value) {
|
||||||
return value.toString();
|
return value.toString();
|
||||||
@@ -51,13 +52,35 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
* @memberof PostgreSQLClient
|
* @memberof PostgreSQLClient
|
||||||
*/
|
*/
|
||||||
async connect () {
|
async connect () {
|
||||||
|
const dbConfig = {
|
||||||
|
host: this._params.host,
|
||||||
|
port: this._params.port,
|
||||||
|
user: this._params.user,
|
||||||
|
password: this._params.password,
|
||||||
|
ssl: null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this._params.database?.length) dbConfig.database = this._params.database;
|
||||||
|
|
||||||
|
if (this._params.ssl) dbConfig.ssl = { ...this._params.ssl };
|
||||||
|
|
||||||
|
if (this._params.ssh) {
|
||||||
|
this._ssh = new SSH2Promise({ ...this._params.ssh });
|
||||||
|
|
||||||
|
this._tunnel = await this._ssh.addTunnel({
|
||||||
|
remoteAddr: this._params.host,
|
||||||
|
remotePort: this._params.port
|
||||||
|
});
|
||||||
|
dbConfig.port = this._tunnel.localPort;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._poolSize) {
|
if (!this._poolSize) {
|
||||||
const client = new Client(this._params);
|
const client = new Client(dbConfig);
|
||||||
await client.connect();
|
await client.connect();
|
||||||
this._connection = client;
|
this._connection = client;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const pool = new Pool({ ...this._params, max: this._poolSize });
|
const pool = new Pool({ ...dbConfig, max: this._poolSize });
|
||||||
this._connection = pool;
|
this._connection = pool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,6 +90,7 @@ export class PostgreSQLClient extends AntaresCore {
|
|||||||
*/
|
*/
|
||||||
destroy () {
|
destroy () {
|
||||||
this._connection.end();
|
this._connection.end();
|
||||||
|
if (this._ssh) this._ssh.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -4,22 +4,21 @@
|
|||||||
<div id="window-content">
|
<div id="window-content">
|
||||||
<TheSettingBar />
|
<TheSettingBar />
|
||||||
<div id="main-content" class="container">
|
<div id="main-content" class="container">
|
||||||
<TheAppWelcome v-if="!connections.length" @new-conn="showNewConnModal" />
|
<div class="columns col-gapless">
|
||||||
<div v-else class="columns col-gapless">
|
|
||||||
<Workspace
|
<Workspace
|
||||||
v-for="connection in connections"
|
v-for="connection in connections"
|
||||||
:key="connection.uid"
|
:key="connection.uid"
|
||||||
:connection="connection"
|
:connection="connection"
|
||||||
/>
|
/>
|
||||||
|
<WorkspaceAddConnectionPanel v-if="selectedWorkspace === 'NEW'" />
|
||||||
</div>
|
</div>
|
||||||
|
<TheFooter />
|
||||||
|
<TheNotificationsBoard />
|
||||||
|
<TheScratchpad v-if="isScratchpad" />
|
||||||
|
<ModalSettings v-if="isSettingModal" />
|
||||||
|
<ModalDiscardChanges v-if="isUnsavedDiscardModal" />
|
||||||
|
<BaseTextEditor class="d-none" value="" />
|
||||||
</div>
|
</div>
|
||||||
<TheFooter />
|
|
||||||
<TheNotificationsBoard />
|
|
||||||
<ModalNewConnection v-if="isNewConnModal" />
|
|
||||||
<TheScratchpad v-if="isScratchpad" />
|
|
||||||
<ModalSettings v-if="isSettingModal" />
|
|
||||||
<ModalDiscardChanges v-if="isUnsavedDiscardModal" />
|
|
||||||
<BaseTextEditor class="d-none" value="" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -36,9 +35,8 @@ export default {
|
|||||||
TheSettingBar: () => import(/* webpackChunkName: "TheSettingBar" */'@/components/TheSettingBar'),
|
TheSettingBar: () => import(/* webpackChunkName: "TheSettingBar" */'@/components/TheSettingBar'),
|
||||||
TheFooter: () => import(/* webpackChunkName: "TheFooter" */'@/components/TheFooter'),
|
TheFooter: () => import(/* webpackChunkName: "TheFooter" */'@/components/TheFooter'),
|
||||||
TheNotificationsBoard: () => import(/* webpackChunkName: "TheNotificationsBoard" */'@/components/TheNotificationsBoard'),
|
TheNotificationsBoard: () => import(/* webpackChunkName: "TheNotificationsBoard" */'@/components/TheNotificationsBoard'),
|
||||||
TheAppWelcome: () => import(/* webpackChunkName: "TheAppWelcome" */'@/components/TheAppWelcome'),
|
|
||||||
Workspace: () => import(/* webpackChunkName: "Workspace" */'@/components/Workspace'),
|
Workspace: () => import(/* webpackChunkName: "Workspace" */'@/components/Workspace'),
|
||||||
ModalNewConnection: () => import(/* webpackChunkName: "ModalNewConnection" */'@/components/ModalNewConnection'),
|
WorkspaceAddConnectionPanel: () => import(/* webpackChunkName: "WorkspaceAddConnectionPanel" */'@/components/WorkspaceAddConnectionPanel'),
|
||||||
ModalSettings: () => import(/* webpackChunkName: "ModalSettings" */'@/components/ModalSettings'),
|
ModalSettings: () => import(/* webpackChunkName: "ModalSettings" */'@/components/ModalSettings'),
|
||||||
TheScratchpad: () => import(/* webpackChunkName: "TheScratchpad" */'@/components/TheScratchpad'),
|
TheScratchpad: () => import(/* webpackChunkName: "TheScratchpad" */'@/components/TheScratchpad'),
|
||||||
ModalDiscardChanges: () => import(/* webpackChunkName: "ModalDiscardChanges" */'@/components/ModalDiscardChanges'),
|
ModalDiscardChanges: () => import(/* webpackChunkName: "ModalDiscardChanges" */'@/components/ModalDiscardChanges'),
|
||||||
@@ -49,9 +47,8 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
|
selectedWorkspace: 'workspaces/getSelected',
|
||||||
isLoading: 'application/isLoading',
|
isLoading: 'application/isLoading',
|
||||||
isNewConnModal: 'application/isNewModal',
|
|
||||||
isEditModal: 'application/isEditModal',
|
|
||||||
isSettingModal: 'application/isSettingModal',
|
isSettingModal: 'application/isSettingModal',
|
||||||
isScratchpad: 'application/isScratchpad',
|
isScratchpad: 'application/isScratchpad',
|
||||||
connections: 'connections/getConnections',
|
connections: 'connections/getConnections',
|
||||||
|
@@ -60,7 +60,7 @@
|
|||||||
{{ $t('word.application') }}
|
{{ $t('word.application') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="column col-8 col-sm-12 mb-2">
|
<div class="column col-8 col-sm-12 mb-2">
|
||||||
<div class="form-group mb-4">
|
<div class="form-group">
|
||||||
<div class="col-6 col-sm-12">
|
<div class="col-6 col-sm-12">
|
||||||
<label class="form-label">
|
<label class="form-label">
|
||||||
<i class="mdi mdi-18px mdi-translate mr-1" />
|
<i class="mdi mdi-18px mdi-translate mr-1" />
|
||||||
|
@@ -3,18 +3,13 @@
|
|||||||
:context-event="contextEvent"
|
:context-event="contextEvent"
|
||||||
@close-context="$emit('close-context')"
|
@close-context="$emit('close-context')"
|
||||||
>
|
>
|
||||||
<div class="context-element" @click="showEditModal(contextConnection)">
|
<div class="context-element" @click="duplicateConnection">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-pencil text-light pr-1" /> {{ $t('word.edit') }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-content-duplicate text-light pr-1" /> {{ $t('word.duplicate') }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="context-element" @click="showConfirmModal">
|
<div class="context-element" @click="showConfirmModal">
|
||||||
<span class="d-flex"><i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ $t('word.delete') }}</span>
|
<span class="d-flex"><i class="mdi mdi-18px mdi-delete text-light pr-1" /> {{ $t('word.delete') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ModalEditConnection
|
|
||||||
v-if="isEditModal"
|
|
||||||
:connection="contextConnection"
|
|
||||||
@close="hideEditModal"
|
|
||||||
/>
|
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
v-if="isConfirmModal"
|
v-if="isConfirmModal"
|
||||||
@confirm="confirmDeleteConnection"
|
@confirm="confirmDeleteConnection"
|
||||||
@@ -36,15 +31,14 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapGetters } from 'vuex';
|
import { mapActions, mapGetters } from 'vuex';
|
||||||
|
import { uidGen } from 'common/libs/uidGen';
|
||||||
import BaseContextMenu from '@/components/BaseContextMenu';
|
import BaseContextMenu from '@/components/BaseContextMenu';
|
||||||
import ConfirmModal from '@/components/BaseConfirmModal';
|
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||||
import ModalEditConnection from '@/components/ModalEditConnection';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SettingBarContext',
|
name: 'SettingBarContext',
|
||||||
components: {
|
components: {
|
||||||
BaseContextMenu,
|
BaseContextMenu,
|
||||||
ModalEditConnection,
|
|
||||||
ConfirmModal
|
ConfirmModal
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -59,7 +53,8 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
getConnectionName: 'connections/getConnectionName'
|
getConnectionName: 'connections/getConnectionName',
|
||||||
|
selectedWorkspace: 'workspaces/getSelected'
|
||||||
}),
|
}),
|
||||||
connectionName () {
|
connectionName () {
|
||||||
return this.getConnectionName(this.contextConnection.uid);
|
return this.getConnectionName(this.contextConnection.uid);
|
||||||
@@ -67,17 +62,25 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
...mapActions({
|
||||||
deleteConnection: 'connections/deleteConnection'
|
addConnection: 'connections/addConnection',
|
||||||
|
deleteConnection: 'connections/deleteConnection',
|
||||||
|
selectWorkspace: 'workspaces/selectWorkspace'
|
||||||
}),
|
}),
|
||||||
confirmDeleteConnection () {
|
confirmDeleteConnection () {
|
||||||
|
if (this.selectedWorkspace === this.contextConnection.uid)
|
||||||
|
this.selectWorkspace();
|
||||||
this.deleteConnection(this.contextConnection);
|
this.deleteConnection(this.contextConnection);
|
||||||
this.closeContext();
|
this.closeContext();
|
||||||
},
|
},
|
||||||
showEditModal () {
|
duplicateConnection () {
|
||||||
this.isEditModal = true;
|
let connectionCopy = Object.assign({}, this.contextConnection);
|
||||||
},
|
connectionCopy = {
|
||||||
hideEditModal () {
|
...connectionCopy,
|
||||||
this.isEditModal = false;
|
uid: uidGen('C'),
|
||||||
|
name: connectionCopy.name ? `${connectionCopy.name}_copy` : ''
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addConnection(connectionCopy);
|
||||||
this.closeContext();
|
this.closeContext();
|
||||||
},
|
},
|
||||||
showConfirmModal () {
|
showConfirmModal () {
|
||||||
|
@@ -25,7 +25,8 @@
|
|||||||
</draggable>
|
</draggable>
|
||||||
<li
|
<li
|
||||||
class="settingbar-element btn btn-link ex-tooltip"
|
class="settingbar-element btn btn-link ex-tooltip"
|
||||||
@click="showNewConnModal"
|
:class="{'selected': 'NEW' === selectedWorkspace}"
|
||||||
|
@click="selectWorkspace('NEW')"
|
||||||
@mouseover.self="tooltipPosition"
|
@mouseover.self="tooltipPosition"
|
||||||
>
|
>
|
||||||
<i class="settingbar-element-icon mdi mdi-24px mdi-plus text-light" />
|
<i class="settingbar-element-icon mdi mdi-24px mdi-plus text-light" />
|
||||||
@@ -92,7 +93,6 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
...mapActions({
|
||||||
updateConnections: 'connections/updateConnections',
|
updateConnections: 'connections/updateConnections',
|
||||||
showNewConnModal: 'application/showNewConnModal',
|
|
||||||
showSettingModal: 'application/showSettingModal',
|
showSettingModal: 'application/showSettingModal',
|
||||||
showScratchpad: 'application/showScratchpad',
|
showScratchpad: 'application/showScratchpad',
|
||||||
selectWorkspace: 'workspaces/selectWorkspace'
|
selectWorkspace: 'workspaces/selectWorkspace'
|
||||||
@@ -167,14 +167,13 @@ export default {
|
|||||||
height: $settingbar-width;
|
height: $settingbar-width;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-left: 3px solid transparent;
|
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
transition: opacity 0.2s;
|
transition: opacity 0.2s;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-content: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: flex-start;
|
||||||
flex-direction: column;
|
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@@ -194,12 +193,12 @@ export default {
|
|||||||
width: 3px;
|
width: 3px;
|
||||||
transition: height 0.2s;
|
transition: height 0.2s;
|
||||||
background-color: $primary-color;
|
background-color: $primary-color;
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
.settingbar-element-icon {
|
.settingbar-element-icon {
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
&.badge::after {
|
&.badge::after {
|
||||||
bottom: -10px;
|
bottom: -10px;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@@ -58,6 +58,7 @@ export default {
|
|||||||
}),
|
}),
|
||||||
windowTitle () {
|
windowTitle () {
|
||||||
if (!this.selectedWorkspace) return '';
|
if (!this.selectedWorkspace) return '';
|
||||||
|
if (this.selectedWorkspace === 'NEW') return this.$t('message.createNewConnection');
|
||||||
|
|
||||||
const connectionName = this.getConnectionName(this.selectedWorkspace);
|
const connectionName = this.getConnectionName(this.selectedWorkspace);
|
||||||
const workspace = this.getWorkspace(this.selectedWorkspace);
|
const workspace = this.getWorkspace(this.selectedWorkspace);
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-show="isSelected" class="workspace column columns col-gapless">
|
<div v-show="isSelected" class="workspace column columns col-gapless">
|
||||||
<WorkspaceExploreBar :connection="connection" :is-selected="isSelected" />
|
<WorkspaceExploreBar
|
||||||
|
v-if="workspace.connection_status === 'connected'"
|
||||||
|
:connection="connection"
|
||||||
|
:is-selected="isSelected"
|
||||||
|
/>
|
||||||
<div v-if="workspace.connection_status === 'connected'" class="workspace-tabs column columns col-gapless">
|
<div v-if="workspace.connection_status === 'connected'" class="workspace-tabs column columns col-gapless">
|
||||||
<ul
|
<ul
|
||||||
id="tabWrap"
|
id="tabWrap"
|
||||||
@@ -152,6 +156,7 @@
|
|||||||
:connection="connection"
|
:connection="connection"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<WorkspaceEditConnectionPanel v-else :connection="connection" />
|
||||||
<ModalProcessesList
|
<ModalProcessesList
|
||||||
v-if="isProcessesModal"
|
v-if="isProcessesModal"
|
||||||
:connection="connection"
|
:connection="connection"
|
||||||
@@ -164,6 +169,7 @@
|
|||||||
import { mapGetters, mapActions } from 'vuex';
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
import Connection from '@/ipc-api/Connection';
|
import Connection from '@/ipc-api/Connection';
|
||||||
import WorkspaceExploreBar from '@/components/WorkspaceExploreBar';
|
import WorkspaceExploreBar from '@/components/WorkspaceExploreBar';
|
||||||
|
import WorkspaceEditConnectionPanel from '@/components/WorkspaceEditConnectionPanel';
|
||||||
import WorkspaceQueryTab from '@/components/WorkspaceQueryTab';
|
import WorkspaceQueryTab from '@/components/WorkspaceQueryTab';
|
||||||
import WorkspaceTableTab from '@/components/WorkspaceTableTab';
|
import WorkspaceTableTab from '@/components/WorkspaceTableTab';
|
||||||
import WorkspacePropsTab from '@/components/WorkspacePropsTab';
|
import WorkspacePropsTab from '@/components/WorkspacePropsTab';
|
||||||
@@ -179,6 +185,7 @@ export default {
|
|||||||
name: 'Workspace',
|
name: 'Workspace',
|
||||||
components: {
|
components: {
|
||||||
WorkspaceExploreBar,
|
WorkspaceExploreBar,
|
||||||
|
WorkspaceEditConnectionPanel,
|
||||||
WorkspaceQueryTab,
|
WorkspaceQueryTab,
|
||||||
WorkspaceTableTab,
|
WorkspaceTableTab,
|
||||||
WorkspacePropsTab,
|
WorkspacePropsTab,
|
||||||
|
519
src/renderer/components/WorkspaceAddConnectionPanel.vue
Normal file
519
src/renderer/components/WorkspaceAddConnectionPanel.vue
Normal file
@@ -0,0 +1,519 @@
|
|||||||
|
<template>
|
||||||
|
<div class="connection-panel">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-nav">
|
||||||
|
<ul class="tab tab-block">
|
||||||
|
<li
|
||||||
|
class="tab-item c-hand"
|
||||||
|
:class="{'active': selectedTab === 'general'}"
|
||||||
|
@click="selectTab('general')"
|
||||||
|
>
|
||||||
|
<a class="tab-link">{{ $t('word.general') }}</a>
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
class="tab-item c-hand"
|
||||||
|
:class="{'active': selectedTab === 'ssl'}"
|
||||||
|
@click="selectTab('ssl')"
|
||||||
|
>
|
||||||
|
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
class="tab-item c-hand"
|
||||||
|
:class="{'active': selectedTab === 'ssh'}"
|
||||||
|
@click="selectTab('ssh')"
|
||||||
|
>
|
||||||
|
<a class="tab-link">{{ $t('word.sshTunnel') }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedTab === 'general'" class="panel-body py-0">
|
||||||
|
<div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<fieldset class="m-0" :disabled="isBusy">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.connectionName') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
ref="firstInput"
|
||||||
|
v-model="connection.name"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.client') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<select v-model="connection.client" class="form-select">
|
||||||
|
<option value="mysql">
|
||||||
|
MySQL
|
||||||
|
</option>
|
||||||
|
<option value="maria">
|
||||||
|
MariaDB
|
||||||
|
</option>
|
||||||
|
<option value="pg">
|
||||||
|
PostgreSQL
|
||||||
|
</option>
|
||||||
|
<!-- <option value="mssql">
|
||||||
|
Microsoft SQL
|
||||||
|
</option>
|
||||||
|
<option value="oracledb">
|
||||||
|
Oracle DB
|
||||||
|
</option> -->
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.host"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.port"
|
||||||
|
class="form-input"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
max="65535"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="customizations.database" class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.database') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.database"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.user"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
:disabled="connection.ask"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.password"
|
||||||
|
class="form-input"
|
||||||
|
type="password"
|
||||||
|
:disabled="connection.ask"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="customizations.connectionSchema" class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.schema') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.schema"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('word.all')"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12" />
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<label class="form-checkbox form-inline">
|
||||||
|
<input v-model="connection.ask" type="checkbox"><i class="form-icon" /> {{ $t('message.askCredentials') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedTab === 'ssl'" class="panel-body py-0">
|
||||||
|
<div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">
|
||||||
|
{{ $t('message.enableSsl') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<label class="form-switch d-inline-block" @click.prevent="toggleSsl">
|
||||||
|
<input type="checkbox" :checked="connection.ssl">
|
||||||
|
<i class="form-icon" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<fieldset class="m-0" :disabled="isBusy || !connection.ssl">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.privateKey') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="connection.key"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('key')"
|
||||||
|
@change="pathSelection($event, 'key')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.certificate') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="connection.cert"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('cert')"
|
||||||
|
@change="pathSelection($event, 'cert')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.caCertificate') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="connection.ca"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('ca')"
|
||||||
|
@change="pathSelection($event, 'ca')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.ciphers') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
ref="firstInput"
|
||||||
|
v-model="connection.ciphers"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedTab === 'ssh'" class="panel-body py-0">
|
||||||
|
<div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">
|
||||||
|
{{ $t('message.enableSsh') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<label class="form-switch d-inline-block" @click.prevent="toggleSsh">
|
||||||
|
<input type="checkbox" :checked="connection.ssh">
|
||||||
|
<i class="form-icon" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<fieldset class="m-0" :disabled="isBusy || !connection.ssh">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshHost"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshUser"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshPass"
|
||||||
|
class="form-input"
|
||||||
|
type="password"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshPort"
|
||||||
|
class="form-input"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
max="65535"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.privateKey') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="connection.sshKey"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('sshKey')"
|
||||||
|
@change="pathSelection($event, 'sshKey')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">
|
||||||
|
<button
|
||||||
|
class="btn btn-gray mr-2 d-flex"
|
||||||
|
:class="{'loading': isTesting}"
|
||||||
|
:disabled="isBusy"
|
||||||
|
@click="startTest"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-lightning-bolt mr-1" />
|
||||||
|
{{ $t('message.testConnection') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-primary mr-2 d-flex"
|
||||||
|
:disabled="isBusy"
|
||||||
|
@click="saveConnection"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
|
{{ $t('word.save') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalAskCredentials
|
||||||
|
v-if="isAsking"
|
||||||
|
@close-asking="closeAsking"
|
||||||
|
@credentials="continueTest"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions } from 'vuex';
|
||||||
|
import customizations from 'common/customizations';
|
||||||
|
import Connection from '@/ipc-api/Connection';
|
||||||
|
import { uidGen } from 'common/libs/uidGen';
|
||||||
|
import ModalAskCredentials from '@/components/ModalAskCredentials';
|
||||||
|
import BaseUploadInput from '@/components/BaseUploadInput';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'WorkspaceAddConnectionPanel',
|
||||||
|
components: {
|
||||||
|
ModalAskCredentials,
|
||||||
|
BaseUploadInput
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
connection: {
|
||||||
|
name: '',
|
||||||
|
client: 'mysql',
|
||||||
|
host: '127.0.0.1',
|
||||||
|
database: null,
|
||||||
|
port: null,
|
||||||
|
user: null,
|
||||||
|
password: '',
|
||||||
|
ask: false,
|
||||||
|
uid: uidGen('C'),
|
||||||
|
ssl: false,
|
||||||
|
cert: '',
|
||||||
|
key: '',
|
||||||
|
ca: '',
|
||||||
|
ciphers: '',
|
||||||
|
ssh: false,
|
||||||
|
sshHost: '',
|
||||||
|
sshUser: '',
|
||||||
|
sshPass: '',
|
||||||
|
sshKey: '',
|
||||||
|
sshPort: 22
|
||||||
|
},
|
||||||
|
isConnecting: false,
|
||||||
|
isTesting: false,
|
||||||
|
isAsking: false,
|
||||||
|
selectedTab: 'general'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
customizations () {
|
||||||
|
return customizations[this.connection.client];
|
||||||
|
},
|
||||||
|
isBusy () {
|
||||||
|
return this.isConnecting || this.isTesting;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.setDefaults();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.$refs.firstInput) this.$refs.firstInput.focus();
|
||||||
|
}, 20);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions({
|
||||||
|
addConnection: 'connections/addConnection',
|
||||||
|
connectWorkspace: 'workspaces/connectWorkspace',
|
||||||
|
addNotification: 'notifications/addNotification',
|
||||||
|
selectWorkspace: 'workspaces/selectWorkspace'
|
||||||
|
}),
|
||||||
|
setDefaults () {
|
||||||
|
this.connection.user = this.customizations.defaultUser;
|
||||||
|
this.connection.port = this.customizations.defaultPort;
|
||||||
|
this.connection.database = this.customizations.defaultDatabase;
|
||||||
|
},
|
||||||
|
async startConnection () {
|
||||||
|
await this.saveConnection();
|
||||||
|
this.isConnecting = true;
|
||||||
|
|
||||||
|
if (this.connection.ask)
|
||||||
|
this.isAsking = true;
|
||||||
|
else {
|
||||||
|
await this.connectWorkspace(this.connection);
|
||||||
|
this.isConnecting = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async startTest () {
|
||||||
|
this.isTesting = true;
|
||||||
|
|
||||||
|
if (this.connection.ask)
|
||||||
|
this.isAsking = true;
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
const res = await Connection.makeTest(this.connection);
|
||||||
|
if (res.status === 'error')
|
||||||
|
this.addNotification({ status: 'error', message: res.response.message });
|
||||||
|
else
|
||||||
|
this.addNotification({ status: 'success', message: this.$t('message.connectionSuccessfullyMade') });
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.addNotification({ status: 'error', message: err.stack });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isTesting = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async continueTest (credentials) { // if "Ask for credentials" is true
|
||||||
|
this.isAsking = false;
|
||||||
|
const params = Object.assign({}, this.connection, credentials);
|
||||||
|
try {
|
||||||
|
if (this.isConnecting) {
|
||||||
|
const params = Object.assign({}, this.connection, credentials);
|
||||||
|
await this.connectWorkspace(params);
|
||||||
|
this.isConnecting = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const res = await Connection.makeTest(params);
|
||||||
|
if (res.status === 'error')
|
||||||
|
this.addNotification({ status: 'error', message: res.response.message });
|
||||||
|
else
|
||||||
|
this.addNotification({ status: 'success', message: this.$t('message.connectionSuccessfullyMade') });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.addNotification({ status: 'error', message: err.stack });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isTesting = false;
|
||||||
|
},
|
||||||
|
saveConnection () {
|
||||||
|
this.selectWorkspace(this.connection.uid);
|
||||||
|
return this.addConnection(this.connection);
|
||||||
|
},
|
||||||
|
closeAsking () {
|
||||||
|
this.isTesting = false;
|
||||||
|
this.isAsking = false;
|
||||||
|
},
|
||||||
|
selectTab (tab) {
|
||||||
|
this.selectedTab = tab;
|
||||||
|
},
|
||||||
|
toggleSsl () {
|
||||||
|
this.connection.ssl = !this.connection.ssl;
|
||||||
|
},
|
||||||
|
toggleSsh () {
|
||||||
|
this.connection.ssh = !this.connection.ssh;
|
||||||
|
},
|
||||||
|
pathSelection (event, name) {
|
||||||
|
const { files } = event.target;
|
||||||
|
if (!files.length) return;
|
||||||
|
|
||||||
|
this.connection[name] = files[0].path;
|
||||||
|
},
|
||||||
|
pathClear (name) {
|
||||||
|
this.connection[name] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.connection-panel {
|
||||||
|
margin-top: 15vh;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
width: 450px;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
flex: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
500
src/renderer/components/WorkspaceEditConnectionPanel.vue
Normal file
500
src/renderer/components/WorkspaceEditConnectionPanel.vue
Normal file
@@ -0,0 +1,500 @@
|
|||||||
|
<template>
|
||||||
|
<div class="connection-panel">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-nav">
|
||||||
|
<ul class="tab tab-block">
|
||||||
|
<li
|
||||||
|
class="tab-item c-hand"
|
||||||
|
:class="{'active': selectedTab === 'general'}"
|
||||||
|
@click="selectTab('general')"
|
||||||
|
>
|
||||||
|
<a class="tab-link">{{ $t('word.general') }}</a>
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
class="tab-item c-hand"
|
||||||
|
:class="{'active': selectedTab === 'ssl'}"
|
||||||
|
@click="selectTab('ssl')"
|
||||||
|
>
|
||||||
|
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||||
|
</li>
|
||||||
|
<li
|
||||||
|
class="tab-item c-hand"
|
||||||
|
:class="{'active': selectedTab === 'ssh'}"
|
||||||
|
@click="selectTab('ssh')"
|
||||||
|
>
|
||||||
|
<a class="tab-link">{{ $t('word.sshTunnel') }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedTab === 'general'" class="panel-body py-0">
|
||||||
|
<div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<fieldset class="m-0" :disabled="isBusy">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.connectionName') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
ref="firstInput"
|
||||||
|
v-model="localConnection.name"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.client') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<select v-model="localConnection.client" class="form-select">
|
||||||
|
<option value="mysql">
|
||||||
|
MySQL
|
||||||
|
</option>
|
||||||
|
<option value="maria">
|
||||||
|
MariaDB
|
||||||
|
</option>
|
||||||
|
<option value="pg">
|
||||||
|
PostgreSQL
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.host"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.port"
|
||||||
|
class="form-input"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
max="65535"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="customizations.database" class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.database') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.database"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.user"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
:disabled="localConnection.ask"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.password"
|
||||||
|
class="form-input"
|
||||||
|
type="password"
|
||||||
|
:disabled="localConnection.ask"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="customizations.connectionSchema" class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.schema') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.schema"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('word.all')"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12" />
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<label class="form-checkbox form-inline">
|
||||||
|
<input v-model="localConnection.ask" type="checkbox"><i class="form-icon" /> {{ $t('message.askCredentials') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedTab === 'ssl'" class="panel-body py-0">
|
||||||
|
<div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">
|
||||||
|
{{ $t('message.enableSsl') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<label class="form-switch d-inline-block" @click.prevent="toggleSsl">
|
||||||
|
<input type="checkbox" :checked="localConnection.ssl">
|
||||||
|
<i class="form-icon" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<fieldset class="m-0" :disabled="isBusy || !localConnection.ssl">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.privateKey') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="localConnection.key"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('key')"
|
||||||
|
@change="pathSelection($event, 'key')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.certificate') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="localConnection.cert"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('cert')"
|
||||||
|
@change="pathSelection($event, 'cert')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.caCertificate') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="localConnection.ca"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('ca')"
|
||||||
|
@change="pathSelection($event, 'ca')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.ciphers') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
ref="firstInput"
|
||||||
|
v-model="localConnection.ciphers"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="selectedTab === 'ssh'" class="panel-body py-0">
|
||||||
|
<div>
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">
|
||||||
|
{{ $t('message.enableSsh') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<label class="form-switch d-inline-block" @click.prevent="toggleSsh">
|
||||||
|
<input type="checkbox" :checked="localConnection.ssh">
|
||||||
|
<i class="form-icon" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<fieldset class="m-0" :disabled="isBusy || !localConnection.ssh">
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshHost"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshUser"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshPass"
|
||||||
|
class="form-input"
|
||||||
|
type="password"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshPort"
|
||||||
|
class="form-input"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
max="65535"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.privateKey') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="localConnection.sshKey"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('sshKey')"
|
||||||
|
@change="pathSelection($event, 'sshKey')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer">
|
||||||
|
<button
|
||||||
|
class="btn btn-gray mr-2 d-flex"
|
||||||
|
:class="{'loading': isTesting}"
|
||||||
|
:disabled="isBusy"
|
||||||
|
@click="startTest"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-lightning-bolt mr-1" />
|
||||||
|
{{ $t('message.testConnection') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-primary mr-2 d-flex"
|
||||||
|
:disabled="isBusy || !hasChanges"
|
||||||
|
@click="saveConnection"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
|
{{ $t('word.save') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-success d-flex"
|
||||||
|
:class="{'loading': isConnecting}"
|
||||||
|
:disabled="isBusy"
|
||||||
|
@click="startConnection"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-connection mr-1" />
|
||||||
|
{{ $t('word.connect') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ModalAskCredentials
|
||||||
|
v-if="isAsking"
|
||||||
|
@close-asking="closeAsking"
|
||||||
|
@credentials="continueTest"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions } from 'vuex';
|
||||||
|
import customizations from 'common/customizations';
|
||||||
|
import Connection from '@/ipc-api/Connection';
|
||||||
|
import ModalAskCredentials from '@/components/ModalAskCredentials';
|
||||||
|
import BaseUploadInput from '@/components/BaseUploadInput';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'WorkspaceEditConnectionPanel',
|
||||||
|
components: {
|
||||||
|
ModalAskCredentials,
|
||||||
|
BaseUploadInput
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
connection: Object
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
isConnecting: false,
|
||||||
|
isTesting: false,
|
||||||
|
isAsking: false,
|
||||||
|
localConnection: null,
|
||||||
|
selectedTab: 'general'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
customizations () {
|
||||||
|
return customizations[this.connection.client];
|
||||||
|
},
|
||||||
|
isBusy () {
|
||||||
|
return this.isConnecting || this.isTesting;
|
||||||
|
},
|
||||||
|
hasChanges () {
|
||||||
|
return JSON.stringify(this.connection) !== JSON.stringify(this.localConnection);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
connection () {
|
||||||
|
this.localConnection = JSON.parse(JSON.stringify(this.connection));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.localConnection = JSON.parse(JSON.stringify(this.connection));
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions({
|
||||||
|
editConnection: 'connections/editConnection',
|
||||||
|
connectWorkspace: 'workspaces/connectWorkspace',
|
||||||
|
addNotification: 'notifications/addNotification'
|
||||||
|
}),
|
||||||
|
async startConnection () {
|
||||||
|
await this.saveConnection();
|
||||||
|
this.isConnecting = true;
|
||||||
|
|
||||||
|
if (this.localConnection.ask)
|
||||||
|
this.isAsking = true;
|
||||||
|
else {
|
||||||
|
await this.connectWorkspace(this.localConnection);
|
||||||
|
this.isConnecting = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async startTest () {
|
||||||
|
this.isTesting = true;
|
||||||
|
|
||||||
|
if (this.localConnection.ask)
|
||||||
|
this.isAsking = true;
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
const res = await Connection.makeTest(this.localConnection);
|
||||||
|
if (res.status === 'error')
|
||||||
|
this.addNotification({ status: 'error', message: res.response.message });
|
||||||
|
else
|
||||||
|
this.addNotification({ status: 'success', message: this.$t('message.connectionSuccessfullyMade') });
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.addNotification({ status: 'error', message: err.stack });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isTesting = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async continueTest (credentials) { // if "Ask for credentials" is true
|
||||||
|
this.isAsking = false;
|
||||||
|
const params = Object.assign({}, this.localConnection, credentials);
|
||||||
|
try {
|
||||||
|
if (this.isConnecting) {
|
||||||
|
const params = Object.assign({}, this.connection, credentials);
|
||||||
|
await this.connectWorkspace(params);
|
||||||
|
this.isConnecting = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const res = await Connection.makeTest(params);
|
||||||
|
if (res.status === 'error')
|
||||||
|
this.addNotification({ status: 'error', message: res.response.message });
|
||||||
|
else
|
||||||
|
this.addNotification({ status: 'success', message: this.$t('message.connectionSuccessfullyMade') });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
this.addNotification({ status: 'error', message: err.stack });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isTesting = false;
|
||||||
|
},
|
||||||
|
saveConnection () {
|
||||||
|
return this.editConnection(this.localConnection);
|
||||||
|
},
|
||||||
|
closeAsking () {
|
||||||
|
this.isTesting = false;
|
||||||
|
this.isAsking = false;
|
||||||
|
},
|
||||||
|
selectTab (tab) {
|
||||||
|
this.selectedTab = tab;
|
||||||
|
},
|
||||||
|
toggleSsl () {
|
||||||
|
this.localConnection.ssl = !this.localConnection.ssl;
|
||||||
|
},
|
||||||
|
toggleSsh () {
|
||||||
|
this.localConnection.ssh = !this.localConnection.ssh;
|
||||||
|
},
|
||||||
|
pathSelection (event, name) {
|
||||||
|
const { files } = event.target;
|
||||||
|
if (!files.length) return;
|
||||||
|
|
||||||
|
this.localConnection[name] = files[0].path;
|
||||||
|
},
|
||||||
|
pathClear (name) {
|
||||||
|
this.localConnection[name] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.connection-panel {
|
||||||
|
margin-top: 15vh;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
width: 450px;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
flex: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -38,12 +38,7 @@
|
|||||||
<i class="form-icon mdi mdi-magnify mdi-18px" />
|
<i class="form-icon mdi mdi-magnify mdi-18px" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<WorkspaceConnectPanel
|
<div class="workspace-explorebar-body">
|
||||||
v-if="workspace.connection_status !== 'connected'"
|
|
||||||
class="workspace-explorebar-body"
|
|
||||||
:connection="connection"
|
|
||||||
/>
|
|
||||||
<div v-else class="workspace-explorebar-body">
|
|
||||||
<WorkspaceExploreBarSchema
|
<WorkspaceExploreBarSchema
|
||||||
v-for="db of workspace.structure"
|
v-for="db of workspace.structure"
|
||||||
:key="db.name"
|
:key="db.name"
|
||||||
@@ -52,6 +47,7 @@
|
|||||||
@show-schema-context="openSchemaContext"
|
@show-schema-context="openSchemaContext"
|
||||||
@show-table-context="openTableContext"
|
@show-table-context="openTableContext"
|
||||||
@show-misc-context="openMiscContext"
|
@show-misc-context="openMiscContext"
|
||||||
|
@show-misc-folder-context="openMiscFolderContext"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -130,6 +126,18 @@
|
|||||||
@close-context="closeMiscContext"
|
@close-context="closeMiscContext"
|
||||||
@reload="refresh"
|
@reload="refresh"
|
||||||
/>
|
/>
|
||||||
|
<MiscFolderContext
|
||||||
|
v-if="isMiscFolderContext"
|
||||||
|
:selected-misc="selectedMisc"
|
||||||
|
:context-event="miscContextEvent"
|
||||||
|
@show-create-trigger-modal="showCreateTriggerModal"
|
||||||
|
@show-create-routine-modal="showCreateRoutineModal"
|
||||||
|
@show-create-function-modal="showCreateFunctionModal"
|
||||||
|
@show-create-trigger-function-modal="showCreateTriggerFunctionModal"
|
||||||
|
@show-create-scheduler-modal="showCreateSchedulerModal"
|
||||||
|
@close-context="closeMiscFolderContext"
|
||||||
|
@reload="refresh"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -143,11 +151,11 @@ import Routines from '@/ipc-api/Routines';
|
|||||||
import Functions from '@/ipc-api/Functions';
|
import Functions from '@/ipc-api/Functions';
|
||||||
import Schedulers from '@/ipc-api/Schedulers';
|
import Schedulers from '@/ipc-api/Schedulers';
|
||||||
|
|
||||||
import WorkspaceConnectPanel from '@/components/WorkspaceConnectPanel';
|
|
||||||
import WorkspaceExploreBarSchema from '@/components/WorkspaceExploreBarSchema';
|
import WorkspaceExploreBarSchema from '@/components/WorkspaceExploreBarSchema';
|
||||||
import DatabaseContext from '@/components/WorkspaceExploreBarSchemaContext';
|
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 MiscFolderContext from '@/components/WorkspaceExploreBarMiscFolderContext';
|
||||||
import ModalNewSchema from '@/components/ModalNewSchema';
|
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';
|
||||||
@@ -160,11 +168,11 @@ import ModalNewScheduler from '@/components/ModalNewScheduler';
|
|||||||
export default {
|
export default {
|
||||||
name: 'WorkspaceExploreBar',
|
name: 'WorkspaceExploreBar',
|
||||||
components: {
|
components: {
|
||||||
WorkspaceConnectPanel,
|
|
||||||
WorkspaceExploreBarSchema,
|
WorkspaceExploreBarSchema,
|
||||||
DatabaseContext,
|
DatabaseContext,
|
||||||
TableContext,
|
TableContext,
|
||||||
MiscContext,
|
MiscContext,
|
||||||
|
MiscFolderContext,
|
||||||
ModalNewSchema,
|
ModalNewSchema,
|
||||||
ModalNewTable,
|
ModalNewTable,
|
||||||
ModalNewView,
|
ModalNewView,
|
||||||
@@ -197,6 +205,7 @@ export default {
|
|||||||
isDatabaseContext: false,
|
isDatabaseContext: false,
|
||||||
isTableContext: false,
|
isTableContext: false,
|
||||||
isMiscContext: false,
|
isMiscContext: false,
|
||||||
|
isMiscFolderContext: false,
|
||||||
|
|
||||||
databaseContextEvent: null,
|
databaseContextEvent: null,
|
||||||
tableContextEvent: null,
|
tableContextEvent: null,
|
||||||
@@ -333,11 +342,20 @@ export default {
|
|||||||
this.miscContextEvent = payload.event;
|
this.miscContextEvent = payload.event;
|
||||||
this.isMiscContext = true;
|
this.isMiscContext = true;
|
||||||
},
|
},
|
||||||
|
openMiscFolderContext (payload) {
|
||||||
|
this.selectedMisc = payload.type;
|
||||||
|
this.miscContextEvent = payload.event;
|
||||||
|
this.isMiscFolderContext = true;
|
||||||
|
},
|
||||||
closeMiscContext () {
|
closeMiscContext () {
|
||||||
this.isMiscContext = false;
|
this.isMiscContext = false;
|
||||||
},
|
},
|
||||||
|
closeMiscFolderContext () {
|
||||||
|
this.isMiscFolderContext = false;
|
||||||
|
},
|
||||||
showCreateViewModal () {
|
showCreateViewModal () {
|
||||||
this.closeDatabaseContext();
|
this.closeDatabaseContext();
|
||||||
|
this.closeMiscFolderContext();
|
||||||
this.isNewViewModal = true;
|
this.isNewViewModal = true;
|
||||||
},
|
},
|
||||||
hideCreateViewModal () {
|
hideCreateViewModal () {
|
||||||
@@ -361,6 +379,7 @@ export default {
|
|||||||
},
|
},
|
||||||
showCreateTriggerModal () {
|
showCreateTriggerModal () {
|
||||||
this.closeDatabaseContext();
|
this.closeDatabaseContext();
|
||||||
|
this.closeMiscFolderContext();
|
||||||
this.isNewTriggerModal = true;
|
this.isNewTriggerModal = true;
|
||||||
},
|
},
|
||||||
hideCreateTriggerModal () {
|
hideCreateTriggerModal () {
|
||||||
@@ -385,6 +404,7 @@ export default {
|
|||||||
},
|
},
|
||||||
showCreateRoutineModal () {
|
showCreateRoutineModal () {
|
||||||
this.closeDatabaseContext();
|
this.closeDatabaseContext();
|
||||||
|
this.closeMiscFolderContext();
|
||||||
this.isNewRoutineModal = true;
|
this.isNewRoutineModal = true;
|
||||||
},
|
},
|
||||||
hideCreateRoutineModal () {
|
hideCreateRoutineModal () {
|
||||||
@@ -408,6 +428,7 @@ export default {
|
|||||||
},
|
},
|
||||||
showCreateFunctionModal () {
|
showCreateFunctionModal () {
|
||||||
this.closeDatabaseContext();
|
this.closeDatabaseContext();
|
||||||
|
this.closeMiscFolderContext();
|
||||||
this.isNewFunctionModal = true;
|
this.isNewFunctionModal = true;
|
||||||
},
|
},
|
||||||
hideCreateFunctionModal () {
|
hideCreateFunctionModal () {
|
||||||
@@ -415,6 +436,7 @@ export default {
|
|||||||
},
|
},
|
||||||
showCreateTriggerFunctionModal () {
|
showCreateTriggerFunctionModal () {
|
||||||
this.closeDatabaseContext();
|
this.closeDatabaseContext();
|
||||||
|
this.closeMiscFolderContext();
|
||||||
this.isNewTriggerFunctionModal = true;
|
this.isNewTriggerFunctionModal = true;
|
||||||
},
|
},
|
||||||
hideCreateTriggerFunctionModal () {
|
hideCreateTriggerFunctionModal () {
|
||||||
@@ -422,6 +444,7 @@ export default {
|
|||||||
},
|
},
|
||||||
showCreateSchedulerModal () {
|
showCreateSchedulerModal () {
|
||||||
this.closeDatabaseContext();
|
this.closeDatabaseContext();
|
||||||
|
this.closeMiscFolderContext();
|
||||||
this.isNewSchedulerModal = true;
|
this.isNewSchedulerModal = true;
|
||||||
},
|
},
|
||||||
hideCreateSchedulerModal () {
|
hideCreateSchedulerModal () {
|
||||||
|
@@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<BaseContextMenu
|
||||||
|
:context-event="contextEvent"
|
||||||
|
@close-context="closeContext"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-if="selectedMisc === 'trigger'"
|
||||||
|
class="context-element"
|
||||||
|
@click="$emit('show-create-trigger-modal')"
|
||||||
|
>
|
||||||
|
<span class="d-flex"><i class="mdi mdi-18px mdi-table-cog text-light pr-1" /> {{ $t('message.createNewTrigger') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="selectedMisc === 'procedure'"
|
||||||
|
class="context-element"
|
||||||
|
@click="$emit('show-create-routine-modal')"
|
||||||
|
>
|
||||||
|
<span class="d-flex"><i class="mdi mdi-18px mdi-sync-circle text-light pr-1" /> {{ $t('message.createNewRoutine') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="selectedMisc === 'function'"
|
||||||
|
class="context-element"
|
||||||
|
@click="$emit('show-create-function-modal')"
|
||||||
|
>
|
||||||
|
<span class="d-flex"><i class="mdi mdi-18px mdi-arrow-right-bold-box text-light pr-1" /> {{ $t('message.createNewFunction') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="selectedMisc === 'triggerFunction'"
|
||||||
|
class="context-element"
|
||||||
|
@click="$emit('show-create-trigger-function-modal')"
|
||||||
|
>
|
||||||
|
<span class="d-flex"><i class="mdi mdi-18px mdi-cog-clockwise text-light pr-1" /> {{ $t('message.createNewFunction') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="selectedMisc === 'scheduler'"
|
||||||
|
class="context-element"
|
||||||
|
@click="$emit('show-create-scheduler-modal')"
|
||||||
|
>
|
||||||
|
<span class="d-flex"><i class="mdi mdi-18px mdi-calendar-clock text-light pr-1" /> {{ $t('message.createNewScheduler') }}</span>
|
||||||
|
</div>
|
||||||
|
</BaseContextMenu>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters, mapActions } from 'vuex';
|
||||||
|
import BaseContextMenu from '@/components/BaseContextMenu';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'WorkspaceExploreBarMiscContext',
|
||||||
|
components: {
|
||||||
|
BaseContextMenu
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
contextEvent: MouseEvent,
|
||||||
|
selectedMisc: String
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
localElement: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
selectedWorkspace: 'workspaces/getSelected',
|
||||||
|
getWorkspace: 'workspaces/getWorkspace'
|
||||||
|
}),
|
||||||
|
workspace () {
|
||||||
|
return this.getWorkspace(this.selectedWorkspace);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions({
|
||||||
|
addNotification: 'notifications/addNotification',
|
||||||
|
changeBreadcrumbs: 'workspaces/changeBreadcrumbs'
|
||||||
|
}),
|
||||||
|
showCreateTableModal () {
|
||||||
|
this.$emit('show-create-table-modal');
|
||||||
|
},
|
||||||
|
showDeleteModal () {
|
||||||
|
this.isDeleteModal = true;
|
||||||
|
},
|
||||||
|
hideDeleteModal () {
|
||||||
|
this.isDeleteModal = false;
|
||||||
|
},
|
||||||
|
showAskParamsModal () {
|
||||||
|
this.isAskingParameters = true;
|
||||||
|
},
|
||||||
|
hideAskParamsModal () {
|
||||||
|
this.isAskingParameters = false;
|
||||||
|
this.closeContext();
|
||||||
|
},
|
||||||
|
closeContext () {
|
||||||
|
this.$emit('close-context');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
@@ -39,7 +39,11 @@
|
|||||||
|
|
||||||
<div v-if="filteredTriggers.length && customizations.triggers" 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}"
|
||||||
|
@contextmenu.prevent="showMiscFolderContext($event, '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" />
|
||||||
{{ $tc('word.trigger', 2) }}
|
{{ $tc('word.trigger', 2) }}
|
||||||
</summary>
|
</summary>
|
||||||
@@ -67,7 +71,11 @@
|
|||||||
|
|
||||||
<div v-if="filteredProcedures.length && customizations.routines" 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}"
|
||||||
|
@contextmenu.prevent="showMiscFolderContext($event, '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" />
|
||||||
{{ $tc('word.storedRoutine', 2) }}
|
{{ $tc('word.storedRoutine', 2) }}
|
||||||
</summary>
|
</summary>
|
||||||
@@ -95,7 +103,11 @@
|
|||||||
|
|
||||||
<div v-if="filteredTriggerFunctions.length && customizations.triggerFunctions" class="database-misc">
|
<div v-if="filteredTriggerFunctions.length && customizations.triggerFunctions" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.triggerFunction}">
|
<summary
|
||||||
|
class="accordion-header misc-name"
|
||||||
|
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.triggerFunction}"
|
||||||
|
@contextmenu.prevent="showMiscFolderContext($event, 'triggerFunction')"
|
||||||
|
>
|
||||||
<i class="misc-icon mdi mdi-18px mdi-folder-refresh mr-1" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-refresh mr-1" />
|
||||||
{{ $tc('word.triggerFunction', 2) }}
|
{{ $tc('word.triggerFunction', 2) }}
|
||||||
</summary>
|
</summary>
|
||||||
@@ -123,7 +135,11 @@
|
|||||||
|
|
||||||
<div v-if="filteredFunctions.length && customizations.functions" 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}"
|
||||||
|
@contextmenu.prevent="showMiscFolderContext($event, '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" />
|
||||||
{{ $tc('word.function', 2) }}
|
{{ $tc('word.function', 2) }}
|
||||||
</summary>
|
</summary>
|
||||||
@@ -151,7 +167,11 @@
|
|||||||
|
|
||||||
<div v-if="filteredSchedulers.length && customizations.schedulers" 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}"
|
||||||
|
@contextmenu.prevent="showMiscFolderContext($event, '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" />
|
||||||
{{ $tc('word.scheduler', 2) }}
|
{{ $tc('word.scheduler', 2) }}
|
||||||
</summary>
|
</summary>
|
||||||
@@ -251,7 +271,7 @@ export default {
|
|||||||
}),
|
}),
|
||||||
formatBytes,
|
formatBytes,
|
||||||
async selectSchema (schema) {
|
async selectSchema (schema) {
|
||||||
if (!this.loadedSchemas.has(schema)) {
|
if (!this.loadedSchemas.has(schema) && !this.isLoading) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
await this.refreshSchema({ uid: this.connection.uid, schema });
|
await this.refreshSchema({ uid: this.connection.uid, schema });
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
@@ -271,6 +291,11 @@ export default {
|
|||||||
this.setBreadcrumbs({ schema: this.database.name, [misc.type]: misc.name });
|
this.setBreadcrumbs({ schema: this.database.name, [misc.type]: misc.name });
|
||||||
this.$emit('show-misc-context', { event, misc });
|
this.$emit('show-misc-context', { event, misc });
|
||||||
},
|
},
|
||||||
|
showMiscFolderContext (event, type) {
|
||||||
|
this.selectSchema(this.database.name);
|
||||||
|
this.setBreadcrumbs({ schema: this.database.name, type });
|
||||||
|
this.$emit('show-misc-folder-context', { event, type });
|
||||||
|
},
|
||||||
piePercentage (val) {
|
piePercentage (val) {
|
||||||
const perc = val / this.maxSize * 100;
|
const perc = val / this.maxSize * 100;
|
||||||
if (this.applicationTheme === 'dark')
|
if (this.applicationTheme === 'dark')
|
||||||
|
@@ -19,8 +19,8 @@
|
|||||||
<div class="panel-header pt-0 pl-0">
|
<div class="panel-header pt-0 pl-0">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<button class="btn btn-dark btn-sm d-flex" @click="addForeign">
|
<button class="btn btn-dark btn-sm d-flex" @click="addForeign">
|
||||||
|
<i class="mdi mdi-24px mdi-link-plus mr-1" />
|
||||||
<span>{{ $t('word.add') }}</span>
|
<span>{{ $t('word.add') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-link-plus ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@click.prevent="clearChanges"
|
@click.prevent="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -19,8 +19,8 @@
|
|||||||
<div class="panel-header pt-0 pl-0">
|
<div class="panel-header pt-0 pl-0">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<button class="btn btn-dark btn-sm d-flex" @click="addParameter">
|
<button class="btn btn-dark btn-sm d-flex" @click="addParameter">
|
||||||
|
<i class="mdi mdi-24px mdi-plus mr-1" />
|
||||||
<span>{{ $t('word.add') }}</span>
|
<span>{{ $t('word.add') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-plus ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@click.prevent="clearChanges"
|
@click.prevent="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -19,8 +19,8 @@
|
|||||||
<div class="panel-header pt-0 pl-0">
|
<div class="panel-header pt-0 pl-0">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<button class="btn btn-dark btn-sm d-flex" @click="addIndex">
|
<button class="btn btn-dark btn-sm d-flex" @click="addIndex">
|
||||||
|
<i class="mdi mdi-24px mdi-key-plus mr-1" />
|
||||||
<span>{{ $t('word.add') }}</span>
|
<span>{{ $t('word.add') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-key-plus ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@click.prevent="clearChanges"
|
@click.prevent="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -19,8 +19,8 @@
|
|||||||
<div class="panel-header pt-0 pl-0">
|
<div class="panel-header pt-0 pl-0">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<button class="btn btn-dark btn-sm d-flex" @click="addParameter">
|
<button class="btn btn-dark btn-sm d-flex" @click="addParameter">
|
||||||
|
<i class="mdi mdi-24px mdi-plus mr-1" />
|
||||||
<span>{{ $t('word.add') }}</span>
|
<span>{{ $t('word.add') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-plus ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
class="btn btn-dark btn-sm d-flex ml-2 mr-0"
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@click.prevent="clearChanges"
|
@click.prevent="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
title="CTRL+S"
|
title="CTRL+S"
|
||||||
@click="saveChanges"
|
@click="saveChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
<span>{{ $t('word.save') }}</span>
|
<span>{{ $t('word.save') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-content-save ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
:title="$t('message.clearChanges')"
|
:title="$t('message.clearChanges')"
|
||||||
@click="clearChanges"
|
@click="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="divider-vert py-3" />
|
<div class="divider-vert py-3" />
|
||||||
@@ -30,24 +30,24 @@
|
|||||||
:title="$t('message.addNewField')"
|
:title="$t('message.addNewField')"
|
||||||
@click="addField"
|
@click="addField"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-playlist-plus mr-1" />
|
||||||
<span>{{ $t('word.add') }}</span>
|
<span>{{ $t('word.add') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-playlist-plus ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-dark btn-sm"
|
class="btn btn-dark btn-sm"
|
||||||
:title="$t('message.manageIndexes')"
|
:title="$t('message.manageIndexes')"
|
||||||
@click="showIntdexesModal"
|
@click="showIntdexesModal"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-key mdi-rotate-45 mr-1" />
|
||||||
<span>{{ $t('word.indexes') }}</span>
|
<span>{{ $t('word.indexes') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-key mdi-rotate-45 ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-dark btn-sm" @click="showForeignModal">
|
<button class="btn btn-dark btn-sm" @click="showForeignModal">
|
||||||
|
<i class="mdi mdi-24px mdi-key-link mr-1" />
|
||||||
<span>{{ $t('word.foreignKeys') }}</span>
|
<span>{{ $t('word.foreignKeys') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-key-link ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
||||||
|
<i class="mdi mdi-24px mdi-cogs mr-1" />
|
||||||
<span>{{ $t('word.options') }}</span>
|
<span>{{ $t('word.options') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-cogs ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
title="CTRL+S"
|
title="CTRL+S"
|
||||||
@click="saveChanges"
|
@click="saveChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
<span>{{ $t('word.save') }}</span>
|
<span>{{ $t('word.save') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-content-save ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
:title="$t('message.clearChanges')"
|
:title="$t('message.clearChanges')"
|
||||||
@click="clearChanges"
|
@click="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="divider-vert py-3" />
|
<div class="divider-vert py-3" />
|
||||||
@@ -30,16 +30,16 @@
|
|||||||
:disabled="isChanged"
|
:disabled="isChanged"
|
||||||
@click="runFunctionCheck"
|
@click="runFunctionCheck"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-play mr-1" />
|
||||||
<span>{{ $t('word.run') }}</span>
|
<span>{{ $t('word.run') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-play ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
||||||
|
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||||
<span>{{ $t('word.parameters') }}</span>
|
<span>{{ $t('word.parameters') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-dots-horizontal ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
||||||
|
<i class="mdi mdi-24px mdi-cogs mr-1" />
|
||||||
<span>{{ $t('word.options') }}</span>
|
<span>{{ $t('word.options') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-cogs ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
title="CTRL+S"
|
title="CTRL+S"
|
||||||
@click="saveChanges"
|
@click="saveChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
<span>{{ $t('word.save') }}</span>
|
<span>{{ $t('word.save') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-content-save ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
:title="$t('message.clearChanges')"
|
:title="$t('message.clearChanges')"
|
||||||
@click="clearChanges"
|
@click="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="divider-vert py-3" />
|
<div class="divider-vert py-3" />
|
||||||
@@ -30,16 +30,16 @@
|
|||||||
:disabled="isChanged"
|
:disabled="isChanged"
|
||||||
@click="runRoutineCheck"
|
@click="runRoutineCheck"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-play mr-1" />
|
||||||
<span>{{ $t('word.run') }}</span>
|
<span>{{ $t('word.run') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-play ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
<button class="btn btn-dark btn-sm" @click="showParamsModal">
|
||||||
|
<i class="mdi mdi-24px mdi-dots-horizontal mr-1" />
|
||||||
<span>{{ $t('word.parameters') }}</span>
|
<span>{{ $t('word.parameters') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-dots-horizontal ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
||||||
|
<i class="mdi mdi-24px mdi-cogs mr-1" />
|
||||||
<span>{{ $t('word.options') }}</span>
|
<span>{{ $t('word.options') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-cogs ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
title="CTRL+S"
|
title="CTRL+S"
|
||||||
@click="saveChanges"
|
@click="saveChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
<span>{{ $t('word.save') }}</span>
|
<span>{{ $t('word.save') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-content-save ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@@ -19,14 +19,14 @@
|
|||||||
:title="$t('message.clearChanges')"
|
:title="$t('message.clearChanges')"
|
||||||
@click="clearChanges"
|
@click="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="divider-vert py-3" />
|
<div class="divider-vert py-3" />
|
||||||
<button class="btn btn-dark btn-sm" @click="showTimingModal">
|
<button class="btn btn-dark btn-sm" @click="showTimingModal">
|
||||||
|
<i class="mdi mdi-24px mdi-timer mr-1" />
|
||||||
<span>{{ $t('word.timing') }}</span>
|
<span>{{ $t('word.timing') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-timer ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
title="CTRL+S"
|
title="CTRL+S"
|
||||||
@click="saveChanges"
|
@click="saveChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
<span>{{ $t('word.save') }}</span>
|
<span>{{ $t('word.save') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-content-save ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
:title="$t('message.clearChanges')"
|
:title="$t('message.clearChanges')"
|
||||||
@click="clearChanges"
|
@click="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
title="CTRL+S"
|
title="CTRL+S"
|
||||||
@click="saveChanges"
|
@click="saveChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
<span>{{ $t('word.save') }}</span>
|
<span>{{ $t('word.save') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-content-save ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@@ -19,15 +19,15 @@
|
|||||||
:title="$t('message.clearChanges')"
|
:title="$t('message.clearChanges')"
|
||||||
@click="clearChanges"
|
@click="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="divider-vert py-3" />
|
<div class="divider-vert py-3" />
|
||||||
|
|
||||||
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
<button class="btn btn-dark btn-sm" @click="showOptionsModal">
|
||||||
|
<i class="mdi mdi-24px mdi-cogs mr-1" />
|
||||||
<span>{{ $t('word.options') }}</span>
|
<span>{{ $t('word.options') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-cogs ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,8 +10,8 @@
|
|||||||
title="CTRL+S"
|
title="CTRL+S"
|
||||||
@click="saveChanges"
|
@click="saveChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-content-save mr-1" />
|
||||||
<span>{{ $t('word.save') }}</span>
|
<span>{{ $t('word.save') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-content-save ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:disabled="!isChanged"
|
:disabled="!isChanged"
|
||||||
@@ -19,8 +19,8 @@
|
|||||||
:title="$t('message.clearChanges')"
|
:title="$t('message.clearChanges')"
|
||||||
@click="clearChanges"
|
@click="clearChanges"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep mr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -28,8 +28,8 @@
|
|||||||
title="F5"
|
title="F5"
|
||||||
@click="runQuery(query)"
|
@click="runQuery(query)"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-play pr-1" />
|
||||||
<span>{{ $t('word.run') }}</span>
|
<span>{{ $t('word.run') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-play" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-dark btn-sm"
|
class="btn btn-dark btn-sm"
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
title="CTRL+F8"
|
title="CTRL+F8"
|
||||||
@click="beautify()"
|
@click="beautify()"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-brush pr-1" />
|
||||||
<span>{{ $t('word.format') }}</span>
|
<span>{{ $t('word.format') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-brush pl-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn btn-link btn-sm"
|
class="btn btn-link btn-sm"
|
||||||
@@ -46,8 +46,8 @@
|
|||||||
title="CTRL+W"
|
title="CTRL+W"
|
||||||
@click="clear()"
|
@click="clear()"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-delete-sweep pr-1" />
|
||||||
<span>{{ $t('word.clear') }}</span>
|
<span>{{ $t('word.clear') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-delete-sweep pl-1" />
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="divider-vert py-3" />
|
<div class="divider-vert py-3" />
|
||||||
@@ -58,8 +58,8 @@
|
|||||||
class="btn btn-dark btn-sm dropdown-toggle mr-0 pr-0"
|
class="btn btn-dark btn-sm dropdown-toggle mr-0 pr-0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||||
<span>{{ $t('word.export') }}</span>
|
<span>{{ $t('word.export') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-file-export ml-1" />
|
|
||||||
<i class="mdi mdi-24px mdi-menu-down" />
|
<i class="mdi mdi-24px mdi-menu-down" />
|
||||||
</button>
|
</button>
|
||||||
<ul class="menu text-left">
|
<ul class="menu text-left">
|
||||||
|
@@ -11,9 +11,9 @@
|
|||||||
title="F5"
|
title="F5"
|
||||||
@click="reloadTable"
|
@click="reloadTable"
|
||||||
>
|
>
|
||||||
|
<i v-if="!+autorefreshTimer" class="mdi mdi-24px mdi-refresh mr-1" />
|
||||||
|
<i v-else class="mdi mdi-24px mdi-history mdi-flip-h mr-1" />
|
||||||
<span>{{ $t('word.refresh') }}</span>
|
<span>{{ $t('word.refresh') }}</span>
|
||||||
<i v-if="!+autorefreshTimer" class="mdi mdi-24px mdi-refresh ml-1" />
|
|
||||||
<i v-else class="mdi mdi-24px mdi-history mdi-flip-h ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
<div class="btn btn-dark btn-sm dropdown-toggle pl-0 pr-0" tabindex="0">
|
<div class="btn btn-dark btn-sm dropdown-toggle pl-0 pr-0" tabindex="0">
|
||||||
<i class="mdi mdi-24px mdi-menu-down" />
|
<i class="mdi mdi-24px mdi-menu-down" />
|
||||||
@@ -77,8 +77,8 @@
|
|||||||
:disabled="isQuering"
|
:disabled="isQuering"
|
||||||
@click="showFakerModal"
|
@click="showFakerModal"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-playlist-plus mr-1" />
|
||||||
<span>{{ $t('message.tableFiller') }}</span>
|
<span>{{ $t('message.tableFiller') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-playlist-plus ml-1" />
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="dropdown table-dropdown pr-2">
|
<div class="dropdown table-dropdown pr-2">
|
||||||
@@ -87,8 +87,8 @@
|
|||||||
class="btn btn-dark btn-sm dropdown-toggle mr-0 pr-0"
|
class="btn btn-dark btn-sm dropdown-toggle mr-0 pr-0"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
|
<i class="mdi mdi-24px mdi-file-export mr-1" />
|
||||||
<span>{{ $t('word.export') }}</span>
|
<span>{{ $t('word.export') }}</span>
|
||||||
<i class="mdi mdi-24px mdi-file-export ml-1" />
|
|
||||||
<i class="mdi mdi-24px mdi-menu-down" />
|
<i class="mdi mdi-24px mdi-menu-down" />
|
||||||
</button>
|
</button>
|
||||||
<ul class="menu text-left">
|
<ul class="menu text-left">
|
||||||
|
@@ -28,6 +28,13 @@
|
|||||||
>
|
>
|
||||||
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li
|
||||||
|
class="tab-item"
|
||||||
|
:class="{'active': selectedTab === 'ssh'}"
|
||||||
|
@click="selectTab('ssh')"
|
||||||
|
>
|
||||||
|
<a class="c-hand">{{ $t('word.sshTunnel') }}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="selectedTab === 'general'" class="panel-body py-0">
|
<div v-if="selectedTab === 'general'" class="panel-body py-0">
|
||||||
@@ -208,7 +215,6 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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.ciphers') }}</label>
|
<label class="form-label">{{ $t('word.ciphers') }}</label>
|
||||||
@@ -231,6 +237,95 @@
|
|||||||
:status="toast.status"
|
:status="toast.status"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="selectedTab === 'ssh'" class="panel-body py-0">
|
||||||
|
<div class="container">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">
|
||||||
|
{{ $t('message.enableSsh') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<label class="form-switch d-inline-block" @click.prevent="toggleSsh">
|
||||||
|
<input type="checkbox" :checked="localConnection.ssh">
|
||||||
|
<i class="form-icon" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<fieldset class="m-0" :disabled="isTesting || !localConnection.ssh">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshHost"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshUser"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshPass"
|
||||||
|
class="form-input"
|
||||||
|
type="password"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="localConnection.sshPort"
|
||||||
|
class="form-input"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
max="65535"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.privateKey') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="localConnection.sshKey"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('sshKey')"
|
||||||
|
@change="pathSelection($event, 'sshKey')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<BaseToast
|
||||||
|
class="mb-2"
|
||||||
|
:message="toast.message"
|
||||||
|
:status="toast.status"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="modal-footer text-light">
|
<div class="modal-footer text-light">
|
||||||
<button
|
<button
|
||||||
class="btn btn-gray mr-2"
|
class="btn btn-gray mr-2"
|
||||||
@@ -369,6 +464,9 @@ export default {
|
|||||||
toggleSsl () {
|
toggleSsl () {
|
||||||
this.localConnection.ssl = !this.localConnection.ssl;
|
this.localConnection.ssl = !this.localConnection.ssl;
|
||||||
},
|
},
|
||||||
|
toggleSsh () {
|
||||||
|
this.localConnection.ssh = !this.localConnection.ssh;
|
||||||
|
},
|
||||||
pathSelection (event, name) {
|
pathSelection (event, name) {
|
||||||
const { files } = event.target;
|
const { files } = event.target;
|
||||||
if (!files.length) return;
|
if (!files.length) return;
|
@@ -29,6 +29,13 @@
|
|||||||
>
|
>
|
||||||
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
<a class="tab-link">{{ $t('word.ssl') }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li
|
||||||
|
class="tab-item"
|
||||||
|
:class="{'active': selectedTab === 'ssh'}"
|
||||||
|
@click="selectTab('ssh')"
|
||||||
|
>
|
||||||
|
<a class="c-hand">{{ $t('word.sshTunnel') }}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="selectedTab === 'general'" class="panel-body py-0">
|
<div v-if="selectedTab === 'general'" class="panel-body py-0">
|
||||||
@@ -213,7 +220,6 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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.ciphers') }}</label>
|
<label class="form-label">{{ $t('word.ciphers') }}</label>
|
||||||
@@ -236,6 +242,95 @@
|
|||||||
:status="toast.status"
|
:status="toast.status"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="selectedTab === 'ssh'" class="panel-body py-0">
|
||||||
|
<div class="container">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">
|
||||||
|
{{ $t('message.enableSsh') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<label class="form-switch d-inline-block" @click.prevent="toggleSsh">
|
||||||
|
<input type="checkbox" :checked="connection.ssh">
|
||||||
|
<i class="form-icon" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<fieldset class="m-0" :disabled="isTesting || !connection.ssh">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.hostName') }}/IP</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshHost"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.user') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshUser"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.password') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshPass"
|
||||||
|
class="form-input"
|
||||||
|
type="password"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.port') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<input
|
||||||
|
v-model="connection.sshPort"
|
||||||
|
class="form-input"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
max="65535"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-4 col-sm-12">
|
||||||
|
<label class="form-label">{{ $t('word.privateKey') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 col-sm-12">
|
||||||
|
<BaseUploadInput
|
||||||
|
:value="connection.sshKey"
|
||||||
|
:message="$t('word.browse')"
|
||||||
|
@clear="pathClear('sshKey')"
|
||||||
|
@change="pathSelection($event, 'sshKey')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<BaseToast
|
||||||
|
class="mb-2"
|
||||||
|
:message="toast.message"
|
||||||
|
:status="toast.status"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer text-light">
|
<div class="modal-footer text-light">
|
||||||
@@ -294,8 +389,13 @@ export default {
|
|||||||
cert: '',
|
cert: '',
|
||||||
key: '',
|
key: '',
|
||||||
ca: '',
|
ca: '',
|
||||||
ciphers: ''
|
ciphers: '',
|
||||||
|
ssh: false,
|
||||||
|
sshHost: '',
|
||||||
|
sshUser: '',
|
||||||
|
sshPass: '',
|
||||||
|
sshKey: '',
|
||||||
|
sshPort: 22
|
||||||
},
|
},
|
||||||
toast: {
|
toast: {
|
||||||
status: '',
|
status: '',
|
||||||
@@ -393,6 +493,9 @@ export default {
|
|||||||
toggleSsl () {
|
toggleSsl () {
|
||||||
this.connection.ssl = !this.connection.ssl;
|
this.connection.ssl = !this.connection.ssl;
|
||||||
},
|
},
|
||||||
|
toggleSsh () {
|
||||||
|
this.connection.ssh = !this.connection.ssh;
|
||||||
|
},
|
||||||
pathSelection (event, name) {
|
pathSelection (event, name) {
|
||||||
const { files } = event.target;
|
const { files } = event.target;
|
||||||
if (!files.length) return;
|
if (!files.length) return;
|
@@ -104,7 +104,8 @@ module.exports = {
|
|||||||
database: 'Datenbank',
|
database: 'Datenbank',
|
||||||
scratchpad: 'Scratchpad',
|
scratchpad: 'Scratchpad',
|
||||||
array: 'Array',
|
array: 'Array',
|
||||||
format: 'Formatierung'
|
format: 'Formatierung',
|
||||||
|
sshTunnel: 'SSH Tunnel'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
appWelcome: 'Willkommen im Antares SQL Client!',
|
appWelcome: 'Willkommen im Antares SQL Client!',
|
||||||
@@ -210,7 +211,8 @@ module.exports = {
|
|||||||
deleteSchema: 'Schema löschen',
|
deleteSchema: 'Schema löschen',
|
||||||
markdownSupported: 'Unterstützt Markdown',
|
markdownSupported: 'Unterstützt Markdown',
|
||||||
plantATree: 'Pflanze einen Baum',
|
plantATree: 'Pflanze einen Baum',
|
||||||
dataTabPageSize: 'Einträge pro Tab / Seite'
|
dataTabPageSize: 'Einträge pro Tab / Seite',
|
||||||
|
enableSsh: 'Aktiviere SSH'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Adresse',
|
address: 'Adresse',
|
||||||
|
@@ -106,13 +106,16 @@ module.exports = {
|
|||||||
array: 'Array',
|
array: 'Array',
|
||||||
changelog: 'Changelog',
|
changelog: 'Changelog',
|
||||||
format: 'Format',
|
format: 'Format',
|
||||||
|
sshTunnel: 'SSH tunnel',
|
||||||
structure: 'Structure',
|
structure: 'Structure',
|
||||||
small: 'Small',
|
small: 'Small',
|
||||||
medium: 'Medium',
|
medium: 'Medium',
|
||||||
large: 'Large',
|
large: 'Large',
|
||||||
row: 'Row | Rows',
|
row: 'Row | Rows',
|
||||||
cell: 'Cell | Cells',
|
cell: 'Cell | Cells',
|
||||||
triggerFunction: 'Trigger function | Trigger functions'
|
triggerFunction: 'Trigger function | Trigger functions',
|
||||||
|
all: 'All',
|
||||||
|
duplicate: 'Duplicate'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
appWelcome: 'Welcome to Antares SQL Client!',
|
appWelcome: 'Welcome to Antares SQL Client!',
|
||||||
@@ -219,6 +222,7 @@ module.exports = {
|
|||||||
markdownSupported: 'Markdown supported',
|
markdownSupported: 'Markdown supported',
|
||||||
plantATree: 'Plant a Tree',
|
plantATree: 'Plant a Tree',
|
||||||
dataTabPageSize: 'DATA tab page size',
|
dataTabPageSize: 'DATA tab page size',
|
||||||
|
enableSsh: 'Enable SSH',
|
||||||
pageNumber: 'Page number',
|
pageNumber: 'Page number',
|
||||||
duplicateTable: 'Duplicate table'
|
duplicateTable: 'Duplicate table'
|
||||||
},
|
},
|
||||||
|
@@ -93,7 +93,8 @@ module.exports = {
|
|||||||
ciphers: 'Chiffrement',
|
ciphers: 'Chiffrement',
|
||||||
upload: 'Charger',
|
upload: 'Charger',
|
||||||
browse: 'Parcourir',
|
browse: 'Parcourir',
|
||||||
faker: 'Faker'
|
faker: 'Faker',
|
||||||
|
sshTunnel: 'SSH tunnel'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
appWelcome: 'Bienvenu sur le client SQL Antares!',
|
appWelcome: 'Bienvenu sur le client SQL Antares!',
|
||||||
@@ -183,7 +184,8 @@ module.exports = {
|
|||||||
preserveOnCompletion: 'Préserver à l\'achèvement',
|
preserveOnCompletion: 'Préserver à l\'achèvement',
|
||||||
enableSsl: 'Activer le SSL',
|
enableSsl: 'Activer le SSL',
|
||||||
manualValue: 'Valeur manuelle',
|
manualValue: 'Valeur manuelle',
|
||||||
tableFiller: 'Remplisseur de table'
|
tableFiller: 'Remplisseur de table',
|
||||||
|
enableSsh: 'Activer le SSH'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Adresse',
|
address: 'Adresse',
|
||||||
|
@@ -105,7 +105,8 @@ module.exports = {
|
|||||||
scratchpad: 'Blocco appunti',
|
scratchpad: 'Blocco appunti',
|
||||||
array: 'Array',
|
array: 'Array',
|
||||||
changelog: 'Changelog',
|
changelog: 'Changelog',
|
||||||
format: 'Formatta'
|
format: 'Formatta',
|
||||||
|
sshTunnel: 'SSH tunnel'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
appWelcome: 'Benvenuto in Antares SQL Client!',
|
appWelcome: 'Benvenuto in Antares SQL Client!',
|
||||||
@@ -210,7 +211,8 @@ module.exports = {
|
|||||||
editSchema: 'Modifica schema',
|
editSchema: 'Modifica schema',
|
||||||
deleteSchema: 'Elimina schema',
|
deleteSchema: 'Elimina schema',
|
||||||
markdownSupported: 'Markdown supportato',
|
markdownSupported: 'Markdown supportato',
|
||||||
plantATree: 'Pianta un albero'
|
plantATree: 'Pianta un albero',
|
||||||
|
enableSsh: 'Abilita SSH'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Indirizzo',
|
address: 'Indirizzo',
|
||||||
|
@@ -105,7 +105,8 @@ module.exports = {
|
|||||||
scratchpad: 'Rascunho',
|
scratchpad: 'Rascunho',
|
||||||
array: 'Array',
|
array: 'Array',
|
||||||
changelog: 'Logs de alteração',
|
changelog: 'Logs de alteração',
|
||||||
format: 'Formato'
|
format: 'Formato',
|
||||||
|
sshTunnel: 'SSH túnel'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
appWelcome: 'Bem vindo ao Antares SQL Client!',
|
appWelcome: 'Bem vindo ao Antares SQL Client!',
|
||||||
@@ -210,7 +211,8 @@ module.exports = {
|
|||||||
editSchema: 'Editar schema',
|
editSchema: 'Editar schema',
|
||||||
deleteSchema: 'Apagar schema',
|
deleteSchema: 'Apagar schema',
|
||||||
markdownSupported: 'Markdown suportado',
|
markdownSupported: 'Markdown suportado',
|
||||||
plantATree: 'Plante uma árvore'
|
plantATree: 'Plante uma árvore',
|
||||||
|
enableSsh: 'Habilitar SSH'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Endereço',
|
address: 'Endereço',
|
||||||
|
@@ -214,9 +214,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.connection-panel {
|
||||||
|
.panel {
|
||||||
|
background: rgba($bg-color-light-dark, 50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bg-checkered {
|
.bg-checkered {
|
||||||
background-image: linear-gradient(to right, rgba(192, 192, 192, 0.75), rgba(192, 192, 192, 0.75)),
|
background-image:
|
||||||
linear-gradient(to right, black 50%, white 50%), linear-gradient(to bottom, black 50%, white 50%);
|
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-blend-mode: normal, difference, normal;
|
||||||
background-size: 2em 2em;
|
background-size: 2em 2em;
|
||||||
}
|
}
|
||||||
|
@@ -205,6 +205,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.connection-panel {
|
||||||
|
.panel {
|
||||||
|
background: rgba($bg-color-light-gray, 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.context {
|
.context {
|
||||||
color: $body-font-color-dark;
|
color: $body-font-color-dark;
|
||||||
|
|
||||||
|
@@ -10,7 +10,8 @@ else
|
|||||||
|
|
||||||
const persistentStore = new Store({
|
const persistentStore = new Store({
|
||||||
name: 'connections',
|
name: 'connections',
|
||||||
encryptionKey: key
|
encryptionKey: key,
|
||||||
|
clearInvalidConfig: true
|
||||||
});
|
});
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -23,6 +24,7 @@ export default {
|
|||||||
getConnections: state => state.connections,
|
getConnections: state => state.connections,
|
||||||
getConnectionName: state => uid => {
|
getConnectionName: state => uid => {
|
||||||
const connection = state.connections.filter(connection => connection.uid === uid)[0];
|
const connection = state.connections.filter(connection => connection.uid === uid)[0];
|
||||||
|
if (!connection) return '';
|
||||||
return connection.name
|
return connection.name
|
||||||
? connection.name
|
? connection.name
|
||||||
: connection.ask
|
: connection.ask
|
||||||
|
@@ -20,7 +20,7 @@ export default {
|
|||||||
getSelected: state => {
|
getSelected: state => {
|
||||||
if (state.selected_workspace) return state.selected_workspace;
|
if (state.selected_workspace) return state.selected_workspace;
|
||||||
if (state.workspaces.length) return state.workspaces[0].uid;
|
if (state.workspaces.length) return state.workspaces[0].uid;
|
||||||
return null;
|
return 'NEW';
|
||||||
},
|
},
|
||||||
getWorkspace: state => uid => {
|
getWorkspace: state => uid => {
|
||||||
return state.workspaces.find(workspace => workspace.uid === uid);
|
return state.workspaces.find(workspace => workspace.uid === uid);
|
||||||
@@ -52,7 +52,10 @@ export default {
|
|||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
SELECT_WORKSPACE (state, uid) {
|
SELECT_WORKSPACE (state, uid) {
|
||||||
state.selected_workspace = uid;
|
if (!uid)
|
||||||
|
state.selected_workspace = state.workspaces.length ? state.workspaces[0].uid : 'NEW';
|
||||||
|
else
|
||||||
|
state.selected_workspace = uid;
|
||||||
},
|
},
|
||||||
SET_CONNECTED (state, payload) {
|
SET_CONNECTED (state, payload) {
|
||||||
const { uid, client, dataTypes, indexTypes, customizations, structure, version } = payload;
|
const { uid, client, dataTypes, indexTypes, customizations, structure, version } = payload;
|
||||||
|
Reference in New Issue
Block a user