From 8d2e310e025dc3d4b190cbece26bb57496e61b6f Mon Sep 17 00:00:00 2001 From: WijesingheD Date: Fri, 1 Nov 2024 12:10:35 +0000 Subject: [PATCH 1/9] Add custom search panel --- src/components/search/FilterComponent.vue | 173 ++++++++++++ src/components/search/SearchDocuments.vue | 2 + .../components/search/FilterComponent.ts | 257 ++++++++++++++++++ 3 files changed, 432 insertions(+) create mode 100644 src/components/search/FilterComponent.vue create mode 100644 src/composables/components/search/FilterComponent.ts diff --git a/src/components/search/FilterComponent.vue b/src/components/search/FilterComponent.vue new file mode 100644 index 00000000..4cdd3be5 --- /dev/null +++ b/src/components/search/FilterComponent.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/components/search/SearchDocuments.vue b/src/components/search/SearchDocuments.vue index c7f2a12f..6e7d11af 100644 --- a/src/components/search/SearchDocuments.vue +++ b/src/components/search/SearchDocuments.vue @@ -38,6 +38,7 @@
+
Query
@@ -92,6 +93,7 @@ import { useSearchDocuments } from '../../composables/components/search/SearchDocuments' import { useTranslation } from '../../composables/i18n.ts' import SearchExamples from './SearchExamples.vue' + import FilterComponent from './FilterComponent.vue'; const CodeEditor = defineAsyncComponent(() => import('../shared/CodeEditor.vue')) const resetAndLoad = () => { diff --git a/src/composables/components/search/FilterComponent.ts b/src/composables/components/search/FilterComponent.ts new file mode 100644 index 00000000..0dce3a75 --- /dev/null +++ b/src/composables/components/search/FilterComponent.ts @@ -0,0 +1,257 @@ +import { onMounted, ref, computed } from 'vue'; +import { useSearchStore } from '../../../store/search'; +import { DEFAULT_SEARCH_QUERY_OBJ } from '../../../consts'; + +export const useFilterComponent = () => { + const searchStore = useSearchStore(); + const filters = ref([ + { + bool: 'must', + field: 'match_all', + op: 'query_string', + fuzzyOp: '', + fuzzyLevel: '', + fuzzyLevelValue: '', + rangeLevel1: '', + rangeLevel1Value: '', + rangeLevel2: '', + rangeLevel2Value: '', + value: '', + }, + ]); + + const allFields = ref([]); + + type TermQuery = + | { [key: string]: { [key: string]: any } } + | { [key: string]: any }; + + interface BoolQuery { + must: TermQuery[]; + must_not: TermQuery[]; + should: TermQuery[]; + } + + interface SearchQuery { + query: { + bool: BoolQuery; + }; + size: number; + from: number; + sort: any[]; + } + + const targetObject: SearchQuery = { + ...DEFAULT_SEARCH_QUERY_OBJ, + query: { + bool: { must: [], must_not: [], should: [] }, + }, + }; + + onMounted(() => { + searchStore.searchQuery = JSON.stringify(targetObject); + allFields.value.push('match_all'); + allFields.value.push('_all'); + const fieldsToAdd = filterDisplayFieldName(searchStore.visibleColumns); + allFields.value.push(...fieldsToAdd); + }); + + const filterDisplayFieldName = (columnNames: string[]) => { + const updatedColumnNames: (string | undefined)[] = columnNames.map( + (column) => { + if (column.endsWith('.keyword')) { + return column.replace(/\.keyword$/, ''); + } else if (column.startsWith('_')) { + column; + } else { + return column; + } + } + ); + return updatedColumnNames.filter((column) => column != undefined); + }; + + const addFilterRow = () => { + filters.value.push({ + bool: 'must', + field: '', + op: 'term', + fuzzyOp: '', + fuzzyLevel: '', + fuzzyLevelValue: '', + rangeLevel1: '', + rangeLevel1Value: '', + rangeLevel2: '', + rangeLevel2Value: '', + value: '', + }); + }; + + const removeFilterRow = (index: number) => { + filters.value.splice(index, 1); + }; + + const updateField = (index: number) => { + const { field } = filters.value[index]; + const computedOp = computed(() => { + return field === '_all' + ? 'query_string' + : field === 'match_all' + ? '' + : 'match'; + }); + filters.value[index].op = computedOp.value; + filters.value[index].value = ''; + field === 'match_all' ? updateMatchAllFilter(index) : updateFilter(index); + }; + + const updateOp = (index: number) => { + const { op } = filters.value[index]; + const computedFuzzyLevel = computed(() => { + return op === 'fuzzy' ? 'max_expansions' : 'match'; + }); + const computedRangeLevel1 = computed(() => { + return op === 'range' ? 'gt' : 'gte'; + }); + const computedRangeLevel2 = computed(() => { + return op === 'range' ? 'it' : 'ite'; + }); + filters.value[index].fuzzyLevel = computedFuzzyLevel.value; + filters.value[index].rangeLevel1 = computedRangeLevel1.value; + filters.value[index].rangeLevel2 = computedRangeLevel2.value; + updateFilter(index); + }; + + const updateFilter = (index: number) => { + const { bool, field, op, value } = filters.value[index]; + handleBoolChange(index); + if (op === 'missing') { + return handleMissingOp(index); + } + const newCondition: TermQuery = { + [op]: { + [field]: value, + }, + }; + if (bool === 'must') { + targetObject.query.bool.must[index] = newCondition; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index] = newCondition; + } else if (bool === 'should') { + targetObject.query.bool.should[index] = newCondition; + } + setSearchQuery(targetObject); + }; + + const setSearchQuery = (targetObject: SearchQuery) => { + const formattedTargetObject: SearchQuery = targetObject ; + formattedTargetObject.query.bool.must = targetObject.query.bool.must.filter(item => item !== null); + formattedTargetObject.query.bool.must_not = targetObject.query.bool.must_not.filter(item => item !== null); + formattedTargetObject.query.bool.should = targetObject.query.bool.should.filter(item => item !== null); + searchStore.searchQuery = JSON.stringify(formattedTargetObject); + } + + const handleBoolChange = (index: number) => { + targetObject.query.bool.must.splice(index, 1); + targetObject.query.bool.must_not.splice(index, 1); + targetObject.query.bool.should.splice(index, 1); + } + + const handleMissingOp = (index: number) => { + const { bool, field, op } = filters.value[index]; + if (op == 'missing') { + const newCondition: TermQuery = { + ['exist']: { + field: field, + }, + }; + if (bool === 'must') { + targetObject.query.bool.must_not[index] = newCondition; + } else { + targetObject.query.bool.must[index] = newCondition; + } + setSearchQuery(targetObject); + } + }; + + const updateMatchAllFilter = (index: number) => { + const { bool, field } = filters.value[index]; + const newCondition: TermQuery = { [field]: {} }; + if (bool === 'must') { + targetObject.query.bool.must[index] = newCondition; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index] = newCondition; + } else if (bool === 'should') { + targetObject.query.bool.should[index] = newCondition; + } + setSearchQuery(targetObject); + }; + + const updateValue = (index: number) => { + const { bool, field, op, value } = filters.value[index]; + if (bool === 'must') { + targetObject.query.bool.must[index][op][field] = value; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index][op][field] = value; + } else if (bool === 'should') { + targetObject.query.bool.should[index][op][field] = value; + } + setSearchQuery(targetObject); + }; + + const updateRangeValue = (index: number) => { + const { + bool, + field, + op, + rangeLevel1, + rangeLevel1Value, + rangeLevel2, + rangeLevel2Value, + } = filters.value[index]; + const newCondition: TermQuery = { + [op]: { + [rangeLevel1]: rangeLevel1Value, + [rangeLevel2]: rangeLevel2Value, + }, + }; + if (bool === 'must') { + targetObject.query.bool.must[index][op][field] = newCondition; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index][op][field] = newCondition; + } else if (bool === 'should') { + targetObject.query.bool.should[index][op][field] = newCondition; + } + setSearchQuery(targetObject); + }; + + const updateFuzzyValue = (index: number) => { + const { bool, field, op, fuzzyOp, fuzzyLevel, fuzzyLevelValue } = + filters.value[index]; + const newCondition: TermQuery = { + ['value']: fuzzyOp, + [fuzzyLevel]: fuzzyLevelValue, + }; + if (bool === 'must') { + targetObject.query.bool.must[index][op][field] = newCondition; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index][op][field] = newCondition; + } else if (bool === 'should') { + targetObject.query.bool.should[index][op][field] = newCondition; + } + setSearchQuery(targetObject); + }; + + return { + filters, + addFilterRow, + removeFilterRow, + updateFilter, + updateValue, + updateRangeValue, + updateFuzzyValue, + updateOp, + updateField, + allFields, + }; +}; From e6b4fa1c56bad671dee8699d865d695137d0b7a6 Mon Sep 17 00:00:00 2001 From: WijesingheD Date: Tue, 5 Nov 2024 11:29:16 +0000 Subject: [PATCH 2/9] filtering options based on column type --- src/components/search/FilterComponent.vue | 22 +- .../components/search/FilterComponent.ts | 222 +++++++++++++----- .../components/search/SearchResultsTable.ts | 2 +- src/store/search.ts | 6 +- 4 files changed, 188 insertions(+), 64 deletions(-) diff --git a/src/components/search/FilterComponent.vue b/src/components/search/FilterComponent.vue index 4cdd3be5..3be831ef 100644 --- a/src/components/search/FilterComponent.vue +++ b/src/components/search/FilterComponent.vue @@ -10,7 +10,7 @@ + + @@ -143,13 +158,14 @@ const { filters, addFilterRow, removeFilterRow, - updateFilter, + updateQueryString, updateValue, updateRangeValue, updateFuzzyValue, updateOp, updateField, allFields, + opOptions, } = useFilterComponent(); diff --git a/src/composables/components/search/FilterComponent.ts b/src/composables/components/search/FilterComponent.ts index 0dce3a75..fb0b6a79 100644 --- a/src/composables/components/search/FilterComponent.ts +++ b/src/composables/components/search/FilterComponent.ts @@ -8,7 +8,7 @@ export const useFilterComponent = () => { { bool: 'must', field: 'match_all', - op: 'query_string', + op: '', fuzzyOp: '', fuzzyLevel: '', fuzzyLevelValue: '', @@ -20,6 +20,20 @@ export const useFilterComponent = () => { }, ]); + const operations = [ + { label: 'match', value: 'match', alwaysShow: false }, + { label: 'term', value: 'term', alwaysShow: false }, + { label: 'wildcard', value: 'wildcard', alwaysShow: false }, + { label: 'prefix', value: 'prefix', alwaysShow: false }, + { label: 'fuzzy', value: 'fuzzy', alwaysShow: false }, + { label: 'range', value: 'range', alwaysShow: false }, + { label: 'query_string', value: 'query_string', alwaysShow: true }, + { label: 'text', value: 'text', alwaysShow: false }, + { label: 'missing', value: 'missing', alwaysShow: false } + ] + + let opOptions = ref([...operations]); + const allFields = ref([]); type TermQuery = @@ -89,20 +103,50 @@ export const useFilterComponent = () => { const removeFilterRow = (index: number) => { filters.value.splice(index, 1); + targetObject.query.bool.must[index] = {}; + targetObject.query.bool.must_not[index] = {}; + targetObject.query.bool.should[index] = {}; + setSearchQuery(targetObject); }; const updateField = (index: number) => { const { field } = filters.value[index]; const computedOp = computed(() => { - return field === '_all' - ? 'query_string' - : field === 'match_all' - ? '' - : 'match'; + return updateFilterWithType(field); }); filters.value[index].op = computedOp.value; filters.value[index].value = ''; - field === 'match_all' ? updateMatchAllFilter(index) : updateFilter(index); + field === 'match_all' ? updateMatchAllFilter(index) : updateQueryString(index); + }; + + const updateFilterWithType = (field: string): string => { + resetOpOptions(); + if (field === '_all') { + removeItemsByLabels(['match', 'term', 'wildcard', 'prefix', 'fuzzy', 'range', 'text', 'missing']); + return 'query_string'; + } + else if(field === 'match_all'){ + removeItemsByLabels(['match', 'term', 'wildcard', 'prefix', 'fuzzy', 'range', 'text', 'missing', 'query_string']); + return ''; + } + else if (searchStore.allColumnProperties[field].type === 'date') { + removeItemsByLabels(['match', 'prefix', 'wildcard', 'text']); + return 'term'; + } + else if (searchStore.allColumnProperties[field].type === 'integer' || searchStore.allColumnProperties[field].type === 'long') { + removeItemsByLabels(['match', 'prefix', 'wildcard', 'text']); + return 'term'; + } + return 'match'; + function removeItemsByLabels(labelsToRemove:string[]) { + opOptions.value = opOptions.value.filter( + (item) => !labelsToRemove.includes(item.label) + ); + opOptions + } + function resetOpOptions() { + opOptions.value = [...operations]; + } }; const updateOp = (index: number) => { @@ -114,64 +158,104 @@ export const useFilterComponent = () => { return op === 'range' ? 'gt' : 'gte'; }); const computedRangeLevel2 = computed(() => { - return op === 'range' ? 'it' : 'ite'; + return op === 'range' ? 'lt' : 'lte'; }); filters.value[index].fuzzyLevel = computedFuzzyLevel.value; filters.value[index].rangeLevel1 = computedRangeLevel1.value; filters.value[index].rangeLevel2 = computedRangeLevel2.value; - updateFilter(index); + updateQueryString(index); }; - const updateFilter = (index: number) => { - const { bool, field, op, value } = filters.value[index]; + const updateQueryString = (index: number) => { + const { bool, op } = filters.value[index]; handleBoolChange(index); + const newCondition: TermQuery = getOpCondition(index); if (op === 'missing') { - return handleMissingOp(index); - } - const newCondition: TermQuery = { - [op]: { - [field]: value, - }, - }; - if (bool === 'must') { - targetObject.query.bool.must[index] = newCondition; - } else if (bool === 'must_not') { - targetObject.query.bool.must_not[index] = newCondition; - } else if (bool === 'should') { - targetObject.query.bool.should[index] = newCondition; + setMissingOperatorQuery(); + } else { + setNonMissingOperatorQuery(); } setSearchQuery(targetObject); + + function setNonMissingOperatorQuery() { + if (bool === 'must') { + targetObject.query.bool.must[index] = newCondition; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index] = newCondition; + } else if (bool === 'should') { + targetObject.query.bool.should[index] = newCondition; + } + } + function setMissingOperatorQuery() { + if (bool === 'must' || bool === 'should') { + targetObject.query.bool.must_not[index] = newCondition; + } else if (bool === 'must_not') { + targetObject.query.bool.must[index] = newCondition; + } + } }; const setSearchQuery = (targetObject: SearchQuery) => { - const formattedTargetObject: SearchQuery = targetObject ; - formattedTargetObject.query.bool.must = targetObject.query.bool.must.filter(item => item !== null); - formattedTargetObject.query.bool.must_not = targetObject.query.bool.must_not.filter(item => item !== null); - formattedTargetObject.query.bool.should = targetObject.query.bool.should.filter(item => item !== null); + const formattedTargetObject: SearchQuery = JSON.parse( + JSON.stringify(targetObject) + ); + formattedTargetObject.query.bool.must = targetObject.query.bool.must.filter( + (item) => item && Object.keys(item).length > 0 + ); + formattedTargetObject.query.bool.must_not = + targetObject.query.bool.must_not.filter( + (item) => item && Object.keys(item).length > 0 + ); + formattedTargetObject.query.bool.should = + targetObject.query.bool.should.filter( + (item) => item && Object.keys(item).length > 0 + ); searchStore.searchQuery = JSON.stringify(formattedTargetObject); - } + }; const handleBoolChange = (index: number) => { - targetObject.query.bool.must.splice(index, 1); - targetObject.query.bool.must_not.splice(index, 1); - targetObject.query.bool.should.splice(index, 1); - } + targetObject.query.bool.must[index] = {}; + targetObject.query.bool.must_not[index] = {}; + targetObject.query.bool.should[index] = {}; + }; - const handleMissingOp = (index: number) => { - const { bool, field, op } = filters.value[index]; - if (op == 'missing') { - const newCondition: TermQuery = { - ['exist']: { + const getOpCondition = (index: number) => { + const { field, op, value } = filters.value[index]; + let newCondition: TermQuery = { + [field]: {}, + }; + if(op === ''){ + return newCondition; + } + if (op === 'missing') { + newCondition = { + ['exists']: { field: field, }, }; - if (bool === 'must') { - targetObject.query.bool.must_not[index] = newCondition; - } else { - targetObject.query.bool.must[index] = newCondition; - } - setSearchQuery(targetObject); + } else if (op === 'query_string') { + newCondition = { + ['query_string']: { + default_field: field, + query: value, + }, + }; + } + else if(op === 'range'){ + newCondition = { + [op]: { + [field]: {}, + }, + }; + } + else{ + newCondition = { + [op]: { + [field]: value, + }, + }; } + return newCondition; }; const updateMatchAllFilter = (index: number) => { @@ -189,14 +273,27 @@ export const useFilterComponent = () => { const updateValue = (index: number) => { const { bool, field, op, value } = filters.value[index]; - if (bool === 'must') { - targetObject.query.bool.must[index][op][field] = value; - } else if (bool === 'must_not') { - targetObject.query.bool.must_not[index][op][field] = value; - } else if (bool === 'should') { - targetObject.query.bool.should[index][op][field] = value; + if (op === 'query_string') { + if (bool === 'must') { + targetObject.query.bool.must[index]['query_string']['query'] = value; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index]['query_string']['query'] = value; + } else if (bool === 'should') { + targetObject.query.bool.should[index]['query_string']['query'] = value; + } + setSearchQuery(targetObject); + return; + } + else{ + if (bool === 'must') { + targetObject.query.bool.must[index][op][field] = value; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index][op][field] = value; + } else if (bool === 'should') { + targetObject.query.bool.should[index][op][field] = value; + } + setSearchQuery(targetObject); } - setSearchQuery(targetObject); }; const updateRangeValue = (index: number) => { @@ -210,10 +307,8 @@ export const useFilterComponent = () => { rangeLevel2Value, } = filters.value[index]; const newCondition: TermQuery = { - [op]: { [rangeLevel1]: rangeLevel1Value, [rangeLevel2]: rangeLevel2Value, - }, }; if (bool === 'must') { targetObject.query.bool.must[index][op][field] = newCondition; @@ -228,10 +323,7 @@ export const useFilterComponent = () => { const updateFuzzyValue = (index: number) => { const { bool, field, op, fuzzyOp, fuzzyLevel, fuzzyLevelValue } = filters.value[index]; - const newCondition: TermQuery = { - ['value']: fuzzyOp, - [fuzzyLevel]: fuzzyLevelValue, - }; + const newCondition: TermQuery = getFuzzyOpCondition(); if (bool === 'must') { targetObject.query.bool.must[index][op][field] = newCondition; } else if (bool === 'must_not') { @@ -240,18 +332,32 @@ export const useFilterComponent = () => { targetObject.query.bool.should[index][op][field] = newCondition; } setSearchQuery(targetObject); + + function getFuzzyOpCondition() { + let newCondition: TermQuery = { + ['value']: fuzzyOp, + [fuzzyLevel]: fuzzyLevelValue, + }; + if (fuzzyLevelValue === '') { + newCondition = { + ['value']: fuzzyOp, + }; + } + return newCondition; + } }; return { filters, addFilterRow, removeFilterRow, - updateFilter, + updateQueryString, updateValue, updateRangeValue, updateFuzzyValue, updateOp, updateField, allFields, + opOptions }; }; diff --git a/src/composables/components/search/SearchResultsTable.ts b/src/composables/components/search/SearchResultsTable.ts index 753535c9..30132477 100644 --- a/src/composables/components/search/SearchResultsTable.ts +++ b/src/composables/components/search/SearchResultsTable.ts @@ -71,7 +71,7 @@ export const useSearchResultsTable = (props: SearchResultsTableProps, emit: any) Object.assign(allProperties, mappings.properties) } }) - + searchStore.allColumnProperties = allProperties; tableColumns.value = results.uniqueColumns.map(field => { const filterableCol = sortableField(field, allProperties[field]) diff --git a/src/store/search.ts b/src/store/search.ts index 5914f4d1..d2c82cb0 100644 --- a/src/store/search.ts +++ b/src/store/search.ts @@ -12,7 +12,8 @@ type SearchState = { visibleColumns: string[] stickyTableHeader: boolean pagination: any - rowsPerPageAccepted: boolean + rowsPerPageAccepted: boolean, + allColumnProperties: any; } export const useSearchStore = () => { @@ -30,7 +31,8 @@ export const useSearchStore = () => { visibleColumns: [], stickyTableHeader: false, pagination: Object.assign({}, DEFAULT_PAGINATION), - rowsPerPageAccepted: false + rowsPerPageAccepted: false, + allColumnProperties: {} }), actions: { resetSearchQuery () { From 20649e3d7446d081e884826d1b563c0f6ac6200b Mon Sep 17 00:00:00 2001 From: WijesingheD Date: Tue, 5 Nov 2024 12:28:24 +0000 Subject: [PATCH 3/9] Extract common logic reusable functions --- .../components/search/FilterComponent.ts | 137 +++++++++--------- 1 file changed, 68 insertions(+), 69 deletions(-) diff --git a/src/composables/components/search/FilterComponent.ts b/src/composables/components/search/FilterComponent.ts index fb0b6a79..745d7922 100644 --- a/src/composables/components/search/FilterComponent.ts +++ b/src/composables/components/search/FilterComponent.ts @@ -29,10 +29,10 @@ export const useFilterComponent = () => { { label: 'range', value: 'range', alwaysShow: false }, { label: 'query_string', value: 'query_string', alwaysShow: true }, { label: 'text', value: 'text', alwaysShow: false }, - { label: 'missing', value: 'missing', alwaysShow: false } - ] + { label: 'missing', value: 'missing', alwaysShow: false }, + ]; - let opOptions = ref([...operations]); + const opOptions = ref([...operations]); const allFields = ref([]); @@ -112,37 +112,58 @@ export const useFilterComponent = () => { const updateField = (index: number) => { const { field } = filters.value[index]; const computedOp = computed(() => { - return updateFilterWithType(field); + return updateFilterWithType(field); }); filters.value[index].op = computedOp.value; filters.value[index].value = ''; - field === 'match_all' ? updateMatchAllFilter(index) : updateQueryString(index); + field === 'match_all' + ? updateMatchAllFilter(index) + : updateQueryString(index); }; const updateFilterWithType = (field: string): string => { resetOpOptions(); - if (field === '_all') { - removeItemsByLabels(['match', 'term', 'wildcard', 'prefix', 'fuzzy', 'range', 'text', 'missing']); + if (field === '_all') { + removeItemsByLabels([ + 'match', + 'term', + 'wildcard', + 'prefix', + 'fuzzy', + 'range', + 'text', + 'missing', + ]); return 'query_string'; - } - else if(field === 'match_all'){ - removeItemsByLabels(['match', 'term', 'wildcard', 'prefix', 'fuzzy', 'range', 'text', 'missing', 'query_string']); - return ''; - } - else if (searchStore.allColumnProperties[field].type === 'date') { + } else if (field === 'match_all') { + removeItemsByLabels([ + 'match', + 'term', + 'wildcard', + 'prefix', + 'fuzzy', + 'range', + 'text', + 'missing', + 'query_string', + ]); + return ''; + } else if (searchStore.allColumnProperties[field].type === 'date') { removeItemsByLabels(['match', 'prefix', 'wildcard', 'text']); return 'term'; - } - else if (searchStore.allColumnProperties[field].type === 'integer' || searchStore.allColumnProperties[field].type === 'long') { + } else if ( + searchStore.allColumnProperties[field].type === 'integer' || + searchStore.allColumnProperties[field].type === 'long' + ) { removeItemsByLabels(['match', 'prefix', 'wildcard', 'text']); return 'term'; } return 'match'; - function removeItemsByLabels(labelsToRemove:string[]) { + function removeItemsByLabels(labelsToRemove: string[]) { opOptions.value = opOptions.value.filter( (item) => !labelsToRemove.includes(item.label) ); - opOptions + opOptions; } function resetOpOptions() { opOptions.value = [...operations]; @@ -224,7 +245,7 @@ export const useFilterComponent = () => { let newCondition: TermQuery = { [field]: {}, }; - if(op === ''){ + if (op === '') { return newCondition; } if (op === 'missing') { @@ -240,15 +261,13 @@ export const useFilterComponent = () => { query: value, }, }; - } - else if(op === 'range'){ + } else if (op === 'range') { newCondition = { [op]: { [field]: {}, }, }; - } - else{ + } else { newCondition = { [op]: { [field]: value, @@ -277,53 +296,47 @@ export const useFilterComponent = () => { if (bool === 'must') { targetObject.query.bool.must[index]['query_string']['query'] = value; } else if (bool === 'must_not') { - targetObject.query.bool.must_not[index]['query_string']['query'] = value; + targetObject.query.bool.must_not[index]['query_string']['query'] = + value; } else if (bool === 'should') { targetObject.query.bool.should[index]['query_string']['query'] = value; } setSearchQuery(targetObject); return; - } - else{ - if (bool === 'must') { - targetObject.query.bool.must[index][op][field] = value; - } else if (bool === 'must_not') { - targetObject.query.bool.must_not[index][op][field] = value; - } else if (bool === 'should') { - targetObject.query.bool.should[index][op][field] = value; - } + } else { + updateTargetObject(index, value); setSearchQuery(targetObject); } }; const updateRangeValue = (index: number) => { - const { - bool, - field, - op, - rangeLevel1, - rangeLevel1Value, - rangeLevel2, - rangeLevel2Value, - } = filters.value[index]; + const { rangeLevel1, rangeLevel1Value, rangeLevel2, rangeLevel2Value } = + filters.value[index]; const newCondition: TermQuery = { - [rangeLevel1]: rangeLevel1Value, - [rangeLevel2]: rangeLevel2Value, + [rangeLevel1]: rangeLevel1Value, + [rangeLevel2]: rangeLevel2Value, }; - if (bool === 'must') { - targetObject.query.bool.must[index][op][field] = newCondition; - } else if (bool === 'must_not') { - targetObject.query.bool.must_not[index][op][field] = newCondition; - } else if (bool === 'should') { - targetObject.query.bool.should[index][op][field] = newCondition; - } + updateTargetObject(index, newCondition); setSearchQuery(targetObject); }; const updateFuzzyValue = (index: number) => { - const { bool, field, op, fuzzyOp, fuzzyLevel, fuzzyLevelValue } = - filters.value[index]; - const newCondition: TermQuery = getFuzzyOpCondition(); + const { fuzzyOp, fuzzyLevel, fuzzyLevelValue } = filters.value[index]; + let newCondition: TermQuery = { + ['value']: fuzzyOp, + [fuzzyLevel]: fuzzyLevelValue, + }; + if (fuzzyLevelValue === '') { + newCondition = { + ['value']: fuzzyOp, + }; + } + updateTargetObject(index, newCondition); + setSearchQuery(targetObject); + }; + + function updateTargetObject(index: number, newCondition: any) { + const { bool, field, op } = filters.value[index]; if (bool === 'must') { targetObject.query.bool.must[index][op][field] = newCondition; } else if (bool === 'must_not') { @@ -331,21 +344,7 @@ export const useFilterComponent = () => { } else if (bool === 'should') { targetObject.query.bool.should[index][op][field] = newCondition; } - setSearchQuery(targetObject); - - function getFuzzyOpCondition() { - let newCondition: TermQuery = { - ['value']: fuzzyOp, - [fuzzyLevel]: fuzzyLevelValue, - }; - if (fuzzyLevelValue === '') { - newCondition = { - ['value']: fuzzyOp, - }; - } - return newCondition; - } - }; + } return { filters, @@ -358,6 +357,6 @@ export const useFilterComponent = () => { updateOp, updateField, allFields, - opOptions + opOptions, }; }; From ccf693473dbd43914899efc35de22780180f9a35 Mon Sep 17 00:00:00 2001 From: WijesingheD Date: Tue, 5 Nov 2024 12:43:47 +0000 Subject: [PATCH 4/9] Initial refactoring step 1 --- .../components/search/FilterComponent.ts | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/composables/components/search/FilterComponent.ts b/src/composables/components/search/FilterComponent.ts index 745d7922..ceb1f69e 100644 --- a/src/composables/components/search/FilterComponent.ts +++ b/src/composables/components/search/FilterComponent.ts @@ -304,7 +304,13 @@ export const useFilterComponent = () => { setSearchQuery(targetObject); return; } else { - updateTargetObject(index, value); + if (bool === 'must') { + targetObject.query.bool.must[index][op][field] = value; + } else if (bool === 'must_not') { + targetObject.query.bool.must_not[index][op][field] = value; + } else if (bool === 'should') { + targetObject.query.bool.should[index][op][field] = value; + } setSearchQuery(targetObject); } }; @@ -322,20 +328,27 @@ export const useFilterComponent = () => { const updateFuzzyValue = (index: number) => { const { fuzzyOp, fuzzyLevel, fuzzyLevelValue } = filters.value[index]; - let newCondition: TermQuery = { - ['value']: fuzzyOp, - [fuzzyLevel]: fuzzyLevelValue, - }; - if (fuzzyLevelValue === '') { - newCondition = { + updateTargetObject(index, getFuzzyOpCondition()); + setSearchQuery(targetObject); + + function getFuzzyOpCondition() { + let newCondition: TermQuery = { ['value']: fuzzyOp, + [fuzzyLevel]: fuzzyLevelValue, }; + if (fuzzyLevelValue === '') { + newCondition = { + ['value']: fuzzyOp, + }; + } + return newCondition; } - updateTargetObject(index, newCondition); - setSearchQuery(targetObject); }; - function updateTargetObject(index: number, newCondition: any) { + function updateTargetObject( + index: number, + newCondition: any + ) { const { bool, field, op } = filters.value[index]; if (bool === 'must') { targetObject.query.bool.must[index][op][field] = newCondition; From c60278997b17e26ab60f398f2bed5539c2a9777d Mon Sep 17 00:00:00 2001 From: WijesingheD Date: Wed, 6 Nov 2024 11:43:06 +0000 Subject: [PATCH 5/9] Refactor and clean code Step 2 --- src/components/search/FilterComponent.vue | 141 +++------- .../components/search/FilterComponent.ts | 245 +++++++----------- 2 files changed, 119 insertions(+), 267 deletions(-) diff --git a/src/components/search/FilterComponent.vue b/src/components/search/FilterComponent.vue index 3be831ef..f32bbd5a 100644 --- a/src/components/search/FilterComponent.vue +++ b/src/components/search/FilterComponent.vue @@ -1,149 +1,65 @@