diff --git a/arches/app/models/migrations/10804_core_search_filters.py b/arches/app/models/migrations/10804_core_search_filters.py index 7437519672a..9e02db02418 100644 --- a/arches/app/models/migrations/10804_core_search_filters.py +++ b/arches/app/models/migrations/10804_core_search_filters.py @@ -32,7 +32,7 @@ class Migration(migrations.Migration): 'standard-search-view', 0, true, - '{"default":true,"requiredComponents":[{"componentname":"paging-filter","searchcomponentid":"7aff5819-651c-4390-9b9a-a61221ba52c6","sortorder":1},{"componentname":"search-results","searchcomponentid":"00673743-8c1c-4cc0-bd85-c073a52e03ec","sortorder":2}],"availableComponents":[{"componentname":"map-filter","searchcomponentid":"09d97fc6-8c83-4319-9cef-3aaa08c3fbec","sortorder":1},{"componentname":"advanced-search","searchcomponentid":"f0e56205-acb5-475b-9c98-f5e44f1dbd2c","sortorder":2},{"componentname":"related-resources-filter","searchcomponentid":"59f28272-d1f1-4805-af51-227771739aed","sortorder":3},{"componentname":"provisional-filter","searchcomponentid":"073406ed-93e5-4b5b-9418-b61c26b3640f","sortorder":4},{"componentname":"resource-type-filter","searchcomponentid":"f1c46b7d-0132-421b-b1f3-95d67f9b3980","sortorder":5},{"componentname":"saved-searches","searchcomponentid":"6dc29637-43a1-4fba-adae-8d9956dcd3b9","sortorder":6},{"componentname":"search-export","searchcomponentid":"9c6a5a9c-a7ec-48d2-8a25-501b55b8eff6","sortorder":7},{"componentname":"search-result-details","searchcomponentid":"f5986dae-8b01-11ea-b65a-77903936669c","sortorder":8},{"componentname":"sort-results","searchcomponentid":"6a2fe122-de54-4e44-8e93-b6a0cda7955c","sortorder":9},{"componentname":"term-filter","searchcomponentid":"1f42f501-ed70-48c5-bae1-6ff7d0d187da","sortorder":10},{"componentname":"time-filter","searchcomponentid":"7497ed4f-2085-40da-bee5-52076a48bcb1","sortorder":11},{"componentname":"paging-filter","searchcomponentid":"7aff5819-651c-4390-9b9a-a61221ba52c6","sortorder":12},{"componentname":"search-results","searchcomponentid":"00673743-8c1c-4cc0-bd85-c073a52e03ec","sortorder":13}]}' + '{"default":true,"linkedSearchFilters":[{"componentname":"map-filter","searchcomponentid":"09d97fc6-8c83-4319-9cef-3aaa08c3fbec","layoutSortorder":1},{"componentname":"advanced-search","searchcomponentid":"f0e56205-acb5-475b-9c98-f5e44f1dbd2c","layoutSortorder":2},{"componentname":"related-resources-filter","searchcomponentid":"59f28272-d1f1-4805-af51-227771739aed","layoutSortorder":3},{"componentname":"provisional-filter","searchcomponentid":"073406ed-93e5-4b5b-9418-b61c26b3640f","layoutSortorder":4},{"componentname":"resource-type-filter","searchcomponentid":"f1c46b7d-0132-421b-b1f3-95d67f9b3980","layoutSortorder":5},{"componentname":"saved-searches","searchcomponentid":"6dc29637-43a1-4fba-adae-8d9956dcd3b9","layoutSortorder":6},{"componentname":"search-export","searchcomponentid":"9c6a5a9c-a7ec-48d2-8a25-501b55b8eff6","layoutSortorder":7},{"componentname":"search-result-details","searchcomponentid":"f5986dae-8b01-11ea-b65a-77903936669c","layoutSortorder":8},{"componentname":"sort-results","searchcomponentid":"6a2fe122-de54-4e44-8e93-b6a0cda7955c","layoutSortorder":9},{"componentname":"term-filter","searchcomponentid":"1f42f501-ed70-48c5-bae1-6ff7d0d187da","layoutSortorder":10},{"componentname":"time-filter","searchcomponentid":"7497ed4f-2085-40da-bee5-52076a48bcb1","layoutSortorder":11},{"componentname":"paging-filter","searchcomponentid":"7aff5819-651c-4390-9b9a-a61221ba52c6","required":true,"layoutSortorder":12,"executionSortorder":2},{"componentname":"search-results","searchcomponentid":"00673743-8c1c-4cc0-bd85-c073a52e03ec","required":true,"layoutSortorder":13,"executionSortorder":1}]}' ); UPDATE search_component SET config = '{"requiredComponents":[{"componentname":"term-filter","searchcomponentid":"1f42f501-ed70-48c5-bae1-6ff7d0d187da","sortorder":1}]}' WHERE componentname = 'provisional-filter'; UPDATE search_component SET config = '{"requiredComponents":[{"componentname":"search-results","searchcomponentid":"00673743-8c1c-4cc0-bd85-c073a52e03ec","sortorder":1}],"layoutType":"tabbed"}' WHERE componentname = 'related-resources-filter'; diff --git a/arches/app/search/components/base.py b/arches/app/search/components/base.py index 633cb5244a2..db881e49ca6 100644 --- a/arches/app/search/components/base.py +++ b/arches/app/search/components/base.py @@ -15,7 +15,7 @@ # "componentpath": "views/components/search/...", # path to ko component # "componentname": "advanced-search", # lowercase unique name # "config": { -# "requiredComponents": [ # other components on which this one depends +# "linkedSearchFilters": [ # other components on which this one depends # { # "componentname": "search-results", # "searchcomponentid": "00673743-8c1c-4cc0-bd85-c073a52e03ec", @@ -123,39 +123,9 @@ def get_searchview_component_instance(self): searchview_component_name = self.get_searchview_component_name() return self.get_filter(searchview_component_name) - def get_sorted_query_dict(self, query_dict, searchview_component): - component_sort_order = { - item["componentname"]: int(item["sortorder"]) - for item in searchview_component.config["requiredComponents"] - } - # Sort the query_dict items based on the requiredComponent's sortorder - sorted_items = sorted( - query_dict.items(), - key=lambda item: component_sort_order.get(item[0], float("inf")), - ) - - return dict(sorted_items) - - def get_query_dict_with_searchview_component(self, query_dict: Dict[str, Any]): - """ - Set search-view=arches-search-view on query_dict to arches-search-view=True - """ - ret = dict(query_dict) - searchview_component_name = self.get_searchview_component_name() - ret[searchview_component_name] = True - # check that all core-search component requiredComponents are present - for required_component in self.search_filters[searchview_component_name].config[ - "requiredComponents" - ]: - if required_component["componentname"] not in ret: - ret[required_component["componentname"]] = {} - - return ret, self.search_filters[searchview_component_name] - def create_search_query_dict(self, key_value_pairs: List[Tuple[str, Any]]): # handles list of key,value tuples so that dict-like data from POST and GET # requests can be concatenated into single method call - query_dict, searchview_component = ( - self.get_query_dict_with_searchview_component(dict(key_value_pairs)) - ) - return self.get_sorted_query_dict(query_dict, searchview_component) + searchview_component_name = self.get_searchview_component_name() + searchview_instance = self.get_filter(searchview_component_name) + return searchview_instance.create_query_dict(dict(key_value_pairs)) diff --git a/arches/app/search/components/base_search_view.py b/arches/app/search/components/base_search_view.py index 21c6ec4c5c6..4a8bc081b62 100644 --- a/arches/app/search/components/base_search_view.py +++ b/arches/app/search/components/base_search_view.py @@ -36,7 +36,7 @@ # "componentname":"search-results","searchcomponentid":"00673743-8c1c-4cc0-bd85-c073a52e03ec","sortorder":13 # } # ], -# "requiredComponents": [ # components that must be applied on the backend +# "linkedSearchFilters": [ # components that must be applied on the backend # { # "componentname": "paging-filter", # "searchcomponentid": "7aff5819-651c-4390-9b9a-a61221ba52c6", @@ -68,43 +68,45 @@ def __init__(self, request=None, user=None, componentname=None): self.searchview_component = models.SearchComponent.objects.get( componentname=componentname ) - required_component_sort_order = { - item["componentname"]: int(item["sortorder"]) - for item in self.searchview_component.config["requiredComponents"] + required_filter_sort_order = { + item["componentname"]: int(item.get("executionSortorder", 99)) + for item in self.searchview_component.config["linkedSearchFilters"] } self._required_search_filters = list( models.SearchComponent.objects.filter( searchcomponentid__in=[ - required_component["searchcomponentid"] - for required_component in self.searchview_component.config[ - "requiredComponents" + linked_filter["searchcomponentid"] + for linked_filter in self.searchview_component.config[ + "linkedSearchFilters" ] + if linked_filter.get("required", False) ] ) ) self._required_search_filters = sorted( self._required_search_filters, - key=lambda item: required_component_sort_order.get( + key=lambda item: required_filter_sort_order.get( item.componentname, float("inf") ), ) - available_component_sort_order = { - item["componentname"]: int(item["sortorder"]) - for item in self.searchview_component.config["availableComponents"] + available_filter_sort_order = { + item["componentname"]: int(item.get("layoutSortorder")) + for item in self.searchview_component.config["linkedSearchFilters"] } - self._available_search_components = list( + self._available_search_filters = list( models.SearchComponent.objects.filter( searchcomponentid__in=[ - available_component["searchcomponentid"] - for available_component in self.searchview_component.config[ - "availableComponents" + available_filter["searchcomponentid"] + for available_filter in self.searchview_component.config[ + "linkedSearchFilters" ] - ] + ], + componentpath__isnull=False, ) ) - self._available_search_components = sorted( - self._available_search_components, - key=lambda item: available_component_sort_order.get( + self._available_search_filters = sorted( + self._available_search_filters, + key=lambda item: available_filter_sort_order.get( item.componentname, float("inf") ), ) @@ -114,11 +116,34 @@ def required_search_filters(self): return self._required_search_filters @property - def available_search_components(self): - return self._available_search_components + def available_search_filters(self): + return self._available_search_filters def get_searchview_filters(self): - return self._available_search_components + [self.searchview_component] + return self.available_search_filters + [self.searchview_component] + + def sort_query_dict(self, query_dict): + filter_sort_order = { + item["componentname"]: int(item.get("executionSortorder", 99)) + for item in self.searchview_component.config["linkedSearchFilters"] + } + sorted_items = sorted( + query_dict.items(), + key=lambda item: filter_sort_order.get(item[0], float("inf")), + ) + + return dict(sorted_items) + + def create_query_dict(self, query_dict): + # check that all searchview required linkedSearchFilters are present + query_dict[self.searchview_component.componentname] = True + for linked_filter in self.searchview_component.config["linkedSearchFilters"]: + if ( + linked_filter.get("required", False) + and linked_filter["componentname"] not in query_dict + ): + query_dict[linked_filter["componentname"]] = {} + return self.sort_query_dict(query_dict) def handle_search_results_query( self, search_query_object, response_object, search_filter_factory, returnDsl diff --git a/arches/app/search/components/standard_search_view.py b/arches/app/search/components/standard_search_view.py index bd017dd1867..d54914de1e8 100644 --- a/arches/app/search/components/standard_search_view.py +++ b/arches/app/search/components/standard_search_view.py @@ -27,7 +27,7 @@ "componentname": "standard-search-view", "config": { "default": True, - "requiredComponents": [ + "linkedSearchFilters": [ { "componentname": "paging-filter", "searchcomponentid": "7aff5819-651c-4390-9b9a-a61221ba52c6", @@ -38,8 +38,6 @@ "searchcomponentid": "00673743-8c1c-4cc0-bd85-c073a52e03ec", "sortorder": 2, }, - ], - "availableComponents": [ { "componentname": "map-filter", "searchcomponentid": "09d97fc6-8c83-4319-9cef-3aaa08c3fbec", @@ -170,23 +168,23 @@ def post_search_hook(self, search_query_object, response_object, **kwargs): response_object["userid"] = self.request.user.id def get_searchview_filters(self): - search_components = [ - available_component - for available_component in self._available_search_components - if available_component.componentname != "search-export" + search_filters = [ + available_filter + for available_filter in self.available_search_filters + if available_filter.componentname != "search-export" ] if user_is_resource_exporter(self.request.user): - search_components.extend( + search_filters.extend( [ - available_component - for available_component in self._available_search_components - if available_component.componentname == "search-export" + available_filter + for available_filter in self.available_search_filters + if available_filter.componentname == "search-export" ] ) - search_components.append(self.searchview_component) + search_filters.append(self.searchview_component) - return search_components + return search_filters def handle_search_results_query( self, search_query_object, response_object, search_filter_factory, returnDsl