mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-29 22:56:41 +08:00
faet(projects): global-search add pinyin-pro history collect
This commit is contained in:
parent
d825b6e260
commit
7b33ce64bd
@ -66,7 +66,6 @@
|
|||||||
"naive-ui": "2.39.0",
|
"naive-ui": "2.39.0",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"pinia": "2.2.0",
|
"pinia": "2.2.0",
|
||||||
"pinyin-pro": "3.23.1",
|
|
||||||
"print-js": "1.6.0",
|
"print-js": "1.6.0",
|
||||||
"swiper": "11.1.5",
|
"swiper": "11.1.5",
|
||||||
"tailwind-merge": "2.4.0",
|
"tailwind-merge": "2.4.0",
|
||||||
@ -103,6 +102,7 @@
|
|||||||
"eslint": "9.8.0",
|
"eslint": "9.8.0",
|
||||||
"eslint-plugin-vue": "9.27.0",
|
"eslint-plugin-vue": "9.27.0",
|
||||||
"lint-staged": "15.2.7",
|
"lint-staged": "15.2.7",
|
||||||
|
"pinyin-pro": "3.23.1",
|
||||||
"sass": "1.77.8",
|
"sass": "1.77.8",
|
||||||
"simple-git-hooks": "2.11.1",
|
"simple-git-hooks": "2.11.1",
|
||||||
"tsx": "4.16.2",
|
"tsx": "4.16.2",
|
||||||
|
143
src/layouts/modules/global-search/components/search-history.vue
Normal file
143
src/layouts/modules/global-search/components/search-history.vue
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useThemeStore } from '@/store/modules/theme';
|
||||||
|
import { $t } from '@/locales';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { Icon } from '@iconify/vue'
|
||||||
|
defineOptions({ name: 'SearchHistory' });
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
options: App.Global.SearchHistoryOrCollect[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const HISTORY_TYPE = "history";
|
||||||
|
const COLLECT_TYPE = "collect";
|
||||||
|
|
||||||
|
const props = defineProps<Props>();
|
||||||
|
|
||||||
|
interface Emits {
|
||||||
|
(e: "collect", val: App.Global.SearchHistoryOrCollect): void;
|
||||||
|
(e: 'enter'): void;
|
||||||
|
(e: 'delete', val: App.Global.SearchHistoryOrCollect): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
|
const theme = useThemeStore();
|
||||||
|
|
||||||
|
const active = defineModel<string>('path', { required: true });
|
||||||
|
|
||||||
|
async function handleMouseEnter(item: App.Global.SearchHistoryOrCollect) {
|
||||||
|
active.value = item.routePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
const titleStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
color: theme.themeColor,
|
||||||
|
fontWeight: 500,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const historyList = computed (() => {
|
||||||
|
return props.options.filter(item => item.type === HISTORY_TYPE)
|
||||||
|
});
|
||||||
|
|
||||||
|
const collectList = computed(() => {
|
||||||
|
return props.options.filter(item => item.type === COLLECT_TYPE)
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleTo() {
|
||||||
|
emit('enter');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete(item: App.Global.SearchHistoryOrCollect) {
|
||||||
|
emit('delete', item);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCollect(item: App.Global.SearchHistoryOrCollect) {
|
||||||
|
emit('collect', item);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NScrollbar>
|
||||||
|
<div class="pb-12px">
|
||||||
|
<template v-if="historyList.length">
|
||||||
|
<div :style="titleStyle">搜索历史</div>
|
||||||
|
<div v-for="item in historyList" :key="item.routePath">
|
||||||
|
<div
|
||||||
|
class="mt-8px h-56px flex-y-center cursor-pointer justify-between rounded-4px bg-#e5e7eb px-14px dark:bg-dark"
|
||||||
|
:style="{
|
||||||
|
background: item.routePath === active ? theme.themeColor : '',
|
||||||
|
color: item.routePath === active ? '#fff' : ''
|
||||||
|
}"
|
||||||
|
@click="handleTo"
|
||||||
|
@mouseenter="handleMouseEnter(item)"
|
||||||
|
>
|
||||||
|
<component :is="item.icon" />
|
||||||
|
<span class="ml-5px flex-1">
|
||||||
|
{{ (item.i18nKey && $t(item.i18nKey)) || item.label }}
|
||||||
|
</span>
|
||||||
|
<button class="w-24px h-24px action-button" @click="handleCollect(item)">
|
||||||
|
<Icon class="w-20px h-20px icon" icon="soybean:star" />
|
||||||
|
</button>
|
||||||
|
<button class="w-24px h-24px action-button" @click="handleDelete(item)">
|
||||||
|
<icon-ion-close class="w-20px h-20px"></icon-ion-close>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="collectList.length">
|
||||||
|
<div :style="titleStyle">收藏记录</div>
|
||||||
|
<div v-for="item in collectList" :key="item.routePath">
|
||||||
|
<div
|
||||||
|
class="mt-8px h-56px flex-y-center cursor-pointer justify-between rounded-4px bg-#e5e7eb px-14px dark:bg-dark"
|
||||||
|
:style="{
|
||||||
|
background: item.routePath === active ? theme.themeColor : '',
|
||||||
|
color: item.routePath === active ? '#fff' : ''
|
||||||
|
}"
|
||||||
|
@click="handleTo"
|
||||||
|
@mouseenter="handleMouseEnter(item)"
|
||||||
|
>
|
||||||
|
<Icon class="w-20px h-20px" icon="soybean:star" />
|
||||||
|
<component :is="item.icon" />
|
||||||
|
<span class="ml-5px flex-1">
|
||||||
|
{{ (item.i18nKey && $t(item.i18nKey)) || item.label }}
|
||||||
|
</span>
|
||||||
|
<button class="w-24px h-24px action-button" @click="handleDelete(item)">
|
||||||
|
<icon-ion-close class="w-20px h-20px"></icon-ion-close>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</NScrollbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.action-button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
appearance: none;
|
||||||
|
background: none;
|
||||||
|
border: 0;
|
||||||
|
line-height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
.action-button:hover {
|
||||||
|
background-color: #0003;
|
||||||
|
transition: background-color .1s ease-in;
|
||||||
|
color:#fff;
|
||||||
|
::v-deep .icon path {
|
||||||
|
fill:currentColor;
|
||||||
|
stroke: currentColor;
|
||||||
|
fill-rule: evenodd;
|
||||||
|
stroke-linecap: round;
|
||||||
|
transition: fill 0.3s ease-in;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
@ -1,5 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, ref, shallowRef } from 'vue';
|
import { computed, ref, shallowRef,watch } from 'vue';
|
||||||
|
import { match } from "pinyin-pro";
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { onKeyStroke, useDebounceFn } from '@vueuse/core';
|
import { onKeyStroke, useDebounceFn } from '@vueuse/core';
|
||||||
import { useRouteStore } from '@/store/modules/route';
|
import { useRouteStore } from '@/store/modules/route';
|
||||||
@ -7,9 +8,16 @@ import { useAppStore } from '@/store/modules/app';
|
|||||||
import { $t } from '@/locales';
|
import { $t } from '@/locales';
|
||||||
import SearchResult from './search-result.vue';
|
import SearchResult from './search-result.vue';
|
||||||
import SearchFooter from './search-footer.vue';
|
import SearchFooter from './search-footer.vue';
|
||||||
|
import SearchHistory from './search-history.vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { localStg } from '@/utils/storage';
|
||||||
|
import { themeSettings } from '@/theme/settings';
|
||||||
|
|
||||||
defineOptions({ name: 'SearchModal' });
|
defineOptions({ name: 'SearchModal' });
|
||||||
|
const SOYBEAN_LOCAL_STG_HISTORY_KEY = 'searchHistory'
|
||||||
|
const SOYBEAN_LOCAL_STG_COLLECT_KEY = 'searchCollect'
|
||||||
|
const HISTORY_TYPE = "history";
|
||||||
|
const COLLECT_TYPE = "collect";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const appStore = useAppStore();
|
const appStore = useAppStore();
|
||||||
const routeStore = useRouteStore();
|
const routeStore = useRouteStore();
|
||||||
@ -18,21 +26,120 @@ const isMobile = computed(() => appStore.isMobile);
|
|||||||
|
|
||||||
const keyword = ref('');
|
const keyword = ref('');
|
||||||
const activePath = ref('');
|
const activePath = ref('');
|
||||||
|
const historyPath = ref("");
|
||||||
const resultOptions = shallowRef<App.Global.Menu[]>([]);
|
const resultOptions = shallowRef<App.Global.Menu[]>([]);
|
||||||
|
const historyOptions = shallowRef<App.Global.SearchHistoryOrCollect[]>([]);
|
||||||
|
const { locale } = useI18n()
|
||||||
const handleSearch = useDebounceFn(search, 300);
|
const handleSearch = useDebounceFn(search, 300);
|
||||||
|
|
||||||
const visible = defineModel<boolean>('show', { required: true });
|
const visible = defineModel<boolean>('show', { required: true });
|
||||||
|
|
||||||
|
const isShowSearchResult = computed(() => {
|
||||||
|
return keyword.value || historyOptions.value.length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const isShowSearchHistory = computed(() => {
|
||||||
|
return !keyword.value && historyOptions.value.length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const showEmpty = computed(() => {
|
||||||
|
return (
|
||||||
|
(!keyword.value && historyOptions.value.length === 0) ||
|
||||||
|
(keyword.value && resultOptions.value.length === 0)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
function search() {
|
function search() {
|
||||||
resultOptions.value = routeStore.searchMenus.filter(menu => {
|
resultOptions.value = routeStore.searchMenus.filter(menu => {
|
||||||
const trimKeyword = keyword.value.toLocaleLowerCase().trim();
|
const trimKeyword = keyword.value.toLocaleLowerCase().trim();
|
||||||
const title = (menu.i18nKey ? $t(menu.i18nKey) : menu.label).toLocaleLowerCase();
|
const title = (menu.i18nKey ? $t(menu.i18nKey) : menu.label).toLocaleLowerCase();
|
||||||
return trimKeyword && title.includes(trimKeyword);
|
const pinyinPro = locale.value === 'zh-CN' && match(title, keyword.value.toLocaleLowerCase().trim())?.every(arg => arg !== null)
|
||||||
|
const result = keyword.value ? (title.includes(trimKeyword) || pinyinPro) : false
|
||||||
|
return result;
|
||||||
});
|
});
|
||||||
activePath.value = resultOptions.value[0]?.routePath ?? '';
|
activePath.value = resultOptions.value[0]?.routePath ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(visible, () => {
|
||||||
|
getHistory()
|
||||||
|
})
|
||||||
|
|
||||||
|
/** get current options */
|
||||||
|
function getCuurentOptionsPath() {
|
||||||
|
const isResultOptions = resultOptions.value.length > 0;
|
||||||
|
const options = isResultOptions? resultOptions.value : historyOptions.value
|
||||||
|
const currentPath = isResultOptions ? activePath.value : historyPath.value
|
||||||
|
return {isResultOptions,options,currentPath}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** get localStg history */
|
||||||
|
function getHistory() {
|
||||||
|
const searchHistoryMenus = localStg.get(SOYBEAN_LOCAL_STG_HISTORY_KEY) || []
|
||||||
|
const searchCollectMenus = localStg.get(SOYBEAN_LOCAL_STG_COLLECT_KEY) || []
|
||||||
|
historyOptions.value = [...searchHistoryMenus,...searchCollectMenus]
|
||||||
|
historyPath.value = historyOptions.value?.[0]?.routePath
|
||||||
|
}
|
||||||
|
|
||||||
|
/** update localStg history */
|
||||||
|
function updateHistory() {
|
||||||
|
let searchHistoryMenus = localStg.get(SOYBEAN_LOCAL_STG_HISTORY_KEY) || [];
|
||||||
|
const historyIndex = searchHistoryMenus.findIndex(item => item.routePath === historyPath.value)
|
||||||
|
if (!~historyIndex) {
|
||||||
|
const [historyItem] = searchHistoryMenus.splice(historyIndex,1)
|
||||||
|
searchHistoryMenus.unshift(historyItem)
|
||||||
|
localStg.set(SOYBEAN_LOCAL_STG_HISTORY_KEY, searchHistoryMenus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** save history */
|
||||||
|
function saveHistory() {
|
||||||
|
const res = resultOptions.value.find(item => item.routePath === activePath.value)
|
||||||
|
const searchHistoryMenus = localStg.get(SOYBEAN_LOCAL_STG_HISTORY_KEY) || []
|
||||||
|
const searchCollectMenus = localStg.get(SOYBEAN_LOCAL_STG_COLLECT_KEY) || []
|
||||||
|
const isCollected = searchCollectMenus.some(item => item.routePath === res?.routePath)
|
||||||
|
const existingIndex = searchHistoryMenus.findIndex(item => item.routePath === res?.routePath);
|
||||||
|
if(!isCollected && res) {
|
||||||
|
if(existingIndex !== -1) {
|
||||||
|
searchHistoryMenus.splice(existingIndex,1)
|
||||||
|
}
|
||||||
|
if(searchHistoryMenus.length < themeSettings.menuSearchHistoryMaxValue) {
|
||||||
|
searchHistoryMenus.unshift({...res, type: HISTORY_TYPE});
|
||||||
|
} else {
|
||||||
|
searchHistoryMenus.pop()
|
||||||
|
}
|
||||||
|
localStg.set(SOYBEAN_LOCAL_STG_HISTORY_KEY, searchHistoryMenus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** handle delete */
|
||||||
|
function handleDelete(options: App.Global.SearchHistoryOrCollect) {
|
||||||
|
let searchHistoryMenus = localStg.get(SOYBEAN_LOCAL_STG_HISTORY_KEY) || []
|
||||||
|
let searchCollectMenus = localStg.get(SOYBEAN_LOCAL_STG_COLLECT_KEY) || []
|
||||||
|
if(options.type === HISTORY_TYPE) {
|
||||||
|
searchHistoryMenus = searchHistoryMenus.filter(item => item.routePath !== options.routePath)
|
||||||
|
localStg.set(SOYBEAN_LOCAL_STG_HISTORY_KEY,searchHistoryMenus)
|
||||||
|
} else {
|
||||||
|
searchCollectMenus = searchCollectMenus.filter(item => item.routePath !== options.routePath)
|
||||||
|
localStg.set(SOYBEAN_LOCAL_STG_COLLECT_KEY,searchCollectMenus)
|
||||||
|
}
|
||||||
|
getHistory()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** handle collect */
|
||||||
|
function handleCollect(options: App.Global.SearchHistoryOrCollect) {
|
||||||
|
let searchHistoryMenus = localStg.get(SOYBEAN_LOCAL_STG_HISTORY_KEY) || []
|
||||||
|
let searchCollectMenus = localStg.get(SOYBEAN_LOCAL_STG_COLLECT_KEY) || []
|
||||||
|
searchHistoryMenus = searchHistoryMenus.filter(item => item.routePath !== options.routePath)
|
||||||
|
localStg.set(SOYBEAN_LOCAL_STG_COLLECT_KEY,searchHistoryMenus)
|
||||||
|
const isCollected = searchCollectMenus.some(item => item.routePath === options.routePath)
|
||||||
|
if(!isCollected) {
|
||||||
|
searchCollectMenus.unshift({...options, type: COLLECT_TYPE});
|
||||||
|
localStg.set(SOYBEAN_LOCAL_STG_COLLECT_KEY,searchCollectMenus)
|
||||||
|
}
|
||||||
|
getHistory()
|
||||||
|
}
|
||||||
|
|
||||||
function handleClose() {
|
function handleClose() {
|
||||||
// handle with setTimeout to prevent user from seeing some operations
|
// handle with setTimeout to prevent user from seeing some operations
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -44,39 +151,44 @@ function handleClose() {
|
|||||||
|
|
||||||
/** key up */
|
/** key up */
|
||||||
function handleUp() {
|
function handleUp() {
|
||||||
const { length } = resultOptions.value;
|
const { isResultOptions,options,currentPath } = getCuurentOptionsPath()
|
||||||
if (length === 0) return;
|
if (options.length === 0) return;
|
||||||
|
const index = options.findIndex(item => item.routePath === currentPath);
|
||||||
const index = getActivePathIndex();
|
const prevIndex = (index - 1 + options.length) % options.length;
|
||||||
if (index === -1) return;
|
if (isResultOptions) {
|
||||||
|
activePath.value = resultOptions.value[prevIndex].routePath;
|
||||||
const activeIndex = index === 0 ? length - 1 : index - 1;
|
} else {
|
||||||
|
historyPath.value = historyOptions.value[prevIndex].routePath;
|
||||||
activePath.value = resultOptions.value[activeIndex].routePath;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** key down */
|
/** key down */
|
||||||
function handleDown() {
|
function handleDown() {
|
||||||
const { length } = resultOptions.value;
|
const { isResultOptions,options,currentPath } = getCuurentOptionsPath()
|
||||||
if (length === 0) return;
|
if (options.length === 0) return;
|
||||||
|
const index = options.findIndex(item => item.routePath === currentPath);
|
||||||
const index = getActivePathIndex();
|
const prevIndex = (index + 1 + options.length) % options.length;
|
||||||
if (index === -1) return;
|
if (isResultOptions) {
|
||||||
|
activePath.value = resultOptions.value[prevIndex].routePath;
|
||||||
const activeIndex = index === length - 1 ? 0 : index + 1;
|
} else {
|
||||||
|
historyPath.value = historyOptions.value[prevIndex].routePath;
|
||||||
activePath.value = resultOptions.value[activeIndex].routePath;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActivePathIndex() {
|
|
||||||
return resultOptions.value.findIndex(item => item.routePath === activePath.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** key enter */
|
/** key enter */
|
||||||
function handleEnter() {
|
function handleEnter() {
|
||||||
if (resultOptions.value?.length === 0 || activePath.value === '') return;
|
const { isResultOptions, options, currentPath } = getCuurentOptionsPath()
|
||||||
|
if (options?.length === 0 || currentPath === '') return;
|
||||||
|
const index = options.findIndex((item) => item.routePath === currentPath);
|
||||||
|
if (index === -1) return;
|
||||||
|
if (isResultOptions) {
|
||||||
|
saveHistory();
|
||||||
|
} else {
|
||||||
|
updateHistory();
|
||||||
|
}
|
||||||
|
router.push(options[index].routePath);
|
||||||
handleClose();
|
handleClose();
|
||||||
router.push(activePath.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerShortcut() {
|
function registerShortcut() {
|
||||||
@ -87,6 +199,7 @@ function registerShortcut() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerShortcut();
|
registerShortcut();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -102,7 +215,7 @@ registerShortcut();
|
|||||||
@after-leave="handleClose"
|
@after-leave="handleClose"
|
||||||
>
|
>
|
||||||
<NInputGroup>
|
<NInputGroup>
|
||||||
<NInput v-model:value="keyword" clearable :placeholder="$t('common.keywordSearch')" @input="handleSearch">
|
<NInput v-model:value="keyword" :spellcheck="false" clearable :placeholder="$t('common.keywordSearch')" @input="handleSearch">
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<icon-uil-search class="text-15px text-#c2c2c2" />
|
<icon-uil-search class="text-15px text-#c2c2c2" />
|
||||||
</template>
|
</template>
|
||||||
@ -111,8 +224,9 @@ registerShortcut();
|
|||||||
</NInputGroup>
|
</NInputGroup>
|
||||||
|
|
||||||
<div class="mt-20px">
|
<div class="mt-20px">
|
||||||
<NEmpty v-if="resultOptions.length === 0" :description="$t('common.noData')" />
|
<NEmpty v-if="showEmpty" :description="$t('common.noData')" />
|
||||||
<SearchResult v-else v-model:path="activePath" :options="resultOptions" @enter="handleEnter" />
|
<SearchHistory v-if="isShowSearchHistory" v-model:path="historyPath" :options="historyOptions" @enter="handleEnter" @collect="handleCollect" @delete="handleDelete" />
|
||||||
|
<SearchResult v-if="isShowSearchResult" v-model:path="activePath" :options="resultOptions" @enter="handleEnter" />
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<SearchFooter v-if="!isMobile" />
|
<SearchFooter v-if="!isMobile" />
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
import { addAPIProvider, disableCache } from '@iconify/vue';
|
import { addAPIProvider, disableCache , addCollection } from '@iconify/vue';
|
||||||
|
|
||||||
/** Setup the iconify offline */
|
/** Setup the iconify offline */
|
||||||
export function setupIconifyOffline() {
|
export function setupIconifyOffline() {
|
||||||
const { VITE_ICONIFY_URL } = import.meta.env;
|
const { VITE_ICONIFY_URL } = import.meta.env;
|
||||||
|
addCollection({
|
||||||
|
prefix: 'soybean',
|
||||||
|
icons:{
|
||||||
|
star:{
|
||||||
|
body: '<path d="M10 14.2L5 17l1-5.6-4-4 5.5-.7 2.5-5 2.5 5 5.6.8-4 4 .9 5.5z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linejoin="round"></path>',
|
||||||
|
width: 20,
|
||||||
|
height: 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
if (VITE_ICONIFY_URL) {
|
if (VITE_ICONIFY_URL) {
|
||||||
addAPIProvider('', { resources: [VITE_ICONIFY_URL] });
|
addAPIProvider('', { resources: [VITE_ICONIFY_URL] });
|
||||||
|
|
||||||
|
@ -74,7 +74,8 @@ export const themeSettings: App.Theme.ThemeSetting = {
|
|||||||
'base-text': 'rgb(224, 224, 224)'
|
'base-text': 'rgb(224, 224, 224)'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
menuSearchHistoryMaxValue: 6
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
7
src/typings/app.d.ts
vendored
7
src/typings/app.d.ts
vendored
@ -109,6 +109,8 @@ declare namespace App {
|
|||||||
[K in keyof ThemeSettingToken]?: Partial<ThemeSettingToken[K]>;
|
[K in keyof ThemeSettingToken]?: Partial<ThemeSettingToken[K]>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
/** menu history max value */
|
||||||
|
menuSearchHistoryMaxValue: number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OtherColor {
|
interface OtherColor {
|
||||||
@ -200,6 +202,11 @@ declare namespace App {
|
|||||||
children?: Menu[];
|
children?: Menu[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** The global search history or collect */
|
||||||
|
type SearchHistoryOrCollect = Menu & {
|
||||||
|
type: 'history' | 'collect';
|
||||||
|
};
|
||||||
|
|
||||||
type Breadcrumb = Omit<Menu, 'children'> & {
|
type Breadcrumb = Omit<Menu, 'children'> & {
|
||||||
options?: Breadcrumb[];
|
options?: Breadcrumb[];
|
||||||
};
|
};
|
||||||
|
1
src/typings/components.d.ts
vendored
1
src/typings/components.d.ts
vendored
@ -29,6 +29,7 @@ declare module 'vue' {
|
|||||||
IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default']
|
IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default']
|
||||||
IconIcRoundRemove: typeof import('~icons/ic/round-remove')['default']
|
IconIcRoundRemove: typeof import('~icons/ic/round-remove')['default']
|
||||||
IconIcRoundSearch: typeof import('~icons/ic/round-search')['default']
|
IconIcRoundSearch: typeof import('~icons/ic/round-search')['default']
|
||||||
|
IconIonClose: typeof import('~icons/ion/close')['default']
|
||||||
IconLocalActivity: typeof import('~icons/local/activity')['default']
|
IconLocalActivity: typeof import('~icons/local/activity')['default']
|
||||||
IconLocalBanner: typeof import('~icons/local/banner')['default']
|
IconLocalBanner: typeof import('~icons/local/banner')['default']
|
||||||
IconLocalCast: typeof import('~icons/local/cast')['default']
|
IconLocalCast: typeof import('~icons/local/cast')['default']
|
||||||
|
4
src/typings/storage.d.ts
vendored
4
src/typings/storage.d.ts
vendored
@ -35,5 +35,9 @@ declare namespace StorageType {
|
|||||||
layout: UnionKey.ThemeLayoutMode;
|
layout: UnionKey.ThemeLayoutMode;
|
||||||
siderCollapse: boolean;
|
siderCollapse: boolean;
|
||||||
};
|
};
|
||||||
|
/** The search history */
|
||||||
|
searchHistory: App.Global.SearchHistoryOrCollect[]
|
||||||
|
/** The search collect */
|
||||||
|
searchCollect: App.Global.SearchHistoryOrCollect[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user