mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
13 Commits
v0.7.22-be
...
v0.7.23-be
Author | SHA1 | Date | |
---|---|---|---|
e19118982b | |||
11f130d91c | |||
|
0bb5cedda6 | ||
de9dac3e8a | |||
dd5b41716a | |||
86acb390ac | |||
2884ec3dd6 | |||
b542a09c01 | |||
6d94a04b67 | |||
8500fc40a1 | |||
586f901bae | |||
6d002efaf5 | |||
58be1abf5f |
4
.github/FUNDING.yml
vendored
4
.github/FUNDING.yml
vendored
@@ -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
|
||||
@@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ['https://paypal.me/fabiodistasio']
|
||||
custom: ['https://paypal.me/fabiodistasio']
|
||||
|
1
.husky/commit-msg
Normal file
1
.husky/commit-msg
Normal file
@@ -0,0 +1 @@
|
||||
npx --no -- commitlint --edit $1
|
1
.husky/pre-commit
Normal file
1
.husky/pre-commit
Normal file
@@ -0,0 +1 @@
|
||||
npm run lint
|
@@ -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"
|
||||
}
|
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,6 +2,22 @@
|
||||
|
||||
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-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)
|
||||
|
||||
|
||||
|
@@ -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 ✨
|
||||
|
||||
|
33
commitlint.config.js
Normal file
33
commitlint.config.js
Normal 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
2259
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.7.22-beta.2",
|
||||
"version": "0.7.23-beta.0",
|
||||
"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",
|
||||
|
@@ -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),
|
||||
accelerator: key,
|
||||
visible: false,
|
||||
click: () => {
|
||||
this._mainWindow.webContents.send(shortcut.event);
|
||||
if (isDevelopment) console.log('LOCAL EVENT:', shortcut);
|
||||
}
|
||||
}]
|
||||
}));
|
||||
submenu.push({
|
||||
label: String(shortcut.event),
|
||||
accelerator: key,
|
||||
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 () {
|
||||
|
@@ -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"
|
||||
/>
|
||||
@@ -314,8 +314,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 +357,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 +785,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) => {
|
||||
|
@@ -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>
|
||||
|
@@ -31,7 +31,7 @@ export const exportRows = (args: {
|
||||
const csv = [];
|
||||
const sd = args.csvOptions.stringDelimiter === 'single'
|
||||
? '\''
|
||||
: args.csvOptions.stringDelimiter === 'single'
|
||||
: args.csvOptions.stringDelimiter === 'double'
|
||||
? '"'
|
||||
: '';
|
||||
|
||||
|
@@ -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});
|
||||
}
|
||||
|
||||
|
@@ -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});
|
||||
}
|
||||
|
||||
|
@@ -55,10 +55,9 @@ export const useApplicationStore = defineStore('application', {
|
||||
},
|
||||
showScratchpad (tag?: string) {
|
||||
this.isScratchpad = true;
|
||||
if (tag) {
|
||||
const { selectedTag } = storeToRefs(useScratchpadStore());
|
||||
selectedTag.value = tag;
|
||||
}
|
||||
if (!tag) tag = 'all';
|
||||
const { selectedTag } = storeToRefs(useScratchpadStore());
|
||||
selectedTag.value = tag;
|
||||
},
|
||||
hideScratchpad () {
|
||||
this.isScratchpad = false;
|
||||
|
Reference in New Issue
Block a user