Opensearch progress.

- Term search works
- Pending faceted search
- Ongoing: highlight of fuzzy results
This commit is contained in:
Porras-Bernardez 2024-06-07 17:44:13 +02:00
parent 6d1c1b28c3
commit 4f53411d07
5 changed files with 292 additions and 204 deletions

View file

@ -2,16 +2,14 @@
// import debounce from 'lodash/debounce';
// import { DatasetService } from "../../services/dataset.service";
import DatasetService from "../../services/dataset.service";
import { SolrSettings } from "@/models/solr";
import { SolrSettings } from "@/models/solr"; // PENDING USE
import { OpenSettings } from "@/models/solr";
// import { ref } from "vue";
import { Component, Vue, Prop, Emit } from "vue-facing-decorator";
// import { Prop, Emit } from "vue-property-decorator";
import { Dataset, Suggestion, SearchType } from "@/models/dataset";
import { SOLR_HOST, SOLR_CORE } from "@/constants";
import { OPEN_HOST, OPEN_CORE } from "@/constants";
import { OPEN_HOST, OPEN_CORE } from "@/constants"; // PENDING USE
@Component({
name: "VsInput",
@ -20,19 +18,20 @@ export default class VsInput extends Vue {
// @Prop()
// private title!: string;
// Define the placeholder text for the input field
@Prop({ default: "Search" })
readonly placeholder!: string;
private display = "";
private display = ""; // Input display value
@Prop()
private propDisplay = "";
private value!: Suggestion | string;
private error = "";
private results: Array<Dataset> = [];
private loading = false;
private selectedIndex = -1;
private results: Array<Dataset> = []; // Array to store search results
private loading = false; // Loading state indicator
private selectedIndex = -1; // Index of the currently selected suggestion
// private selectedDisplay = "";
private solr: SolrSettings = {
core: SOLR_CORE, //"rdr_data", // SOLR.core;
@ -49,9 +48,10 @@ export default class VsInput extends Vue {
};
// private rdrAPI!: DatasetService;
itemRefs!: Array<Element>;
emits = ["filter"];
itemRefs!: Array<Element>; // Array to store references to suggestion items
emits = ["filter"]; // Emits filter event
// Set reference for each item
setItemRef(el: Element): void {
this.itemRefs.push(el);
}
@ -80,6 +80,7 @@ export default class VsInput extends Vue {
return this.error !== null;
}
// Computed property to generate suggestions based on search results
get suggestions(): Suggestion[] {
// const suggestion = {
// titles: new Array<string>(),
@ -89,12 +90,17 @@ export default class VsInput extends Vue {
const suggestions = new Array<Suggestion>();
console.log("Display:", this.display);
// console.log("results:", this.results );
console.log("results:", this.results );
// Generate suggestions based on search results
this.results.forEach((dataset) => {
console.log("suggestions:foreach:", dataset.id);
let foundAny = false;
console.log("get suggestions:id", dataset.id);
console.log("get suggestions:title_output", dataset.title_output);
console.log("get suggestions:author", dataset.author);
console.log("get suggestions:subjects", dataset.subjects);
// const del = dataset.title_output?.toLowerCase();
if (dataset.title_output.toLowerCase().includes(this.display.toLowerCase())) {
@ -102,29 +108,40 @@ export default class VsInput extends Vue {
// if (!suggestion["titles"].find((value) => value === title)) {
// suggestion.titles.push(title);
// }
// Check if there is already a suggestion with this title and type
const hasTitleSuggestion = suggestions.some((suggestion) => suggestion.value === title && suggestion.type == SearchType.Title);
if (!hasTitleSuggestion) {
// If there is no such suggestion, create a new one and add it to the suggestions array
const suggestion = new Suggestion(title, SearchType.Title);
suggestions.push(suggestion);
foundAny = true;
}
}
if (this.find(dataset.author, this.display.toLowerCase()) !== "") {
const author = this.find(dataset.author, this.display.toLowerCase());
// Check if there is already a suggestion with this author and type
const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.value === author && suggestion.type == SearchType.Author);
if (!hasAuthorSuggestion) {
const suggestion = new Suggestion(author, SearchType.Author);
suggestions.push(suggestion);
foundAny = true;
}
}
if (this.find(dataset.subjects, this.display.toLowerCase()) != "") {
const subject = this.find(dataset.subjects, this.display.toLowerCase());
const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.value === subject && suggestion.type == SearchType.Subject);
if (!hasSubjectSuggestion) {
const suggestion = new Suggestion(subject, SearchType.Subject);
suggestions.push(suggestion);
foundAny = true;
}
}
// if (this.find(dataset.author, this.display.toLowerCase()) !== "") {
// const author = this.find(dataset.author, this.display.toLowerCase());
// const hasAuthorSuggestion = suggestions.some((suggestion) => suggestion.value === author && suggestion.type == SearchType.Author);
// if (!hasAuthorSuggestion) {
// const suggestion = new Suggestion(author, SearchType.Author);
// suggestions.push(suggestion);
// }
// }
// if (this.find(dataset.subject, this.display.toLowerCase()) != "") {
// const subject = this.find(dataset.subject, this.display.toLowerCase());
// const hasSubjectSuggestion = suggestions.some((suggestion) => suggestion.value === subject && suggestion.type == SearchType.Subject);
// if (!hasSubjectSuggestion) {
// const suggestion = new Suggestion(subject, SearchType.Subject);
// suggestions.push(suggestion);
// }
// if (!foundAny) {
// const suggestion = new Suggestion(dataset.title_output, SearchType.Fuzzy);
// suggestions.push(suggestion);
// }
});
return suggestions;
@ -151,6 +168,7 @@ export default class VsInput extends Vue {
return this.display;
}
// Handler for search input change
searchChanged(): void {
console.log("Search changed!");
this.selectedIndex = -1;
@ -164,6 +182,7 @@ export default class VsInput extends Vue {
}
}
// Perform the search request
private resourceSearch() {
if (!this.display) {
this.results = [];
@ -174,6 +193,7 @@ export default class VsInput extends Vue {
this.request();
}
// Make the API request to search for datasets
private request(): void {
console.log("request()");
// DatasetService.searchTerm(this.display, this.solr.core, this.solr.host).subscribe({
@ -184,6 +204,7 @@ export default class VsInput extends Vue {
});
}
// Handle the search results
private dataHandler(datasets: Dataset[]): void {
this.results = datasets;
// console.log(datasets);
@ -192,6 +213,7 @@ export default class VsInput extends Vue {
// this.loading = false;
}
// Handle errors from the search request
private errorHandler(err: string): void {
this.error = err;
// this.loading = false;
@ -206,6 +228,7 @@ export default class VsInput extends Vue {
return key === this.selectedIndex;
}
// Handle arrow down key press to navigate suggestions
onArrowDown(ev: Event): void {
ev.preventDefault();
if (this.selectedIndex === -1) {
@ -216,6 +239,7 @@ export default class VsInput extends Vue {
this.fixScrolling();
}
// Scroll the selected suggestion into view
private fixScrolling() {
const currentElement = this.itemRefs[this.selectedIndex];
currentElement.scrollIntoView({
@ -225,6 +249,7 @@ export default class VsInput extends Vue {
});
}
// Handle arrow up key press to navigate suggestions
onArrowUp(ev: Event): void {
ev.preventDefault();
if (this.selectedIndex === -1) {
@ -235,6 +260,7 @@ export default class VsInput extends Vue {
this.fixScrolling();
}
// Handle enter key press to select a suggestion
onEnter(): void {
if (this.selectedIndex === -1) {
// this.$emit("nothingSelected", this.display);
@ -260,6 +286,7 @@ export default class VsInput extends Vue {
return this.value;
}
// Find a search term in an array
private find(myarray: Array<string>, searchterm: string): string {
for (let i = 0, len = myarray.length; i < len; i += 1) {
if (typeof myarray[i] === "string" && myarray[i].toLowerCase().indexOf(searchterm) !== -1) {