152 lines
4.2 KiB
Vue
152 lines
4.2 KiB
Vue
<template>
|
|
<div class="tree-view-search-wrapper">
|
|
<div>
|
|
<el-input
|
|
:placeholder="t('search-signal')"
|
|
size="large"
|
|
v-model="searchManage.content"
|
|
input-style="font-size: 16px;"
|
|
@input="safeSearch"
|
|
@focus="searchManage.displayResult = true"
|
|
@blur="searchManage.displayResult = false"
|
|
/>
|
|
</div>
|
|
<div class="search-result-wrapper" v-if="searchManage.displayResult">
|
|
<div class="search-result">
|
|
<div v-if="searchManage.searchResult.length > 0">
|
|
<div v-for="(searchResult, index) in searchManage.searchResult"
|
|
:key="index"
|
|
:class="globalLookup.currentWires.has(searchResult.module) ? 'vcd-treeview-selected' : ''"
|
|
@click="toggleRender(searchResult.module)">
|
|
<div v-html="searchResult.htmlString" class="search-result-item"></div>
|
|
</div>
|
|
|
|
</div>
|
|
<div v-else>
|
|
{{ t('search-nothing') }}
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { reactive } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import { globalSetting, globalLookup, emitter } from '@/hook/global';
|
|
import { debounceWrapper, makeSearchResultItem } from '@/hook/utils';
|
|
import { toggleRender } from '@/hook/render';
|
|
|
|
export default {
|
|
name: 'tree-view-search',
|
|
setup() {
|
|
const { t } = useI18n();
|
|
|
|
const searchManage = reactive({
|
|
content: '',
|
|
displayResult: false,
|
|
searchResult: []
|
|
});
|
|
|
|
|
|
|
|
function search() {
|
|
const searchString = searchManage.content.trim();
|
|
if (searchString.length === 0) {
|
|
searchManage.displayResult = false;
|
|
return;
|
|
}
|
|
|
|
searchManage.displayResult = true;
|
|
searchManage.searchResult = [];
|
|
|
|
const stacks = [ { name: '', body: globalLookup.topModules } ];
|
|
const searchRule = new Set(globalSetting.searchScope);
|
|
const caseSensitivity = globalSetting.caseSensitivity;
|
|
const displayParentOnly = globalSetting.displayParentOnly;
|
|
|
|
while (stacks.length > 0) {
|
|
const p = stacks.pop();
|
|
if (p.body && p.body.length) {
|
|
p.body.forEach(mod => stacks.push(mod));
|
|
}
|
|
|
|
const searchResultItem = makeSearchResultItem(searchString, p, searchRule, caseSensitivity, displayParentOnly);
|
|
if (searchResultItem) {
|
|
emitter.emit('signal-search', searchResultItem);
|
|
}
|
|
}
|
|
}
|
|
|
|
emitter.on('signal-search', searchResultItem => {
|
|
searchManage.searchResult.push(searchResultItem);
|
|
});
|
|
|
|
const safeSearch = debounceWrapper(search, 500);
|
|
|
|
return {
|
|
searchManage,
|
|
safeSearch,
|
|
globalLookup,
|
|
debounceWrapper,
|
|
t,
|
|
toggleRender
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.tree-view-search-wrapper {
|
|
min-height: 30px;
|
|
padding: 10px;
|
|
transition: flex .5s ease-in-out;
|
|
}
|
|
|
|
.search-result-wrapper {
|
|
position: absolute;
|
|
padding: 10px;
|
|
margin: 10px;
|
|
background-color: var(--sidebar);
|
|
border: 1.5px solid var(--main-color);
|
|
color: var(--sidebar-item-text);
|
|
border-radius: .5em;
|
|
min-width: 500px;
|
|
z-index: 10;
|
|
}
|
|
|
|
.search-result {
|
|
overflow-x: scroll;
|
|
overflow-y: scroll;
|
|
max-height: 80vh;
|
|
max-width: 600px;
|
|
|
|
padding-right: 5px;
|
|
}
|
|
|
|
.search-result-item {
|
|
display: flex;
|
|
align-items: center;
|
|
height: 25px;
|
|
margin: 3px;
|
|
width: 800px;
|
|
padding-left: 3px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.search-result-item:hover {
|
|
background-color: var(--sidebar-item-selected);
|
|
border-radius: .3em;
|
|
}
|
|
|
|
.dep-arrow {
|
|
height: 7px;
|
|
width: 7px;
|
|
border-top: solid 1.7px var(--sidebar-item-text);
|
|
border-left: solid 1.7px var(--sidebar-item-text);
|
|
transform: rotate(135deg);
|
|
margin-right: 8px;
|
|
margin-left: 3px;
|
|
}
|
|
</style> |