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

Compare commits

...

13 Commits

16 changed files with 2306 additions and 125 deletions

4
.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
@@ -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
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,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)

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 ✨

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-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",

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),
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 () {

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"
/>
@@ -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) => {

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

@@ -31,7 +31,7 @@ export const exportRows = (args: {
const csv = [];
const sd = args.csvOptions.stringDelimiter === 'single'
? '\''
: args.csvOptions.stringDelimiter === 'single'
: args.csvOptions.stringDelimiter === 'double'
? '"'
: '';

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) {
const { selectedTag } = storeToRefs(useScratchpadStore());
selectedTag.value = tag;
}
if (!tag) tag = 'all';
const { selectedTag } = storeToRefs(useScratchpadStore());
selectedTag.value = tag;
},
hideScratchpad () {
this.isScratchpad = false;