mirror of https://github.com/Fabio286/antares.git
feat: filter schemas in sidebar, closes #555
This commit is contained in:
parent
d802b32597
commit
8be9f932e7
|
@ -32,13 +32,20 @@
|
|||
</span>
|
||||
</div>
|
||||
<div class="workspace-explorebar-search">
|
||||
<div v-if="workspace.connectionStatus === 'connected'" class="has-icon-right">
|
||||
<div v-if="workspace.connectionStatus === 'connected'" class="input-group has-icon-right">
|
||||
<div
|
||||
class="input-group-addon px-1 py-0 p-vcentered c-hand"
|
||||
:title="t('message.switchSearchMethod')"
|
||||
@click="toggleSearchMethod"
|
||||
>
|
||||
<i class="mdi mdi-18px" :class="[searchMethod === 'elements' ? 'mdi-shape' : 'mdi-database']" />
|
||||
</div>
|
||||
<input
|
||||
ref="searchInput"
|
||||
v-model="searchTerm"
|
||||
class="form-input input-sm"
|
||||
type="text"
|
||||
:placeholder="t('message.searchForElements')"
|
||||
:placeholder="searchMethod === 'elements' ? t('message.searchForElements') : t('message.searchForSchemas')"
|
||||
>
|
||||
<i v-if="!searchTerm" class="form-icon mdi mdi-magnify mdi-18px" />
|
||||
<i
|
||||
|
@ -50,11 +57,12 @@
|
|||
</div>
|
||||
<div class="workspace-explorebar-body" @click="explorebar.focus()">
|
||||
<WorkspaceExploreBarSchema
|
||||
v-for="db of workspace.structure"
|
||||
v-for="db of filteredSchemas"
|
||||
:key="db.name"
|
||||
ref="schema"
|
||||
:database="db"
|
||||
:connection="connection"
|
||||
:search-method="searchMethod"
|
||||
@show-schema-context="openSchemaContext"
|
||||
@show-table-context="openTableContext"
|
||||
@show-misc-context="openMiscContext"
|
||||
|
@ -181,6 +189,7 @@ const selectedSchema = ref('');
|
|||
const selectedTable = ref(null);
|
||||
const selectedMisc = ref(null);
|
||||
const searchTerm = ref('');
|
||||
const searchMethod: Ref<'elements' | 'schemas'> = ref('elements');
|
||||
|
||||
const workspace = computed(() => {
|
||||
return getWorkspace(props.connection.uid);
|
||||
|
@ -194,6 +203,13 @@ const customizations = computed(() => {
|
|||
return workspace.value.customizations;
|
||||
});
|
||||
|
||||
const filteredSchemas = computed(() => {
|
||||
if (searchMethod.value === 'schemas')
|
||||
return workspace.value.structure.filter(schema => schema.name.search(searchTerm.value) >= 0);
|
||||
else
|
||||
return workspace.value.structure;
|
||||
});
|
||||
|
||||
watch(localWidth, (val: number) => {
|
||||
clearTimeout(explorebarWidthInterval.value);
|
||||
|
||||
|
@ -403,6 +419,15 @@ const duplicateTable = async (payload: { schema: string; table: { name: string }
|
|||
});
|
||||
};
|
||||
|
||||
const toggleSearchMethod = () => {
|
||||
searchTerm.value = '';
|
||||
setSearchTerm(searchTerm.value);
|
||||
|
||||
if (searchMethod.value === 'elements')
|
||||
searchMethod.value = 'schemas';
|
||||
else
|
||||
searchMethod.value = 'elements';
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -478,6 +503,8 @@ const duplicateTable = async (payload: { schema: string; table: { name: string }
|
|||
justify-content: space-between;
|
||||
font-size: 0.6rem;
|
||||
height: 28px;
|
||||
margin: 5px 0;
|
||||
z-index: 10;
|
||||
|
||||
.has-icon-right {
|
||||
width: 100%;
|
||||
|
@ -491,6 +518,7 @@ const duplicateTable = async (payload: { schema: string; table: { name: string }
|
|||
.form-input {
|
||||
height: 1.2rem;
|
||||
padding-left: 0.2rem;
|
||||
border-radius:0 $border-radius $border-radius 0;
|
||||
|
||||
&:focus + .form-icon {
|
||||
opacity: 0.9;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<i v-else class="icon mdi mdi-18px mdi-chevron-right" />
|
||||
<i class="database-icon mdi mdi-18px mdi-database mr-1" />
|
||||
<div class="">
|
||||
<span>{{ database.name }}</span>
|
||||
<span v-html="highlightWord(database.name, 'schemas')" />
|
||||
<div
|
||||
v-if="database.size"
|
||||
class="schema-size tooltip tooltip-left mr-1"
|
||||
|
@ -249,7 +249,8 @@ const { t } = useI18n();
|
|||
|
||||
const props = defineProps({
|
||||
database: Object as Prop<WorkspaceStructure>,
|
||||
connection: Object
|
||||
connection: Object,
|
||||
searchMethod: String as Prop<'elements' | 'schemas'>
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
|
@ -282,29 +283,51 @@ const searchTerm = computed(() => {
|
|||
});
|
||||
|
||||
const filteredTables = computed(() => {
|
||||
return props.database.tables.filter(table => table.name.search(searchTerm.value) >= 0);
|
||||
if (props.searchMethod === 'elements')
|
||||
return props.database.tables.filter(table => table.name.search(searchTerm.value) >= 0);
|
||||
else
|
||||
return props.database.tables;
|
||||
});
|
||||
|
||||
const filteredTriggers = computed(() => {
|
||||
return props.database.triggers.filter(trigger => trigger.name.search(searchTerm.value) >= 0);
|
||||
if (props.searchMethod === 'elements')
|
||||
return props.database.triggers.filter(trigger => trigger.name.search(searchTerm.value) >= 0);
|
||||
else
|
||||
return props.database.triggers;
|
||||
});
|
||||
|
||||
const filteredProcedures = computed(() => {
|
||||
return props.database.procedures.filter(procedure => procedure.name.search(searchTerm.value) >= 0);
|
||||
if (props.searchMethod === 'elements')
|
||||
return props.database.procedures.filter(procedure => procedure.name.search(searchTerm.value) >= 0);
|
||||
else
|
||||
return props.database.procedures;
|
||||
});
|
||||
|
||||
const filteredFunctions = computed(() => {
|
||||
return props.database.functions.filter(func => func.name.search(searchTerm.value) >= 0);
|
||||
if (props.searchMethod === 'elements')
|
||||
return props.database.functions.filter(func => func.name.search(searchTerm.value) >= 0);
|
||||
else
|
||||
return props.database.functions;
|
||||
});
|
||||
|
||||
const filteredTriggerFunctions = computed(() => {
|
||||
return props.database.triggerFunctions
|
||||
? props.database.triggerFunctions.filter(func => func.name.search(searchTerm.value) >= 0)
|
||||
: [];
|
||||
if (props.searchMethod === 'elements') {
|
||||
return props.database.triggerFunctions
|
||||
? props.database.triggerFunctions.filter(func => func.name.search(searchTerm.value) >= 0)
|
||||
: [];
|
||||
}
|
||||
else {
|
||||
return props.database.triggerFunctions
|
||||
? props.database.triggerFunctions
|
||||
: [];
|
||||
}
|
||||
});
|
||||
|
||||
const filteredSchedulers = computed(() => {
|
||||
return props.database.schedulers.filter(scheduler => scheduler.name.search(searchTerm.value) >= 0);
|
||||
if (props.searchMethod === 'elements')
|
||||
return props.database.schedulers.filter(scheduler => scheduler.name.search(searchTerm.value) >= 0);
|
||||
else
|
||||
return props.database.schedulers;
|
||||
});
|
||||
|
||||
const workspace = computed(() => {
|
||||
|
@ -446,10 +469,10 @@ const setBreadcrumbs = (payload: Breadcrumb) => {
|
|||
changeBreadcrumbs(payload);
|
||||
};
|
||||
|
||||
const highlightWord = (string: string) => {
|
||||
const highlightWord = (string: string, type = 'elements') => {
|
||||
string = string.replaceAll('<', '<').replaceAll('>', '>');
|
||||
|
||||
if (searchTerm.value) {
|
||||
if (searchTerm.value && props.searchMethod === type) {
|
||||
const regexp = new RegExp(`(${searchTerm.value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
|
||||
return string.replace(regexp, '<span class="text-primary">$1</span>');
|
||||
}
|
||||
|
|
|
@ -337,7 +337,9 @@ export const enUS = {
|
|||
executeSelectedQuery: 'Execute selected query',
|
||||
defaultCopyType: 'Default copy type',
|
||||
showTableSize: 'Show table size in sidebar',
|
||||
showTableSizeDescription: 'MySQL/MariaDB only. Enable this option may affects performance on schema with many tables.'
|
||||
showTableSizeDescription: 'MySQL/MariaDB only. Enable this option may affects performance on schema with many tables.',
|
||||
searchForSchemas: 'Search for schemas',
|
||||
switchSearchMethod: 'Switch search method'
|
||||
},
|
||||
faker: {
|
||||
address: 'Address',
|
||||
|
|
Loading…
Reference in New Issue