mirror of https://github.com/Fabio286/antares.git
feat(UI): search filter in explore bar
This commit is contained in:
parent
9b60bfff8d
commit
2f58007af4
|
@ -27,6 +27,17 @@
|
|||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="workspace-explorebar-search">
|
||||
<div v-if="workspace.connected" class="has-icon-right">
|
||||
<input
|
||||
v-model="searchTerm"
|
||||
class="form-input input-sm"
|
||||
type="text"
|
||||
:placeholder="$t('message.searchForElements')"
|
||||
>
|
||||
<i class="form-icon mdi mdi-magnify mdi-18px" />
|
||||
</div>
|
||||
</div>
|
||||
<WorkspaceConnectPanel
|
||||
v-if="!workspace.connected"
|
||||
class="workspace-explorebar-body"
|
||||
|
@ -171,7 +182,8 @@ export default {
|
|||
isNewSchedulerModal: false,
|
||||
|
||||
localWidth: null,
|
||||
debounceInterval: null,
|
||||
explorebarWidthInterval: null,
|
||||
searchTermInterval: null,
|
||||
isDatabaseContext: false,
|
||||
isTableContext: false,
|
||||
isMiscContext: false,
|
||||
|
@ -182,7 +194,8 @@ export default {
|
|||
|
||||
selectedDatabase: '',
|
||||
selectedTable: null,
|
||||
selectedMisc: null
|
||||
selectedMisc: null,
|
||||
searchTerm: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -200,14 +213,21 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
localWidth (val) {
|
||||
clearTimeout(this.debounceInterval);
|
||||
clearTimeout(this.explorebarWidthInterval);
|
||||
|
||||
this.debounceInterval = setTimeout(() => {
|
||||
this.explorebarWidthInterval = setTimeout(() => {
|
||||
this.changeExplorebarSize(val);
|
||||
}, 500);
|
||||
},
|
||||
isSelected (val) {
|
||||
if (val) this.localWidth = this.explorebarSize;
|
||||
},
|
||||
searchTerm () {
|
||||
clearTimeout(this.searchTermInterval);
|
||||
|
||||
this.searchTermInterval = setTimeout(() => {
|
||||
this.setSearchTerm(this.searchTerm);
|
||||
}, 200);
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
@ -229,6 +249,7 @@ export default {
|
|||
refreshStructure: 'workspaces/refreshStructure',
|
||||
changeBreadcrumbs: 'workspaces/changeBreadcrumbs',
|
||||
selectTab: 'workspaces/selectTab',
|
||||
setSearchTerm: 'workspaces/setSearchTerm',
|
||||
addNotification: 'notifications/addNotification',
|
||||
changeExplorebarSize: 'settings/changeExplorebarSize'
|
||||
}),
|
||||
|
@ -481,9 +502,40 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.workspace-explorebar-search {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.6rem;
|
||||
height: 28px;
|
||||
|
||||
.has-icon-right {
|
||||
width: 100%;
|
||||
padding: 0.1rem;
|
||||
|
||||
.form-icon {
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
height: 1.2rem;
|
||||
padding-left: 0.2rem;
|
||||
|
||||
&:focus + .form-icon {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&::placeholder {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.workspace-explorebar-body {
|
||||
width: 100%;
|
||||
height: calc((100vh - 30px) - #{$excluding-size});
|
||||
height: calc((100vh - 58px) - #{$excluding-size});
|
||||
overflow: overlay;
|
||||
padding: 0 0.1rem;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<div class="database-tables">
|
||||
<ul class="menu menu-nav pt-0">
|
||||
<li
|
||||
v-for="table of database.tables"
|
||||
v-for="table of filteredTables"
|
||||
:key="table.name"
|
||||
class="menu-item"
|
||||
:class="{'text-bold': breadcrumbs.schema === database.name && [breadcrumbs.table, breadcrumbs.view].includes(table.name)}"
|
||||
|
@ -24,7 +24,7 @@
|
|||
>
|
||||
<a class="table-name">
|
||||
<i class="table-icon mdi mdi-18px mr-1" :class="table.type === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
|
||||
<span>{{ table.name }}</span>
|
||||
<span v-html="highlightWord(table.name)" />
|
||||
</a>
|
||||
<div
|
||||
v-if="table.type === 'table'"
|
||||
|
@ -37,7 +37,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="database.triggers.length" class="database-misc">
|
||||
<div v-if="filteredTriggers.length" class="database-misc">
|
||||
<details class="accordion">
|
||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger}">
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-cog mr-1" />
|
||||
|
@ -47,7 +47,7 @@
|
|||
<div>
|
||||
<ul class="menu menu-nav pt-0">
|
||||
<li
|
||||
v-for="trigger of database.triggers"
|
||||
v-for="trigger of filteredTriggers"
|
||||
:key="trigger.name"
|
||||
class="menu-item"
|
||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger === trigger.name}"
|
||||
|
@ -56,7 +56,7 @@
|
|||
>
|
||||
<a class="table-name">
|
||||
<i class="table-icon mdi mdi-table-cog mdi-18px mr-1" />
|
||||
<span>{{ trigger.name }}</span>
|
||||
<span v-html="highlightWord(trigger.name)" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -65,7 +65,7 @@
|
|||
</details>
|
||||
</div>
|
||||
|
||||
<div v-if="database.procedures.length" class="database-misc">
|
||||
<div v-if="filteredProcedures.length" class="database-misc">
|
||||
<details class="accordion">
|
||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.procedure}">
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-sync mr-1" />
|
||||
|
@ -75,7 +75,7 @@
|
|||
<div>
|
||||
<ul class="menu menu-nav pt-0">
|
||||
<li
|
||||
v-for="procedure of database.procedures"
|
||||
v-for="procedure of filteredProcedures"
|
||||
:key="procedure.name"
|
||||
class="menu-item"
|
||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.procedure === procedure.name}"
|
||||
|
@ -84,7 +84,7 @@
|
|||
>
|
||||
<a class="table-name">
|
||||
<i class="table-icon mdi mdi-sync-circle mdi-18px mr-1" />
|
||||
<span>{{ procedure.name }}</span>
|
||||
<span v-html="highlightWord(procedure.name)" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -93,7 +93,7 @@
|
|||
</details>
|
||||
</div>
|
||||
|
||||
<div v-if="database.functions.length" class="database-misc">
|
||||
<div v-if="filteredFunctions.length" class="database-misc">
|
||||
<details class="accordion">
|
||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.function}">
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-move mr-1" />
|
||||
|
@ -103,7 +103,7 @@
|
|||
<div>
|
||||
<ul class="menu menu-nav pt-0">
|
||||
<li
|
||||
v-for="func of database.functions"
|
||||
v-for="func of filteredFunctions"
|
||||
:key="func.name"
|
||||
class="menu-item"
|
||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.function === func.name}"
|
||||
|
@ -112,7 +112,7 @@
|
|||
>
|
||||
<a class="table-name">
|
||||
<i class="table-icon mdi mdi-arrow-right-bold-box mdi-18px mr-1" />
|
||||
<span>{{ func.name }}</span>
|
||||
<span v-html="highlightWord(func.name)" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -121,7 +121,7 @@
|
|||
</details>
|
||||
</div>
|
||||
|
||||
<div v-if="database.schedulers.length" class="database-misc">
|
||||
<div v-if="filteredSchedulers.length" class="database-misc">
|
||||
<details class="accordion">
|
||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.scheduler}">
|
||||
<i class="misc-icon mdi mdi-18px mdi-folder-clock mr-1" />
|
||||
|
@ -131,7 +131,7 @@
|
|||
<div>
|
||||
<ul class="menu menu-nav pt-0">
|
||||
<li
|
||||
v-for="scheduler of database.schedulers"
|
||||
v-for="scheduler of filteredSchedulers"
|
||||
:key="scheduler.name"
|
||||
class="menu-item"
|
||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.scheduler === scheduler.name}"
|
||||
|
@ -140,7 +140,7 @@
|
|||
>
|
||||
<a class="table-name">
|
||||
<i class="table-icon mdi mdi-calendar-clock mdi-18px mr-1" />
|
||||
<span>{{ scheduler.name }}</span>
|
||||
<span v-html="highlightWord(scheduler.name)" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -170,8 +170,27 @@ export default {
|
|||
computed: {
|
||||
...mapGetters({
|
||||
getLoadedSchemas: 'workspaces/getLoadedSchemas',
|
||||
getWorkspace: 'workspaces/getWorkspace'
|
||||
getWorkspace: 'workspaces/getWorkspace',
|
||||
getSearchTerm: 'workspaces/getSearchTerm'
|
||||
}),
|
||||
searchTerm () {
|
||||
return this.getSearchTerm(this.connection.uid);
|
||||
},
|
||||
filteredTables () {
|
||||
return this.database.tables.filter(table => table.name.search(this.searchTerm) >= 0);
|
||||
},
|
||||
filteredTriggers () {
|
||||
return this.database.triggers.filter(trigger => trigger.name.search(this.searchTerm) >= 0);
|
||||
},
|
||||
filteredProcedures () {
|
||||
return this.database.procedures.filter(procedure => procedure.name.search(this.searchTerm) >= 0);
|
||||
},
|
||||
filteredFunctions () {
|
||||
return this.database.functions.filter(func => func.name.search(this.searchTerm) >= 0);
|
||||
},
|
||||
filteredSchedulers () {
|
||||
return this.database.schedulers.filter(scheduler => scheduler.name.search(this.searchTerm) >= 0);
|
||||
},
|
||||
breadcrumbs () {
|
||||
return this.getWorkspace(this.connection.uid).breadcrumbs;
|
||||
},
|
||||
|
@ -222,6 +241,14 @@ export default {
|
|||
setBreadcrumbs (payload) {
|
||||
if (this.breadcrumbs.schema === payload.schema && this.breadcrumbs.table === payload.table) return;
|
||||
this.changeBreadcrumbs(payload);
|
||||
},
|
||||
highlightWord (string) {
|
||||
if (this.searchTerm) {
|
||||
const regexp = new RegExp(`(${this.searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
|
||||
return string.replace(regexp, '<span class="text-primary">$1</span>');
|
||||
}
|
||||
else
|
||||
return string;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -184,7 +184,8 @@ module.exports = {
|
|||
enableSsl: 'Enable SSL',
|
||||
manualValue: 'Manual value',
|
||||
tableFiller: 'Table Filler',
|
||||
fakeDataLanguage: 'Fake data language'
|
||||
fakeDataLanguage: 'Fake data language',
|
||||
searchForElements: 'Search for elements'
|
||||
},
|
||||
faker: {
|
||||
address: 'Address',
|
||||
|
|
|
@ -43,6 +43,9 @@ export default {
|
|||
getLoadedSchemas: state => uid => {
|
||||
return state.workspaces.find(workspace => workspace.uid === uid).loaded_schemas;
|
||||
},
|
||||
getSearchTerm: state => uid => {
|
||||
return state.workspaces.find(workspace => workspace.uid === uid).search_term;
|
||||
},
|
||||
isUnsavedDiscardModal: state => {
|
||||
return state.is_unsaved_discard_modal;
|
||||
}
|
||||
|
@ -141,6 +144,14 @@ export default {
|
|||
}
|
||||
: workspace);
|
||||
},
|
||||
SET_SEARCH_TERM (state, { uid, term }) {
|
||||
state.workspaces = state.workspaces.map(workspace => workspace.uid === uid
|
||||
? {
|
||||
...workspace,
|
||||
search_term: term
|
||||
}
|
||||
: workspace);
|
||||
},
|
||||
NEW_TAB (state, { uid, tab }) {
|
||||
tabIndex[uid] = tabIndex[uid] ? ++tabIndex[uid] : 1;
|
||||
const newTab = {
|
||||
|
@ -368,6 +379,7 @@ export default {
|
|||
uid,
|
||||
connected: false,
|
||||
selected_tab: 0,
|
||||
search_term: '',
|
||||
tabs: [],
|
||||
structure: {},
|
||||
variables: [],
|
||||
|
@ -415,6 +427,9 @@ export default {
|
|||
if (payload.schema)
|
||||
commit('ADD_LOADED_SCHEMA', { uid: getters.getSelected, schema: payload.schema });
|
||||
},
|
||||
setSearchTerm ({ commit, getters }, term) {
|
||||
commit('SET_SEARCH_TERM', { uid: getters.getSelected, term });
|
||||
},
|
||||
newTab ({ commit }, uid) {
|
||||
const tab = uidGen('T');
|
||||
|
||||
|
|
Loading…
Reference in New Issue