11<template >
22 <div class =" settings-container" >
33 <div class =" settings-sidebar" >
4+ <SettingSearchBox
5+ class =" settings-search-box"
6+ v-model:modelValue =" searchQuery"
7+ @search =" handleSearch"
8+ />
49 <Listbox
510 v-model =" activeCategory"
611 :options =" categories"
712 optionLabel =" label"
813 scrollHeight =" 100%"
14+ :disabled =" inSearch"
915 :pt =" { root: { class: 'border-none' } }"
1016 />
1117 </div >
1218 <Divider layout =" vertical" />
13- <div class =" settings-content" v-if =" activeCategory" >
14- <Tabs :value =" activeCategory.label" >
15- <TabPanels >
19+ <div class =" settings-content" >
20+ <Tabs :value =" tabValue" >
21+ <TabPanels class =" settings-tab-panels" >
22+ <TabPanel key =" search-results" value =" Search Results" >
23+ <div v-if =" searchResults.length > 0" >
24+ <SettingGroup
25+ v-for =" (group, i) in searchResults"
26+ :key =" group.label"
27+ :divider =" i !== 0"
28+ :group =" group"
29+ />
30+ </div >
31+ <NoResultsPlaceholder
32+ v-else
33+ icon =" pi pi-search"
34+ :title =" $t('noResultsFound')"
35+ :message =" $t('searchFailedMessage')"
36+ />
37+ </TabPanel >
1638 <TabPanel
1739 v-for =" category in categories"
1840 :key =" category.key"
1941 :value =" category.label"
2042 >
2143 <SettingGroup
22- v-for =" group in sortedGroups(category)"
44+ v-for =" ( group, i) in sortedGroups(category)"
2345 :key =" group.label"
46+ :divider =" i !== 0"
2447 :group =" {
2548 label: group.label,
2649 settings: flattenTree<SettingParams>(group)
@@ -43,15 +66,22 @@ import Divider from 'primevue/divider'
4366import { SettingTreeNode , useSettingStore } from ' @/stores/settingStore'
4467import { SettingParams } from ' @/types/settingTypes'
4568import SettingGroup from ' ./setting/SettingGroup.vue'
69+ import SettingSearchBox from ' ./setting/SettingSearchBox.vue'
70+ import NoResultsPlaceholder from ' @/components/common/NoResultsPlaceholder.vue'
4671import { flattenTree } from ' @/utils/treeUtil'
4772
73+ interface ISettingGroup {
74+ label: string
75+ settings: SettingParams []
76+ }
77+
4878const settingStore = useSettingStore ()
4979const settingRoot = computed <SettingTreeNode >(() => settingStore .settingTree )
5080const categories = computed <SettingTreeNode []>(
5181 () => settingRoot .value .children || []
5282)
53-
5483const activeCategory = ref <SettingTreeNode | null >(null )
84+ const searchResults = ref <ISettingGroup []>([])
5585
5686watch (activeCategory , (newCategory , oldCategory ) => {
5787 if (newCategory === null ) {
@@ -68,13 +98,59 @@ const sortedGroups = (category: SettingTreeNode) => {
6898 a .label .localeCompare (b .label )
6999 )
70100}
101+
102+ const searchQuery = ref <string >(' ' )
103+ const searchInProgress = ref <boolean >(false )
104+ watch (searchQuery , () => (searchInProgress .value = true ))
105+
106+ const handleSearch = (query : string ) => {
107+ if (! query ) {
108+ searchResults .value = []
109+ return
110+ }
111+
112+ const allSettings = flattenTree <SettingParams >(settingRoot .value )
113+ const filteredSettings = allSettings .filter (
114+ (setting ) =>
115+ setting .id .toLowerCase ().includes (query .toLowerCase ()) ||
116+ setting .name .toLowerCase ().includes (query .toLowerCase ())
117+ )
118+
119+ const groupedSettings: { [key : string ]: SettingParams [] } = {}
120+ filteredSettings .forEach ((setting ) => {
121+ const groupLabel = setting .id .split (' .' )[1 ]
122+ if (! groupedSettings [groupLabel ]) {
123+ groupedSettings [groupLabel ] = []
124+ }
125+ groupedSettings [groupLabel ].push (setting )
126+ })
127+
128+ searchResults .value = Object .entries (groupedSettings ).map (
129+ ([label , settings ]) => ({
130+ label ,
131+ settings
132+ })
133+ )
134+ searchInProgress .value = false
135+ }
136+
137+ const inSearch = computed (
138+ () => searchQuery .value .length > 0 && ! searchInProgress .value
139+ )
140+ const tabValue = computed (() =>
141+ inSearch .value ? ' Search Results' : activeCategory .value ?.label
142+ )
71143 </script >
72144
73145<style >
74146/* Remove after we have tailwind setup */
75147.border-none {
76148 border : none !important ;
77149}
150+
151+ .settings-tab-panels {
152+ padding-top : 0px !important ;
153+ }
78154 </style >
79155
80156<style scoped>
@@ -95,6 +171,11 @@ const sortedGroups = (category: SettingTreeNode) => {
95171 padding : 10px ;
96172}
97173
174+ .settings-search-box {
175+ width : 100% ;
176+ margin-bottom : 10px ;
177+ }
178+
98179.settings-content {
99180 flex-grow : 1 ;
100181 overflow-y : auto ;
0 commit comments