mirror of
https://github.com/Fabio286/antares.git
synced 2025-02-20 13:40:37 +01:00
feat(UI): connections customization
This commit is contained in:
parent
72accb7b0e
commit
212b2bdba9
183
src/renderer/components/ModalConnectionAppearence.vue
Normal file
183
src/renderer/components/ModalConnectionAppearence.vue
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
<template>
|
||||||
|
<Teleport to="#window-content">
|
||||||
|
<div class="modal active">
|
||||||
|
<a class="modal-overlay" @click.stop="closeModal" />
|
||||||
|
<div ref="trapRef" class="modal-container p-0">
|
||||||
|
<div class="modal-header pl-2">
|
||||||
|
<div class="modal-title h6">
|
||||||
|
<div class="d-flex">
|
||||||
|
<i class="mdi mdi-24px mdi-brush-variant mr-1" />
|
||||||
|
<span class="cut-text">{{ t('message.editConnectionAppearence') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||||
|
</div>
|
||||||
|
<div class="modal-body pb-0">
|
||||||
|
<div class="content">
|
||||||
|
<form class="form-horizontal">
|
||||||
|
<div class="form-group mb-4">
|
||||||
|
<div class="col-3">
|
||||||
|
<label class="form-label">{{ t('word.label') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-9">
|
||||||
|
<input
|
||||||
|
ref="firstInput"
|
||||||
|
v-model="localConnection.name"
|
||||||
|
class="form-input"
|
||||||
|
type="text"
|
||||||
|
:placeholder="getConnectionName(localConnection.uid)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-3">
|
||||||
|
<label class="form-label">{{ t('word.icon') }}</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-9 icons-wrapper">
|
||||||
|
<div
|
||||||
|
v-for="icon in icons"
|
||||||
|
:key="icon.name"
|
||||||
|
class="icon-box"
|
||||||
|
:title="icon.name"
|
||||||
|
:class="[icon.code ? `mdi ${icon.code} mdi-36px` : `dbi dbi-${connection.client}`, {'selected': localConnection.icon === icon.code}]"
|
||||||
|
@click="localConnection.icon = icon.code"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-primary mr-2" @click.stop="editFolderAppearence">
|
||||||
|
{{ t('word.update') }}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-link" @click.stop="closeModal">
|
||||||
|
{{ t('word.close') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onBeforeUnmount, PropType, Ref, ref } from 'vue';
|
||||||
|
import { useFocusTrap } from '@/composables/useFocusTrap';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { SidebarElement, useConnectionsStore } from '@/stores/connections';
|
||||||
|
import { unproxify } from '@/libs/unproxify';
|
||||||
|
|
||||||
|
const connectionsStore = useConnectionsStore();
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
connection: {
|
||||||
|
type: Object as PropType<SidebarElement>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
|
const { updateConnectionOrder, getConnectionName } = connectionsStore;
|
||||||
|
|
||||||
|
const icons = [
|
||||||
|
{ name: 'default', code: null },
|
||||||
|
|
||||||
|
// Symbols
|
||||||
|
{ name: 'account-group', code: 'mdi-account-group-outline' },
|
||||||
|
{ name: 'cloud', code: 'mdi-cloud-outline' },
|
||||||
|
{ name: 'key-chain', code: 'mdi-key-chain-variant' },
|
||||||
|
{ name: 'filmstrip', code: 'mdi-filmstrip' },
|
||||||
|
{ name: 'map-marker', code: 'mdi-map-marker-radius-outline' },
|
||||||
|
{ name: 'api', code: 'mdi-api' },
|
||||||
|
{ name: 'chart-line', code: 'mdi-chart-line' },
|
||||||
|
{ name: 'chat', code: 'mdi-chat-outline' },
|
||||||
|
{ name: 'bug', code: 'mdi-bug-outline' },
|
||||||
|
{ name: 'shield', code: 'mdi-shield-outline' },
|
||||||
|
{ name: 'cart', code: 'mdi-cart-variant' },
|
||||||
|
{ name: 'bank', code: 'mdi-bank-outline' },
|
||||||
|
{ name: 'receipt', code: 'mdi-receipt-text-outline' },
|
||||||
|
{ name: 'heart', code: 'mdi-heart-outline' },
|
||||||
|
{ name: 'book', code: 'mdi-book-outline' },
|
||||||
|
{ name: 'anchor', code: 'mdi-anchor' },
|
||||||
|
{ name: 'leaf', code: 'mdi-leaf' },
|
||||||
|
{ name: 'music', code: 'mdi-music' },
|
||||||
|
{ name: 'camera', code: 'mdi-camera-outline' },
|
||||||
|
{ name: 'cash-register', code: 'mdi-cash-register' },
|
||||||
|
{ name: 'food', code: 'mdi-food-outline' },
|
||||||
|
{ name: 'controller', code: 'mdi-controller' },
|
||||||
|
|
||||||
|
// Vehicles
|
||||||
|
{ name: 'truck', code: 'mdi-truck-outline' },
|
||||||
|
{ name: 'car', code: 'mdi-car' },
|
||||||
|
{ name: 'motorbike', code: 'mdi-motorbike' },
|
||||||
|
{ name: 'train', code: 'mdi-train' },
|
||||||
|
{ name: 'airplane', code: 'mdi-airplane' },
|
||||||
|
{ name: 'ferry', code: 'mdi-ferry' },
|
||||||
|
|
||||||
|
// Brand
|
||||||
|
{ name: 'docker', code: 'mdi-docker' },
|
||||||
|
{ name: 'open-source', code: 'mdi-open-source-initiative' },
|
||||||
|
{ name: 'aws', code: 'mdi-aws' },
|
||||||
|
{ name: 'google-cloud', code: 'mdi-google-cloud' },
|
||||||
|
{ name: 'microsoft-azure', code: 'mdi-microsoft-azure' },
|
||||||
|
{ name: 'debian', code: 'mdi-debian' },
|
||||||
|
{ name: 'ubuntu', code: 'mdi-ubuntu' },
|
||||||
|
{ name: 'arch', code: 'mdi-arch' },
|
||||||
|
{ name: 'redhat', code: 'mdi-redhat' },
|
||||||
|
{ name: 'fedora', code: 'mdi-fedora' },
|
||||||
|
{ name: 'android', code: 'mdi-android' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const { trapRef } = useFocusTrap();
|
||||||
|
|
||||||
|
const firstInput: Ref<HTMLInputElement> = ref(null);
|
||||||
|
const localConnection: Ref<SidebarElement> = ref(unproxify(props.connection));
|
||||||
|
|
||||||
|
const editFolderAppearence = () => {
|
||||||
|
updateConnectionOrder(localConnection.value);
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = () => emit('close');
|
||||||
|
|
||||||
|
const onKey =(e: KeyboardEvent) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (e.key === 'Escape')
|
||||||
|
closeModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
window.removeEventListener('keydown', onKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.modal-container {
|
||||||
|
max-width: 360px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icons-wrapper{
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, 40px);
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
.icon-box {
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
outline: 2px solid $primary-color;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -87,20 +87,20 @@ const { updateConnectionOrder } = connectionsStore;
|
|||||||
|
|
||||||
const colorPalette = [
|
const colorPalette = [
|
||||||
{ name: 'default', hex: '#E36929' },
|
{ name: 'default', hex: '#E36929' },
|
||||||
{ name: 'grapefruit', hex: '#ED5565' },
|
{ name: 'grape-fruit', hex: '#ED5565' },
|
||||||
{ name: 'rose', hex: '#E3242B' },
|
{ name: 'rose', hex: '#E3242B' },
|
||||||
{ name: 'fire', hex: '#FDA50F' },
|
{ name: 'fire', hex: '#FDA50F' },
|
||||||
{ name: 'sunflower', hex: '#FFCE54' },
|
{ name: 'sunflower', hex: '#FFCE54' },
|
||||||
{ name: 'moss', hex: '#8A985E' },
|
{ name: 'moss', hex: '#8A985E' },
|
||||||
{ name: 'grass', hex: '#A0D468' },
|
{ name: 'grass', hex: '#6DCD05' },
|
||||||
{ name: 'emerald', hex: '#038835' },
|
{ name: 'emerald', hex: '#038835' },
|
||||||
{ name: 'mint', hex: '#48CFAD' },
|
{ name: 'mint', hex: '#48CFAD' },
|
||||||
{ name: 'aqua', hex: '#4FC1E9' },
|
{ name: 'aqua', hex: '#4FC1E9' },
|
||||||
{ name: 'royalblue', hex: '#4169E1' },
|
{ name: 'roya-lblue', hex: '#4169E1' },
|
||||||
{ name: 'bluejeans', hex: '#5D9CEC' },
|
{ name: 'blue-jeans', hex: '#5D9CEC' },
|
||||||
{ name: 'stone', hex: '#59788E' },
|
{ name: 'stone', hex: '#59788E' },
|
||||||
{ name: 'lavander', hex: '#AC92EC' },
|
{ name: 'lavander', hex: '#AC92EC' },
|
||||||
{ name: 'pinkrose', hex: '#EC87C0' },
|
{ name: 'pink-rose', hex: '#EC87C0' },
|
||||||
{ name: 'smoke', hex: '#BEBDB8' },
|
{ name: 'smoke', hex: '#BEBDB8' },
|
||||||
{ name: 'slate', hex: '#757C88' }
|
{ name: 'slate', hex: '#757C88' }
|
||||||
];
|
];
|
||||||
|
@ -40,9 +40,9 @@
|
|||||||
<div class="settingbar-element-icon-wrapper">
|
<div class="settingbar-element-icon-wrapper">
|
||||||
<i
|
<i
|
||||||
class="settingbar-element-icon dbi"
|
class="settingbar-element-icon dbi"
|
||||||
:class="[`dbi-${element.client}`, getStatusBadge(element.uid)]"
|
:class="[element.icon ? `mdi ${element.icon} mdi-36px`: `dbi-${element.client}`, getStatusBadge(element.uid)]"
|
||||||
/>
|
/>
|
||||||
<small class="settingbar-element-name">{{ getConnectionName(element.uid) }}</small>
|
<small class="settingbar-element-name">{{ element.name || getConnectionName(element.uid) }}</small>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@ -204,4 +204,8 @@ watch(() => props.modelValue, (value) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settingbar-element-icon {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -43,13 +43,13 @@
|
|||||||
class="folder-element"
|
class="folder-element"
|
||||||
:class="{ 'selected': element === selectedWorkspace }"
|
:class="{ 'selected': element === selectedWorkspace }"
|
||||||
@click="emit('select-workspace', element)"
|
@click="emit('select-workspace', element)"
|
||||||
@contextmenu.stop="emit('context', {event: $event, content: getConnectionByUid(element)})"
|
@contextmenu.stop="emit('context', {event: $event, content: getConnectionOrderByUid(element)})"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="folder-element-icon dbi"
|
class="folder-element-icon dbi"
|
||||||
:class="[`dbi-${getConnectionByUid(element)?.client}`, getStatusBadge(getConnectionByUid(element).uid)]"
|
:class="[getConnectionOrderByUid(element).icon ? `mdi ${getConnectionOrderByUid(element).icon}`: `dbi-${getConnectionOrderByUid(element).client}`, getStatusBadge(element)]"
|
||||||
/>
|
/>
|
||||||
<small v-if="isOpen" class="folder-element-name">{{ getConnectionName(element) }}</small>
|
<small v-if="isOpen" class="folder-element-name">{{ getConnectionOrderByUid(element).name || getConnectionName(element) }}</small>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</Draggable>
|
</Draggable>
|
||||||
@ -80,7 +80,7 @@ const { getFolders: folders } = storeToRefs(connectionsStore);
|
|||||||
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
|
||||||
|
|
||||||
const { getWorkspace } = workspacesStore;
|
const { getWorkspace } = workspacesStore;
|
||||||
const { getConnectionByUid, getConnectionName, addToFolder } = connectionsStore;
|
const { getConnectionOrderByUid, getConnectionName, addToFolder } = connectionsStore;
|
||||||
|
|
||||||
const foldersOpened = JSON.parse(localStorage.getItem('opened-folders')) || [];
|
const foldersOpened = JSON.parse(localStorage.getItem('opened-folders')) || [];
|
||||||
|
|
||||||
@ -265,6 +265,8 @@ watch(() => dummyNested.value.length, () => {
|
|||||||
|
|
||||||
.folder-element-icon {
|
.folder-element-icon {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
font-size: 36px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
&.badge::after {
|
&.badge::after {
|
||||||
top: 14px;
|
top: 14px;
|
||||||
@ -364,6 +366,7 @@ watch(() => dummyNested.value.length, () => {
|
|||||||
.folder-element-icon {
|
.folder-element-icon {
|
||||||
width: 21px;
|
width: 21px;
|
||||||
height: 21px;
|
height: 21px;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -389,6 +392,7 @@ watch(() => dummyNested.value.length, () => {
|
|||||||
|
|
||||||
.folder-element-icon {
|
.folder-element-icon {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
font-size: 36px;
|
||||||
|
|
||||||
&.badge::after {
|
&.badge::after {
|
||||||
top: 5px;
|
top: 5px;
|
||||||
|
@ -45,6 +45,11 @@
|
|||||||
:folder="contextConnection"
|
:folder="contextConnection"
|
||||||
@close="hideAppearenceModal"
|
@close="hideAppearenceModal"
|
||||||
/>
|
/>
|
||||||
|
<ModalConnectionAppearence
|
||||||
|
v-if="isConnectionEdit"
|
||||||
|
:connection="contextConnection"
|
||||||
|
@close="hideAppearenceModal"
|
||||||
|
/>
|
||||||
</BaseContextMenu>
|
</BaseContextMenu>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -58,6 +63,7 @@ import { useWorkspacesStore } from '@/stores/workspaces';
|
|||||||
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
import BaseContextMenu from '@/components/BaseContextMenu.vue';
|
||||||
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
import ConfirmModal from '@/components/BaseConfirmModal.vue';
|
||||||
import ModalFolderAppearence from '@/components/ModalFolderAppearence.vue';
|
import ModalFolderAppearence from '@/components/ModalFolderAppearence.vue';
|
||||||
|
import ModalConnectionAppearence from '@/components/ModalConnectionAppearence.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@ -116,7 +122,7 @@ const showAppearenceModal = () => {
|
|||||||
if (props.contextConnection.isFolder)
|
if (props.contextConnection.isFolder)
|
||||||
isFolderEdit.value = true;
|
isFolderEdit.value = true;
|
||||||
else
|
else
|
||||||
isFolderEdit.value = true;
|
isConnectionEdit.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideAppearenceModal = () => {
|
const hideAppearenceModal = () => {
|
||||||
|
@ -146,7 +146,9 @@ export const enUS = {
|
|||||||
shortcuts: 'Shortcuts',
|
shortcuts: 'Shortcuts',
|
||||||
folder: 'Folder | Folders',
|
folder: 'Folder | Folders',
|
||||||
appearence: 'Appearence',
|
appearence: 'Appearence',
|
||||||
color: 'Color'
|
color: 'Color',
|
||||||
|
label: 'Label',
|
||||||
|
icon: 'Icon'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
appWelcome: 'Welcome to Antares SQL Client!',
|
appWelcome: 'Welcome to Antares SQL Client!',
|
||||||
@ -329,7 +331,8 @@ export const enUS = {
|
|||||||
fillCell: 'Fill cell',
|
fillCell: 'Fill cell',
|
||||||
editFolder: 'Edit folder',
|
editFolder: 'Edit folder',
|
||||||
folderName: 'Folder name',
|
folderName: 'Folder name',
|
||||||
deleteFolder: 'Delete folder'
|
deleteFolder: 'Delete folder',
|
||||||
|
editConnectionAppearence: 'Edit connection appearence'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Address',
|
address: 'Address',
|
||||||
|
@ -71,6 +71,7 @@ export const useConnectionsStore = defineStore('connections', {
|
|||||||
return connectionsOrder;
|
return connectionsOrder;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getConnectionOrderByUid: state => (uid:string) => state.connectionsOrder.find(connection => connection.uid === uid),
|
||||||
getFolders: state => state.connectionsOrder.filter(conn => conn.isFolder)
|
getFolders: state => state.connectionsOrder.filter(conn => conn.isFolder)
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@ -159,7 +160,9 @@ export const useConnectionsStore = defineStore('connections', {
|
|||||||
connections.splice(el.index, 1, { // Move to new position
|
connections.splice(el.index, 1, { // Move to new position
|
||||||
isFolder: false,
|
isFolder: false,
|
||||||
client: conn.client,
|
client: conn.client,
|
||||||
uid: conn.uid
|
uid: conn.uid,
|
||||||
|
icon: conn.icon,
|
||||||
|
name: conn.name
|
||||||
});
|
});
|
||||||
|
|
||||||
connIndex = connections.findIndex(conn => conn.uid === el.uid);
|
connIndex = connections.findIndex(conn => conn.uid === el.uid);
|
||||||
@ -185,6 +188,7 @@ export const useConnectionsStore = defineStore('connections', {
|
|||||||
el = element;
|
el = element;
|
||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
|
persistentStore.set('connectionsOrder', this.connectionsOrder);
|
||||||
},
|
},
|
||||||
updateLastConnection (uid: string) {
|
updateLastConnection (uid: string) {
|
||||||
const cIndex = (this.lastConnections as {uid: string; time: number}[]).findIndex((c) => c.uid === uid);
|
const cIndex = (this.lastConnections as {uid: string; time: number}[]).findIndex((c) => c.uid === uid);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user