mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
d743d486b8 |
2
.github/workflows/build-linux.yml
vendored
2
.github/workflows/build-linux.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Build/release [LINUX]
|
||||
name: Build/release [linux]
|
||||
|
||||
on: push
|
||||
|
||||
|
2
.github/workflows/build-mac.yml
vendored
2
.github/workflows/build-mac.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Build/release [MAC]
|
||||
name: Build/release [mac]
|
||||
|
||||
on: push
|
||||
|
||||
|
2
.github/workflows/build-win.yml
vendored
2
.github/workflows/build-win.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Build/release [WINDOWS]
|
||||
name: Build/release [windows]
|
||||
|
||||
on: push
|
||||
|
||||
|
26
.github/workflows/create-artifact-linux.yml
vendored
26
.github/workflows/create-artifact-linux.yml
vendored
@@ -1,26 +0,0 @@
|
||||
name: Create artifact [LINUX]
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: npm install & build
|
||||
run: |
|
||||
npm install
|
||||
npm run build:local
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linux-build
|
||||
retention-days: 3
|
||||
path: |
|
||||
build
|
||||
!build/*-unpacked
|
||||
!build/.icon-ico
|
2
.github/workflows/test-e2e-linux.yml
vendored
2
.github/workflows/test-e2e-linux.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Test end-to-end [LINUX]
|
||||
name: Test end-to-end [linux]
|
||||
|
||||
on: push
|
||||
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -6,8 +6,7 @@
|
||||
"PostgreSQL",
|
||||
"SQLite",
|
||||
"Windows",
|
||||
"translation",
|
||||
"Linux"
|
||||
"translation"
|
||||
],
|
||||
"svg.preview.background": "transparent"
|
||||
}
|
63
CHANGELOG.md
63
CHANGELOG.md
@@ -2,69 +2,6 @@
|
||||
|
||||
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.5.7](https://github.com/antares-sql/antares/compare/v0.5.4...v0.5.7) (2022-06-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* added dropdown animation ([5398964](https://github.com/antares-sql/antares/commit/539896419064db9127f6a72acdbb11af2c4aa60a))
|
||||
* dynamic app window title ([0024269](https://github.com/antares-sql/antares/commit/00242697a102f82dd0c731a3529c984fbdf83b3e))
|
||||
* hotkeys to navigate forward or backward between tabs ([d3b9e08](https://github.com/antares-sql/antares/commit/d3b9e08446708654b3c6fad565b734d93effe683))
|
||||
* hotkeys to navigate inside a table resultset ([49abd1e](https://github.com/antares-sql/antares/commit/49abd1ea7f5ec368e9a9201f8fd5b6520c4bd0a8))
|
||||
* **translation:** russian translation, closes [#266](https://github.com/antares-sql/antares/issues/266) ([9082960](https://github.com/antares-sql/antares/commit/9082960310573a6e4d14bfbe82ed2eb1489f308d))
|
||||
* **UI:** BaseSelect disabled state ([2b436d8](https://github.com/antares-sql/antares/commit/2b436d8613a1e3dff55d73adbddf5d2cd2452f27))
|
||||
* **UI:** BaseSelect in table filters ([a037d0c](https://github.com/antares-sql/antares/commit/a037d0cc0148444e8e6c5b87c79f6ba9c2a6f0fe))
|
||||
* **UI:** BaseSelect option list scrolls automatically using up/down keys ([0043d07](https://github.com/antares-sql/antares/commit/0043d077081fc49724722a5d5a74986d990c539d))
|
||||
* **UI:** BaseSelect small variant ([5582a12](https://github.com/antares-sql/antares/commit/5582a12bbfade75dbcc7f9d71ada7190ed08d3c2))
|
||||
* **UI:** BaseSelect supports disabled options ([f7e04d6](https://github.com/antares-sql/antares/commit/f7e04d633340a53420ce1c434e906c9434620e6e))
|
||||
* **UI:** BaseSelect supports option groups ([1869e6a](https://github.com/antares-sql/antares/commit/1869e6a1482daf9381d9ac2244bf0aeffa758edc))
|
||||
* **UI:** ForeignKeySelect implements BaseSelect component ([302c664](https://github.com/antares-sql/antares/commit/302c66457deeb50facf4735291640fcf48b78f66))
|
||||
* **UI:** initial BaseSelect integration ([22622df](https://github.com/antares-sql/antares/commit/22622df2cfcb71054c6f6110b7ad9d4f635553dc))
|
||||
* **UI:** new BaseSelect component ([745d551](https://github.com/antares-sql/antares/commit/745d551cc9253eae4e39e5d3406ceee051a7d6c1))
|
||||
* **UI:** select tab replace with BaseSelect component ([42bc919](https://github.com/antares-sql/antares/commit/42bc9196ffc2f64b77f9cb42136255fc74815034))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* empty query tab schema select if no schema selected ([31b7999](https://github.com/antares-sql/antares/commit/31b7999bba5d115913d42087614b9888bc761068))
|
||||
* exception on app start setting window title ([5b33419](https://github.com/antares-sql/antares/commit/5b33419b6421d7d198a978e79e22d0a76306cdb4))
|
||||
* fields sorting in table setting tabs ([77d9cac](https://github.com/antares-sql/antares/commit/77d9cac092fbb806810c3463ca066395fcab5307))
|
||||
* inline field update not working with tables missing primary key ([caf776b](https://github.com/antares-sql/antares/commit/caf776bd55606c793c9763c204aa9f05d1feb27f))
|
||||
* **Linux:** setting bar tooltip position ([6bad032](https://github.com/antares-sql/antares/commit/6bad032f0d1094736f651b6c06a60d2a0df36c98))
|
||||
* main process not closed after window close on some conditions ([23acf00](https://github.com/antares-sql/antares/commit/23acf00def77b5662e48b84591a31760737774a7))
|
||||
* **PostgreSQL:** idle timeout disabled ([a082514](https://github.com/antares-sql/antares/commit/a082514f88040c7e0ffdf4e8357bab45370a4c39))
|
||||
* query tab content disappears reordering or closing other tabs, closes [#261](https://github.com/antares-sql/antares/issues/261) ([c5baf2b](https://github.com/antares-sql/antares/commit/c5baf2b0d379fdd28ee8cb907628bbfca940e2f6))
|
||||
* reload tab content on tab sort ([d214c1f](https://github.com/antares-sql/antares/commit/d214c1f35ba231a8a01dbe8c0faad07d4b337752))
|
||||
* selected foreign key value not visible in the insert row modal ([cba2ce2](https://github.com/antares-sql/antares/commit/cba2ce2e37cedbf0b242cc474b37bf052009ae62))
|
||||
* **SQLite:** unable to insert rows with TEXT fields ([a7d5e19](https://github.com/antares-sql/antares/commit/a7d5e1973cd59d7d0ef1e74bdcf44d87fba43559))
|
||||
* SSH tunnel connection error with private key, closes [#260](https://github.com/antares-sql/antares/issues/260) ([c826888](https://github.com/antares-sql/antares/commit/c826888b0dd0908958a4f727ddfa642e846269cf))
|
||||
* **UI:** BaseSelect keyboard navigation ([7c45203](https://github.com/antares-sql/antares/commit/7c452036368fa0db6b9cde7c35e60a8e57bfece7))
|
||||
* **UI:** BaseSelect style ([71b0736](https://github.com/antares-sql/antares/commit/71b0736d0ddbd599ab41cde0a6b0823e2bb7da2f))
|
||||
* **UI:** select closes clicking on scrollbar ([8870304](https://github.com/antares-sql/antares/commit/8870304c15346257a90193807b9ae07c1393e3e2))
|
||||
* unable to add new table fields ([ee623b0](https://github.com/antares-sql/antares/commit/ee623b0a0f121df0ac53d49d8be437c76ddb8539))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* improved precision of MariaDB or MySQL auto detection ([26aad51](https://github.com/antares-sql/antares/commit/26aad519df6ea1bbc7dffbf540193a7b2ed9ae2a))
|
||||
* **Linux:** title bar improvements ([85cec05](https://github.com/antares-sql/antares/commit/85cec05f7037a1339ee223554cf127693a527aa1))
|
||||
* **UI:** max height for query text area increased ([5d5f1da](https://github.com/antares-sql/antares/commit/5d5f1da97b9adfa743197d8fa0bbb6addd565a7a))
|
||||
* **Windows:** title bar improvements ([5fa8bf3](https://github.com/antares-sql/antares/commit/5fa8bf38e433ef2fb31bcb893cd9e75549bd6a49))
|
||||
|
||||
### [0.5.6](https://github.com/antares-sql/antares/compare/v0.5.4...v0.5.6) (2022-06-02)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* empty query tab schema select if no schema selected ([31b7999](https://github.com/antares-sql/antares/commit/31b7999bba5d115913d42087614b9888bc761068))
|
||||
* inline field update not working with tables missing primary key ([caf776b](https://github.com/antares-sql/antares/commit/caf776bd55606c793c9763c204aa9f05d1feb27f))
|
||||
* **SQLite:** unable to insert rows with TEXT fields ([a7d5e19](https://github.com/antares-sql/antares/commit/a7d5e1973cd59d7d0ef1e74bdcf44d87fba43559))
|
||||
* **UI:** select closes clicking on scrollbar ([8870304](https://github.com/antares-sql/antares/commit/8870304c15346257a90193807b9ae07c1393e3e2))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* improved precision of MariaDB or MySQL auto detection ([26aad51](https://github.com/antares-sql/antares/commit/26aad519df6ea1bbc7dffbf540193a7b2ed9ae2a))
|
||||
|
||||
### [0.5.5](https://github.com/antares-sql/antares/compare/v0.5.4...v0.5.5) (2022-05-24)
|
||||
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 43 KiB |
10
package.json
10
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.5.7",
|
||||
"version": "0.5.5",
|
||||
"description": "A modern, fast and productivity driven SQL client with a focus in UX.",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/antares-sql/antares.git",
|
||||
@@ -13,7 +13,7 @@
|
||||
"compile:workers": "webpack --mode=production --config webpack.workers.config.js",
|
||||
"compile:renderer": "webpack --mode=production --config webpack.renderer.config.js",
|
||||
"build": "cross-env NODE_ENV=production npm run compile",
|
||||
"build:local": "npm run build && electron-builder --publish never",
|
||||
"build:local": "npm run build && electron-builder",
|
||||
"build:appx": "npm run build:local -- --win appx",
|
||||
"rebuild:electron": "rimraf ./dist && npm run postinstall",
|
||||
"release": "standard-version",
|
||||
@@ -82,12 +82,6 @@
|
||||
"license": "./LICENSE",
|
||||
"category": "Development"
|
||||
},
|
||||
"nsis": {
|
||||
"license": "./LICENSE",
|
||||
"installerIcon": "assets/icon.ico",
|
||||
"uninstallerIcon": "assets/icon.ico",
|
||||
"installerHeader": "assets/icon.ico"
|
||||
},
|
||||
"portable": {
|
||||
"artifactName": "${productName}-${version}-portable.exe"
|
||||
},
|
||||
|
@@ -104,6 +104,8 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
escapedParam = `"${sqlEscaper(params.content)}"`;
|
||||
break;
|
||||
case 'pg':
|
||||
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||
break;
|
||||
case 'sqlite':
|
||||
escapedParam = `'${params.content.replaceAll('\'', '\'\'')}'`;
|
||||
break;
|
||||
@@ -169,8 +171,6 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
}
|
||||
else {
|
||||
const { orgRow } = params;
|
||||
delete orgRow._antares_id;
|
||||
|
||||
reload = true;
|
||||
|
||||
for (const key in orgRow) {
|
||||
@@ -341,7 +341,6 @@ export default (connections: {[key: string]: antares.Client}) => {
|
||||
escapedParam = `"${sqlEscaper(params.row[key].value)}"`;
|
||||
break;
|
||||
case 'pg':
|
||||
case 'sqlite':
|
||||
escapedParam = `'${params.row[key].value.replaceAll('\'', '\'\'')}'`;
|
||||
break;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { app, BrowserWindow, /* session, */ nativeImage, Menu, ipcMain } from 'electron';
|
||||
import { app, BrowserWindow, /* session, */ nativeImage, Menu } from 'electron';
|
||||
import * as path from 'path';
|
||||
import * as Store from 'electron-store';
|
||||
import * as windowStateKeeper from 'electron-window-state';
|
||||
@@ -7,13 +7,9 @@ import * as remoteMain from '@electron/remote/main';
|
||||
import ipcHandlers from './ipc-handlers';
|
||||
|
||||
Store.initRenderer();
|
||||
const persistentStore = new Store({ name: 'settings' });
|
||||
|
||||
const appTheme = persistentStore.get('application_theme');
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
const isMacOS = process.platform === 'darwin';
|
||||
const isLinux = process.platform === 'linux';
|
||||
const isWindows = process.platform === 'win32';
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
|
||||
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true';
|
||||
@@ -23,7 +19,7 @@ let mainWindow: BrowserWindow;
|
||||
let mainWindowState: windowStateKeeper.State;
|
||||
|
||||
async function createMainWindow () {
|
||||
const icon = require('../renderer/images/logo-64.png');
|
||||
const icon = require('../renderer/images/logo-32.png');
|
||||
const window = new BrowserWindow({
|
||||
width: mainWindowState.width,
|
||||
height: mainWindowState.height,
|
||||
@@ -32,21 +28,15 @@ async function createMainWindow () {
|
||||
minWidth: 900,
|
||||
minHeight: 550,
|
||||
title: 'Antares SQL',
|
||||
autoHideMenuBar: true,
|
||||
icon: nativeImage.createFromDataURL(icon.default),
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false,
|
||||
spellcheck: false
|
||||
},
|
||||
autoHideMenuBar: true,
|
||||
titleBarStyle: isLinux ? 'default' :'hidden',
|
||||
titleBarOverlay: isWindows
|
||||
? {
|
||||
color: appTheme === 'dark' ? '#3f3f3f' : '#fff',
|
||||
symbolColor: appTheme === 'dark' ? '#fff' : '#000',
|
||||
height: 30
|
||||
}
|
||||
: false,
|
||||
frame: false,
|
||||
titleBarStyle: isMacOS ? 'hidden' : 'default',
|
||||
trafficLightPosition: isMacOS ? { x: 10, y: 8 } : undefined,
|
||||
backgroundColor: '#1d1d1d'
|
||||
});
|
||||
@@ -83,24 +73,10 @@ else {
|
||||
// Initialize ipcHandlers
|
||||
ipcHandlers();
|
||||
|
||||
ipcMain.on('refresh-theme-settings', () => {
|
||||
const appTheme = persistentStore.get('application_theme');
|
||||
if (isWindows) {
|
||||
mainWindow.setTitleBarOverlay({
|
||||
color: appTheme === 'dark' ? '#3f3f3f' : '#fff',
|
||||
symbolColor: appTheme === 'dark' ? '#fff' : '#000'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.on('change-window-title', (event, title: string) => {
|
||||
if (mainWindow) mainWindow.setTitle(title);
|
||||
});
|
||||
|
||||
// quit application when all windows are closed
|
||||
app.on('window-all-closed', () => {
|
||||
// on macOS it is common for applications to stay open until the user explicitly quits
|
||||
if (!isMacOS) app.quit();
|
||||
if (isMacOS) app.quit();
|
||||
});
|
||||
|
||||
app.on('activate', async () => {
|
||||
|
@@ -37,8 +37,6 @@
|
||||
v-if="isOpen"
|
||||
ref="optionList"
|
||||
:class="`select__list-wrapper ${dropdownClass ? dropdownClass : '' }`"
|
||||
@mousedown="isMouseDown = true"
|
||||
@mouseup="handleMouseUpEvent()"
|
||||
>
|
||||
<ul class="select__list" @mousedown.prevent>
|
||||
<li
|
||||
@@ -138,7 +136,6 @@ export default defineComponent({
|
||||
setup (props, { emit }) {
|
||||
const hightlightedIndex = ref(0);
|
||||
const isOpen = ref(false);
|
||||
const isMouseDown = ref(false);
|
||||
const internalValue = ref(props.modelValue || props.value);
|
||||
const el = ref(null);
|
||||
const searchInput = ref(null);
|
||||
@@ -154,7 +151,7 @@ export default defineComponent({
|
||||
if (typeof prop === 'function')
|
||||
return prop(item);
|
||||
|
||||
return item[prop] !== undefined ? item[prop] : item;
|
||||
return item[prop] || item;
|
||||
};
|
||||
|
||||
const flattenOptions = computed(() => {
|
||||
@@ -222,16 +219,8 @@ export default defineComponent({
|
||||
hightlightedIndex.value = 0;
|
||||
});
|
||||
|
||||
watch(() => props.modelValue, (val) => {
|
||||
internalValue.value = val;
|
||||
});
|
||||
|
||||
watch(() => props.value, (val) => {
|
||||
internalValue.value = val;
|
||||
});
|
||||
|
||||
const currentOptionLabel = computed(() =>
|
||||
flattenOptions.value.find(d => d.value === internalValue.value)?.label
|
||||
flattenOptions.value.find(d => d.value === props.modelValue)?.label
|
||||
);
|
||||
|
||||
const select = (opt) => {
|
||||
@@ -330,24 +319,12 @@ export default defineComponent({
|
||||
};
|
||||
|
||||
const handleBlurEvent = () => {
|
||||
if (isMouseDown.value) return;
|
||||
deactivate();
|
||||
emit('blur');
|
||||
};
|
||||
|
||||
const handleMouseUpEvent = () => {
|
||||
isMouseDown.value = false;
|
||||
searchInput.value.focus();
|
||||
};
|
||||
|
||||
const handleWheelEvent = (e) => {
|
||||
if (!e.target.className.includes('select__')) deactivate();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('resize', adjustListPosition);
|
||||
window.addEventListener('wheel', handleWheelEvent);
|
||||
|
||||
nextTick(() => {
|
||||
// fix position when the component is created and opened at the same time
|
||||
if (isOpen.value) {
|
||||
@@ -359,7 +336,6 @@ export default defineComponent({
|
||||
});
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', adjustListPosition);
|
||||
window.removeEventListener('wheel', handleWheelEvent);
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -375,12 +351,10 @@ export default defineComponent({
|
||||
isSelected,
|
||||
keyArrows,
|
||||
isOpen,
|
||||
isMouseDown,
|
||||
hightlightedIndex,
|
||||
optionList,
|
||||
optionRefs,
|
||||
handleBlurEvent,
|
||||
handleMouseUpEvent
|
||||
handleBlurEvent
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -388,49 +362,48 @@ export default defineComponent({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.select {
|
||||
display: block;
|
||||
display: block;
|
||||
|
||||
&:focus,
|
||||
&--open {
|
||||
z-index: 10;
|
||||
}
|
||||
&:focus, &--open {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&__search-input {
|
||||
appearance: none;
|
||||
border: none;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
color: currentColor;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
&__search-input {
|
||||
appearance: none;
|
||||
border: none;
|
||||
background: transparent;
|
||||
outline: none;
|
||||
color: currentColor;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__list-wrapper {
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
display: block;
|
||||
z-index: 5;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
max-height: 240px;
|
||||
overflow: auto;
|
||||
left: 0;
|
||||
top: 40px;
|
||||
}
|
||||
&__list-wrapper {
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
display: block;
|
||||
z-index: 5;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
max-height: 240px;
|
||||
overflow: auto;
|
||||
left: 0;
|
||||
top: 40px;
|
||||
}
|
||||
|
||||
&__list {
|
||||
list-style: none;
|
||||
}
|
||||
&__list {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
&__option {
|
||||
&--disabled {
|
||||
&__option {
|
||||
&--disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
&--disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -43,7 +43,7 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
foreignList: [],
|
||||
currentValue: this.modelValue || null
|
||||
currentValue: this.modelValue
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@@ -98,7 +98,6 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
dragElement: null,
|
||||
isLinux: process.platform === 'linux',
|
||||
isContext: false,
|
||||
isDragging: false,
|
||||
contextEvent: null,
|
||||
@@ -130,9 +129,7 @@ export default {
|
||||
},
|
||||
tooltipPosition (e) {
|
||||
const el = e.target ? e.target : e;
|
||||
const fromTop = this.isLinux
|
||||
? window.scrollY + el.getBoundingClientRect().top + (el.offsetHeight / 4)
|
||||
: window.scrollY + el.getBoundingClientRect().top - (el.offsetHeight / 4)
|
||||
const fromTop = window.pageYOffset + el.getBoundingClientRect().top - (el.offsetHeight / 4);
|
||||
el.querySelector('.ex-tooltip-content').style.top = `${fromTop}px`;
|
||||
},
|
||||
getStatusBadge (uid) {
|
||||
|
@@ -1,9 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="!isLinux"
|
||||
id="titlebar"
|
||||
@dblclick="toggleFullScreen"
|
||||
>
|
||||
<div id="titlebar" @dblclick="toggleFullScreen">
|
||||
<div class="titlebar-resizer" />
|
||||
<div class="titlebar-elements">
|
||||
<img
|
||||
@@ -30,16 +26,15 @@
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-refresh" />
|
||||
</div>
|
||||
<div v-if="isWindows" style="width: 140px;" />
|
||||
<!-- <div
|
||||
v-if="isLinux"
|
||||
<div
|
||||
v-if="!isMacOS"
|
||||
class="titlebar-element"
|
||||
@click="minimizeApp"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-minus" />
|
||||
</div>
|
||||
<div
|
||||
v-if="isLinux"
|
||||
v-if="!isMacOS"
|
||||
class="titlebar-element"
|
||||
@click="toggleFullScreen"
|
||||
>
|
||||
@@ -47,12 +42,12 @@
|
||||
<i v-else class="mdi mdi-24px mdi-fullscreen" />
|
||||
</div>
|
||||
<div
|
||||
v-if="isLinux"
|
||||
v-if="!isMacOS"
|
||||
class="titlebar-element close-button"
|
||||
@click="closeApp"
|
||||
>
|
||||
<i class="mdi mdi-24px mdi-close" />
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -85,9 +80,7 @@ export default {
|
||||
w: getCurrentWindow(),
|
||||
isMaximized: getCurrentWindow().isMaximized(),
|
||||
isDevelopment: process.env.NODE_ENV === 'development',
|
||||
isMacOS: process.platform === 'darwin',
|
||||
isWindows: process.platform === 'win32',
|
||||
isLinux: process.platform === 'linux'
|
||||
isMacOS: process.platform === 'darwin'
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -102,11 +95,6 @@ export default {
|
||||
return [connectionName, ...breadcrumbs].join(' • ');
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
windowTitle: function (val) {
|
||||
ipcRenderer.send('change-window-title', val);
|
||||
}
|
||||
},
|
||||
created () {
|
||||
window.addEventListener('resize', this.onResize);
|
||||
},
|
||||
@@ -183,7 +171,7 @@ export default {
|
||||
height: $titlebar-height;
|
||||
line-height: 0;
|
||||
padding: 0 0.7rem;
|
||||
opacity: 0.9;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.2s;
|
||||
-webkit-app-region: no-drag;
|
||||
|
||||
|
@@ -315,9 +315,10 @@
|
||||
</template>
|
||||
</Draggable>
|
||||
<WorkspaceEmptyState v-if="!workspace.tabs.length" @new-tab="addQueryTab" />
|
||||
<template v-for="tab of workspace.tabs" :key="tab.uid">
|
||||
<template v-for="tab of workspace.tabs">
|
||||
<WorkspaceTabQuery
|
||||
v-if="tab.type ==='query'"
|
||||
v-if="tab.type==='query'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -325,7 +326,7 @@
|
||||
/>
|
||||
<WorkspaceTabTable
|
||||
v-else-if="['temp-data', 'data'].includes(tab.type)"
|
||||
v-once
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:connection="connection"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -335,6 +336,7 @@
|
||||
/>
|
||||
<WorkspaceTabNewTable
|
||||
v-else-if="tab.type === 'new-table'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:connection="connection"
|
||||
@@ -343,6 +345,7 @@
|
||||
/>
|
||||
<WorkspaceTabPropsTable
|
||||
v-else-if="tab.type === 'table-props'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:connection="connection"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -351,6 +354,7 @@
|
||||
/>
|
||||
<WorkspaceTabNewView
|
||||
v-else-if="tab.type === 'new-view'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:connection="connection"
|
||||
@@ -359,6 +363,7 @@
|
||||
/>
|
||||
<WorkspaceTabPropsView
|
||||
v-else-if="tab.type === 'view-props'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
:connection="connection"
|
||||
@@ -367,6 +372,7 @@
|
||||
/>
|
||||
<WorkspaceTabNewTrigger
|
||||
v-else-if="tab.type === 'new-trigger'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:connection="connection"
|
||||
@@ -376,6 +382,7 @@
|
||||
/>
|
||||
<WorkspaceTabPropsTrigger
|
||||
v-else-if="['temp-trigger-props', 'trigger-props'].includes(tab.type)"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:connection="connection"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -384,6 +391,7 @@
|
||||
/>
|
||||
<WorkspaceTabNewTriggerFunction
|
||||
v-else-if="tab.type === 'new-trigger-function'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:connection="connection"
|
||||
@@ -393,6 +401,7 @@
|
||||
/>
|
||||
<WorkspaceTabPropsTriggerFunction
|
||||
v-else-if="['temp-trigger-function-props', 'trigger-function-props'].includes(tab.type)"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:connection="connection"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -401,6 +410,7 @@
|
||||
/>
|
||||
<WorkspaceTabNewRoutine
|
||||
v-else-if="tab.type === 'new-routine'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:connection="connection"
|
||||
@@ -410,6 +420,7 @@
|
||||
/>
|
||||
<WorkspaceTabPropsRoutine
|
||||
v-else-if="['temp-routine-props', 'routine-props'].includes(tab.type)"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:connection="connection"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -418,6 +429,7 @@
|
||||
/>
|
||||
<WorkspaceTabNewFunction
|
||||
v-else-if="tab.type === 'new-function'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:connection="connection"
|
||||
@@ -427,6 +439,7 @@
|
||||
/>
|
||||
<WorkspaceTabPropsFunction
|
||||
v-else-if="['temp-function-props', 'function-props'].includes(tab.type)"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:connection="connection"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -435,6 +448,7 @@
|
||||
/>
|
||||
<WorkspaceTabNewScheduler
|
||||
v-else-if="tab.type === 'new-scheduler'"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:tab="tab"
|
||||
:connection="connection"
|
||||
@@ -444,6 +458,7 @@
|
||||
/>
|
||||
<WorkspaceTabPropsScheduler
|
||||
v-else-if="['temp-scheduler-props', 'scheduler-props'].includes(tab.type)"
|
||||
:key="tab.uid"
|
||||
:tab-uid="tab.uid"
|
||||
:connection="connection"
|
||||
:is-selected="selectedTab === tab.uid"
|
||||
@@ -541,9 +556,7 @@ export default {
|
||||
selectTab,
|
||||
newTab,
|
||||
removeTab,
|
||||
updateTabs,
|
||||
selectNextTab,
|
||||
selectPrevTab
|
||||
updateTabs
|
||||
} = workspacesStore;
|
||||
|
||||
return {
|
||||
@@ -555,9 +568,7 @@ export default {
|
||||
selectTab,
|
||||
newTab,
|
||||
removeTab,
|
||||
updateTabs,
|
||||
selectNextTab,
|
||||
selectPrevTab
|
||||
updateTabs
|
||||
};
|
||||
},
|
||||
data () {
|
||||
@@ -659,22 +670,6 @@ export default {
|
||||
if (currentTab)
|
||||
this.closeTab(currentTab);
|
||||
}
|
||||
|
||||
// select next tab
|
||||
if (e.altKey && (e.ctrlKey || e.metaKey) && e.key === 'ArrowRight')
|
||||
this.selectNextTab({ uid: this.connection.uid });
|
||||
|
||||
// select prev tab
|
||||
if (e.altKey && (e.ctrlKey || e.metaKey) && e.key === 'ArrowLeft')
|
||||
this.selectPrevTab({ uid: this.connection.uid });
|
||||
|
||||
// select tab by index (range 1-9). CTRL|CMD number
|
||||
if ((e.ctrlKey || e.metaKey) && !e.altKey && e.keyCode >= 49 && e.keyCode <= 57) {
|
||||
const newIndex = parseInt(e.key) - 1;
|
||||
|
||||
if (this.workspace.tabs[newIndex])
|
||||
this.selectTab({ uid: this.connection.uid, tab: this.workspace.tabs[newIndex].uid });
|
||||
}
|
||||
},
|
||||
openAsPermanentTab (tab) {
|
||||
const permanentTabs = {
|
||||
|
@@ -543,9 +543,9 @@ export default {
|
||||
|
||||
this.isTesting = false;
|
||||
},
|
||||
async saveConnection () {
|
||||
await this.addConnection(this.connection);
|
||||
saveConnection () {
|
||||
this.selectWorkspace(this.connection.uid);
|
||||
return this.addConnection(this.connection);
|
||||
},
|
||||
closeAsking () {
|
||||
this.isTesting = false;
|
||||
|
@@ -438,13 +438,15 @@ export default {
|
||||
|
||||
// Fields Changes
|
||||
const changes = [];
|
||||
this.localFields.forEach((field, i) => {
|
||||
const originalField = this.originalFields.find(oField => oField._antares_id === field._antares_id);
|
||||
if (!originalField) return;
|
||||
const after = i > 0 ? this.localFields[i - 1].name : false;
|
||||
this.originalFields.forEach((originalField, oI) => {
|
||||
const lI = this.localFields.findIndex(localField => localField._antares_id === originalField._antares_id);
|
||||
const originalSibling = oI > 0 ? this.originalFields[oI - 1]._antares_id : false;
|
||||
const localSibling = lI > 0 ? this.localFields[lI - 1]._antares_id : false;
|
||||
const after = lI > 0 ? this.localFields[lI - 1].name : false;
|
||||
const orgName = originalField.name;
|
||||
|
||||
changes.push({ ...field, after, orgName });
|
||||
if (JSON.stringify(originalField) !== JSON.stringify(this.localFields[lI]) || originalSibling !== localSibling)
|
||||
if (this.localFields[lI]) changes.push({ ...this.localFields[lI], after, orgName });
|
||||
});
|
||||
|
||||
// OPTIONS
|
||||
|
@@ -151,7 +151,7 @@
|
||||
|
||||
<BaseSelect
|
||||
v-model="selectedSchema"
|
||||
:options="[{value: null, label: $t('message.noSchema')}, ...databaseSchemas.map(el => ({label: el, value: el}))]"
|
||||
:options="[{value: 'null', label: $t('message.noSchema')}, ...databaseSchemas.map(el => ({label: el, value: el}))]"
|
||||
class="form-select select-sm text-bold"
|
||||
/>
|
||||
</div>
|
||||
|
@@ -5,6 +5,7 @@
|
||||
tabindex="0"
|
||||
:style="{'height': resultsSize+'px'}"
|
||||
@keyup.delete="showDeleteConfirmModal"
|
||||
@keydown.ctrl.a="selectAllRows($event)"
|
||||
@keydown.esc="deselectRows"
|
||||
>
|
||||
<TableContext
|
||||
@@ -77,11 +78,7 @@
|
||||
:key-usage="keyUsage"
|
||||
:element-type="elementType"
|
||||
:class="{'selected': selectedRows.includes(row._antares_id)}"
|
||||
:selected="selectedRows.includes(row._antares_id)"
|
||||
:selected-cell="selectedRows.length === 1 && selectedRows.includes(row._antares_id) ? selectedField : null"
|
||||
@start-editing="isEditingRow = true"
|
||||
@stop-editing="isEditingRow = false"
|
||||
@select-row="selectRow"
|
||||
@select-row="selectRow($event, row._antares_id)"
|
||||
@update-field="updateField($event, row)"
|
||||
@contextmenu="contextMenu"
|
||||
/>
|
||||
@@ -165,9 +162,7 @@ export default {
|
||||
currentSortDir: 'asc',
|
||||
resultsetIndex: 0,
|
||||
scrollElement: null,
|
||||
rowHeight: 23,
|
||||
selectedField: null,
|
||||
isEditingRow: false
|
||||
rowHeight: 23
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -273,11 +268,9 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
window.addEventListener('resize', this.resizeResults);
|
||||
window.addEventListener('keydown', this.onKey);
|
||||
},
|
||||
unmounted () {
|
||||
window.removeEventListener('resize', this.resizeResults);
|
||||
window.removeEventListener('keydown', this.onKey);
|
||||
},
|
||||
methods: {
|
||||
fieldType (cKey) {
|
||||
@@ -454,23 +447,20 @@ export default {
|
||||
return row;
|
||||
});
|
||||
},
|
||||
selectRow (event, row, field) {
|
||||
this.selectedField = field;
|
||||
const selectedRowId = row._antares_id;
|
||||
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (this.selectedRows.includes(selectedRowId))
|
||||
this.selectedRows = this.selectedRows.filter(el => el !== selectedRowId);
|
||||
selectRow (event, row) {
|
||||
if (event.ctrlKey) {
|
||||
if (this.selectedRows.includes(row))
|
||||
this.selectedRows = this.selectedRows.filter(el => el !== row);
|
||||
else
|
||||
this.selectedRows.push(selectedRowId);
|
||||
this.selectedRows.push(row);
|
||||
}
|
||||
else if (event.shiftKey) {
|
||||
if (!this.selectedRows.length)
|
||||
this.selectedRows.push(selectedRowId);
|
||||
this.selectedRows.push(row);
|
||||
else {
|
||||
const lastID = this.selectedRows.slice(-1)[0];
|
||||
const lastIndex = this.sortedResults.findIndex(el => el._antares_id === lastID);
|
||||
const clickedIndex = this.sortedResults.findIndex(el => el._antares_id === selectedRowId);
|
||||
const clickedIndex = this.sortedResults.findIndex(el => el._antares_id === row);
|
||||
if (lastIndex > clickedIndex) {
|
||||
for (let i = clickedIndex; i < lastIndex; i++)
|
||||
this.selectedRows.push(this.sortedResults[i]._antares_id);
|
||||
@@ -482,20 +472,18 @@ export default {
|
||||
}
|
||||
}
|
||||
else
|
||||
this.selectedRows = [selectedRowId];
|
||||
this.selectedRows = [row];
|
||||
},
|
||||
selectAllRows (e) {
|
||||
if (e.target.classList.contains('editable-field')) return;
|
||||
|
||||
this.selectedField = 0;
|
||||
this.selectedRows = this.localResults.reduce((acc, curr) => {
|
||||
acc.push(curr._antares_id);
|
||||
return acc;
|
||||
}, []);
|
||||
},
|
||||
deselectRows () {
|
||||
if (!this.isEditingRow)
|
||||
this.selectedRows = [];
|
||||
this.selectedRows = [];
|
||||
},
|
||||
contextMenu (event, cell) {
|
||||
if (event.target.localName === 'input') return;
|
||||
@@ -548,113 +536,6 @@ export default {
|
||||
content: rows,
|
||||
filename
|
||||
});
|
||||
},
|
||||
onKey (e) {
|
||||
if (!this.isSelected)
|
||||
return;
|
||||
|
||||
if (this.isEditingRow)
|
||||
return;
|
||||
|
||||
if ((e.ctrlKey || e.metaKey) && e.code === 'KeyA' && !e.altKey)
|
||||
this.selectAllRows(e);
|
||||
|
||||
// row naviation stuff
|
||||
if ((e.code.includes('Arrow') || e.code === 'Tab') && this.sortedResults.length > 0 && !e.altKey) {
|
||||
e.preventDefault();
|
||||
|
||||
const aviableFields= Object.keys(this.sortedResults[0]).slice(0, -1); // removes _antares_id
|
||||
|
||||
if (!this.selectedField)
|
||||
this.selectedField = aviableFields[0];
|
||||
|
||||
const selectedId = this.selectedRows[0];
|
||||
const selectedIndex = this.sortedResults.findIndex(row => row._antares_id === selectedId);
|
||||
const selectedFieldIndex = aviableFields.findIndex(field => field === this.selectedField);
|
||||
let nextIndex = 0;
|
||||
let nextFieldIndex = 0;
|
||||
|
||||
if (selectedIndex > -1) {
|
||||
switch (e.code) {
|
||||
case 'ArrowDown':
|
||||
nextIndex = selectedIndex + 1;
|
||||
nextFieldIndex = selectedFieldIndex;
|
||||
|
||||
if (nextIndex > this.sortedResults.length -1)
|
||||
nextIndex = this.sortedResults.length -1;
|
||||
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
nextIndex = selectedIndex - 1;
|
||||
nextFieldIndex = selectedFieldIndex;
|
||||
|
||||
if (nextIndex < 0)
|
||||
nextIndex = 0;
|
||||
|
||||
break;
|
||||
|
||||
case 'ArrowRight':
|
||||
nextIndex = selectedIndex;
|
||||
nextFieldIndex = selectedFieldIndex + 1;
|
||||
|
||||
if (nextFieldIndex > aviableFields.length -1)
|
||||
nextFieldIndex = 0;
|
||||
|
||||
break;
|
||||
|
||||
case 'ArrowLeft':
|
||||
nextIndex = selectedIndex;
|
||||
nextFieldIndex = selectedFieldIndex - 1;
|
||||
|
||||
if (nextFieldIndex < 0)
|
||||
nextFieldIndex = aviableFields.length -1;
|
||||
|
||||
break;
|
||||
|
||||
case 'Tab':
|
||||
nextIndex = selectedIndex;
|
||||
if (e.shiftKey) {
|
||||
nextFieldIndex = selectedFieldIndex - 1;
|
||||
if (nextFieldIndex < 0)
|
||||
nextFieldIndex = aviableFields.length -1;
|
||||
}
|
||||
else {
|
||||
nextFieldIndex = selectedFieldIndex + 1;
|
||||
if (nextFieldIndex > aviableFields.length -1)
|
||||
nextFieldIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sortedResults[nextIndex] && nextIndex !== selectedIndex) {
|
||||
this.selectedRows = [this.sortedResults[nextIndex]._antares_id];
|
||||
this.$nextTick(() => this.scrollToCell(this.scrollElement.querySelector('.td.selected')));
|
||||
}
|
||||
|
||||
if (aviableFields[nextFieldIndex] && nextFieldIndex !== selectedFieldIndex) {
|
||||
this.selectedField = aviableFields[nextFieldIndex];
|
||||
this.$nextTick(() => this.scrollToCell(this.scrollElement.querySelector('.td.selected')));
|
||||
}
|
||||
}
|
||||
},
|
||||
scrollToCell (el) {
|
||||
if (!el) return;
|
||||
const visYMin = this.scrollElement.scrollTop;
|
||||
const visYMax = this.scrollElement.scrollTop + this.scrollElement.clientHeight - el.clientHeight;
|
||||
const visXMin = this.scrollElement.scrollLeft;
|
||||
const visXMax = this.scrollElement.scrollLeft + this.scrollElement.clientWidth - el.clientWidth;
|
||||
|
||||
if (el.offsetTop < visYMin)
|
||||
this.scrollElement.scrollTop = el.offsetTop;
|
||||
|
||||
else if (el.offsetTop >= visYMax)
|
||||
this.scrollElement.scrollTop = el.offsetTop - this.scrollElement.clientHeight + el.clientHeight;
|
||||
|
||||
if (el.offsetLeft < visXMin)
|
||||
this.scrollElement.scrollLeft = el.offsetLeft;
|
||||
|
||||
else if (el.offsetLeft >= visXMax)
|
||||
this.scrollElement.scrollLeft = el.offsetLeft - this.scrollElement.clientWidth + el.clientWidth;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -2,15 +2,14 @@
|
||||
<div
|
||||
class="tr"
|
||||
:style="{height: itemHeight+'px'}"
|
||||
@click="selectRow($event, row._antares_id)"
|
||||
>
|
||||
<div
|
||||
v-for="(col, cKey) in row"
|
||||
v-show="cKey !== '_antares_id'"
|
||||
:key="cKey"
|
||||
class="td p-0"
|
||||
:class="{selected: selectedCell === cKey}"
|
||||
@click="selectRow($event, cKey)"
|
||||
|
||||
tabindex="0"
|
||||
@contextmenu.prevent="openContext($event, { id: row._antares_id, orgField: cKey })"
|
||||
>
|
||||
<template v-if="cKey !== '_antares_id'">
|
||||
@@ -18,7 +17,7 @@
|
||||
v-if="!isInlineEditor[cKey] && fields[cKey]"
|
||||
class="cell-content"
|
||||
:class="`${isNull(col)} ${typeClass(fields[cKey].type)}`"
|
||||
@dblclick="editON(cKey)"
|
||||
@dblclick="editON($event, col, cKey)"
|
||||
>{{ cutText(typeFormat(col, fields[cKey].type.toLowerCase(), fields[cKey].length)) }}</span>
|
||||
<ForeignKeySelect
|
||||
v-else-if="isForeignKey(cKey)"
|
||||
@@ -106,7 +105,7 @@
|
||||
<div class="mr-4">
|
||||
<b>{{ $t('word.size') }}</b>: {{ editingContent ? editingContent.length : 0 }}
|
||||
</div>
|
||||
<div v-if="editingType">
|
||||
<div>
|
||||
<b>{{ $t('word.type') }}</b>: {{ editingType.toUpperCase() }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -171,9 +170,7 @@
|
||||
<b>{{ $t('word.size') }}</b>: {{ formatBytes(editingContent.length) }}<br>
|
||||
<b>{{ $t('word.mimeType') }}</b>: {{ contentInfo.mime }}
|
||||
</div>
|
||||
<div v-if="editingType">
|
||||
<b>{{ $t('word.type') }}</b>: {{ editingType.toUpperCase() }}
|
||||
</div>
|
||||
<div><b>{{ $t('word.type') }}</b>: {{ editingType.toUpperCase() }}</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<label>{{ $t('message.uploadFile') }}</label>
|
||||
@@ -233,11 +230,9 @@ export default {
|
||||
fields: Object,
|
||||
keyUsage: Array,
|
||||
itemHeight: Number,
|
||||
elementType: { type: String, default: 'table' },
|
||||
selected: { type: Boolean, default: false },
|
||||
selectedCell: { type: String, default: null }
|
||||
elementType: { type: String, default: 'table' }
|
||||
},
|
||||
emits: ['update-field', 'select-row', 'contextmenu', 'start-editing', 'stop-editing'],
|
||||
emits: ['update-field', 'select-row', 'contextmenu'],
|
||||
data () {
|
||||
return {
|
||||
isInlineEditor: {},
|
||||
@@ -341,9 +336,6 @@ export default {
|
||||
|
||||
return false;
|
||||
},
|
||||
isBaseSelectField () {
|
||||
return this.isForeignKey(this.editingField) || this.inputProps.type === 'boolean' || this.enumArray;
|
||||
},
|
||||
enumArray () {
|
||||
if (this.fields[this.editingField] && this.fields[this.editingField].enumValues)
|
||||
return this.fields[this.editingField].enumValues.replaceAll('\'', '').split(',');
|
||||
@@ -370,21 +362,8 @@ export default {
|
||||
this.editorMode = this.availableLanguages.find(lang => lang.id === filteredLanguages[0].languageId).slug;
|
||||
})();
|
||||
}
|
||||
},
|
||||
selected (isSelected) {
|
||||
if (isSelected)
|
||||
window.addEventListener('keydown', this.onKey);
|
||||
|
||||
else {
|
||||
this.editOFF();
|
||||
window.removeEventListener('keydown', this.onKey);
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
if (this.selected)
|
||||
window.removeEventListener('keydown', this.onKey);
|
||||
},
|
||||
methods: {
|
||||
isForeignKey (key) {
|
||||
if (key.includes('.'))
|
||||
@@ -403,10 +382,11 @@ export default {
|
||||
bufferToBase64 (val) {
|
||||
return bufferToBase64(val);
|
||||
},
|
||||
editON (field) {
|
||||
editON (event, content, field) {
|
||||
if (!this.isEditable || this.editingType === 'none') return;
|
||||
|
||||
const content = this.row[field];
|
||||
window.addEventListener('keydown', this.onKey);
|
||||
|
||||
const type = this.fields[field].type.toUpperCase();
|
||||
this.originalContent = this.typeFormat(content, type, this.fields[field].length);
|
||||
this.editingType = type;
|
||||
@@ -416,7 +396,6 @@ export default {
|
||||
if ([...LONG_TEXT, ...ARRAY, ...TEXT_SEARCH].includes(type)) {
|
||||
this.isTextareaEditor = true;
|
||||
this.editingContent = this.typeFormat(content, type);
|
||||
this.$emit('start-editing', field);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -426,7 +405,6 @@ export default {
|
||||
this.isMapModal = true;
|
||||
this.editingContent = this.typeFormat(content, type);
|
||||
}
|
||||
this.$emit('start-editing', field);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -448,21 +426,19 @@ export default {
|
||||
};
|
||||
}
|
||||
}
|
||||
this.$emit('start-editing', field);
|
||||
return;
|
||||
}
|
||||
|
||||
// Inline editable fields
|
||||
this.editingContent = this.originalContent;
|
||||
this.$nextTick(() => { // Focus on input
|
||||
event.target.blur();
|
||||
|
||||
this.$nextTick(() => document.querySelector('.editable-field').focus());
|
||||
});
|
||||
|
||||
const obj = { [field]: true };
|
||||
this.isInlineEditor = { ...this.isInlineEditor, ...obj };
|
||||
|
||||
this.$nextTick(() => { // Focus on input
|
||||
document.querySelector('.editable-field').focus();
|
||||
});
|
||||
|
||||
this.$emit('start-editing', field);
|
||||
},
|
||||
editOFF () {
|
||||
if (!this.editingField) return;
|
||||
@@ -475,13 +451,7 @@ export default {
|
||||
this.editingContent = this.editingContent.slice(0, -1);
|
||||
}
|
||||
|
||||
// If not changed
|
||||
if (this.editingContent === this.typeFormat(this.originalContent, this.editingType, this.editingLength)) {
|
||||
this.editingType = null;
|
||||
this.editingField = null;
|
||||
this.$emit('stop-editing', this.editingField);
|
||||
return;
|
||||
}
|
||||
if (this.editingContent === this.typeFormat(this.originalContent, this.editingType, this.editingLength)) return;// If not changed
|
||||
|
||||
content = this.editingContent;
|
||||
}
|
||||
@@ -502,17 +472,15 @@ export default {
|
||||
content
|
||||
});
|
||||
|
||||
this.$emit('stop-editing', this.editingField);
|
||||
|
||||
this.editingType = null;
|
||||
this.editingField = null;
|
||||
window.removeEventListener('keydown', this.onKey);
|
||||
},
|
||||
hideEditorModal () {
|
||||
this.isTextareaEditor = false;
|
||||
this.isBlobEditor = false;
|
||||
this.isMapModal = false;
|
||||
this.isMultiSpatial = false;
|
||||
this.$emit('stop-editing', this.editingField);
|
||||
},
|
||||
downloadFile () {
|
||||
const downloadLink = document.createElement('a');
|
||||
@@ -540,8 +508,8 @@ export default {
|
||||
};
|
||||
this.willBeDeleted = true;
|
||||
},
|
||||
selectRow (event, field) {
|
||||
this.$emit('select-row', event, this.row, field);
|
||||
selectRow (event, row) {
|
||||
this.$emit('select-row', event, row);
|
||||
},
|
||||
getKeyUsage (keyName) {
|
||||
if (keyName.includes('.'))
|
||||
@@ -555,17 +523,10 @@ export default {
|
||||
},
|
||||
onKey (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if (!this.editingField && e.key === 'Enter')
|
||||
return this.editON(this.selectedCell);
|
||||
|
||||
if (this.editingField && e.key === 'Enter' && !this.isBaseSelectField)
|
||||
return this.editOFF();
|
||||
|
||||
if (this.editingField && e.key === 'Escape') {
|
||||
if (e.key === 'Escape') {
|
||||
this.isInlineEditor[this.editingField] = false;
|
||||
this.editingField = null;
|
||||
this.$emit('stop-editing', this.editingField);
|
||||
window.removeEventListener('keydown', this.onKey);
|
||||
}
|
||||
},
|
||||
formatBytes,
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 5.8 KiB |
@@ -27,14 +27,4 @@ $titlebar-height: 1.5rem;
|
||||
$settingbar-width: 3rem;
|
||||
$explorebar-width: 14rem;
|
||||
$footer-height: 1.5rem;
|
||||
|
||||
@function get-excluding-size(){
|
||||
@if $platform == linux{
|
||||
@return $footer-height;
|
||||
}
|
||||
@else {
|
||||
@return $footer-height + $titlebar-height;
|
||||
}
|
||||
}
|
||||
|
||||
$excluding-size: get-excluding-size();
|
||||
$excluding-size: $footer-height + $titlebar-height;
|
||||
|
@@ -231,8 +231,7 @@
|
||||
.td {
|
||||
border-color: $body-bg-dark;
|
||||
|
||||
&:focus,
|
||||
&.selected {
|
||||
&:focus {
|
||||
box-shadow: inset 0 0 0 2px darken($body-font-color-dark, 40%);
|
||||
background-color: rgba($color: #000, $alpha: 0.3);
|
||||
}
|
||||
@@ -361,7 +360,7 @@
|
||||
.titlebar-element {
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
background: rgba($color: #fff, $alpha: 0.1);
|
||||
background: rgba($color: #fff, $alpha: 0.2);
|
||||
}
|
||||
|
||||
&.close-button:hover {
|
||||
|
@@ -132,7 +132,7 @@
|
||||
.titlebar-element {
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
background: rgba($color: rgb(172, 172, 172), $alpha: 0.3);
|
||||
background: rgba($color: rgb(172, 172, 172), $alpha: 0.2);
|
||||
}
|
||||
|
||||
&.close-button:hover {
|
||||
@@ -252,8 +252,7 @@
|
||||
.td {
|
||||
border-color: $body-bg;
|
||||
|
||||
&:focus,
|
||||
&.selected {
|
||||
&:focus {
|
||||
box-shadow: inset 0 0 0 2px lighten($body-font-color, 10%);
|
||||
background-color: $body-font-color-dark;
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { defineStore, acceptHMRUpdate } from 'pinia';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import i18n from '@/i18n';
|
||||
import Store from 'electron-store';
|
||||
const persistentStore = new Store({ name: 'settings' });
|
||||
@@ -55,7 +54,6 @@ export const useSettingsStore = defineStore('settings', {
|
||||
changeApplicationTheme (theme) {
|
||||
this.applicationTheme = theme;
|
||||
persistentStore.set('application_theme', this.applicationTheme);
|
||||
ipcRenderer.send('refresh-theme-settings');
|
||||
},
|
||||
changeEditorTheme (theme) {
|
||||
this.editorTheme = theme;
|
||||
|
@@ -117,14 +117,13 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
||||
|
||||
// Check if Maria or MySQL
|
||||
const isMySQL = version.name.includes('MySQL');
|
||||
const isMaria = version.name.includes('Maria');
|
||||
|
||||
if (isMySQL && connection.client !== 'mysql') {
|
||||
const connProxy = Object.assign({}, connection);
|
||||
connProxy.client = 'mysql';
|
||||
connectionsStore.editConnection(connProxy);
|
||||
}
|
||||
else if (isMaria && connection.client === 'mysql') {
|
||||
else if (!isMySQL && connection.client === 'mysql') {
|
||||
const connProxy = Object.assign({}, connection);
|
||||
connProxy.client = 'maria';
|
||||
connectionsStore.editConnection(connProxy);
|
||||
@@ -610,26 +609,6 @@ export const useWorkspacesStore = defineStore('workspaces', {
|
||||
: workspace
|
||||
);
|
||||
},
|
||||
selectNextTab ({ uid }) {
|
||||
const workspace = this.workspaces.find(workspace => workspace.uid === uid);
|
||||
|
||||
let newIndex = workspace.tabs.findIndex(tab => tab.selected || tab.uid === workspace.selectedTab) + 1;
|
||||
|
||||
if (newIndex > workspace.tabs.length -1)
|
||||
newIndex = 0;
|
||||
|
||||
this.selectTab({ uid, tab: workspace.tabs[newIndex].uid });
|
||||
},
|
||||
selectPrevTab ({ uid }) {
|
||||
const workspace = this.workspaces.find(workspace => workspace.uid === uid);
|
||||
|
||||
let newIndex = workspace.tabs.findIndex(tab => tab.selected || tab.uid === workspace.selectedTab) - 1;
|
||||
|
||||
if (newIndex < 0)
|
||||
newIndex = workspace.tabs.length -1;
|
||||
|
||||
this.selectTab({ uid, tab: workspace.tabs[newIndex].uid });
|
||||
},
|
||||
updateTabs ({ uid, tabs }) {
|
||||
this.workspaces = this.workspaces.map(workspace => workspace.uid === uid
|
||||
? { ...workspace, tabs }
|
||||
|
@@ -21,7 +21,7 @@ test('launch app', async () => {
|
||||
|
||||
test('main window elements visibility', async () => {
|
||||
const visibleSelectors = [
|
||||
// '#titlebar',
|
||||
'#titlebar',
|
||||
'#window-content',
|
||||
'#settingbar',
|
||||
'#footer'
|
||||
|
@@ -104,9 +104,7 @@ const config = {
|
||||
{
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
additionalData: `
|
||||
$platform: ${process.platform};
|
||||
@import "@/scss/_variables.scss";`,
|
||||
additionalData: '@import "@/scss/_variables.scss";',
|
||||
sassOptions: { quietDeps: true }
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user