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>
|
</span>
|
||||||
</div>
|
</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
|
<WorkspaceConnectPanel
|
||||||
v-if="!workspace.connected"
|
v-if="!workspace.connected"
|
||||||
class="workspace-explorebar-body"
|
class="workspace-explorebar-body"
|
||||||
|
@ -171,7 +182,8 @@ export default {
|
||||||
isNewSchedulerModal: false,
|
isNewSchedulerModal: false,
|
||||||
|
|
||||||
localWidth: null,
|
localWidth: null,
|
||||||
debounceInterval: null,
|
explorebarWidthInterval: null,
|
||||||
|
searchTermInterval: null,
|
||||||
isDatabaseContext: false,
|
isDatabaseContext: false,
|
||||||
isTableContext: false,
|
isTableContext: false,
|
||||||
isMiscContext: false,
|
isMiscContext: false,
|
||||||
|
@ -182,7 +194,8 @@ export default {
|
||||||
|
|
||||||
selectedDatabase: '',
|
selectedDatabase: '',
|
||||||
selectedTable: null,
|
selectedTable: null,
|
||||||
selectedMisc: null
|
selectedMisc: null,
|
||||||
|
searchTerm: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -200,14 +213,21 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
localWidth (val) {
|
localWidth (val) {
|
||||||
clearTimeout(this.debounceInterval);
|
clearTimeout(this.explorebarWidthInterval);
|
||||||
|
|
||||||
this.debounceInterval = setTimeout(() => {
|
this.explorebarWidthInterval = setTimeout(() => {
|
||||||
this.changeExplorebarSize(val);
|
this.changeExplorebarSize(val);
|
||||||
}, 500);
|
}, 500);
|
||||||
},
|
},
|
||||||
isSelected (val) {
|
isSelected (val) {
|
||||||
if (val) this.localWidth = this.explorebarSize;
|
if (val) this.localWidth = this.explorebarSize;
|
||||||
|
},
|
||||||
|
searchTerm () {
|
||||||
|
clearTimeout(this.searchTermInterval);
|
||||||
|
|
||||||
|
this.searchTermInterval = setTimeout(() => {
|
||||||
|
this.setSearchTerm(this.searchTerm);
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
@ -229,6 +249,7 @@ export default {
|
||||||
refreshStructure: 'workspaces/refreshStructure',
|
refreshStructure: 'workspaces/refreshStructure',
|
||||||
changeBreadcrumbs: 'workspaces/changeBreadcrumbs',
|
changeBreadcrumbs: 'workspaces/changeBreadcrumbs',
|
||||||
selectTab: 'workspaces/selectTab',
|
selectTab: 'workspaces/selectTab',
|
||||||
|
setSearchTerm: 'workspaces/setSearchTerm',
|
||||||
addNotification: 'notifications/addNotification',
|
addNotification: 'notifications/addNotification',
|
||||||
changeExplorebarSize: 'settings/changeExplorebarSize'
|
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 {
|
.workspace-explorebar-body {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc((100vh - 30px) - #{$excluding-size});
|
height: calc((100vh - 58px) - #{$excluding-size});
|
||||||
overflow: overlay;
|
overflow: overlay;
|
||||||
padding: 0 0.1rem;
|
padding: 0 0.1rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<div class="database-tables">
|
<div class="database-tables">
|
||||||
<ul class="menu menu-nav pt-0">
|
<ul class="menu menu-nav pt-0">
|
||||||
<li
|
<li
|
||||||
v-for="table of database.tables"
|
v-for="table of filteredTables"
|
||||||
:key="table.name"
|
:key="table.name"
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
:class="{'text-bold': breadcrumbs.schema === database.name && [breadcrumbs.table, breadcrumbs.view].includes(table.name)}"
|
:class="{'text-bold': breadcrumbs.schema === database.name && [breadcrumbs.table, breadcrumbs.view].includes(table.name)}"
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
>
|
>
|
||||||
<a class="table-name">
|
<a class="table-name">
|
||||||
<i class="table-icon mdi mdi-18px mr-1" :class="table.type === 'view' ? 'mdi-table-eye' : 'mdi-table'" />
|
<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>
|
</a>
|
||||||
<div
|
<div
|
||||||
v-if="table.type === 'table'"
|
v-if="table.type === 'table'"
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="database.triggers.length" class="database-misc">
|
<div v-if="filteredTriggers.length" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger}">
|
<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" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-cog mr-1" />
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
<div>
|
<div>
|
||||||
<ul class="menu menu-nav pt-0">
|
<ul class="menu menu-nav pt-0">
|
||||||
<li
|
<li
|
||||||
v-for="trigger of database.triggers"
|
v-for="trigger of filteredTriggers"
|
||||||
:key="trigger.name"
|
:key="trigger.name"
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger === trigger.name}"
|
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.trigger === trigger.name}"
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
>
|
>
|
||||||
<a class="table-name">
|
<a class="table-name">
|
||||||
<i class="table-icon mdi mdi-table-cog mdi-18px mr-1" />
|
<i class="table-icon mdi mdi-table-cog mdi-18px mr-1" />
|
||||||
<span>{{ trigger.name }}</span>
|
<span v-html="highlightWord(trigger.name)" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="database.procedures.length" class="database-misc">
|
<div v-if="filteredProcedures.length" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.procedure}">
|
<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" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-sync mr-1" />
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<div>
|
<div>
|
||||||
<ul class="menu menu-nav pt-0">
|
<ul class="menu menu-nav pt-0">
|
||||||
<li
|
<li
|
||||||
v-for="procedure of database.procedures"
|
v-for="procedure of filteredProcedures"
|
||||||
:key="procedure.name"
|
:key="procedure.name"
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.procedure === procedure.name}"
|
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.procedure === procedure.name}"
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
>
|
>
|
||||||
<a class="table-name">
|
<a class="table-name">
|
||||||
<i class="table-icon mdi mdi-sync-circle mdi-18px mr-1" />
|
<i class="table-icon mdi mdi-sync-circle mdi-18px mr-1" />
|
||||||
<span>{{ procedure.name }}</span>
|
<span v-html="highlightWord(procedure.name)" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="database.functions.length" class="database-misc">
|
<div v-if="filteredFunctions.length" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.function}">
|
<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" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-move mr-1" />
|
||||||
|
@ -103,7 +103,7 @@
|
||||||
<div>
|
<div>
|
||||||
<ul class="menu menu-nav pt-0">
|
<ul class="menu menu-nav pt-0">
|
||||||
<li
|
<li
|
||||||
v-for="func of database.functions"
|
v-for="func of filteredFunctions"
|
||||||
:key="func.name"
|
:key="func.name"
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.function === func.name}"
|
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.function === func.name}"
|
||||||
|
@ -112,7 +112,7 @@
|
||||||
>
|
>
|
||||||
<a class="table-name">
|
<a class="table-name">
|
||||||
<i class="table-icon mdi mdi-arrow-right-bold-box mdi-18px mr-1" />
|
<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>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="database.schedulers.length" class="database-misc">
|
<div v-if="filteredSchedulers.length" class="database-misc">
|
||||||
<details class="accordion">
|
<details class="accordion">
|
||||||
<summary class="accordion-header misc-name" :class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.scheduler}">
|
<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" />
|
<i class="misc-icon mdi mdi-18px mdi-folder-clock mr-1" />
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
<div>
|
<div>
|
||||||
<ul class="menu menu-nav pt-0">
|
<ul class="menu menu-nav pt-0">
|
||||||
<li
|
<li
|
||||||
v-for="scheduler of database.schedulers"
|
v-for="scheduler of filteredSchedulers"
|
||||||
:key="scheduler.name"
|
:key="scheduler.name"
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.scheduler === scheduler.name}"
|
:class="{'text-bold': breadcrumbs.schema === database.name && breadcrumbs.scheduler === scheduler.name}"
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
>
|
>
|
||||||
<a class="table-name">
|
<a class="table-name">
|
||||||
<i class="table-icon mdi mdi-calendar-clock mdi-18px mr-1" />
|
<i class="table-icon mdi mdi-calendar-clock mdi-18px mr-1" />
|
||||||
<span>{{ scheduler.name }}</span>
|
<span v-html="highlightWord(scheduler.name)" />
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -170,8 +170,27 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
getLoadedSchemas: 'workspaces/getLoadedSchemas',
|
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 () {
|
breadcrumbs () {
|
||||||
return this.getWorkspace(this.connection.uid).breadcrumbs;
|
return this.getWorkspace(this.connection.uid).breadcrumbs;
|
||||||
},
|
},
|
||||||
|
@ -222,6 +241,14 @@ export default {
|
||||||
setBreadcrumbs (payload) {
|
setBreadcrumbs (payload) {
|
||||||
if (this.breadcrumbs.schema === payload.schema && this.breadcrumbs.table === payload.table) return;
|
if (this.breadcrumbs.schema === payload.schema && this.breadcrumbs.table === payload.table) return;
|
||||||
this.changeBreadcrumbs(payload);
|
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',
|
enableSsl: 'Enable SSL',
|
||||||
manualValue: 'Manual value',
|
manualValue: 'Manual value',
|
||||||
tableFiller: 'Table Filler',
|
tableFiller: 'Table Filler',
|
||||||
fakeDataLanguage: 'Fake data language'
|
fakeDataLanguage: 'Fake data language',
|
||||||
|
searchForElements: 'Search for elements'
|
||||||
},
|
},
|
||||||
faker: {
|
faker: {
|
||||||
address: 'Address',
|
address: 'Address',
|
||||||
|
|
|
@ -43,6 +43,9 @@ export default {
|
||||||
getLoadedSchemas: state => uid => {
|
getLoadedSchemas: state => uid => {
|
||||||
return state.workspaces.find(workspace => workspace.uid === uid).loaded_schemas;
|
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 => {
|
isUnsavedDiscardModal: state => {
|
||||||
return state.is_unsaved_discard_modal;
|
return state.is_unsaved_discard_modal;
|
||||||
}
|
}
|
||||||
|
@ -141,6 +144,14 @@ export default {
|
||||||
}
|
}
|
||||||
: workspace);
|
: 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 }) {
|
NEW_TAB (state, { uid, tab }) {
|
||||||
tabIndex[uid] = tabIndex[uid] ? ++tabIndex[uid] : 1;
|
tabIndex[uid] = tabIndex[uid] ? ++tabIndex[uid] : 1;
|
||||||
const newTab = {
|
const newTab = {
|
||||||
|
@ -368,6 +379,7 @@ export default {
|
||||||
uid,
|
uid,
|
||||||
connected: false,
|
connected: false,
|
||||||
selected_tab: 0,
|
selected_tab: 0,
|
||||||
|
search_term: '',
|
||||||
tabs: [],
|
tabs: [],
|
||||||
structure: {},
|
structure: {},
|
||||||
variables: [],
|
variables: [],
|
||||||
|
@ -415,6 +427,9 @@ export default {
|
||||||
if (payload.schema)
|
if (payload.schema)
|
||||||
commit('ADD_LOADED_SCHEMA', { uid: getters.getSelected, schema: 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) {
|
newTab ({ commit }, uid) {
|
||||||
const tab = uidGen('T');
|
const tab = uidGen('T');
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue