1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-06-05 21:59:22 +02:00

Compare commits

..

21 Commits

Author SHA1 Message Date
allcontributors[bot]
d163cbfac8 docs: update .all-contributorsrc [skip ci] 2024-04-08 10:49:32 +00:00
allcontributors[bot]
4537d96f3e docs: update README.md [skip ci] 2024-04-08 10:49:31 +00:00
a752dcb6a9 chore(release): 0.7.23 2024-04-07 16:54:05 +02:00
1875e895ae chore(release): 0.7.23-beta.1 2024-04-02 09:10:17 +02:00
2064294119 feat: add the page reference in the export file name, closes #772 2024-03-25 09:08:30 +01:00
62e3115860 feat: move connections out of folder from context menu, related to #773 2024-03-24 11:10:00 +01:00
9aef287a98 feat: move connections to folders from context menu, related to #773 2024-03-23 18:45:38 +01:00
65ec4c5da6 fix: bad format of timestamp fields on CSV export, fixes 776 2024-03-23 16:33:19 +01:00
e19118982b chore(release): 0.7.23-beta.0 2024-03-21 23:09:09 +01:00
11f130d91c Merge pull request #778 from dyaskur/fix_shortcut_on_macos
fix: shortcut not working on mac os
2024-03-14 09:05:07 +01:00
Yaskur
0bb5cedda6 fix: shortcut not working on mac os 2024-03-13 15:48:59 +07:00
de9dac3e8a fix: query result sort not working with aliased tables, fixes #765 2024-03-10 16:04:24 +01:00
dd5b41716a fix: CSV export does not escape strings when needed, fixes #770 2024-03-09 15:42:36 +01:00
86acb390ac build: add husky and commitlint 2024-03-09 15:05:55 +01:00
2884ec3dd6 chore(release): 0.7.22 2024-02-26 18:20:31 +01:00
b542a09c01 Merge branch 'beta' of https://github.com/antares-sql/antares 2024-02-26 18:19:35 +01:00
6d94a04b67 Merge branch 'develop' of https://github.com/antares-sql/antares into beta 2024-02-26 18:19:14 +01:00
8500fc40a1 refactor: improved note tab selection 2024-02-26 18:17:15 +01:00
586f901bae fix: delete record modal pressing del when editing a field, fixes #767 2024-02-23 18:08:02 +01:00
6d002efaf5 Update FUNDING.yml 2024-02-09 12:07:16 +01:00
58be1abf5f Update README.md 2024-02-09 09:27:16 +01:00
25 changed files with 2464 additions and 141 deletions

View File

@@ -266,6 +266,15 @@
"contributions": [
"translation"
]
},
{
"login": "bagusindrayana",
"name": "Bagus Indrayana",
"avatar_url": "https://avatars.githubusercontent.com/u/36830534?v=4",
"profile": "https://github.com/bagusindrayana",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

2
.github/FUNDING.yml vendored
View File

@@ -1,6 +1,6 @@
# These are supported funding model platforms
github: [fabio286]
github: [antares-sql,fabio286]
patreon: #fabio286
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username

1
.husky/commit-msg Normal file
View File

@@ -0,0 +1 @@
npx --no -- commitlint --edit $1

1
.husky/pre-commit Normal file
View File

@@ -0,0 +1 @@
npm run lint

View File

@@ -5,14 +5,14 @@
],
"fix": true,
"formatter": "verbose",
"customSyntax": "postcss-html",
"plugins": [
"stylelint-scss"
],
"rules": {
"at-rule-no-unknown": null,
"no-descending-specificity": null,
"font-family-no-missing-generic-family-keyword": null,
"declaration-colon-newline-after": "always-multi-line"
"font-family-no-missing-generic-family-keyword": null
},
"syntax": "scss"
}

View File

