refactor: ts and composition api for modals

This commit is contained in:
Fabio Di Stasio 2022-05-24 23:02:14 +02:00
parent 84826ff4c0
commit cdca6eaa35
9 changed files with 31368 additions and 440 deletions

1
.gitignore vendored
View File

@ -7,5 +7,4 @@ node_modules
thumbs.db thumbs.db
NOTES.md NOTES.md
*.txt *.txt
package-lock.json
*.heapsnapshot *.heapsnapshot

30996
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -145,6 +145,7 @@
"@playwright/test": "~1.21.1", "@playwright/test": "~1.21.1",
"@types/better-sqlite3": "~7.5.0", "@types/better-sqlite3": "~7.5.0",
"@types/leaflet": "~1.7.9", "@types/leaflet": "~1.7.9",
"@types/marked": "~4.0.3",
"@types/node": "~17.0.23", "@types/node": "~17.0.23",
"@types/pg": "~8.6.5", "@types/pg": "~8.6.5",
"@typescript-eslint/eslint-plugin": "~5.18.0", "@typescript-eslint/eslint-plugin": "~5.18.0",

View File

@ -294,13 +294,13 @@ const closeContext = () => {
}; };
const copyCell = () => { const copyCell = () => {
const row = results.value.find(row => row.id === selectedRow.value); const row = results.value.find(row => Number(row.id) === selectedRow.value);
const valueToCopy = row[selectedCell.value.field]; const valueToCopy = row[selectedCell.value.field];
navigator.clipboard.writeText(valueToCopy); navigator.clipboard.writeText(valueToCopy);
}; };
const copyRow = () => { const copyRow = () => {
const row = results.value.find(row => row.id === selectedRow.value); const row = results.value.find(row => Number(row.id) === selectedRow.value);
const rowToCopy = JSON.parse(JSON.stringify(row)); const rowToCopy = JSON.parse(JSON.stringify(row));
navigator.clipboard.writeText(JSON.stringify(rowToCopy)); navigator.clipboard.writeText(JSON.stringify(rowToCopy));
}; };

View File

@ -1,14 +1,14 @@
<template> <template>
<BaseContextMenu <BaseContextMenu
:context-event="contextEvent" :context-event="props.contextEvent"
@close-context="closeContext" @close-context="closeContext"
> >
<div v-if="selectedRow" class="context-element"> <div v-if="props.selectedRow" class="context-element">
<span class="d-flex"><i class="mdi mdi-18px mdi-content-copy text-light pr-1" /> {{ $t('word.copy') }}</span> <span class="d-flex"><i class="mdi mdi-18px mdi-content-copy text-light pr-1" /> {{ $t('word.copy') }}</span>
<i class="mdi mdi-18px mdi-chevron-right text-light pl-1" /> <i class="mdi mdi-18px mdi-chevron-right text-light pl-1" />
<div class="context-submenu"> <div class="context-submenu">
<div <div
v-if="selectedRow" v-if="props.selectedRow"
class="context-element" class="context-element"
@click="copyCell" @click="copyCell"
> >
@ -17,7 +17,7 @@
</span> </span>
</div> </div>
<div <div
v-if="selectedRow" v-if="props.selectedRow"
class="context-element" class="context-element"
@click="copyRow" @click="copyRow"
> >
@ -28,7 +28,7 @@
</div> </div>
</div> </div>
<div <div
v-if="selectedRow" v-if="props.selectedRow"
class="context-element" class="context-element"
@click="killProcess" @click="killProcess"
> >
@ -39,38 +39,33 @@
</BaseContextMenu> </BaseContextMenu>
</template> </template>
<script> <script setup lang="ts">
import BaseContextMenu from '@/components/BaseContextMenu'; import BaseContextMenu from '@/components/BaseContextMenu.vue';
export default { const props = defineProps({
name: 'ModalProcessesListContext',
components: {
BaseContextMenu
},
props: {
contextEvent: MouseEvent, contextEvent: MouseEvent,
selectedRow: Number, selectedRow: Number,
selectedCell: Object selectedCell: Object
}, });
emits: ['close-context', 'copy-cell', 'copy-row', 'kill-process'],
computed: { const emit = defineEmits(['close-context', 'copy-cell', 'copy-row', 'kill-process']);
},
methods: { const closeContext = () => {
closeContext () { emit('close-context');
this.$emit('close-context'); };
},
copyCell () { const copyCell = () => {
this.$emit('copy-cell'); emit('copy-cell');
this.closeContext(); closeContext();
}, };
copyRow () {
this.$emit('copy-row'); const copyRow = () => {
this.closeContext(); emit('copy-row');
}, closeContext();
killProcess () { };
this.$emit('kill-process');
this.closeContext(); const killProcess = () => {
} emit('kill-process');
} closeContext();
}; };
</script> </script>

