1
1
mirror of https://github.com/Fabio286/antares.git synced 2025-02-18 20:50:48 +01:00

feat: ability to pin/unpin and delete connections from the "all connections" modal

This commit is contained in:
Fabio Di Stasio 2022-07-04 17:03:24 +02:00
parent 56b0a4815c
commit 8e705706ae

View File

@ -16,10 +16,7 @@
<div class="columns"> <div class="columns">
<div class="connections-search column col-12 columns col-gapless"> <div class="connections-search column col-12 columns col-gapless">
<div class="column col-12 mt-2"> <div class="column col-12 mt-2">
<div <div ref="searchForm" class="form-group has-icon-right p-2 m-0">
ref="searchForm"
class="form-group has-icon-right p-2 m-0"
>
<input <input
v-model="searchTerm" v-model="searchTerm"
class="form-input" class="form-input"
@ -44,9 +41,11 @@
tabindex="0" tabindex="0"
@click.stop="selectConnection(connection.uid)" @click.stop="selectConnection(connection.uid)"
@keypress.stop.enter="selectConnection(connection.uid)" @keypress.stop.enter="selectConnection(connection.uid)"
@mouseover="connectionHover = connection.uid"
@mouseleave="connectionHover = null"
> >
<div class="panel"> <div class="panel">
<div class="panel-header p-2 text-center"> <div class="panel-header p-2 text-center p-relative">
<figure class="avatar avatar-lg pt-1 mb-1"> <figure class="avatar avatar-lg pt-1 mb-1">
<i class="settingbar-element-icon dbi" :class="[`dbi-${connection.client}`]" /> <i class="settingbar-element-icon dbi" :class="[`dbi-${connection.client}`]" />
</figure> </figure>
@ -56,31 +55,58 @@
<div class="panel-subtitle"> <div class="panel-subtitle">
{{ clients.get(connection.client) || connection.client }} {{ clients.get(connection.client) || connection.client }}
</div> </div>
<div class="all-connections-buttons p-absolute d-flex" style="top: 0; right: 0;">
<i
v-if="connection.isPinned"
class="all-connections-pinned mdi mdi-18px"
:class="connectionHover === connection.uid ? 'mdi-pin-off' : 'mdi-pin'"
:title="t('word.unpin')"
@click.stop="unpinConnection(connection.uid)"
/>
<i
v-else
class="all-connections-pin mdi mdi-18px mdi-pin mdi-rotate-45"
:title="t('word.pin')"
@click.stop="pinConnection(connection.uid)"
/>
<i
class="all-connections-delete mdi mdi-delete mdi-18px ml-2"
:title="t('word.delete')"
@click.stop="askToDelete(connection)"
/>
</div>
</div> </div>
<div class="panel-body text-center"> <div class="panel-body text-center">
<div v-if="connection.databasePath"> <div v-if="connection.databasePath">
<div class="text-ellipsis" :title="connection.databasePath"> <div class="text-ellipsis" :title="connection.databasePath">
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.databasePath }}</span> <i class="mdi mdi-database d-inline" /> <span class="text-bold">{{
connection.databasePath
}}</span>
</div> </div>
</div> </div>
<div v-else> <div v-else>
<div class="text-ellipsis" :title="`${connection.host}:${connection.port}`"> <div class="text-ellipsis" :title="`${connection.host}:${connection.port}`">
<i class="mdi mdi-server d-inline" /> <span class="text-bold">{{ connection.host }}:{{ connection.port }}</span> <i class="mdi mdi-server d-inline" /> <span class="text-bold">{{ connection.host
}}:{{ connection.port }}</span>
</div> </div>
</div> </div>
<div v-if="connection.user"> <div v-if="connection.user">
<div class="text-ellipsis"> <div class="text-ellipsis">
<i class="mdi mdi-account d-inline" /> <span class="text-bold">{{ connection.user }}</span> <i class="mdi mdi-account d-inline" /> <span class="text-bold">{{ connection.user
}}</span>
</div> </div>
</div> </div>
<div v-if="connection.schema"> <div v-if="connection.schema">
<div class="text-ellipsis"> <div class="text-ellipsis">
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.schema }}</span> <i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.schema
}}</span>
</div> </div>
</div> </div>
<div v-if="connection.database"> <div v-if="connection.database">
<div class="text-ellipsis"> <div class="text-ellipsis">
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.database }}</span> <i class="mdi mdi-database d-inline" /> <span class="text-bold">{{
connection.database
}}</span>
</div> </div>
</div> </div>
</div> </div>
@ -97,34 +123,65 @@
</div> </div>
</div> </div>
<input <input
key="trick"
readonly readonly
class="p-absolute" class="p-absolute"
style="width: 1px; height: 1px; opacity: 0" style="width: 1px; height: 1px; opacity: 0"
type="text" type="text"
><!-- workaround for useFocusTrap $lastFocusable --> >
<!-- workaround for useFocusTrap $lastFocusable -->
</TransitionGroup> </TransitionGroup>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<ConfirmModal
v-if="isConfirmModal"
@confirm="confirmDeleteConnection"
@hide="isConfirmModal = false"
>
<template #header>
<div class="d-flex">
<i class="mdi mdi-24px mdi-server-remove mr-1" /> {{ t('message.deleteConnection') }}
</div>
</template>
<template #body>
<div class="mb-2">
{{ t('message.deleteCorfirm') }} <b>{{ selectedConnectionName }}</b>?
</div>
</template>
</ConfirmModal>
</Teleport> </Teleport>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from 'vue'; import { computed, Ref, ref } from 'vue';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useFocusTrap } from '@/composables/useFocusTrap'; import { useFocusTrap } from '@/composables/useFocusTrap';
import { useConnectionsStore } from '@/stores/connections'; import { useConnectionsStore } from '@/stores/connections';
import { useWorkspacesStore } from '@/stores/workspaces'; import { useWorkspacesStore } from '@/stores/workspaces';
import ConfirmModal from '@/components/BaseConfirmModal.vue';
import { ConnectionParams } from 'common/interfaces/antares';
const { t } = useI18n(); const { t } = useI18n();
const connectionsStore = useConnectionsStore(); const connectionsStore = useConnectionsStore();
const workspacesStore = useWorkspacesStore(); const workspacesStore = useWorkspacesStore();
const { connections } = storeToRefs(connectionsStore); const { connections,
const { getConnectionName } = connectionsStore; pinnedConnections,
lastConnections
} = storeToRefs(connectionsStore);
const { getSelected: selectedWorkspace } = storeToRefs(workspacesStore);
const {
getConnectionName,
pinConnection,
unpinConnection,
deleteConnection
} = connectionsStore;
const { selectWorkspace } = workspacesStore; const { selectWorkspace } = workspacesStore;
const { trapRef } = useFocusTrap(); const { trapRef } = useFocusTrap();
@ -139,9 +196,31 @@ const clients = new Map([
]); ]);
const searchTerm = ref(''); const searchTerm = ref('');
const isConfirmModal = ref(false);
const connectionHover: Ref<string> = ref(null);
const selectedConnection: Ref<ConnectionParams> = ref(null);
const sortedConnections = computed(() => {
return connections.value
.map(c => {
const connTime = lastConnections.value.find((lc) => lc.uid === c.uid)?.time || 0;
return {
...c,
time: connTime,
isPinned: pinnedConnections.value.has(c.uid)
};
})
.sort((a, b) => {
if (a.isPinned < b.isPinned) return 1;
if (a.isPinned > b.isPinned) return -1;
if (a.time < b.time) return 1;
if (a.time > b.time) return -1;
return 0;
});
});
const filteredConnections = computed(() => { const filteredConnections = computed(() => {
return connections.value.filter(connection => { return sortedConnections.value.filter(connection => {
return connection.name?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) || return connection.name?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
connection.host?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) || connection.host?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
connection.database?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) || connection.database?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
@ -152,6 +231,8 @@ const filteredConnections = computed(() => {
}); });
}); });
const selectedConnectionName = computed(() => getConnectionName(selectedConnection.value?.uid));
const closeModal = () => emit('close'); const closeModal = () => emit('close');
const selectConnection = (uid: string) => { const selectConnection = (uid: string) => {
@ -159,6 +240,17 @@ const selectConnection = (uid: string) => {
closeModal(); closeModal();
}; };
const askToDelete = (connection: ConnectionParams) => {
selectedConnection.value = connection;
isConfirmModal.value = true;
};
const confirmDeleteConnection = () => {
if (selectedWorkspace.value === selectedConnection.value.uid)
selectWorkspace(null);
deleteConnection(selectedConnection.value);
};
const onKey = (e: KeyboardEvent) => { const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') { if (e.key === 'Escape') {
e.stopPropagation(); e.stopPropagation();
@ -180,6 +272,7 @@ window.addEventListener('keydown', onKey, { capture: true });
} }
.column-resizable { .column-resizable {
&:hover, &:hover,
&:active { &:active {
resize: horizontal; resize: horizontal;
@ -220,5 +313,37 @@ window.addEventListener('keydown', onKey, { capture: true });
cursor: pointer; cursor: pointer;
transition: all .2s; transition: all .2s;
border-radius: $border-radius; border-radius: $border-radius;
&:hover {
.all-connections-buttons {
.all-connections-delete,
.all-connections-pinned,
.all-connections-pin {
opacity: .5;
}
}
}
.all-connections-buttons {
.all-connections-pinned {
opacity: .3;
transition: opacity .2s;
&:hover {
opacity: 1;
}
}
.all-connections-delete,
.all-connections-pin {
opacity: 0;
transition: opacity .2s;
&:hover {
opacity: 1;
}
}
}
} }
</style> </style>