diff --git a/pkg/harvester/components/SettingList.vue b/pkg/harvester/components/SettingList.vue index c7e98160..54623eb9 100644 --- a/pkg/harvester/components/SettingList.vue +++ b/pkg/harvester/components/SettingList.vue @@ -30,15 +30,23 @@ export default { category: { type: String, required: true, + }, + + searchQuery: { + type: String, + default: '' } }, data() { const categorySettings = this.filterCategorySettings(); + const filteredSettings = this.filterSearchSettings(categorySettings, this.searchQuery); return { HCI_SETTING, categorySettings, + filteredSettings, + originalHideMap: this.createHideMap(categorySettings) }; }, @@ -48,12 +56,81 @@ export default { settings: { deep: true, handler() { - this['categorySettings'] = this.filterCategorySettings(); + this.categorySettings = this.filterCategorySettings(); + this.filteredSettings = this.filterSearchSettings(this.categorySettings, this.searchQuery); + } + }, + searchQuery: { + immediate: true, + handler(newQuery) { + const filtered = this.filterSearchSettings(this.categorySettings, newQuery); + + this.filteredSettings = newQuery ? this.openJsonSettings(filtered) : filtered.map((s) => ({ ...s, hide: this.originalHideMap[s.id] ?? false })); } } }, methods: { + createHideMap(settings = []) { + const map = settings.reduce((acc, s) => { + acc[s.id] = s.hide ?? false; + + return acc; + }, {} ); + + return map; + }, + filterSearchSettings(settings, searchKey) { + if (!searchKey) { + return this.filterCategorySettings(); + } + const searchQuery = searchKey.toLowerCase(); + + return settings.filter((setting) => { + const id = setting.id?.toLowerCase() || ''; + + // filter by id + if (id.includes(searchQuery) ) { + return true; + } + + const description = this.t(setting.description, {}, true)?.toLowerCase() || ''; + + // filter by description + if (description.includes(searchQuery)) { + return true; + } + + // filter by customized value + if (setting.customized === true && setting.data?.value) { + const value = setting.data.value?.toLowerCase() || ''; + + return value.includes(searchQuery); + } + + // filter by json value + if (setting.kind === 'json' && setting.json) { + try { + const json = JSON.parse(setting.json); + const jsonString = JSON.stringify(json).toLowerCase(); + + return jsonString.includes(searchQuery); + } catch (e) { + console.error(`${ setting.id }: wrong format`, e); // eslint-disable-line no-console + + return false; + } + } + + // filter by default value + if (setting.data?.default) { + return setting.data?.default.includes(searchQuery); + } + + return false; + }); + }, + filterCategorySettings() { return this.settings.filter((s) => { if (!this.getFeatureEnabled(s.featureFlag)) { @@ -87,12 +164,17 @@ export default { return HCI_ALLOWED_SETTINGS.find((setting) => setting.id === id); }, + openJsonSettings(settings) { + return settings.map((s) => s.hide ? { ...s, hide: false } : s); + }, + toggleHide(s) { - this.categorySettings.find((setting) => { - if (setting.id === s.id) { - setting.hide = !setting.hide; - } - }); + const setting = this.filteredSettings.find((setting) => setting.id === s.id); + + if (setting) { + setting.hide = !setting.hide; + this.originalHideMap[setting.id] = setting.hide; + } }, async testConnect(buttonDone, value) { @@ -126,7 +208,7 @@ export default { @@ -271,4 +359,8 @@ export default { padding: 2px 10px; font-size: 12px; } + +.no-search-match { + text-align: center; +} diff --git a/pkg/harvester/l10n/en-us.yaml b/pkg/harvester/l10n/en-us.yaml index 531284dc..9f91091d 100644 --- a/pkg/harvester/l10n/en-us.yaml +++ b/pkg/harvester/l10n/en-us.yaml @@ -1041,6 +1041,7 @@ harvester: accessKeyId: Specify your access key ID secretAccessKey: Specify your secret access key cert: Upload a self-signed SSL certificate + noSearchMatch: No settings match your search. vlanChangeTip: The newly modified default network interface only applies to newly added nodes, not existing ones. defaultPhysicalNIC: Default Network Interface modifiedMessage: Settings that have been customized from default settings are tagged with 'Modified'. diff --git a/pkg/harvester/list/harvesterhci.io.setting.vue b/pkg/harvester/list/harvesterhci.io.setting.vue index c7fe5797..05edc170 100644 --- a/pkg/harvester/list/harvesterhci.io.setting.vue +++ b/pkg/harvester/list/harvesterhci.io.setting.vue @@ -85,7 +85,7 @@ export default { }, data() { - return { initSettings: [] }; + return { initSettings: [], searchQuery: '' }; }, computed: { @@ -135,9 +135,19 @@ export default { {{ t('harvester.setting.modifiedMessage') }} - + @@ -156,6 +167,7 @@ export default { > @@ -167,4 +179,20 @@ export default { .settings-banner { margin-top: 0; } + +.harvester-settings-search { + padding: 0; +} + +.search { + display: flex; + justify-content: flex-end; +} + +.search-box { + height: 40px; + margin-left: 10px; + min-width: 180px; +} +