View File

@ -31,11 +31,12 @@
<div> <div>
<div> <div>
<TextEditor <TextEditor
:value="row.info || ''" :model-value="props.row.info || ''"
editor-class="textarea-editor" editor-class="textarea-editor"
:mode="editorMode" :mode="editorMode"
:read-only="true" :read-only="true"
/> />
<div class="mb-4" />
</div> </div>
</div> </div>
</template> </template>
@ -43,60 +44,46 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import ConfirmModal from '@/components/BaseConfirmModal'; import { Ref, ref } from 'vue';
import TextEditor from '@/components/BaseTextEditor'; import ConfirmModal from '@/components/BaseConfirmModal.vue';
import TextEditor from '@/components/BaseTextEditor.vue';
export default { const props = defineProps({
name: 'ModalProcessesListRow',
components: {
ConfirmModal,
TextEditor
},
props: {
row: Object row: Object
}, });
emits: ['select-row', 'contextmenu', 'stop-refresh'],
data () { const emit = defineEmits(['select-row', 'contextmenu', 'stop-refresh']);
return {
isInlineEditor: {}, const isInlineEditor: Ref<{[key: string]: boolean}> = ref({});
isInfoModal: false, const isInfoModal = ref(false);
editorMode: 'sql' const editorMode = ref('sql');
};
}, const isNull = (value: string | number) => value === null ? ' is-null' : '';
computed: {},
methods: { const selectRow = () => {
isNull (value) { emit('select-row');
return value === null ? ' is-null' : ''; };
},
selectRow () { const openContext = (event: MouseEvent, payload: { id: number; field: string }) => {
this.$emit('select-row'); emit('contextmenu', event, payload);
}, };
openContext (event, payload) {
this.$emit('contextmenu', event, payload); const hideInfoModal = () => {
}, isInfoModal.value = false;
hideInfoModal () { };
this.isInfoModal = false;
}, const dblClick = (col: string) => {
dblClick (col) {
if (col !== 'info') return; if (col !== 'info') return;
this.$emit('stop-refresh'); emit('stop-refresh');
this.isInfoModal = true; isInfoModal.value = true;
}, };
onKey (e) {
e.stopPropagation(); const cutText = (val: string | number) => {
if (e.key === 'Escape') {
this.isInlineEditor[this.editingField] = false;
this.editingField = null;
window.removeEventListener('keydown', this.onKey);
}
},
cutText (val) {
if (typeof val !== 'string') return val; if (typeof val !== 'string') return val;
return val.length > 250 ? `${val.substring(0, 250)}[...]` : val; return val.length > 250 ? `${val.substring(0, 250)}[...]` : val;
}
}
}; };
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -7,7 +7,7 @@
<div class="modal-title h6"> <div class="modal-title h6">
<div class="d-flex"> <div class="d-flex">
<i class="mdi mdi-24px mdi-cog mr-1" /> <i class="mdi mdi-24px mdi-cog mr-1" />
<span class="cut-text">{{ $t('word.settings') }}</span> <span class="cut-text">{{ t('word.settings') }}</span>
</div> </div>
</div> </div>
<a class="btn btn-clear c-hand" @click="closeModal" /> <a class="btn btn-clear c-hand" @click="closeModal" />
@ -21,14 +21,14 @@
:class="{'active': selectedTab === 'general'}" :class="{'active': selectedTab === 'general'}"
@click="selectTab('general')" @click="selectTab('general')"
> >
<a class="tab-link">{{ $t('word.general') }}</a> <a class="tab-link">{{ t('word.general') }}</a>
</li> </li>
<li <li
class="tab-item c-hand" class="tab-item c-hand"
:class="{'active': selectedTab === 'themes'}" :class="{'active': selectedTab === 'themes'}"
@click="selectTab('themes')" @click="selectTab('themes')"
> >
<a class="tab-link">{{ $t('word.themes') }}</a> <a class="tab-link">{{ t('word.themes') }}</a>
</li> </li>
<li <li
v-if="updateStatus !== 'disabled'" v-if="updateStatus !== 'disabled'"
@ -36,21 +36,21 @@
:class="{'active': selectedTab === 'update'}" :class="{'active': selectedTab === 'update'}"
@click="selectTab('update')" @click="selectTab('update')"
> >
<a class="tab-link" :class="{'badge badge-update': hasUpdates}">{{ $t('word.update') }}</a> <a class="tab-link" :class="{'badge badge-update': hasUpdates}">{{ t('word.update') }}</a>
</li> </li>
<li <li
class="tab-item c-hand" class="tab-item c-hand"
:class="{'active': selectedTab === 'changelog'}" :class="{'active': selectedTab === 'changelog'}"
@click="selectTab('changelog')" @click="selectTab('changelog')"
> >
<a class="tab-link">{{ $t('word.changelog') }}</a> <a class="tab-link">{{ t('word.changelog') }}</a>
</li> </li>
<li <li
class="tab-item c-hand" class="tab-item c-hand"
:class="{'active': selectedTab === 'about'}" :class="{'active': selectedTab === 'about'}"
@click="selectTab('about')" @click="selectTab('about')"
> >
<a class="tab-link">{{ $t('word.about') }}</a> <a class="tab-link">{{ t('word.about') }}</a>
</li> </li>
</ul> </ul>
</div> </div>
@ -58,14 +58,14 @@
<div class="container"> <div class="container">
<form class="form-horizontal columns"> <form class="form-horizontal columns">
<div class="column col-12 h6 text-uppercase mb-1"> <div class="column col-12 h6 text-uppercase mb-1">
{{ $t('word.application') }} {{ t('word.application') }}
</div> </div>
<div class="column col-12 col-sm-12 mb-2 columns"> <div class="column col-12 col-sm-12 mb-2 columns">
<div class="form-group column col-12"> <div class="form-group column col-12">
<div class="col-5 col-sm-12"> <div class="col-5 col-sm-12">
<label class="form-label"> <label class="form-label">
<i class="mdi mdi-18px mdi-translate mr-1" /> <i class="mdi mdi-18px mdi-translate mr-1" />
{{ $t('word.language') }} {{ t('word.language') }}
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
@ -85,15 +85,15 @@
</div> </div>
<div class="col-4 col-sm-12 px-2 p-vcentered"> <div class="col-4 col-sm-12 px-2 p-vcentered">
<small class="d-block" style="line-height:1.1; font-size:70%;"> <small class="d-block" style="line-height:1.1; font-size:70%;">
{{ $t('message.missingOrIncompleteTranslation') }}<br> {{ t('message.missingOrIncompleteTranslation') }}<br>
<a class="text-bold c-hand" @click="openOutside('https://github.com/antares-sql/antares/wiki/Translate-Antares')">{{ $t('message.findOutHowToContribute') }}</a> <a class="text-bold c-hand" @click="openOutside('https://github.com/antares-sql/antares/wiki/Translate-Antares')">{{ t('message.findOutHowToContribute') }}</a>
</small> </small>
</div> </div>
</div> </div>
<div class="form-group column col-12"> <div class="form-group column col-12">
<div class="col-5 col-sm-12"> <div class="col-5 col-sm-12">
<label class="form-label"> <label class="form-label">
{{ $t('message.dataTabPageSize') }} {{ t('message.dataTabPageSize') }}
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
@ -114,7 +114,7 @@
<div class="form-group column col-12 mb-0"> <div class="form-group column col-12 mb-0">
<div class="col-5 col-sm-12"> <div class="col-5 col-sm-12">
<label class="form-label"> <label class="form-label">
{{ $t('message.restorePreviourSession') }} {{ t('message.restorePreviourSession') }}
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
@ -127,7 +127,7 @@
<div class="form-group column col-12 mb-0"> <div class="form-group column col-12 mb-0">
<div class="col-5 col-sm-12"> <div class="col-5 col-sm-12">
<label class="form-label"> <label class="form-label">
{{ $t('message.disableBlur') }} {{ t('message.disableBlur') }}
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
@ -140,7 +140,7 @@
<div class="form-group column col-12"> <div class="form-group column col-12">
<div class="col-5 col-sm-12"> <div class="col-5 col-sm-12">
<label class="form-label"> <label class="form-label">
{{ $t('message.notificationsTimeout') }} {{ t('message.notificationsTimeout') }}
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
@ -152,19 +152,19 @@
min="1" min="1"
@focusout="checkNotificationsTimeout" @focusout="checkNotificationsTimeout"
> >
<span class="input-group-addon">{{ $t('word.seconds') }}</span> <span class="input-group-addon">{{ t('word.seconds') }}</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="column col-12 h6 mt-4 text-uppercase mb-1"> <div class="column col-12 h6 mt-4 text-uppercase mb-1">
{{ $t('word.editor') }} {{ t('word.editor') }}
</div> </div>
<div class="column col-12 col-sm-12 columns"> <div class="column col-12 col-sm-12 columns">
<div class="form-group column col-12 mb-0"> <div class="form-group column col-12 mb-0">
<div class="col-5 col-sm-12"> <div class="col-5 col-sm-12">
<label class="form-label"> <label class="form-label">
{{ $t('word.autoCompletion') }} {{ t('word.autoCompletion') }}
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
@ -177,7 +177,7 @@
<div class="form-group column col-12 mb-0"> <div class="form-group column col-12 mb-0">
<div class="col-5 col-sm-12"> <div class="col-5 col-sm-12">
<label class="form-label"> <label class="form-label">
{{ $t('message.wrapLongLines') }} {{ t('message.wrapLongLines') }}
</label> </label>
</div> </div>
<div class="col-3 col-sm-12"> <div class="col-3 col-sm-12">
@ -196,18 +196,18 @@
<div class="container"> <div class="container">
<div class="columns"> <div class="columns">
<div class="column col-12 h6 text-uppercase mb-2"> <div class="column col-12 h6 text-uppercase mb-2">
{{ $t('message.applicationTheme') }} {{ t('message.applicationTheme') }}
</div> </div>
<div <div
class="column col-6 c-hand theme-block" class="column col-6 c-hand theme-block"
:class="{'selected': applicationTheme === 'dark'}" :class="{'selected': applicationTheme === 'dark'}"
@click="changeApplicationTheme('dark')" @click="changeApplicationTheme('dark')"
> >
<img src="../images/dark.png" class="img-responsive img-fit-cover s-rounded"> <img :src="darkPreview" class="img-responsive img-fit-cover s-rounded">
<div class="theme-name text-light"> <div class="theme-name text-light">
<i class="mdi mdi-moon-waning-crescent mdi-48px" /> <i class="mdi mdi-moon-waning-crescent mdi-48px" />
<div class="h6 mt-4"> <div class="h6 mt-4">
{{ $t('word.dark') }} {{ t('word.dark') }}
</div> </div>
</div> </div>
</div> </div>
@ -216,11 +216,11 @@
:class="{'selected': applicationTheme === 'light'}" :class="{'selected': applicationTheme === 'light'}"
@click="changeApplicationTheme('light')" @click="changeApplicationTheme('light')"
> >
<img src="../images/light.png" class="img-responsive img-fit-cover s-rounded"> <img :src="lightPreview" class="img-responsive img-fit-cover s-rounded">
<div class="theme-name text-dark"> <div class="theme-name text-dark">
<i class="mdi mdi-white-balance-sunny mdi-48px" /> <i class="mdi mdi-white-balance-sunny mdi-48px" />
<div class="h6 mt-4"> <div class="h6 mt-4">
{{ $t('word.light') }} {{ t('word.light') }}
</div> </div>
</div> </div>
</div> </div>
@ -228,7 +228,7 @@
<div class="columns mt-4"> <div class="columns mt-4">
<div class="column col-12 h6 text-uppercase mb-2 mt-4"> <div class="column col-12 h6 text-uppercase mb-2 mt-4">
{{ $t('message.editorTheme') }} {{ t('message.editorTheme') }}
</div> </div>
<div class="column col-6 h5 mb-4"> <div class="column col-6 h5 mb-4">
<select <select
@ -259,21 +259,21 @@
:class="{'active': editorFontSize === 'small'}" :class="{'active': editorFontSize === 'small'}"
@click="changeEditorFontSize('small')" @click="changeEditorFontSize('small')"
> >
{{ $t('word.small') }} {{ t('word.small') }}
</button> </button>
<button <button
class="btn btn-dark cut-text" class="btn btn-dark cut-text"
:class="{'active': editorFontSize === 'medium'}" :class="{'active': editorFontSize === 'medium'}"
@click="changeEditorFontSize('medium')" @click="changeEditorFontSize('medium')"
> >
{{ $t('word.medium') }} {{ t('word.medium') }}
</button> </button>
<button <button
class="btn btn-dark cut-text" class="btn btn-dark cut-text"
:class="{'active': editorFontSize === 'large'}" :class="{'active': editorFontSize === 'large'}"
@click="changeEditorFontSize('large')" @click="changeEditorFontSize('large')"
> >
{{ $t('word.large') }} {{ t('word.large') }}
</button> </button>
</div> </div>
</div> </div>
@ -299,19 +299,19 @@
<div v-show="selectedTab === 'about'" class="panel-body py-4"> <div v-show="selectedTab === 'about'" class="panel-body py-4">
<div class="text-center"> <div class="text-center">
<img src="../images/logo.svg" width="128"> <img :src="appLogo" width="128">
<h4>{{ appName }}</h4> <h4>{{ appName }}</h4>
<p class="mb-2"> <p class="mb-2">
{{ $t('word.version') }} {{ appVersion }}<br> {{ t('word.version') }} {{ appVersion }}<br>
<a class="c-hand" @click="openOutside('https://github.com/antares-sql/antares')"><i class="mdi mdi-github d-inline" /> GitHub</a> <a class="c-hand" @click="openOutside('https://twitter.com/AntaresSQL')"><i class="mdi mdi-twitter d-inline" /> Twitter</a> <a class="c-hand" @click="openOutside('https://antares-sql.app/')"><i class="mdi mdi-web d-inline" /> Website</a><br> <a class="c-hand" @click="openOutside('https://github.com/antares-sql/antares')"><i class="mdi mdi-github d-inline" /> GitHub</a> <a class="c-hand" @click="openOutside('https://twitter.com/AntaresSQL')"><i class="mdi mdi-twitter d-inline" /> Twitter</a> <a class="c-hand" @click="openOutside('https://antares-sql.app/')"><i class="mdi mdi-web d-inline" /> Website</a><br>
<small>{{ $t('word.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">{{ appAuthor }}</a></small><br> <small>{{ t('word.author') }} <a class="c-hand" @click="openOutside('https://github.com/Fabio286')">{{ appAuthor }}</a></small><br>
</p> </p>
<div class="mb-2"> <div class="mb-2">
<small class="d-block text-uppercase">{{ $t('word.contributors') }}:</small> <small class="d-block text-uppercase">{{ t('word.contributors') }}:</small>
<div class="d-block py-1"> <div class="d-block py-1">
<small v-for="(contributor, i) in otherContributors" :key="i">{{ i !== 0 ? ', ' : '' }}{{ contributor }}</small> <small v-for="(contributor, i) in otherContributors" :key="i">{{ i !== 0 ? ', ' : '' }}{{ contributor }}</small>
</div> </div>
<small>{{ $t('message.madeWithJS') }}</small> <small>{{ t('message.madeWithJS') }}</small>
</div> </div>
</div> </div>
</div> </div>
@ -322,34 +322,31 @@
</Teleport> </Teleport>
</template> </template>
<script> <script setup lang="ts">
import { onBeforeUnmount, Ref, ref } from 'vue';
import { shell } from 'electron'; import { shell } from 'electron';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useApplicationStore } from '@/stores/application'; import { useApplicationStore } from '@/stores/application';
import { useSettingsStore } from '@/stores/settings'; import { useSettingsStore } from '@/stores/settings';
import { useWorkspacesStore } from '@/stores/workspaces'; import { useWorkspacesStore } from '@/stores/workspaces';
import { localesNames } from '@/i18n/supported-locales'; import { localesNames } from '@/i18n/supported-locales';
import ModalSettingsUpdate from '@/components/ModalSettingsUpdate'; import ModalSettingsUpdate from '@/components/ModalSettingsUpdate.vue';
import ModalSettingsChangelog from '@/components/ModalSettingsChangelog'; import ModalSettingsChangelog from '@/components/ModalSettingsChangelog.vue';
import BaseTextEditor from '@/components/BaseTextEditor'; import BaseTextEditor from '@/components/BaseTextEditor.vue';
import { computed } from '@vue/reactivity';
export default { const { t, availableLocales } = useI18n();
name: 'ModalSettings',
components: {
ModalSettingsUpdate,
ModalSettingsChangelog,
BaseTextEditor
},
setup () {
const applicationStore = useApplicationStore();
const settingsStore = useSettingsStore();
const workspacesStore = useWorkspacesStore();
const { const applicationStore = useApplicationStore();
const settingsStore = useSettingsStore();
const workspacesStore = useWorkspacesStore();
const {
selectedSettingTab, selectedSettingTab,
updateStatus updateStatus
} = storeToRefs(applicationStore); } = storeToRefs(applicationStore);
const { const {
locale: selectedLocale, locale: selectedLocale,
dataTabLimit: pageSize, dataTabLimit: pageSize,
autoComplete: selectedAutoComplete, autoComplete: selectedAutoComplete,
@ -360,11 +357,11 @@ export default {
applicationTheme, applicationTheme,
editorTheme, editorTheme,
editorFontSize editorFontSize
} = storeToRefs(settingsStore); } = storeToRefs(settingsStore);
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore); const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
const { const {
changeLocale, changeLocale,
changePageSize, changePageSize,
changeRestoreTabs, changeRestoreTabs,
@ -375,56 +372,23 @@ export default {
changeEditorTheme, changeEditorTheme,
changeEditorFontSize, changeEditorFontSize,
updateNotificationsTimeout updateNotificationsTimeout
} = settingsStore; } = settingsStore;
const { const {
hideSettingModal, hideSettingModal: closeModal,
appName, appName,
appVersion appVersion
} = applicationStore; } = applicationStore;
const { getWorkspace } = workspacesStore; const { getWorkspace } = workspacesStore;
return { const appAuthor = 'Fabio Di Stasio';
appName, const pageSizes = [30, 40, 100, 250, 500, 1000];
appVersion, const contributors = process.env.APP_CONTRIBUTORS;
selectedSettingTab, const appLogo = require('../images/logo.svg');
updateStatus, const darkPreview = require('../images/dark.png');
closeModal: hideSettingModal, const lightPreview = require('../images/light.png');
selectedLocale, const editorThemes= [
pageSize,
selectedAutoComplete,
selectedLineWrap,
notificationsTimeout,
restoreTabs,
disableBlur,
applicationTheme,
editorTheme,
editorFontSize,
changeLocale,
changePageSize,
changeRestoreTabs,
changeDisableBlur,
changeAutoComplete,
changeLineWrap,
changeApplicationTheme,
changeEditorTheme,
changeEditorFontSize,
updateNotificationsTimeout,
selectedWorkspace,
getWorkspace
};
},
data () {
return {
appAuthor: 'Fabio Di Stasio',
localLocale: null,
localPageSize: null,
localTimeout: null,
localEditorTheme: null,
selectedTab: 'general',
pageSizes: [30, 40, 100, 250, 500, 1000],
editorThemes: [
{ {
group: this.$t('word.light'), group: t('word.light'),
themes: [ themes: [
{ code: 'chrome', name: 'Chrome' }, { code: 'chrome', name: 'Chrome' },
{ code: 'clouds', name: 'Clouds' }, { code: 'clouds', name: 'Clouds' },
@ -444,7 +408,7 @@ export default {
] ]
}, },
{ {
group: this.$t('word.dark'), group: t('word.dark'),
themes: [ themes: [
{ code: 'ambiance', name: 'Ambiance' }, { code: 'ambiance', name: 'Ambiance' },
{ code: 'chaos', name: 'Chaos' }, { code: 'chaos', name: 'Chaos' },
@ -470,26 +434,8 @@ export default {
{ code: 'vibrant_ink', name: 'Vibrant Ink' } { code: 'vibrant_ink', name: 'Vibrant Ink' }
] ]
} }
], ];
contributors: process.env.APP_CONTRIBUTORS const exampleQuery = `-- This is an example
};
},
computed: {
locales () {
const locales = [];
for (const locale of this.$i18n.availableLocales)
locales.push({ code: locale, name: localesNames[locale] });
return locales;
},
hasUpdates () {
return ['available', 'downloading', 'downloaded', 'link'].includes(this.updateStatus);
},
workspace () {
return this.getWorkspace(this.selectedWorkspace);
},
exampleQuery () {
return `-- This is an example
SELECT SELECT
employee.id, employee.id,
employee.first_name, employee.first_name,
@ -504,57 +450,81 @@ GROUP BY
ORDER BY ORDER BY
employee.id ASC; employee.id ASC;
`; `;
},
otherContributors () {
return this.contributors
.split(',')
.filter(c => !c.includes(this.appAuthor))
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
}
},
created () {
this.localLocale = this.selectedLocale;
this.localPageSize = this.pageSize;
this.localTimeout = this.notificationsTimeout;
this.localEditorTheme = this.editorTheme;
this.selectedTab = this.selectedSettingTab;
window.addEventListener('keydown', this.onKey);
},
beforeUnmount () {
window.removeEventListener('keydown', this.onKey);
},
methods: {
selectTab (tab) {
this.selectedTab = tab;
},
openOutside (link) {
shell.openExternal(link);
},
checkNotificationsTimeout () {
if (!this.localTimeout)
this.localTimeout = 10;
this.updateNotificationsTimeout(+this.localTimeout); const localLocale: Ref<string> = ref(null);
}, const localPageSize: Ref<number> = ref(null);
onKey (e) { const localTimeout: Ref<number> = ref(null);
const localEditorTheme: Ref<string> = ref(null);
const selectedTab: Ref<string> = ref('general');
const locales = computed(() => {
const locales = [];
for (const locale of availableLocales)
locales.push({ code: locale, name: localesNames[locale] });
return locales;
});
const hasUpdates = computed(() => ['available', 'downloading', 'downloaded', 'link'].includes(updateStatus.value));
const workspace = computed(() => {
return getWorkspace(selectedWorkspace.value);
});
const otherContributors = computed(() => {
return contributors
.split(',')
.filter(c => !c.includes(appAuthor))
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
});
const selectTab = (tab: string) => {
selectedTab.value = tab;
};
const openOutside = (link: string) => {
shell.openExternal(link);
};
const checkNotificationsTimeout = () => {
if (!localTimeout.value)
localTimeout.value = 10;
updateNotificationsTimeout(+localTimeout.value);
};
const onKey = (e: KeyboardEvent) => {
e.stopPropagation(); e.stopPropagation();
if (e.key === 'Escape') if (e.key === 'Escape')
this.closeModal(); closeModal();
},
toggleRestoreSession () {
this.changeRestoreTabs(!this.restoreTabs);
},
toggleDisableBlur () {
this.changeDisableBlur(!this.disableBlur);
},
toggleAutoComplete () {
this.changeAutoComplete(!this.selectedAutoComplete);
},
toggleLineWrap () {
this.changeLineWrap(!this.selectedLineWrap);
}
}
}; };
const toggleRestoreSession = () => {
changeRestoreTabs(!restoreTabs.value);
};
const toggleDisableBlur = () => {
changeDisableBlur(!disableBlur.value);
};
const toggleAutoComplete = () => {
changeAutoComplete(!selectedAutoComplete.value);
};
const toggleLineWrap = () => {
changeLineWrap(!selectedLineWrap.value);
};
localLocale.value = selectedLocale.value as string;
localPageSize.value = pageSize.value as number;
localTimeout.value = notificationsTimeout.value as number;
localEditorTheme.value = editorTheme.value as string;
selectedTab.value = selectedSettingTab.value;
window.addEventListener('keydown', onKey);
onBeforeUnmount(() => {
window.removeEventListener('keydown', onKey);
});
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -13,36 +13,22 @@
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts">
<script>
import { marked } from 'marked'; import { marked } from 'marked';
import BaseLoader from '@/components/BaseLoader'; import BaseLoader from '@/components/BaseLoader.vue';
import { useApplicationStore } from '@/stores/application'; import { useApplicationStore } from '@/stores/application';
import { ref } from 'vue';
export default { const { appVersion } = useApplicationStore();
name: 'ModalSettingsChangelog',
components: { const changelog = ref('');
BaseLoader const isLoading = ref(true);
}, const error = ref('');
setup () { const isError = ref(false);
const { appVersion } = useApplicationStore();
return { appVersion }; const getChangelog = async () => {
},
data () {
return {
changelog: '',
isLoading: true,
error: '',
isError: false
};
},
created () {
this.getChangelog();
},
methods: {
async getChangelog () {
try { try {
const apiRes = await fetch(`https://api.github.com/repos/antares-sql/antares/releases/tags/v${this.appVersion}`, { const apiRes = await fetch(`https://api.github.com/repos/antares-sql/antares/releases/tags/v${appVersion}`, {
method: 'GET' method: 'GET'
}); });
@ -53,26 +39,27 @@ export default {
: body; : body;
const renderer = { const renderer = {
link (href, title, text) { link (href: string, title: string, text: string) {
return text; return text;
}, },
listitem (text) { listitem (text: string) {
return `<li>${text.replace(/ *\([^)]*\) */g, '')}</li>`; return `<li>${text.replace(/ *\([^)]*\) */g, '')}</li>`;
} }
}; };
marked.use({ renderer }); marked.use({ renderer });
this.changelog = marked(markdown); changelog.value = marked(markdown);
} }
catch (err) { catch (err) {
this.error = err.message; error.value = err.message;
this.isError = true; isError.value = true;
}
this.isLoading = false;
}
} }
isLoading.value = false;
}; };
getChangelog();
</script> </script>
<style lang="scss"> <style lang="scss">
#changelog { #changelog {

View File

@ -52,68 +52,61 @@
</div> </div>
</template> </template>
<script> <script setup lang="ts">
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { ipcRenderer, shell } from 'electron'; import { ipcRenderer, shell } from 'electron';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useApplicationStore } from '@/stores/application'; import { useApplicationStore } from '@/stores/application';
import { useSettingsStore } from '@/stores/settings'; import { useSettingsStore } from '@/stores/settings';
export default { const { t } = useI18n();
name: 'ModalSettingsUpdate',
setup () {
const applicationStore = useApplicationStore();
const settingsStore = useSettingsStore();
const { const applicationStore = useApplicationStore();
const settingsStore = useSettingsStore();
const {
updateStatus, updateStatus,
getDownloadProgress getDownloadProgress: downloadPercentage
} = storeToRefs(applicationStore); } = storeToRefs(applicationStore);
const { allowPrerelease } = storeToRefs(settingsStore); const { allowPrerelease } = storeToRefs(settingsStore);
const { changeAllowPrerelease } = settingsStore; const { changeAllowPrerelease } = settingsStore;
return { const updateMessage = computed(() => {
updateStatus, switch (updateStatus.value) {
downloadPercentage: getDownloadProgress,
allowPrerelease,
changeAllowPrerelease
};
},
computed: {
updateMessage () {
switch (this.updateStatus) {
case 'noupdate': case 'noupdate':
return this.$t('message.noUpdatesAvailable'); return t('message.noUpdatesAvailable');
case 'checking': case 'checking':
return this.$t('message.checkingForUpdate'); return t('message.checkingForUpdate');
case 'nocheck': case 'nocheck':
return this.$t('message.checkFailure'); return t('message.checkFailure');
case 'available': case 'available':
return this.$t('message.updateAvailable'); return t('message.updateAvailable');
case 'downloading': case 'downloading':
return this.$t('message.downloadingUpdate'); return t('message.downloadingUpdate');
case 'downloaded': case 'downloaded':
return this.$t('message.updateDownloaded'); return t('message.updateDownloaded');
case 'link': case 'link':
return this.$t('message.updateAvailable'); return t('message.updateAvailable');
default: default:
return this.updateStatus; return updateStatus.value;
} }
} });
},
methods: { const openOutside = (link: string) => {
openOutside (link) {
shell.openExternal(link); shell.openExternal(link);
}, };
checkForUpdates () {
const checkForUpdates = () => {
ipcRenderer.send('check-for-updates'); ipcRenderer.send('check-for-updates');
}, };
restartToUpdate () {
const restartToUpdate = () => {
ipcRenderer.send('restart-to-update'); ipcRenderer.send('restart-to-update');
}, };
toggleAllowPrerelease () {
this.changeAllowPrerelease(!this.allowPrerelease); const toggleAllowPrerelease = () => {
} changeAllowPrerelease(!allowPrerelease.value);
}
}; };
</script> </script>