mirror of
https://github.com/Fabio286/antares.git
synced 2025-02-10 00:30:48 +01:00
feat: search form in all connections modal
This commit is contained in:
parent
a703dcc53e
commit
ec5ab73b19
@ -14,60 +14,89 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body py-0">
|
<div class="modal-body py-0">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div
|
<div class="connections-search column col-12 columns col-gapless">
|
||||||
v-for="connection in connections"
|
<div class="column col-12 mt-2">
|
||||||
:key="connection.uid"
|
<div
|
||||||
class="column col-md-6 col-lg-4 col-3 p-3"
|
ref="searchForm"
|
||||||
>
|
class="form-group has-icon-right p-2 m-0"
|
||||||
<div class="panel">
|
>
|
||||||
<div class="panel-header text-center">
|
<input
|
||||||
<figure class="avatar avatar-lg">
|
v-model="searchTerm"
|
||||||
<i class="settingbar-element-icon dbi" :class="[`dbi-${connection.client}`]" />
|
class="form-input"
|
||||||
</figure>
|
type="text"
|
||||||
<div class="panel-title h6 mt-10">
|
:placeholder="t('message.searchForConnections')"
|
||||||
{{ getConnectionName(connection.uid) }}
|
@keypress.esc="searchTerm = ''"
|
||||||
</div>
|
>
|
||||||
<div class="panel-subtitle">
|
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px pr-4" />
|
||||||
{{ connection.client }}
|
<i
|
||||||
</div>
|
v-else
|
||||||
</div>
|
class="form-icon c-hand mdi mdi-backspace mdi-18px pr-4"
|
||||||
<div class="panel-body text-center">
|
@click="searchTerm = ''"
|
||||||
<div v-if="connection.databasePath">
|
/>
|
||||||
<div class="pl-1 text-break">
|
|
||||||
<span class="text-bold">PATH:</span> {{ connection.databasePath }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<div class="pl-1 text-break">
|
|
||||||
<span class="text-bold">HOST:</span> {{ connection.host }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="connection.user">
|
|
||||||
<div class="pl-1 text-break">
|
|
||||||
<span class="text-bold">USER:</span> {{ connection.user }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="connection.schema">
|
|
||||||
<div class="pl-1 text-break">
|
|
||||||
<span class="text-bold">SCHEMA:</span> {{ connection.schema }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="connection.database">
|
|
||||||
<div class="pl-1 text-break">
|
|
||||||
<span class="text-bold">DATABASE:</span> {{ connection.database }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel-footer text-center py-0">
|
|
||||||
<div v-if="connection.ssl" class="chip bg-success mt-2">
|
|
||||||
SSL
|
|
||||||
</div>
|
|
||||||
<div v-if="connection.ssh" class="chip bg-success mt-2">
|
|
||||||
SSH
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<TransitionGroup name="fade" :duration="{enter: 200, leave: 200}">
|
||||||
|
<div
|
||||||
|
v-for="connection in filteredConnections"
|
||||||
|
:key="connection.uid"
|
||||||
|
class="connection-block column col-md-6 col-lg-4 col-3 p-3"
|
||||||
|
tabindex="0"
|
||||||
|
@click.stop="selectConnection(connection.uid)"
|
||||||
|
@keypress.stop.enter="selectConnection(connection.uid)"
|
||||||
|
>
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-header p-2 text-center">
|
||||||
|
<figure class="avatar avatar-lg pt-1 mb-1">
|
||||||
|
<i class="settingbar-element-icon dbi" :class="[`dbi-${connection.client}`]" />
|
||||||
|
</figure>
|
||||||
|
<div class="panel-title h6 text-ellipsis">
|
||||||
|
{{ getConnectionName(connection.uid) }}
|
||||||
|
</div>
|
||||||
|
<div class="panel-subtitle">
|
||||||
|
{{ clients.get(connection.client) || connection.client }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body text-center">
|
||||||
|
<div v-if="connection.databasePath">
|
||||||
|
<div class="text-ellipsis" :title="connection.databasePath">
|
||||||
|
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.databasePath }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="connection.user">
|
||||||
|
<div class="text-ellipsis">
|
||||||
|
<i class="mdi mdi-account d-inline" /> <span class="text-bold">{{ connection.user }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="connection.schema">
|
||||||
|
<div class="text-ellipsis">
|
||||||
|
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.schema }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="connection.database">
|
||||||
|
<div class="text-ellipsis">
|
||||||
|
<i class="mdi mdi-database d-inline" /> <span class="text-bold">{{ connection.database }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer text-center py-0">
|
||||||
|
<div v-if="connection.ssl" class="chip bg-success mt-2">
|
||||||
|
<i class="mdi mdi-lock mdi-18px mr-1" />
|
||||||
|
SSL
|
||||||
|
</div>
|
||||||
|
<div v-if="connection.ssh" class="chip bg-success mt-2">
|
||||||
|
<i class="mdi mdi-console-network mdi-18px mr-1" />
|
||||||
|
SSH
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TransitionGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -76,44 +105,61 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
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 { storeToRefs } from 'pinia';
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const connectionsStore = useConnectionsStore();
|
const connectionsStore = useConnectionsStore();
|
||||||
const workspacesStore = useWorkspacesStore();
|
const workspacesStore = useWorkspacesStore();
|
||||||
|
|
||||||
const { connections } = storeToRefs(connectionsStore);
|
const { connections } = storeToRefs(connectionsStore);
|
||||||
const { getConnectionName } = connectionsStore;
|
const { getConnectionName } = connectionsStore;
|
||||||
const { getWorkspace } = workspacesStore;
|
const { selectWorkspace } = workspacesStore;
|
||||||
|
|
||||||
const { trapRef } = useFocusTrap();
|
const { trapRef } = useFocusTrap();
|
||||||
|
|
||||||
const emit = defineEmits(['close']);
|
const emit = defineEmits(['close']);
|
||||||
|
|
||||||
|
const clients = new Map([
|
||||||
|
['mysql', 'MySQL'],
|
||||||
|
['maria', 'MariaDB'],
|
||||||
|
['pg', 'PostgreSQL'],
|
||||||
|
['sqlite', 'SQLite']
|
||||||
|
]);
|
||||||
|
|
||||||
|
const searchTerm = ref('');
|
||||||
|
|
||||||
|
const filteredConnections = computed(() => {
|
||||||
|
return connections.value.filter(connection => {
|
||||||
|
return connection.name?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
|
||||||
|
connection.host?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
|
||||||
|
connection.database?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
|
||||||
|
connection.databasePath?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
|
||||||
|
connection.schema?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
|
||||||
|
connection.user?.toLocaleLowerCase().includes(searchTerm.value.toLocaleLowerCase()) ||
|
||||||
|
String(connection.port)?.includes(searchTerm.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const closeModal = () => emit('close');
|
const closeModal = () => emit('close');
|
||||||
|
|
||||||
const onKey = (e:KeyboardEvent) => {
|
const selectConnection = (uid: string) => {
|
||||||
e.stopPropagation();
|
selectWorkspace(uid);
|
||||||
if (e.key === 'Escape')
|
closeModal();
|
||||||
closeModal();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStatusBadge = (uid: string) => {
|
const onKey = (e:KeyboardEvent) => {
|
||||||
if (getWorkspace(uid)) {
|
if (e.key === 'Escape') {
|
||||||
const status = getWorkspace(uid).connectionStatus;
|
e.stopPropagation();
|
||||||
|
if ((e.target as HTMLInputElement).tagName === 'INPUT' && searchTerm.value.length > 0)
|
||||||
switch (status) {
|
searchTerm.value = '';
|
||||||
case 'connected':
|
else
|
||||||
return 'badge badge-connected';
|
closeModal();
|
||||||
case 'connecting':
|
|
||||||
return 'badge badge-connecting';
|
|
||||||
case 'failed':
|
|
||||||
return 'badge badge-failed';
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,11 +192,6 @@ window.addEventListener('keydown', onKey, { capture: true });
|
|||||||
margin-left: 0.2rem;
|
margin-left: 0.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.result-tabs {
|
|
||||||
background: transparent !important;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
@ -164,8 +205,14 @@ window.addEventListener('keydown', onKey, { capture: true });
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.processes-toolbar {
|
.connections-search{
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connection-block{
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all .2s;
|
||||||
|
border-radius: $border-radius;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -214,6 +214,19 @@ watch(unpinnedConnectionsArr, (newVal, oldVal) => {
|
|||||||
}, 50);
|
}, 50);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(selectedWorkspace, (newVal, oldVal) => {
|
||||||
|
if (newVal !== oldVal) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const element = document.querySelector<HTMLElement>('.settingbar-element.selected');
|
||||||
|
if (element) {
|
||||||
|
element.setAttribute('tabindex', '-1');
|
||||||
|
element.focus();
|
||||||
|
element.removeAttribute('tabindex');
|
||||||
|
}
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@ -411,12 +411,12 @@ const workspacesStore = useWorkspacesStore();
|
|||||||
|
|
||||||
const { connectWorkspace, selectWorkspace } = workspacesStore;
|
const { connectWorkspace, selectWorkspace } = workspacesStore;
|
||||||
|
|
||||||
const clients = ref([
|
const clients = [
|
||||||
{ name: 'MySQL', slug: 'mysql' },
|
{ name: 'MySQL', slug: 'mysql' },
|
||||||
{ name: 'MariaDB', slug: 'maria' },
|
{ name: 'MariaDB', slug: 'maria' },
|
||||||
{ name: 'PostgreSQL', slug: 'pg' },
|
{ name: 'PostgreSQL', slug: 'pg' },
|
||||||
{ name: 'SQLite', slug: 'sqlite' }
|
{ name: 'SQLite', slug: 'sqlite' }
|
||||||
]);
|
];
|
||||||
|
|
||||||
const connection = ref({
|
const connection = ref({
|
||||||
name: '',
|
name: '',
|
||||||
|
@ -253,6 +253,14 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group columns">
|
||||||
|
<div class="column col-4 col-sm-12" />
|
||||||
|
<div class="column col-8 col-sm-12">
|
||||||
|
<label class="form-checkbox form-inline">
|
||||||
|
<input v-model="localConnection.untrustedConnection" type="checkbox"><i class="form-icon" /> {{ t('message.untrustedConnection') }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -416,12 +424,12 @@ const { editConnection } = useConnectionsStore();
|
|||||||
const { addNotification } = useNotificationsStore();
|
const { addNotification } = useNotificationsStore();
|
||||||
const { connectWorkspace } = useWorkspacesStore();
|
const { connectWorkspace } = useWorkspacesStore();
|
||||||
|
|
||||||
const clients = ref([
|
const clients = [
|
||||||
{ name: 'MySQL', slug: 'mysql' },
|
{ name: 'MySQL', slug: 'mysql' },
|
||||||
{ name: 'MariaDB', slug: 'maria' },
|
{ name: 'MariaDB', slug: 'maria' },
|
||||||
{ name: 'PostgreSQL', slug: 'pg' },
|
{ name: 'PostgreSQL', slug: 'pg' },
|
||||||
{ name: 'SQLite', slug: 'sqlite' }
|
{ name: 'SQLite', slug: 'sqlite' }
|
||||||
]);
|
];
|
||||||
|
|
||||||
const firstInput: Ref<HTMLInputElement> = ref(null);
|
const firstInput: Ref<HTMLInputElement> = ref(null);
|
||||||
const localConnection: Ref<ConnectionParams & { pgConnString: string }> = ref(null);
|
const localConnection: Ref<ConnectionParams & { pgConnString: string }> = ref(null);
|
||||||
|
@ -294,7 +294,8 @@ module.exports = {
|
|||||||
missingOrIncompleteTranslation: 'Missing or incomplete translation?',
|
missingOrIncompleteTranslation: 'Missing or incomplete translation?',
|
||||||
findOutHowToContribute: 'Find out how to contribute',
|
findOutHowToContribute: 'Find out how to contribute',
|
||||||
disableFKChecks: 'Disable foreigh key checks',
|
disableFKChecks: 'Disable foreigh key checks',
|
||||||
allConnections: 'All connections'
|
allConnections: 'All connections',
|
||||||
|
searchForConnections: 'Search for connections'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Address',
|
address: 'Address',
|
||||||
|
@ -256,6 +256,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.connection-block{
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-light-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bg-checkered {
|
.bg-checkered {
|
||||||
background-image:
|
background-image:
|
||||||
linear-gradient(to right, rgba(192, 192, 192, 0.75), rgba(192, 192, 192, 0.75)),
|
linear-gradient(to right, rgba(192, 192, 192, 0.75), rgba(192, 192, 192, 0.75)),
|
||||||
|
@ -274,6 +274,12 @@
|
|||||||
background: rgba($bg-color-light-gray, 100%);
|
background: rgba($bg-color-light-gray, 100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.connection-block{
|
||||||
|
&:hover {
|
||||||
|
background: $bg-color-light-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.context {
|
.context {
|
||||||
color: $body-font-color-dark;
|
color: $body-font-color-dark;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user