@@ -2,6 +2,38 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.7.23](https://github.com/antares-sql/antares/compare/v0.7.23-beta.1...v0.7.23) (2024-04-07)
### [0.7.23-beta.1](https://github.com/antares-sql/antares/compare/v0.7.23-beta.0...v0.7.23-beta.1) (2024-04-02)
### Features
* add the page reference in the export file name, closes [#772](https://github.com/antares-sql/antares/issues/772) ([2064294](https://github.com/antares-sql/antares/commit/2064294119ed9dfab2a9968dfb5b35d52e2ae03b))
* move connections out of folder from context menu, related to [#773](https://github.com/antares-sql/antares/issues/773) ([62e3115](https://github.com/antares-sql/antares/commit/62e311586073ae7ee4896305198c7168f637c1af))
* move connections to folders from context menu, related to [#773](https://github.com/antares-sql/antares/issues/773) ([9aef287](https://github.com/antares-sql/antares/commit/9aef287a983754158cdbdc9b2a72db9ab82f76c8))
### Bug Fixes
* bad format of timestamp fields on CSV export, fixes 776 ([65ec4c5](https://github.com/antares-sql/antares/commit/65ec4c5da6187a7ab2dfff59326cd12bfa788c3b))
### [0.7.23-beta.0](https://github.com/antares-sql/antares/compare/v0.7.22...v0.7.23-beta.0) (2024-03-21)
### Bug Fixes
* CSV export does not escape strings when needed, fixes [#770](https://github.com/antares-sql/antares/issues/770) ([dd5b417](https://github.com/antares-sql/antares/commit/dd5b41716a10cf9500f2c611b232f5b5b0756a68))
* query result sort not working with aliased tables, fixes [#765](https://github.com/antares-sql/antares/issues/765) ([de9dac3](https://github.com/antares-sql/antares/commit/de9dac3e8abf3b3261f8c54c88cf2386a5be2207))
* shortcut not working on mac os ([0bb5ced](https://github.com/antares-sql/antares/commit/0bb5cedda6a67ccbeea8c127b799f533395101a2))
### [0.7.22](https://github.com/antares-sql/antares/compare/v0.7.22-beta.2...v0.7.22) (2024-02-26)
### Bug Fixes
* delete record modal pressing del when editing a field, fixes [#767](https://github.com/antares-sql/antares/issues/767) ([586f901](https://github.com/antares-sql/antares/commit/586f901bae9a80c0e53ac1d804cbae3f05e26d8e))
### [0.7.22-beta.2](https://github.com/antares-sql/antares/compare/v0.7.22-beta.1...v0.7.22-beta.2) (2024-02-18)

View File

@@ -101,7 +101,7 @@ On macOS you can run `.dmg` distribution following [this guide](https://support.
- 🌍 [Translate Antares](https://github.com/Fabio286/antares/wiki/Translate-Antares)
- 📖 [Contributors Guide](https://github.com/Fabio286/antares/wiki/Contributors-Guide)
- 🚧 [Project Board](https://github.com/antares-sql/antares/projects/1)
- 🚧 [Project Board](https://github.com/orgs/antares-sql/projects/3/views/2)
## Contributors ✨
@@ -148,6 +148,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Lawondyss"><img src="https://avatars.githubusercontent.com/u/272130?v=4?s=100" width="100px;" alt="Ladislav Vondráček"/><br /><sub><b>Ladislav Vondráček</b></sub></a><br /><a href="#translation-Lawondyss" title="Translation">🌍</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/zvlad"><img src="https://avatars.githubusercontent.com/u/9055134?v=4?s=100" width="100px;" alt="Vladyslav"/><br /><sub><b>Vladyslav</b></sub></a><br /><a href="#translation-zvlad" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/bagusindrayana"><img src="https://avatars.githubusercontent.com/u/36830534?v=4?s=100" width="100px;" alt="Bagus Indrayana"/><br /><sub><b>Bagus Indrayana</b></sub></a><br /><a href="https://github.com/antares-sql/antares/commits?author=bagusindrayana" title="Code">💻</a></td>
</tr>
</tbody>
</table>

33
commitlint.config.js Normal file
View File

@@ -0,0 +1,33 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// TODO Add Scope Enum Here
// 'scope-enum': [2, 'always', ['yourscope', 'yourscope']],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'docs',
'chore',
'style',
'refactor',
'build',
'ci',
'test',
'revert',
'perf'
]
],
'subject-case': [
2,
'never',
[
'upper-case',
'pascal-case',
'start-case'
]
]
}
};

2259
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "antares",
"productName": "Antares",
"version": "0.7.22-beta.2",
"version": "0.7.23",
"description": "A modern, fast and productivity driven SQL client with a focus in UX.",
"license": "MIT",
"repository": "https://github.com/antares-sql/antares.git",
@@ -25,7 +25,8 @@
"lint": "eslint . --ext .js,.ts,.vue && stylelint \"./src/**/*.{css,scss,sass,vue}\"",
"lint:fix": "eslint . --ext .js,.ts,.vue --fix && stylelint \"./src/**/*.{css,scss,sass,vue}\" --fix",
"contributors:add": "all-contributors add",
"contributors:generate": "all-contributors generate"
"contributors:generate": "all-contributors generate",
"prepare": "husky"
},
"author": "Fabio Di Stasio <info@fabiodistasio.it>",
"main": "./dist/main.js",
@@ -179,6 +180,8 @@
"@babel/eslint-parser": "~7.15.7",
"@babel/preset-env": "~7.15.8",
"@babel/preset-typescript": "~7.16.7",
"@commitlint/cli": "~19.0.3",
"@commitlint/config-conventional": "~19.0.3",
"@playwright/test": "~1.28.1",
"@types/better-sqlite3": "~7.5.0",
"@types/leaflet": "~1.7.9",
@@ -198,6 +201,7 @@
"eslint-plugin-promise": "~5.2.0",
"eslint-plugin-simple-import-sort": "~10.0.0",
"eslint-plugin-vue": "~8.0.3",
"husky": "~9.0.11",
"playwright": "~1.28.1",
"playwright-core": "~1.28.1",
"standard-version": "~9.3.1",

View File

@@ -70,23 +70,21 @@ export class ShortcutRegister {
}
private setLocalShortcuts () {
const isMenuVisible = process.platform === 'darwin';
const submenu = [];
for (const shortcut of this.shortcuts) {
if (shortcut.os.includes(process.platform)) {
for (const key of shortcut.keys) {
try {
this._menu.append(new MenuItem({
label: '.',
visible: false,
submenu: [{
label: String(key),
submenu.push({
label: String(shortcut.event),
accelerator: key,
visible: false,
visible: isMenuVisible,
click: () => {
this._mainWindow.webContents.send(shortcut.event);
if (isDevelopment) console.log('LOCAL EVENT:', shortcut);
}
}]
}));
});
}
catch (error) {
if (isDevelopment) console.log(error);
@@ -96,6 +94,11 @@ export class ShortcutRegister {
}
}
}
this._menu.append(new MenuItem({
label: 'Shortcut',
visible: isMenuVisible,
submenu
}));
}
private setGlobalShortcuts () {

View File

@@ -127,8 +127,8 @@ app.on('ready', async () => {
if (isWindows)
mainWindow.show();
// if (isDevelopment)
// mainWindow.webContents.openDevTools();
if (isDevelopment && !isWindows)// Because on Windows you can open devtools from title-bar
mainWindow.webContents.openDevTools();
process.on('uncaughtException', error => {
mainWindow.webContents.send('unhandled-exception', error);

View File

@@ -15,6 +15,56 @@
:size="18"
/> {{ t('connection.disconnect') }}</span>
</div>
<div v-if="!contextConnection.isFolder" class="context-element">
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiFolderMove"
:size="18"
/> {{ t('general.moveTo') }}</span>
<BaseIcon
class="text-light ml-1"
icon-name="mdiChevronRight"
:size="18"
/>
<div class="context-submenu">
<div class="context-element" @click.stop="moveToFolder(null)">
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiFolderPlus"
:size="18"
/> {{ t('application.newFolder') }}</span>
</div>
<div
v-for="folder in filteredFolders"
:key="folder.uid"
class="context-element"
@click.stop="moveToFolder(folder.uid)"
>
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiFolder"
:size="18"
:style="`color: ${folder.color}!important`"
/> {{ folder.name || t('general.folder') }}</span>
</div>
<div
v-if="isInFolder"
class="context-element"
@click="outOfFolder"
>
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiFolderOff"
:size="18"
/> {{ t('application.outOfFolder') }}</span>
</div>
</div>
</div>
<div class="context-element" @click.stop="showAppearanceModal">
<span class="d-flex">
<BaseIcon
@@ -79,6 +129,7 @@
<script setup lang="ts">
import { uidGen } from 'common/libs/uidGen';
import { storeToRefs } from 'pinia';
import { computed, Prop, ref } from 'vue';
import { useI18n } from 'vue-i18n';
@@ -98,9 +149,14 @@ const {
getConnectionByUid,
getConnectionName,
addConnection,
deleteConnection
deleteConnection,
addFolder,
addToFolder,
removeFromFolders
} = connectionsStore;
const { getFolders: folders } = storeToRefs(connectionsStore);
const workspacesStore = useWorkspacesStore();
const {
@@ -121,6 +177,8 @@ const isConnectionEdit = ref(false);
const connectionName = computed(() => props.contextConnection.name || getConnectionName(props.contextConnection.uid) || t('general.folder', 1));
const isConnected = computed(() => getWorkspace(props.contextConnection.uid)?.connectionStatus === 'connected');
const filteredFolders = computed(() => folders.value.filter(f => !f.connections.includes(props.contextConnection.uid)));
const isInFolder = computed(() => folders.value.some(f => f.connections.includes(props.contextConnection.uid)));
const confirmDeleteConnection = () => {
if (isConnected.value)
@@ -129,6 +187,27 @@ const confirmDeleteConnection = () => {
closeContext();
};
const moveToFolder = (folderUid?: string) => {
if (!folderUid) {
addFolder({
connections: [props.contextConnection.uid]
});
}
else {
addToFolder({
folder: folderUid,
connection: props.contextConnection.uid
});
}
closeContext();
};
const outOfFolder = () => {
removeFromFolders(props.contextConnection.uid);
closeContext();
};
const duplicateConnection = () => {
let connectionCopy = getConnectionByUid(props.contextConnection.uid);
connectionCopy = {

View File

@@ -101,7 +101,13 @@ const props = defineProps({
selectedField: Object
});
const emit = defineEmits(['close-context', 'duplicate-selected', 'delete-selected', 'add-new-index', 'add-to-index']);
const emit = defineEmits([
'close-context',
'duplicate-selected',
'delete-selected',
'add-new-index',
'add-to-index'
]);
const hasPrimary = computed(() => props.indexes.some(index => index.type === 'PRIMARY'));

View File

@@ -150,7 +150,13 @@ const props = defineProps({
mode: String
});
const emit = defineEmits(['add-new-index', 'add-to-index', 'rename-field', 'duplicate-field', 'remove-field']);
const emit = defineEmits([
'add-new-index',
'add-to-index',
'rename-field',
'duplicate-field',
'remove-field'
]);
const workspacesStore = useWorkspacesStore();
const consoleStore = useConsoleStore();

View File

@@ -31,7 +31,7 @@
:class="{ 'active': resultsetIndex === index }"
@click="selectResultset(index)"
>
<a>{{ result.fields ? result.fields[0]?.table : '' }} ({{ result.rows.length }})</a>
<a>{{ result.fields ? result.fields[0]?.tableAlias ?? result.fields[0]?.table : `${t('general.results')} #${index}` }} ({{ result.rows.length }})</a>
</li>
</ul>
<div ref="table" class="table table-hover">
@@ -44,7 +44,7 @@
:title="`${field.type} ${fieldLength(field) ? `(${fieldLength(field)})` : ''}`"
>
<div ref="columnResize" class="column-resizable">
<div class="table-column-title" @click="sort(field.name)">
<div class="table-column-title" @click="sort(field)">
<div v-if="field.key" :title="keyName(field.key)">
<BaseIcon
icon-name="mdiKey"
@@ -56,8 +56,8 @@
</div>
<span>{{ field.alias || field.name }}</span>
<BaseIcon
v-if="isSortable && currentSort === field.name || currentSort === `${field.table}.${field.name}`"
:icon-name="currentSortDir === 'asc' ? 'mdiSortAscending' : 'mdiSortDescending'"
v-if="isSortable && currentSort[resultsetIndex]?.field === field.name || currentSort[resultsetIndex]?.field === `${field.tableAlias || field.table}.${field.name}`"
:icon-name="currentSort[resultsetIndex].dir === 'asc' ? 'mdiSortAscending' : 'mdiSortDescending'"
:size="18"
class="sort-icon ml-1"
/>
@@ -292,6 +292,10 @@ const props = defineProps({
results: Array as Prop<QueryResult[]>,
connUid: String,
mode: String as Prop<'table' | 'query'>,
page: {
type: Number,
required: false
},
isSelected: Boolean,
elementType: { type: String, default: 'table' }
});
@@ -314,8 +318,7 @@ const hasFocus = ref(false);
const contextEvent = ref(null);
const selectedCell = ref(null);
const selectedRows = ref([]);
const currentSort = ref('');
const currentSortDir = ref('asc');
const currentSort: Ref<{field: string; dir: 'asc' | 'desc'}[]> = ref([]);
const resultsetIndex = ref(0);
const scrollElement = ref(null);
const rowHeight = ref(23);
@@ -358,14 +361,16 @@ const isHardSort = computed(() => {
});
const sortedResults = computed(() => {
if (currentSort.value && !isHardSort.value) {
if (currentSort.value[resultsetIndex.value] && !isHardSort.value) {
const sortObj = currentSort.value[resultsetIndex.value];
return [...localResults.value].sort((a: any, b: any) => {
let modifier = 1;
let valA = typeof a[currentSort.value] === 'string' ? a[currentSort.value].toLowerCase() : a[currentSort.value];
let valA = typeof a[sortObj.field] === 'string' ? a[sortObj.field].toLowerCase() : a[sortObj.field];
if (!isNaN(valA)) valA = Number(valA);
let valB = typeof b[currentSort.value] === 'string' ? b[currentSort.value].toLowerCase() : b[currentSort.value];
let valB = typeof b[sortObj.field] === 'string' ? b[sortObj.field].toLowerCase() : b[sortObj.field];
if (!isNaN(valB)) valB = Number(valB);
if (currentSortDir.value === 'desc') modifier = -1;
if (sortObj.dir === 'desc') modifier = -1;
if (valA < valB) return -1 * modifier;
if (valA > valB) return 1 * modifier;
return 0;
@@ -784,32 +789,42 @@ const contextMenu = (event: MouseEvent, cell: any) => {
isContext.value = true;
};
const sort = (field: string) => {
const sort = (field: TableField) => {
if (!isSortable.value) return;
selectedRows.value = [];
let fieldName = field.name;
const hasTableInFieldname = Object.keys(localResults.value[0]).find(k => k !== '_antares_id').includes('.');
if (props.mode === 'query')
field = `${getTable(resultsetIndex.value)}.${field}`;
if (props.mode === 'query' && hasTableInFieldname)
fieldName = `${field.tableAlias || field.table}.${field.name}`;
if (field === currentSort.value) {
if (currentSortDir.value === 'asc')
currentSortDir.value = 'desc';
if (fieldName === currentSort.value[resultsetIndex.value]?.field) {
if (currentSort.value[resultsetIndex.value].dir === 'asc')
currentSort.value[resultsetIndex.value].dir = 'desc';
else
resetSort();
}
else {
currentSortDir.value = 'asc';
currentSort.value = field;
currentSort.value[resultsetIndex.value] = {
field: fieldName,
dir: 'asc'
};
}
if (isHardSort.value)
emit('hard-sort', { field: currentSort.value, dir: currentSortDir.value });
if (isHardSort.value) {
emit('hard-sort', {
field: currentSort.value[resultsetIndex.value].field,
dir: currentSort.value[resultsetIndex.value].dir
});
}
};
const resetSort = () => {
currentSort.value = '';
currentSortDir.value = 'asc';
currentSort.value[resultsetIndex.value] = {
field: null,
dir: 'asc'
};
};
const selectResultset = (index: number) => {
@@ -857,6 +872,7 @@ const downloadTable = (format: 'csv' | 'json' | 'sql' | 'php', table: string, po
},
client: workspaceClient.value,
table,
page: props.page,
sqlOptions: popup ? { ...sqlExportOptions.value } : null,
csvOptions: popup ? { ...csvExportOptions.value } : null
});

View File

@@ -43,6 +43,7 @@
autofocus
class="editable-field form-input input-sm px-1"
@blur="editOFF"
@keyup.delete.stop
>
<BaseSelect
v-else-if="inputProps.type === 'boolean'"
@@ -50,6 +51,7 @@
:options="['true', 'false']"
class="form-select small-select editable-field"
@blur="editOFF"
@keyup.delete.stop
/>
<BaseSelect
v-else-if="enumArray"
@@ -58,6 +60,7 @@
class="form-select small-select editable-field"
dropdown-class="small-select"
@blur="editOFF"
@keyup.delete.stop
/>
<input
v-else
@@ -67,6 +70,7 @@
autofocus
class="editable-field form-input input-sm px-1"
@blur="editOFF"
@keyup.delete.stop
>
</template>
</template>

View File

@@ -202,6 +202,7 @@
v-if="results"
ref="queryTable"
:results="results"
:page="page"
:tab-uid="tabUid"
:conn-uid="connection.uid"
:is-selected="isSelected"

View File

@@ -79,7 +79,8 @@ export const enUS = {
search: 'Search',
title: 'Title',
archive: 'Archive', // verb
undo: 'Undo'
undo: 'Undo',
moveTo: 'Move to'
},
connection: { // Database connection
connection: 'Connection',
@@ -332,7 +333,7 @@ export const enUS = {
wrapLongLines: 'Wrap long lines',
markdownSupported: 'Markdown supported',
plantATree: 'Plant a Tree',
dataTabPageSize: 'DATA tab page size',
dataTabPageSize: 'Results per page',
noOpenTabs: 'There are no open tabs, navigate on the left bar or:',
restorePreviousSession: 'Restore previous session',
closeTab: 'Close tab',
@@ -363,6 +364,8 @@ export const enUS = {
editFolder: 'Edit folder',
folderName: 'Folder name',
deleteFolder: 'Delete folder',
newFolder: 'New folder',
outOfFolder: 'Out of folder',
editConnectionAppearance: 'Edit connection appearance',
defaultCopyType: 'Default copy type',
showTableSize: 'Show table size in sidebar',

View File

@@ -1,11 +1,13 @@
import { ClientCode } from 'common/interfaces/antares';
import { jsonToSqlInsert } from 'common/libs/sqlUtils';
import * as json2php from 'json2php';
import * as moment from 'moment';
export const exportRows = (args: {
type: 'csv' | 'json'| 'sql' | 'php';
content: object[];
table: string;
page?: number;
client?: ClientCode;
fields?: {
[key: string]: {type: string; datePrecision: number};
@@ -31,7 +33,7 @@ export const exportRows = (args: {
const csv = [];
const sd = args.csvOptions.stringDelimiter === 'single'
? '\''
: args.csvOptions.stringDelimiter === 'single'
: args.csvOptions.stringDelimiter === 'double'
? '"'
: '';
@@ -41,6 +43,7 @@ export const exportRows = (args: {
for (const row of args.content) {
csv.push(Object.values(row).map(col => {
if (typeof col === 'string') return `${sd}${col}${sd}`;
if (col instanceof Date) return `${sd}${moment(col).format('YYYY-MM-DD HH:mm:ss')}${sd}`;
if (col instanceof Buffer) return col.toString('base64');
if (col instanceof Uint8Array) return Buffer.from(col).toString('base64');
return col;
@@ -81,7 +84,7 @@ export const exportRows = (args: {
const file = new Blob([content], { type: mime });
const downloadLink = document.createElement('a');
downloadLink.download = `${args.sqlOptions?.targetTable || args.table}.${args.type}`;
downloadLink.download = `${args.sqlOptions?.targetTable || args.table}${args.page ? `-${args.page}` : ''}.${args.type}`;
downloadLink.href = window.URL.createObjectURL(file);
downloadLink.style.display = 'none';
document.body.appendChild(downloadLink);

View File

@@ -415,8 +415,7 @@
box-shadow: 0 0 1px 0 #000;
.settingbar-top-elements {
overflow-x: hidden;
overflow-y: overlay;
overflow: hidden overlay;
max-height: calc((100vh - 3.5rem) - #{$excluding-size});
}

View File

@@ -164,8 +164,7 @@
box-shadow: 0 0 1px 0 #000;
.settingbar-top-elements {
overflow-x: hidden;
overflow-y: overlay;
overflow: hidden overlay;
max-height: calc((100vh - 3.5rem) - #{$excluding-size});
}

View File

@@ -55,10 +55,9 @@ export const useApplicationStore = defineStore('application', {
},
showScratchpad (tag?: string) {
this.isScratchpad = true;
if (tag) {
if (!tag) tag = 'all';
const { selectedTag } = storeToRefs(useScratchpadStore());
selectedTag.value = tag;
}
},
hideScratchpad () {
this.isScratchpad = false;

View File

@@ -90,8 +90,12 @@ export const useConnectionsStore = defineStore('connections', {
});
persistentStore.set('connectionsOrder', this.connectionsOrder);
},
addFolder (params: {after: string; connections: [string, string]}) {
const index = this.connectionsOrder.findIndex((conn: SidebarElement) => conn.uid === params.after);
addFolder (params: {after?: string; connections: [string, string?]}) {
const index = params.after
? this.connectionsOrder.findIndex((conn: SidebarElement) => conn.uid === params.after)
: this.connectionsOrder.length;
this.removeFromFolders(...params.connections);
this.connectionsOrder.splice(index, 0, {
isFolder: true,
@@ -102,7 +106,18 @@ export const useConnectionsStore = defineStore('connections', {
});
persistentStore.set('connectionsOrder', this.connectionsOrder);
},
removeFromFolders (...connections: string[]) { // Removes connections from folders
this.connectionsOrder = (this.connectionsOrder as SidebarElement[]).map(el => {
if (el.isFolder)
el.connections = el.connections.filter(uid => !connections.includes(uid));
return el;
});
this.clearEmptyFolders();
},
addToFolder (params: {folder: string; connection: string}) {
this.removeFromFolders(params.connection);
this.connectionsOrder = this.connectionsOrder.map((conn: SidebarElement) => {
if (conn.uid === params.folder)
conn.connections.push(params.connection);
@@ -113,11 +128,7 @@ export const useConnectionsStore = defineStore('connections', {
this.clearEmptyFolders();
},
deleteConnection (connection: SidebarElement | ConnectionParams) {
this.connectionsOrder = (this.connectionsOrder as SidebarElement[]).map(el => { // Removes connection from folders
if (el.isFolder && el.connections.includes(connection.uid))
el.connections = el.connections.filter(uid => uid !== connection.uid);
return el;
});
this.removeFromFolders(connection.uid);
this.connectionsOrder = (this.connectionsOrder as SidebarElement[]).filter(el => el.uid !== connection.uid);
this.lastConnections = (this.lastConnections as SidebarElement[]).filter(el => el.uid !== connection.uid);

View File

@@ -66,7 +66,7 @@ export interface Workspace {
uid: string;
client?: ClientCode;
database?: string;
connectionStatus: 'connected' | 'disconnected' | 'failed';
connectionStatus: 'connected' | 'connecting' | 'disconnected' | 'failed';
selectedTab: string;
searchTerm: string;
tabs: WorkspaceTab[];