import { Component, Vue, Prop } from "vue-facing-decorator"; import VsInput from "@/components/vs-input/vs-input.vue"; import VsResult from "@/components/vs-result/vs-result.vue"; import FacetCategory from "@/components/face-category/facet-category.vue"; import ActiveFacetCategory from "@/components/active-facet-category/active-facet-category.vue"; // import { SolrSettings } from "@/models/solr"; import { OpenSettings } from "@/models/solr"; // import { DatasetService } from "@/services/dataset.service"; import DatasetService from "../../services/dataset.service"; import { Suggestion, Dataset, SearchType } from "@/models/dataset"; // import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance } from "@/models/headers"; // import { SolrResponse, FacetFields, FacetItem, FacetResults, FacetInstance, OpenSearchResponse, HitHighlight } from "@/models/headers"; import { FacetFields, FacetItem, FacetResults, FacetInstance, OpenSearchResponse, HitHighlight } from "@/models/headers"; import { ActiveFilterCategories } from "@/models/solr"; // import { SOLR_HOST, SOLR_CORE } from "@/constants"; import { IPagination } from "@/models/pagination"; import PaginationComponent from "@/components/PaginationComponent.vue"; import { OPEN_HOST, OPEN_CORE } from "@/constants"; // Decorate the component and define its name and components @Component({ name: "SearchViewComponent", components: { VsInput, VsResult, FacetCategory, ActiveFacetCategory, PaginationComponent, }, }) // Define the SearchViewComponent class export default class SearchViewComponent extends Vue { @Prop() display!: string; @Prop() type!: string; results: Array = []; // facets: FacetFields = new FacetFields(); facets: FacetResults = new FacetResults(); searchTerm: string | Suggestion = ""; // activeFilterCategories: Object = {}; activeFilterCategories: ActiveFilterCategories = new ActiveFilterCategories(); // = new Array(); pagination: IPagination = { total: 0, perPage: 10, currentPage: 1, // lastPage: 0, data: [], }; loaded = false; numFound!: number; // private solr: SolrSettings = { // core: SOLR_CORE, //"rdr_data", // SOLR.core; // host: SOLR_HOST, //"tethys.at", // }; private open: OpenSettings = { core: OPEN_CORE, //"rdr_data", // SOLR.core; host: OPEN_HOST, //"tethys.at", }; private error = ""; // Computed property to get search term as string get stringSearchTerm(): string { // console.log("stringSearchTerm:", this.searchTerm); if (typeof this.searchTerm === "string") { return this.searchTerm; } else if (this.searchTerm instanceof Suggestion) { return this.searchTerm.value + " (" + this.searchTerm.type + ")"; } else { return ""; } } // Method to check if a search term is present hasSearchTerm(): boolean { if (typeof this.searchTerm === "string" && this.searchTerm !== "") { return true; } else if (this.searchTerm instanceof Suggestion && this.searchTerm.value !== "") { return true; } else { return false; } } // getKeyName(value: string) { // return Object.entries(Suggestion).find(([key, val]) => val === value)?.[0]; // } // Method to get enum key by enum value getEnumKeyByEnumValue(myEnum: T, enumValue: string): keyof T | null { const keys = Object.keys(myEnum).filter((x) => myEnum[x] == enumValue); return keys.length > 0 ? keys[0] : null; // return keys[0]; } // Lifecycle hook: executed before the component is mounted beforeMount(): void { // console.log("beforeMount!"); // this.rdrAPI = new DatasetService(); // Trigger search based on provided display and type props if (this.display != "" && this.type != undefined) { const enumKey: "Title" | "Author" | "Subject" | null = this.getEnumKeyByEnumValue(SearchType, this.type); if (enumKey) { const suggestion = new Suggestion(this.display, "NO-IDEA", SearchType[enumKey]); // const suggestion = new Suggestion(this.display, "" , SearchType[enumKey]); this.onSearch(suggestion); } else { this.onSearch(this.display); } } else if (this.display != "" && this.type == undefined) { this.onSearch(this.display); } else { this.onSearch(""); } } // Method to trigger a search onSearch(suggestion: Suggestion | string): void { // console.log("ONSEARCH"); // Reset active filter categories and facet results this.activeFilterCategories = new ActiveFilterCategories(); this.facets = new FacetResults(); this.searchTerm = suggestion; console.log("ONSEARCH > suggestion: ", suggestion); // /* Perform faceted search. The method returns an Observable, and the code subscribes to this Observable to handle the response. If the response is successful, it calls the dataHandler method // with the Solr response as a parameter. If there is an error, it calls the errorHandler method with the error message as a parameter */ // DatasetService.facetedSearch(suggestion, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ // next: (res: SolrResponse) => this.dataHandler(res), // error: (error: string) => this.errorHandler(error), // }); DatasetService.facetedSearchOPEN(suggestion, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ // next: (res: { datasets: Dataset[], highlights: HitHighlight[] }) => this.dataHandlerOpen(res.datasets, res.highlights), next: (res: OpenSearchResponse) => this.dataHandlerOPEN(res), error: (error: string) => this.errorHandler(error), }); } // Handle the search results private dataHandlerOPEN(res: OpenSearchResponse, filterItem?: FacetItem): void { this.results = res.hits.hits.map(hit => hit._source); this.numFound = res.hits.total.value; // console.log("dataHandlerOPEN (results, numFound):"); // console.log(this.results); // console.log(this.numFound); // console.log(res.hits.hits); // console.log(res.hits.total.value); console.log(res); // for (const key in this.results) { // if (Object.prototype.hasOwnProperty.call(this.results, key)) { // const element = this.results[key]; // // console.log(element.abstract[0]); // // console.log(element.language); // console.log(element.server_date_published); // } // } this.pagination.total = res.hits.total.value; this.pagination.perPage = 10; this.pagination.data = this.results; this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); // if (res.aggregations) { // const facet_fields = res.aggregations; // let prop: keyof typeof facet_fields; // for (prop in facet_fields) { // const facetCategory = facet_fields[prop]; // if (facetCategory.buckets) { // const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count)); // this.facets[prop] = facetItems.filter(el => el.count > 0); // } // } // } if (res.aggregations) { const facet_fields = res.aggregations; let prop: keyof typeof facet_fields; // Iterate through facet fields for (prop in facet_fields) { const facetCategory = facet_fields[prop]; if (facetCategory.buckets) { const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count)); let facetValues = facetItems.map((facetItem) => { let rObj: FacetItem; // Check if current facet item matches filter item if (filterItem?.val == facetItem.val) { rObj = filterItem; } else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); rObj = this.facets[prop][indexOfFacetValue]; rObj.count = facetItem.count; } else { // Create new facet item rObj = new FacetItem(facetItem.val, facetItem.count); } return rObj; }); // Filter out null values and values with count <= 0 facetValues = facetValues.filter(el => el.count > 0); this.facets[prop] = facetValues; } } } } // // Method to handle search response // private dataHandler(res: SolrResponse, filterItem?: FacetItem): void { // // console.log("dataHandlerSOLR (docs, numFound):"); // // console.log(res.response.docs); // // console.log(res.response.numFound); // // Update results // this.results = res.response.docs; // this.numFound = res.response.numFound; // // Update pagination // this.pagination["total"] = res.response.numFound; // this.pagination["perPage"] = res.responseHeader.params.rows as number; // this.pagination["data"] = res.response.docs; // this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); // const facet_fields: FacetFields = res.facets; // /* This code declares a variable prop with a type of keys of the facet_fields object. The keyof typeof facet_fields type represents the keys of the facet_fields object. // This means that prop can only hold values that are keys of the facet_fields object. */ // let prop: keyof typeof facet_fields; // // Iterate through facet fields // for (prop in facet_fields) { // const facetCategory = facet_fields[prop]; // if (facetCategory.buckets) { // const facetItems: Array = facetCategory.buckets; // let facetValues = facetItems.map((facetItem) => { // let rObj: FacetItem; // // Check if current facet item matches filter item // if (filterItem?.val == facetItem.val) { // rObj = filterItem; // } else if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { // // console.log(facetValue + " is included") // // Update existing facet item with new count // const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); // // console.log(indexOfFacetValue); // rObj = this.facets[prop][indexOfFacetValue]; // rObj.count = facetItem.count; // // rObj = new FacetItem(val, count); // } else { // // Create new facet item // rObj = new FacetItem(facetItem.val, facetItem.count); // } // return rObj; // }); // // Filter out null values and values with count <= 0 // facetValues = facetValues.filter(function (el) { // return el != null && el.count > 0; // }); // // this.facets[prop] = facetCategory; // // Update facet values // this.facets[prop] = facetValues; // } // } // } // Method to handle search errors private errorHandler(err: string): void { this.error = err; } // Method to handle pagination onMenuClick(page: number) { console.log("onMenuClick"); this.pagination.currentPage = page; const start = page * this.pagination.perPage - this.pagination.perPage; // // Trigger new search with updated pagination parameters // DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, start.toString()).subscribe( // (res: SolrResponse) => this.dataHandler(res), // (error: string) => this.errorHandler(error), // ); DatasetService.facetedSearchOPEN(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, start.toString()).subscribe({ next: (res: OpenSearchResponse) => this.dataHandlerOPEN(res), error: (error: string) => this.errorHandler(error), }); } // Method to handle facet filtering onFilter(facetItem: FacetItem): void { console.log("onFilter"); // Reset current page this.pagination.currentPage = 1; // console.log(facetItem.val); // console.log(facetItem.category); // if (!this.activeFilterCategories.hasOwnProperty(facetItem.category)) { // Check if filter item already exists if (!Object.prototype.hasOwnProperty.call(this.activeFilterCategories, facetItem.category)) { this.activeFilterCategories[facetItem.category] = new Array(); // console.log(this.activeFilterCategories); } // if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) { // Check if filter item is not already applied if (!this.activeFilterCategories[facetItem.category].some((e) => e === facetItem.val)) { // Add filter item to active filter categories this.activeFilterCategories[facetItem.category].push(facetItem.val); // Trigger new search with updated filter // DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe( // (res: SolrResponse) => this.dataHandler(res, facetItem), // (error: string) => this.errorHandler(error), // ); // console.log(this.activeFilterCategories); DatasetService.facetedSearchOPEN(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ next: (res: OpenSearchResponse) => this.dataHandlerOPEN(res, facetItem), error: (error: string) => this.errorHandler(error), }); } } // // // Method to clear facet category filter // onClearFacetCategory(categoryName: string): void { // console.log("onClearFacetCategory"); // delete this.activeFilterCategories[categoryName]; // // Trigger new search with updated filter // DatasetService.facetedSearch(this.searchTerm, this.activeFilterCategories, this.solr.core, this.solr.host, undefined).subscribe({ // next: (res: SolrResponse) => { // this.results = res.response.docs; // this.numFound = res.response.numFound; // // pagination // this.pagination["total"] = res.response.numFound; // this.pagination["perPage"] = res.responseHeader.params.rows as number; // this.pagination["currentPage"] = 1; // this.pagination["data"] = res.response.docs; // const facet_fields: FacetFields = res.facets; // let prop: keyof typeof facet_fields; // for (prop in facet_fields) { // const facetCategory: FacetInstance = facet_fields[prop]; // if (facetCategory.buckets) { // const facetItems: Array = facetCategory.buckets; // const facetValues = facetItems.map((facetItem) => { // let rObj: FacetItem; // if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { // // console.log(facetValue + " is included") // // Update existing facet item with new count // const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); // // console.log(indexOfFacetValue); // rObj = this.facets[prop][indexOfFacetValue]; // rObj.count = facetItem.count; // // rObj = new FacetItem(val, count); // // if facet ccategory is reactivated category, deactivate all filter items // if (prop == categoryName) { // rObj.active = false; // } // } else { // // Create new facet item // rObj = new FacetItem(facetItem.val, facetItem.count); // } // return rObj; // }); // this.facets[prop] = facetValues; // } // } // }, // error: (error: string) => this.errorHandler(error), // complete: () => console.log("clear facet category completed"), // }); // } // Method to clear facet category filter onClearFacetCategoryOPEN(categoryName: string): void { // console.log("onClearFacetCategory"); delete this.activeFilterCategories[categoryName]; // Trigger new search with updated filter DatasetService.facetedSearchOPEN(this.searchTerm, this.activeFilterCategories, this.open.core, this.open.host, undefined).subscribe({ next: (res: OpenSearchResponse) => { this.results = res.hits.hits.map(hit => hit._source); this.numFound = res.hits.total.value; // Update pagination this.pagination.total = res.hits.total.value; this.pagination.perPage = 10; this.pagination.currentPage = 1; this.pagination.data = this.results; this.pagination.lastPage = Math.ceil(this.pagination.total / this.pagination.perPage); if (res.aggregations) { const facet_fields = res.aggregations; let prop: keyof typeof facet_fields; for (prop in facet_fields) { const facetCategory = facet_fields[prop]; if (facetCategory.buckets) { const facetItems = facetCategory.buckets.map(bucket => new FacetItem(bucket.key, bucket.doc_count)); const facetValues = facetItems.map((facetItem) => { let rObj: FacetItem; if (this.facets[prop]?.some((e) => e.val === facetItem.val)) { // Update existing facet item with new count const indexOfFacetValue = this.facets[prop].findIndex((i) => i.val === facetItem.val); rObj = this.facets[prop][indexOfFacetValue]; rObj.count = facetItem.count; // if facet category is reactivated category, deactivate all filter items if (prop === categoryName) { rObj.active = false; } } else { // Create new facet item rObj = new FacetItem(facetItem.val, facetItem.count); } return rObj; }).filter(el => el.count > 0); // Filter out items with count <= 0 this.facets[prop] = facetValues; } } } }, error: (error: string) => this.errorHandler(error), complete: () => console.log("clear facet category completed"), }); } }