@memberjunction/ng-search 5.30.0 → 5.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/search-results.component.d.ts +2 -1
- package/dist/lib/search-results.component.d.ts.map +1 -1
- package/dist/lib/search-results.component.js +5 -5
- package/dist/lib/search-results.component.js.map +1 -1
- package/dist/lib/search.service.d.ts +8 -0
- package/dist/lib/search.service.d.ts.map +1 -1
- package/dist/lib/search.service.js +13 -4
- package/dist/lib/search.service.js.map +1 -1
- package/package.json +7 -6
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { EventEmitter } from '@angular/core';
|
|
9
9
|
import { SearchResultItem, SearchResultGroup, SearchResultSelectedEvent } from './search-types';
|
|
10
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
10
11
|
import * as i0 from "@angular/core";
|
|
11
|
-
export declare class SearchResultsComponent {
|
|
12
|
+
export declare class SearchResultsComponent extends BaseAngularComponent {
|
|
12
13
|
private cdr;
|
|
13
14
|
/** Grouped search results to display (used when DisplayMode is 'grouped') */
|
|
14
15
|
ResultGroups: SearchResultGroup[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-results.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-results.component.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEH,YAAY,EAKf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;;
|
|
1
|
+
{"version":3,"file":"search-results.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-results.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* in the Knowledge Hub search dashboard.
|
|
7
7
|
*/
|
|
8
8
|
import { Component, EventEmitter, Input, Output, ChangeDetectorRef, inject } from '@angular/core';
|
|
9
|
-
import { Metadata } from '@memberjunction/core';
|
|
10
9
|
import { EscapeHTML } from '@memberjunction/global';
|
|
10
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
11
11
|
import * as i0 from "@angular/core";
|
|
12
12
|
import * as i1 from "@angular/common";
|
|
13
13
|
import * as i2 from "@memberjunction/ng-shared-generic";
|
|
@@ -438,7 +438,7 @@ function SearchResultsComponent_ng_template_3_Template(rf, ctx) { if (rf & 1) {
|
|
|
438
438
|
i0.ɵɵadvance();
|
|
439
439
|
i0.ɵɵconditional(ctx_r0.IsExpanded(result_r12.ID) ? 14 : -1);
|
|
440
440
|
} }
|
|
441
|
-
export class SearchResultsComponent {
|
|
441
|
+
export class SearchResultsComponent extends BaseAngularComponent {
|
|
442
442
|
cdr = inject(ChangeDetectorRef);
|
|
443
443
|
/** Grouped search results to display (used when DisplayMode is 'grouped') */
|
|
444
444
|
ResultGroups = [];
|
|
@@ -669,7 +669,7 @@ export class SearchResultsComponent {
|
|
|
669
669
|
return this.linkFieldsCache.get(entityName);
|
|
670
670
|
}
|
|
671
671
|
try {
|
|
672
|
-
const md =
|
|
672
|
+
const md = this.ProviderToUse;
|
|
673
673
|
const entityInfo = md.Entities.find(e => e.Name === entityName);
|
|
674
674
|
if (!entityInfo) {
|
|
675
675
|
this.linkFieldsCache.set(entityName, []);
|
|
@@ -690,8 +690,8 @@ export class SearchResultsComponent {
|
|
|
690
690
|
return [];
|
|
691
691
|
}
|
|
692
692
|
}
|
|
693
|
-
static ɵfac = function SearchResultsComponent_Factory(__ngFactoryType__) { return
|
|
694
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SearchResultsComponent, selectors: [["mj-search-results"]], inputs: { ResultGroups: "ResultGroups", FlatResults: "FlatResults", DisplayMode: "DisplayMode", IsLoading: "IsLoading", TotalCount: "TotalCount", ElapsedMs: "ElapsedMs", MaxPerGroup: "MaxPerGroup", PageSize: "PageSize", ShowSummary: "ShowSummary", ShowScores: "ShowScores", ShowTags: "ShowTags", ShowSourceIcons: "ShowSourceIcons", HighlightText: "HighlightText" }, outputs: { ResultSelected: "ResultSelected", OpenRecordRequested: "OpenRecordRequested", MoreLikeThisRequested: "MoreLikeThisRequested" }, standalone: false, decls: 5, vars: 1, consts: [["resultCardTpl", ""], [1, "results-loading"], [1, "results-empty"], ["text", "Searching...", "size", "medium"], [1, "fa-solid", "fa-search", "results-empty-icon"], [1, "results-empty-text"], [1, "results-summary"], [1, "results-summary-time"], [1, "results-scroll-area"], [1, "results-pager"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], ["aria-label", "Previous page", 1, "pager-btn", "pager-prev", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-left"], ["aria-label", "Next page", 1, "pager-btn", "pager-next", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-right"], [1, "pager-ellipsis"], [1, "pager-btn", "pager-num", 3, "pager-active"], [1, "pager-btn", "pager-num", 3, "click"], [1, "results-group"], [1, "results-group-header", 3, "click"], [3, "class"], [1, "results-group-label"], [1, "results-group-count"], [1, "fa-solid", "results-group-chevron"], [1, "results-show-more"], [1, "results-show-more", 3, "click"], [1, "fa-solid", "fa-chevron-down"], [1, "result-card"], [1, "result-card-main", 3, "click"], [1, "result-card-icon-wrap"], [1, "result-card-body"], [1, "result-card-title", 3, "innerHTML"], [1, "result-card-entity", 3, "innerHTML"], [1, "result-card-tags"], [1, "result-card-score"], [1, "result-card-actions"], [1, "result-open-btn", 3, "click", "title"], ["title", "Expand details", "aria-label", "Expand details", 1, "result-expand-btn", 3, "click"], [1, "fa-solid"], [1, "result-card-detail"], [1, "result-tag-chip", 3, "innerHTML"], [1, "result-tag-more"], [1, "score-circle"], [1, "score-value"], [1, "detail-section"], [1, "detail-meta"], [1, "detail-meta-item"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-fingerprint"], [1, "detail-record-id"], [1, "fa-solid", "fa-signal"], [1, "detail-tags"], [1, "detail-links"], [1, "detail-actions"], [1, "detail-open-btn", 3, "click"], [1, "detail-similar-btn", 3, "click"], [1, "fa-solid", "fa-shuffle"], [1, "detail-label"], [1, "detail-snippet", 3, "innerHTML"], [1, "fa-solid", "fa-chart-bar"], [1, "result-card-tag", 3, "innerHTML"], ["target", "_blank", 1, "detail-link", 3, "href"], [1, "detail-link", "detail-link-email", 3, "href"], ["target", "_blank", 1, "detail-link", 3, "click", "href"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "detail-link", "detail-link-email", 3, "click", "href"], [1, "fa-solid", "fa-envelope"], [1, "fa-solid", "fa-external-link"]], template: function SearchResultsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
693
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵSearchResultsComponent_BaseFactory; return function SearchResultsComponent_Factory(__ngFactoryType__) { return (ɵSearchResultsComponent_BaseFactory || (ɵSearchResultsComponent_BaseFactory = i0.ɵɵgetInheritedFactory(SearchResultsComponent)))(__ngFactoryType__ || SearchResultsComponent); }; })();
|
|
694
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SearchResultsComponent, selectors: [["mj-search-results"]], inputs: { ResultGroups: "ResultGroups", FlatResults: "FlatResults", DisplayMode: "DisplayMode", IsLoading: "IsLoading", TotalCount: "TotalCount", ElapsedMs: "ElapsedMs", MaxPerGroup: "MaxPerGroup", PageSize: "PageSize", ShowSummary: "ShowSummary", ShowScores: "ShowScores", ShowTags: "ShowTags", ShowSourceIcons: "ShowSourceIcons", HighlightText: "HighlightText" }, outputs: { ResultSelected: "ResultSelected", OpenRecordRequested: "OpenRecordRequested", MoreLikeThisRequested: "MoreLikeThisRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 1, consts: [["resultCardTpl", ""], [1, "results-loading"], [1, "results-empty"], ["text", "Searching...", "size", "medium"], [1, "fa-solid", "fa-search", "results-empty-icon"], [1, "results-empty-text"], [1, "results-summary"], [1, "results-summary-time"], [1, "results-scroll-area"], [1, "results-pager"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], ["aria-label", "Previous page", 1, "pager-btn", "pager-prev", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-left"], ["aria-label", "Next page", 1, "pager-btn", "pager-next", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-right"], [1, "pager-ellipsis"], [1, "pager-btn", "pager-num", 3, "pager-active"], [1, "pager-btn", "pager-num", 3, "click"], [1, "results-group"], [1, "results-group-header", 3, "click"], [3, "class"], [1, "results-group-label"], [1, "results-group-count"], [1, "fa-solid", "results-group-chevron"], [1, "results-show-more"], [1, "results-show-more", 3, "click"], [1, "fa-solid", "fa-chevron-down"], [1, "result-card"], [1, "result-card-main", 3, "click"], [1, "result-card-icon-wrap"], [1, "result-card-body"], [1, "result-card-title", 3, "innerHTML"], [1, "result-card-entity", 3, "innerHTML"], [1, "result-card-tags"], [1, "result-card-score"], [1, "result-card-actions"], [1, "result-open-btn", 3, "click", "title"], ["title", "Expand details", "aria-label", "Expand details", 1, "result-expand-btn", 3, "click"], [1, "fa-solid"], [1, "result-card-detail"], [1, "result-tag-chip", 3, "innerHTML"], [1, "result-tag-more"], [1, "score-circle"], [1, "score-value"], [1, "detail-section"], [1, "detail-meta"], [1, "detail-meta-item"], [1, "fa-solid", "fa-layer-group"], [1, "fa-solid", "fa-fingerprint"], [1, "detail-record-id"], [1, "fa-solid", "fa-signal"], [1, "detail-tags"], [1, "detail-links"], [1, "detail-actions"], [1, "detail-open-btn", 3, "click"], [1, "detail-similar-btn", 3, "click"], [1, "fa-solid", "fa-shuffle"], [1, "detail-label"], [1, "detail-snippet", 3, "innerHTML"], [1, "fa-solid", "fa-chart-bar"], [1, "result-card-tag", 3, "innerHTML"], ["target", "_blank", 1, "detail-link", 3, "href"], [1, "detail-link", "detail-link-email", 3, "href"], ["target", "_blank", 1, "detail-link", 3, "click", "href"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "detail-link", "detail-link-email", 3, "click", "href"], [1, "fa-solid", "fa-envelope"], [1, "fa-solid", "fa-external-link"]], template: function SearchResultsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
695
695
|
i0.ɵɵconditionalCreate(0, SearchResultsComponent_Conditional_0_Template, 2, 0, "div", 1)(1, SearchResultsComponent_Conditional_1_Template, 4, 0, "div", 2)(2, SearchResultsComponent_Conditional_2_Template, 3, 2);
|
|
696
696
|
i0.ɵɵtemplate(3, SearchResultsComponent_ng_template_3_Template, 15, 17, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
697
697
|
} if (rf & 2) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-results.component.js","sourceRoot":"","sources":["../../src/lib/search-results.component.ts","../../src/lib/search-results.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Results Component\n *\n * Displays search results grouped by source type with expandable sections.\n * Used both within the search overlay and as a standalone results view\n * in the Knowledge Hub search dashboard.\n */\n\nimport {\n Component,\n EventEmitter,\n Input,\n Output,\n ChangeDetectorRef,\n inject\n} from '@angular/core';\nimport { SearchResultItem, SearchResultGroup, SearchResultSelectedEvent } from './search-types';\nimport { Metadata } from '@memberjunction/core';\nimport { EscapeHTML } from '@memberjunction/global';\n\n@Component({\n standalone: false,\n selector: 'mj-search-results',\n templateUrl: './search-results.component.html',\n styleUrls: ['./search-results.component.css']\n})\nexport class SearchResultsComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Grouped search results to display (used when DisplayMode is 'grouped') */\n @Input() ResultGroups: SearchResultGroup[] = [];\n\n /** Flat list of all results sorted by score (used when DisplayMode is 'flat') */\n @Input() FlatResults: SearchResultItem[] = [];\n\n /** Display mode: 'flat' for blended list sorted by score, 'grouped' for source-type groups */\n @Input() DisplayMode: 'flat' | 'grouped' = 'flat';\n\n /** Whether results are currently loading */\n @Input() IsLoading = false;\n\n /** Total result count */\n @Input() TotalCount = 0;\n\n /** Elapsed search time in ms */\n @Input() ElapsedMs = 0;\n\n /** Maximum results per group before \"Show more\" (grouped mode only) */\n @Input() MaxPerGroup = 5;\n\n /** Results per page in flat mode */\n @Input() PageSize = 10;\n\n /** Whether to show the results summary line (count + time). Set false when parent provides its own header. */\n @Input() ShowSummary = true;\n\n /** Whether to show score badges */\n @Input() ShowScores = true;\n\n /** Whether to show tags */\n @Input() ShowTags = true;\n\n /** Whether to show source type icons */\n @Input() ShowSourceIcons = true;\n\n /** Text to highlight within result cards (e.g. from a client-side filter) */\n @Input() HighlightText = '';\n\n @Output() ResultSelected = new EventEmitter<SearchResultSelectedEvent>();\n\n /** Emitted when user clicks \"Open Record\" — parent handles navigation */\n @Output() OpenRecordRequested = new EventEmitter<SearchResultItem>();\n\n /** Emitted when user clicks \"See Similar Items\" — parent runs a \"more like this\" search */\n @Output() MoreLikeThisRequested = new EventEmitter<SearchResultItem>();\n\n /** Current page (1-based) for flat mode pagination */\n public CurrentPage = 1;\n\n /** Tracks which groups are expanded */\n public ExpandedGroups = new Set<string>();\n\n /** Set of expanded result card IDs — multiple can be open simultaneously */\n public ExpandedResultIDs = new Set<string>();\n\n // ── Flat mode pagination ──\n\n /** Get results for the current page in flat mode */\n public get PagedResults(): SearchResultItem[] {\n const start = (this.CurrentPage - 1) * this.PageSize;\n return this.FlatResults.slice(start, start + this.PageSize);\n }\n\n /** Total number of pages */\n public get TotalPages(): number {\n return Math.ceil(this.FlatResults.length / this.PageSize);\n }\n\n /** Page numbers to display in the pager */\n public get PageNumbers(): number[] {\n const total = this.TotalPages;\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);\n\n const pages: number[] = [1];\n const start = Math.max(2, this.CurrentPage - 2);\n const end = Math.min(total - 1, this.CurrentPage + 2);\n if (start > 2) pages.push(-1); // ellipsis marker\n for (let i = start; i <= end; i++) pages.push(i);\n if (end < total - 1) pages.push(-1); // ellipsis marker\n pages.push(total);\n return pages;\n }\n\n /** Navigate to a specific page */\n public GoToPage(page: number): void {\n if (page < 1 || page > this.TotalPages) return;\n this.CurrentPage = page;\n this.cdr.detectChanges();\n }\n\n // ── Grouped mode ──\n\n /** Toggle group expansion */\n public ToggleGroup(sourceType: string): void {\n if (this.ExpandedGroups.has(sourceType)) {\n this.ExpandedGroups.delete(sourceType);\n } else {\n this.ExpandedGroups.add(sourceType);\n }\n this.cdr.detectChanges();\n }\n\n /** Whether a group is expanded */\n public IsGroupExpanded(sourceType: string): boolean {\n return this.ExpandedGroups.has(sourceType);\n }\n\n /** Get visible results for a group (respecting max per group unless expanded) */\n public GetVisibleResults(group: SearchResultGroup): SearchResultItem[] {\n if (this.IsGroupExpanded(group.SourceType)) {\n return group.Results;\n }\n return group.Results.slice(0, this.MaxPerGroup);\n }\n\n /** Whether a group has more results than shown */\n public HasMoreResults(group: SearchResultGroup): boolean {\n return group.Results.length > this.MaxPerGroup && !this.IsGroupExpanded(group.SourceType);\n }\n\n /** Get the count of hidden results */\n public GetHiddenCount(group: SearchResultGroup): number {\n return group.Results.length - this.MaxPerGroup;\n }\n\n /** Handle clicking a result */\n public OnResultClick(result: SearchResultItem, event: MouseEvent): void {\n this.ResultSelected.emit({\n Result: result,\n OpenInNewTab: event.metaKey || event.ctrlKey\n });\n }\n\n /** Toggle expand/collapse of a result card — multiple can be open */\n public ToggleExpand(result: SearchResultItem, event?: MouseEvent): void {\n if (event) event.stopPropagation();\n if (this.ExpandedResultIDs.has(result.ID)) {\n this.ExpandedResultIDs.delete(result.ID);\n } else {\n this.ExpandedResultIDs.add(result.ID);\n }\n this.cdr.detectChanges();\n }\n\n /** Check if a result card is expanded */\n public IsExpanded(resultID: string): boolean {\n return this.ExpandedResultIDs.has(resultID);\n }\n\n /** Handle \"Open Record\" button click */\n public OnOpenRecord(result: SearchResultItem, event: MouseEvent): void {\n event.stopPropagation();\n this.OpenRecordRequested.emit(result);\n }\n\n /** Handle \"See Similar Items\" button click — emits the result for a \"more like this\" search */\n public OnMoreLikeThis(result: SearchResultItem, event: MouseEvent): void {\n event.stopPropagation();\n this.MoreLikeThisRequested.emit(result);\n }\n\n /**\n * Wrap substrings matching HighlightText in <mark> tags for visual emphasis.\n * The input is regex-escaped so user text is treated as a literal string.\n */\n public HighlightMatch(text: string): string {\n if (!text) return text;\n const safeText = EscapeHTML(text);\n if (!this.HighlightText) return safeText;\n\n const safeHighlightText = EscapeHTML(this.HighlightText);\n const escaped = safeHighlightText.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(`(${escaped})`, 'gi');\n return safeText.replace(regex, '<mark class=\"search-highlight\">$1</mark>');\n }\n\n /** Format a score as a percentage */\n public FormatScore(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Format elapsed time */\n public FormatTime(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n }\n\n /** Resolved link cache per result ID */\n private resolvedLinksCache = new Map<string, { Value: string; Label: string; Type: 'URL' | 'Email' }[]>();\n\n /**\n * Resolve URL and Email fields from the result's RawMetadata using entity ExtendedType metadata.\n * Returns clickable link entries with proper type classification.\n */\n public GetResolvedLinks(result: SearchResultItem): { Value: string; Label: string; Type: 'URL' | 'Email' }[] {\n if (this.resolvedLinksCache.has(result.ID)) {\n return this.resolvedLinksCache.get(result.ID)!;\n }\n\n const links: { Value: string; Label: string; Type: 'URL' | 'Email' }[] = [];\n\n if (result.RawMetadata) {\n try {\n const meta = JSON.parse(result.RawMetadata) as Record<string, unknown>;\n const linkFields = this.GetLinkFields(result.EntityName);\n\n for (const field of linkFields) {\n const value = meta[field.Name];\n if (value && typeof value === 'string' && value.trim().length > 0) {\n links.push({\n Value: value,\n Label: field.DisplayName,\n Type: field.Type\n });\n }\n }\n } catch { /* ignore parse errors */ }\n }\n\n // Fallback: extract URLs from snippet if no ExtendedType fields found\n if (links.length === 0) {\n const urls = this.ExtractUrls(result.Snippet);\n for (const url of urls) {\n links.push({ Value: url, Label: '', Type: 'URL' });\n }\n }\n\n this.resolvedLinksCache.set(result.ID, links);\n return links;\n }\n\n /** Extract URLs from snippet text */\n public ExtractUrls(snippet: string): string[] {\n if (!snippet) return [];\n const urlRegex = /https?:\\/\\/[^\\s,;)>\"']+/g;\n const matches = snippet.match(urlRegex);\n return matches ? [...new Set(matches)] : [];\n }\n\n /** Truncate a URL for display */\n public TruncateUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const path = parsed.pathname.length > 30\n ? parsed.pathname.substring(0, 30) + '...'\n : parsed.pathname;\n return parsed.hostname + path;\n } catch {\n return url.length > 50 ? url.substring(0, 50) + '...' : url;\n }\n }\n\n /** Cache of URL/Email field info per entity name */\n private linkFieldsCache = new Map<string, { Name: string; DisplayName: string; Type: 'URL' | 'Email' }[]>();\n\n /**\n * Get URL and Email fields for an entity using ExtendedType from entity metadata.\n * Returns fields with ExtendedType='URL' or ExtendedType='Email'.\n */\n public GetLinkFields(entityName: string): { Name: string; DisplayName: string; Type: 'URL' | 'Email' }[] {\n if (this.linkFieldsCache.has(entityName)) {\n return this.linkFieldsCache.get(entityName)!;\n }\n\n try {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this.linkFieldsCache.set(entityName, []);\n return [];\n }\n\n const linkFields = entityInfo.Fields\n .filter(f => f.ExtendedType === 'URL' || f.ExtendedType === 'Email')\n .map(f => ({\n Name: f.Name,\n DisplayName: f.DisplayNameOrName,\n Type: f.ExtendedType as 'URL' | 'Email'\n }));\n\n this.linkFieldsCache.set(entityName, linkFields);\n return linkFields;\n } catch {\n this.linkFieldsCache.set(entityName, []);\n return [];\n }\n }\n}\n","@if (IsLoading) {\n <div class=\"results-loading\">\n <mj-loading text=\"Searching...\" size=\"medium\"></mj-loading>\n </div>\n} @else if ((DisplayMode === 'flat' ? FlatResults.length : ResultGroups.length) === 0 && TotalCount === 0) {\n <div class=\"results-empty\">\n <i class=\"fa-solid fa-search results-empty-icon\"></i>\n <p class=\"results-empty-text\">No results to display</p>\n </div>\n} @else {\n <!-- Results summary -->\n @if (ShowSummary) {\n <div class=\"results-summary\">\n <span>{{ TotalCount }} results</span>\n @if (ElapsedMs > 0) {\n <span class=\"results-summary-time\"> in {{ FormatTime(ElapsedMs) }}</span>\n }\n </div>\n }\n\n @if (DisplayMode === 'flat') {\n <!-- ══════ FLAT BLENDED LIST (sorted by score) ══════ -->\n <div class=\"results-scroll-area\">\n @for (result of PagedResults; track result.ID) {\n <ng-container *ngTemplateOutlet=\"resultCardTpl; context: { $implicit: result }\"></ng-container>\n }\n </div>\n\n <!-- Google-style pagination (sticky at bottom) -->\n @if (TotalPages > 1) {\n <div class=\"results-pager\">\n <button class=\"pager-btn pager-prev\" [disabled]=\"CurrentPage === 1\"\n (click)=\"GoToPage(CurrentPage - 1)\" aria-label=\"Previous page\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n @for (p of PageNumbers; track $index) {\n @if (p === -1) {\n <span class=\"pager-ellipsis\">...</span>\n } @else {\n <button class=\"pager-btn pager-num\" [class.pager-active]=\"p === CurrentPage\"\n (click)=\"GoToPage(p)\">{{ p }}</button>\n }\n }\n <button class=\"pager-btn pager-next\" [disabled]=\"CurrentPage === TotalPages\"\n (click)=\"GoToPage(CurrentPage + 1)\" aria-label=\"Next page\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n }\n } @else {\n <!-- ══════ GROUPED BY SOURCE TYPE ══════ -->\n @for (group of ResultGroups; track group.SourceType) {\n <div class=\"results-group\">\n <div class=\"results-group-header\" (click)=\"ToggleGroup(group.SourceType)\">\n @if (ShowSourceIcons) {\n <i [class]=\"group.Icon + ' results-group-icon'\"></i>\n }\n <span class=\"results-group-label\">{{ group.Label }}</span>\n <span class=\"results-group-count\">({{ group.TotalCount }})</span>\n <i class=\"fa-solid results-group-chevron\"\n [class.fa-chevron-down]=\"!IsGroupExpanded(group.SourceType)\"\n [class.fa-chevron-up]=\"IsGroupExpanded(group.SourceType)\"></i>\n </div>\n\n @for (result of GetVisibleResults(group); track result.ID) {\n <ng-container *ngTemplateOutlet=\"resultCardTpl; context: { $implicit: result }\"></ng-container>\n }\n\n @if (HasMoreResults(group)) {\n <button class=\"results-show-more\" (click)=\"ToggleGroup(group.SourceType)\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n Show {{ GetHiddenCount(group) }} more results\n </button>\n }\n </div>\n }\n }\n}\n\n<!-- ═══ Shared result card template ═══ -->\n<ng-template #resultCardTpl let-result>\n <div class=\"result-card\" [class.result-card-expanded]=\"IsExpanded(result.ID)\">\n <!-- Main row -->\n <div class=\"result-card-main\" (click)=\"ToggleExpand(result)\">\n <div class=\"result-card-icon-wrap\">\n <i [class]=\"result.EntityIcon || result.SourceIcon || 'fa-solid fa-database'\"></i>\n </div>\n <div class=\"result-card-body\">\n <div class=\"result-card-title\" [innerHTML]=\"HighlightMatch(result.RecordName || result.Title)\"></div>\n <div class=\"result-card-entity\" [innerHTML]=\"HighlightMatch(result.EntityName)\"></div>\n @if (result.Tags && result.Tags.length > 0) {\n <div class=\"result-card-tags\">\n @for (tag of result.Tags.slice(0, 5); track tag) {\n <span class=\"result-tag-chip\" [innerHTML]=\"HighlightMatch(tag)\"></span>\n }\n @if (result.Tags.length > 5) {\n <span class=\"result-tag-more\">+{{ result.Tags.length - 5 }}</span>\n }\n </div>\n }\n </div>\n @if (ShowScores) {\n <div class=\"result-card-score\">\n <div class=\"score-circle\" [class.score-high]=\"result.Score >= 0.40\" [class.score-medium]=\"result.Score >= 0.15 && result.Score < 0.40\" [class.score-low]=\"result.Score < 0.15\">\n <span class=\"score-value\">{{ FormatScore(result.Score) }}</span>\n </div>\n </div>\n }\n <div class=\"result-card-actions\">\n <button class=\"result-open-btn\" (click)=\"OnOpenRecord(result, $event)\"\n [title]=\"result.ResultType === 'storage-file' ? 'Open file' : 'Open record'\"\n [attr.aria-label]=\"result.ResultType === 'storage-file' ? 'Open file' : 'Open record'\">\n <i [class]=\"result.ResultType === 'storage-file' ? 'fa-solid fa-external-link' : 'fa-solid fa-arrow-up-right-from-square'\"></i>\n </button>\n <button class=\"result-expand-btn\" (click)=\"ToggleExpand(result, $event)\" title=\"Expand details\" aria-label=\"Expand details\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsExpanded(result.ID)\"\n [class.fa-chevron-up]=\"IsExpanded(result.ID)\"></i>\n </button>\n </div>\n </div>\n\n <!-- Expanded detail -->\n @if (IsExpanded(result.ID)) {\n <div class=\"result-card-detail\">\n @if (result.Snippet) {\n <div class=\"detail-section\">\n <span class=\"detail-label\">Preview</span>\n <p class=\"detail-snippet\" [innerHTML]=\"HighlightMatch(result.Snippet)\"></p>\n </div>\n }\n <div class=\"detail-meta\">\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n <span>{{ result.EntityName }}</span>\n </div>\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-fingerprint\"></i>\n <span class=\"detail-record-id\">{{ result.RecordID }}</span>\n </div>\n <!-- SR-1: Show overall score consistently -->\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-signal\"></i>\n <span>Relevance: {{ FormatScore(result.Score) }}</span>\n </div>\n @if (result.ScoreBreakdown) {\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n <span>\n @if (result.ScoreBreakdown.Vector) { Vector: {{ FormatScore(result.ScoreBreakdown.Vector) }} }\n @if (result.ScoreBreakdown.FullText) { FTS: {{ FormatScore(result.ScoreBreakdown.FullText) }} }\n </span>\n </div>\n }\n </div>\n @if (ShowTags && result.Tags.length > 0) {\n <div class=\"detail-tags\">\n @for (tag of result.Tags; track tag) {\n <span class=\"result-card-tag\" [innerHTML]=\"HighlightMatch(tag)\"></span>\n }\n </div>\n }\n @if (GetResolvedLinks(result).length > 0) {\n <div class=\"detail-links\">\n @for (link of GetResolvedLinks(result); track link.Value) {\n @if (link.Type === 'URL') {\n <a [href]=\"link.Value\" target=\"_blank\" class=\"detail-link\" (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n {{ TruncateUrl(link.Value) }}\n </a>\n } @else if (link.Type === 'Email') {\n <a [href]=\"'mailto:' + link.Value\" class=\"detail-link detail-link-email\" (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-envelope\"></i>\n {{ link.Value }}\n </a>\n }\n }\n </div>\n }\n <div class=\"detail-actions\">\n <button class=\"detail-open-btn\" (click)=\"OnOpenRecord(result, $event)\">\n @if (result.ResultType === 'storage-file') {\n <i class=\"fa-solid fa-external-link\"></i> Open File\n } @else {\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Record\n }\n </button>\n <button class=\"detail-similar-btn\" (click)=\"OnMoreLikeThis(result, $event)\">\n <i class=\"fa-solid fa-shuffle\"></i> See Similar Items\n </button>\n </div>\n </div>\n }\n </div>\n</ng-template>\n"]}
|
|
1
|
+
{"version":3,"file":"search-results.component.js","sourceRoot":"","sources":["../../src/lib/search-results.component.ts","../../src/lib/search-results.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Results Component\n *\n * Displays search results grouped by source type with expandable sections.\n * Used both within the search overlay and as a standalone results view\n * in the Knowledge Hub search dashboard.\n */\n\nimport {\n Component,\n EventEmitter,\n Input,\n Output,\n ChangeDetectorRef,\n inject\n} from '@angular/core';\nimport { SearchResultItem, SearchResultGroup, SearchResultSelectedEvent } from './search-types';\nimport { EscapeHTML } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n\n@Component({\n standalone: false,\n selector: 'mj-search-results',\n templateUrl: './search-results.component.html',\n styleUrls: ['./search-results.component.css']\n})\nexport class SearchResultsComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Grouped search results to display (used when DisplayMode is 'grouped') */\n @Input() ResultGroups: SearchResultGroup[] = [];\n\n /** Flat list of all results sorted by score (used when DisplayMode is 'flat') */\n @Input() FlatResults: SearchResultItem[] = [];\n\n /** Display mode: 'flat' for blended list sorted by score, 'grouped' for source-type groups */\n @Input() DisplayMode: 'flat' | 'grouped' = 'flat';\n\n /** Whether results are currently loading */\n @Input() IsLoading = false;\n\n /** Total result count */\n @Input() TotalCount = 0;\n\n /** Elapsed search time in ms */\n @Input() ElapsedMs = 0;\n\n /** Maximum results per group before \"Show more\" (grouped mode only) */\n @Input() MaxPerGroup = 5;\n\n /** Results per page in flat mode */\n @Input() PageSize = 10;\n\n /** Whether to show the results summary line (count + time). Set false when parent provides its own header. */\n @Input() ShowSummary = true;\n\n /** Whether to show score badges */\n @Input() ShowScores = true;\n\n /** Whether to show tags */\n @Input() ShowTags = true;\n\n /** Whether to show source type icons */\n @Input() ShowSourceIcons = true;\n\n /** Text to highlight within result cards (e.g. from a client-side filter) */\n @Input() HighlightText = '';\n\n @Output() ResultSelected = new EventEmitter<SearchResultSelectedEvent>();\n\n /** Emitted when user clicks \"Open Record\" — parent handles navigation */\n @Output() OpenRecordRequested = new EventEmitter<SearchResultItem>();\n\n /** Emitted when user clicks \"See Similar Items\" — parent runs a \"more like this\" search */\n @Output() MoreLikeThisRequested = new EventEmitter<SearchResultItem>();\n\n /** Current page (1-based) for flat mode pagination */\n public CurrentPage = 1;\n\n /** Tracks which groups are expanded */\n public ExpandedGroups = new Set<string>();\n\n /** Set of expanded result card IDs — multiple can be open simultaneously */\n public ExpandedResultIDs = new Set<string>();\n\n // ── Flat mode pagination ──\n\n /** Get results for the current page in flat mode */\n public get PagedResults(): SearchResultItem[] {\n const start = (this.CurrentPage - 1) * this.PageSize;\n return this.FlatResults.slice(start, start + this.PageSize);\n }\n\n /** Total number of pages */\n public get TotalPages(): number {\n return Math.ceil(this.FlatResults.length / this.PageSize);\n }\n\n /** Page numbers to display in the pager */\n public get PageNumbers(): number[] {\n const total = this.TotalPages;\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);\n\n const pages: number[] = [1];\n const start = Math.max(2, this.CurrentPage - 2);\n const end = Math.min(total - 1, this.CurrentPage + 2);\n if (start > 2) pages.push(-1); // ellipsis marker\n for (let i = start; i <= end; i++) pages.push(i);\n if (end < total - 1) pages.push(-1); // ellipsis marker\n pages.push(total);\n return pages;\n }\n\n /** Navigate to a specific page */\n public GoToPage(page: number): void {\n if (page < 1 || page > this.TotalPages) return;\n this.CurrentPage = page;\n this.cdr.detectChanges();\n }\n\n // ── Grouped mode ──\n\n /** Toggle group expansion */\n public ToggleGroup(sourceType: string): void {\n if (this.ExpandedGroups.has(sourceType)) {\n this.ExpandedGroups.delete(sourceType);\n } else {\n this.ExpandedGroups.add(sourceType);\n }\n this.cdr.detectChanges();\n }\n\n /** Whether a group is expanded */\n public IsGroupExpanded(sourceType: string): boolean {\n return this.ExpandedGroups.has(sourceType);\n }\n\n /** Get visible results for a group (respecting max per group unless expanded) */\n public GetVisibleResults(group: SearchResultGroup): SearchResultItem[] {\n if (this.IsGroupExpanded(group.SourceType)) {\n return group.Results;\n }\n return group.Results.slice(0, this.MaxPerGroup);\n }\n\n /** Whether a group has more results than shown */\n public HasMoreResults(group: SearchResultGroup): boolean {\n return group.Results.length > this.MaxPerGroup && !this.IsGroupExpanded(group.SourceType);\n }\n\n /** Get the count of hidden results */\n public GetHiddenCount(group: SearchResultGroup): number {\n return group.Results.length - this.MaxPerGroup;\n }\n\n /** Handle clicking a result */\n public OnResultClick(result: SearchResultItem, event: MouseEvent): void {\n this.ResultSelected.emit({\n Result: result,\n OpenInNewTab: event.metaKey || event.ctrlKey\n });\n }\n\n /** Toggle expand/collapse of a result card — multiple can be open */\n public ToggleExpand(result: SearchResultItem, event?: MouseEvent): void {\n if (event) event.stopPropagation();\n if (this.ExpandedResultIDs.has(result.ID)) {\n this.ExpandedResultIDs.delete(result.ID);\n } else {\n this.ExpandedResultIDs.add(result.ID);\n }\n this.cdr.detectChanges();\n }\n\n /** Check if a result card is expanded */\n public IsExpanded(resultID: string): boolean {\n return this.ExpandedResultIDs.has(resultID);\n }\n\n /** Handle \"Open Record\" button click */\n public OnOpenRecord(result: SearchResultItem, event: MouseEvent): void {\n event.stopPropagation();\n this.OpenRecordRequested.emit(result);\n }\n\n /** Handle \"See Similar Items\" button click — emits the result for a \"more like this\" search */\n public OnMoreLikeThis(result: SearchResultItem, event: MouseEvent): void {\n event.stopPropagation();\n this.MoreLikeThisRequested.emit(result);\n }\n\n /**\n * Wrap substrings matching HighlightText in <mark> tags for visual emphasis.\n * The input is regex-escaped so user text is treated as a literal string.\n */\n public HighlightMatch(text: string): string {\n if (!text) return text;\n const safeText = EscapeHTML(text);\n if (!this.HighlightText) return safeText;\n\n const safeHighlightText = EscapeHTML(this.HighlightText);\n const escaped = safeHighlightText.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regex = new RegExp(`(${escaped})`, 'gi');\n return safeText.replace(regex, '<mark class=\"search-highlight\">$1</mark>');\n }\n\n /** Format a score as a percentage */\n public FormatScore(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Format elapsed time */\n public FormatTime(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n return `${(ms / 1000).toFixed(1)}s`;\n }\n\n /** Resolved link cache per result ID */\n private resolvedLinksCache = new Map<string, { Value: string; Label: string; Type: 'URL' | 'Email' }[]>();\n\n /**\n * Resolve URL and Email fields from the result's RawMetadata using entity ExtendedType metadata.\n * Returns clickable link entries with proper type classification.\n */\n public GetResolvedLinks(result: SearchResultItem): { Value: string; Label: string; Type: 'URL' | 'Email' }[] {\n if (this.resolvedLinksCache.has(result.ID)) {\n return this.resolvedLinksCache.get(result.ID)!;\n }\n\n const links: { Value: string; Label: string; Type: 'URL' | 'Email' }[] = [];\n\n if (result.RawMetadata) {\n try {\n const meta = JSON.parse(result.RawMetadata) as Record<string, unknown>;\n const linkFields = this.GetLinkFields(result.EntityName);\n\n for (const field of linkFields) {\n const value = meta[field.Name];\n if (value && typeof value === 'string' && value.trim().length > 0) {\n links.push({\n Value: value,\n Label: field.DisplayName,\n Type: field.Type\n });\n }\n }\n } catch { /* ignore parse errors */ }\n }\n\n // Fallback: extract URLs from snippet if no ExtendedType fields found\n if (links.length === 0) {\n const urls = this.ExtractUrls(result.Snippet);\n for (const url of urls) {\n links.push({ Value: url, Label: '', Type: 'URL' });\n }\n }\n\n this.resolvedLinksCache.set(result.ID, links);\n return links;\n }\n\n /** Extract URLs from snippet text */\n public ExtractUrls(snippet: string): string[] {\n if (!snippet) return [];\n const urlRegex = /https?:\\/\\/[^\\s,;)>\"']+/g;\n const matches = snippet.match(urlRegex);\n return matches ? [...new Set(matches)] : [];\n }\n\n /** Truncate a URL for display */\n public TruncateUrl(url: string): string {\n try {\n const parsed = new URL(url);\n const path = parsed.pathname.length > 30\n ? parsed.pathname.substring(0, 30) + '...'\n : parsed.pathname;\n return parsed.hostname + path;\n } catch {\n return url.length > 50 ? url.substring(0, 50) + '...' : url;\n }\n }\n\n /** Cache of URL/Email field info per entity name */\n private linkFieldsCache = new Map<string, { Name: string; DisplayName: string; Type: 'URL' | 'Email' }[]>();\n\n /**\n * Get URL and Email fields for an entity using ExtendedType from entity metadata.\n * Returns fields with ExtendedType='URL' or ExtendedType='Email'.\n */\n public GetLinkFields(entityName: string): { Name: string; DisplayName: string; Type: 'URL' | 'Email' }[] {\n if (this.linkFieldsCache.has(entityName)) {\n return this.linkFieldsCache.get(entityName)!;\n }\n\n try {\n const md = this.ProviderToUse;\n const entityInfo = md.Entities.find(e => e.Name === entityName);\n if (!entityInfo) {\n this.linkFieldsCache.set(entityName, []);\n return [];\n }\n\n const linkFields = entityInfo.Fields\n .filter(f => f.ExtendedType === 'URL' || f.ExtendedType === 'Email')\n .map(f => ({\n Name: f.Name,\n DisplayName: f.DisplayNameOrName,\n Type: f.ExtendedType as 'URL' | 'Email'\n }));\n\n this.linkFieldsCache.set(entityName, linkFields);\n return linkFields;\n } catch {\n this.linkFieldsCache.set(entityName, []);\n return [];\n }\n }\n}\n","@if (IsLoading) {\n <div class=\"results-loading\">\n <mj-loading text=\"Searching...\" size=\"medium\"></mj-loading>\n </div>\n} @else if ((DisplayMode === 'flat' ? FlatResults.length : ResultGroups.length) === 0 && TotalCount === 0) {\n <div class=\"results-empty\">\n <i class=\"fa-solid fa-search results-empty-icon\"></i>\n <p class=\"results-empty-text\">No results to display</p>\n </div>\n} @else {\n <!-- Results summary -->\n @if (ShowSummary) {\n <div class=\"results-summary\">\n <span>{{ TotalCount }} results</span>\n @if (ElapsedMs > 0) {\n <span class=\"results-summary-time\"> in {{ FormatTime(ElapsedMs) }}</span>\n }\n </div>\n }\n\n @if (DisplayMode === 'flat') {\n <!-- ══════ FLAT BLENDED LIST (sorted by score) ══════ -->\n <div class=\"results-scroll-area\">\n @for (result of PagedResults; track result.ID) {\n <ng-container *ngTemplateOutlet=\"resultCardTpl; context: { $implicit: result }\"></ng-container>\n }\n </div>\n\n <!-- Google-style pagination (sticky at bottom) -->\n @if (TotalPages > 1) {\n <div class=\"results-pager\">\n <button class=\"pager-btn pager-prev\" [disabled]=\"CurrentPage === 1\"\n (click)=\"GoToPage(CurrentPage - 1)\" aria-label=\"Previous page\">\n <i class=\"fa-solid fa-chevron-left\"></i>\n </button>\n @for (p of PageNumbers; track $index) {\n @if (p === -1) {\n <span class=\"pager-ellipsis\">...</span>\n } @else {\n <button class=\"pager-btn pager-num\" [class.pager-active]=\"p === CurrentPage\"\n (click)=\"GoToPage(p)\">{{ p }}</button>\n }\n }\n <button class=\"pager-btn pager-next\" [disabled]=\"CurrentPage === TotalPages\"\n (click)=\"GoToPage(CurrentPage + 1)\" aria-label=\"Next page\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n }\n } @else {\n <!-- ══════ GROUPED BY SOURCE TYPE ══════ -->\n @for (group of ResultGroups; track group.SourceType) {\n <div class=\"results-group\">\n <div class=\"results-group-header\" (click)=\"ToggleGroup(group.SourceType)\">\n @if (ShowSourceIcons) {\n <i [class]=\"group.Icon + ' results-group-icon'\"></i>\n }\n <span class=\"results-group-label\">{{ group.Label }}</span>\n <span class=\"results-group-count\">({{ group.TotalCount }})</span>\n <i class=\"fa-solid results-group-chevron\"\n [class.fa-chevron-down]=\"!IsGroupExpanded(group.SourceType)\"\n [class.fa-chevron-up]=\"IsGroupExpanded(group.SourceType)\"></i>\n </div>\n\n @for (result of GetVisibleResults(group); track result.ID) {\n <ng-container *ngTemplateOutlet=\"resultCardTpl; context: { $implicit: result }\"></ng-container>\n }\n\n @if (HasMoreResults(group)) {\n <button class=\"results-show-more\" (click)=\"ToggleGroup(group.SourceType)\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n Show {{ GetHiddenCount(group) }} more results\n </button>\n }\n </div>\n }\n }\n}\n\n<!-- ═══ Shared result card template ═══ -->\n<ng-template #resultCardTpl let-result>\n <div class=\"result-card\" [class.result-card-expanded]=\"IsExpanded(result.ID)\">\n <!-- Main row -->\n <div class=\"result-card-main\" (click)=\"ToggleExpand(result)\">\n <div class=\"result-card-icon-wrap\">\n <i [class]=\"result.EntityIcon || result.SourceIcon || 'fa-solid fa-database'\"></i>\n </div>\n <div class=\"result-card-body\">\n <div class=\"result-card-title\" [innerHTML]=\"HighlightMatch(result.RecordName || result.Title)\"></div>\n <div class=\"result-card-entity\" [innerHTML]=\"HighlightMatch(result.EntityName)\"></div>\n @if (result.Tags && result.Tags.length > 0) {\n <div class=\"result-card-tags\">\n @for (tag of result.Tags.slice(0, 5); track tag) {\n <span class=\"result-tag-chip\" [innerHTML]=\"HighlightMatch(tag)\"></span>\n }\n @if (result.Tags.length > 5) {\n <span class=\"result-tag-more\">+{{ result.Tags.length - 5 }}</span>\n }\n </div>\n }\n </div>\n @if (ShowScores) {\n <div class=\"result-card-score\">\n <div class=\"score-circle\" [class.score-high]=\"result.Score >= 0.40\" [class.score-medium]=\"result.Score >= 0.15 && result.Score < 0.40\" [class.score-low]=\"result.Score < 0.15\">\n <span class=\"score-value\">{{ FormatScore(result.Score) }}</span>\n </div>\n </div>\n }\n <div class=\"result-card-actions\">\n <button class=\"result-open-btn\" (click)=\"OnOpenRecord(result, $event)\"\n [title]=\"result.ResultType === 'storage-file' ? 'Open file' : 'Open record'\"\n [attr.aria-label]=\"result.ResultType === 'storage-file' ? 'Open file' : 'Open record'\">\n <i [class]=\"result.ResultType === 'storage-file' ? 'fa-solid fa-external-link' : 'fa-solid fa-arrow-up-right-from-square'\"></i>\n </button>\n <button class=\"result-expand-btn\" (click)=\"ToggleExpand(result, $event)\" title=\"Expand details\" aria-label=\"Expand details\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!IsExpanded(result.ID)\"\n [class.fa-chevron-up]=\"IsExpanded(result.ID)\"></i>\n </button>\n </div>\n </div>\n\n <!-- Expanded detail -->\n @if (IsExpanded(result.ID)) {\n <div class=\"result-card-detail\">\n @if (result.Snippet) {\n <div class=\"detail-section\">\n <span class=\"detail-label\">Preview</span>\n <p class=\"detail-snippet\" [innerHTML]=\"HighlightMatch(result.Snippet)\"></p>\n </div>\n }\n <div class=\"detail-meta\">\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-layer-group\"></i>\n <span>{{ result.EntityName }}</span>\n </div>\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-fingerprint\"></i>\n <span class=\"detail-record-id\">{{ result.RecordID }}</span>\n </div>\n <!-- SR-1: Show overall score consistently -->\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-signal\"></i>\n <span>Relevance: {{ FormatScore(result.Score) }}</span>\n </div>\n @if (result.ScoreBreakdown) {\n <div class=\"detail-meta-item\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n <span>\n @if (result.ScoreBreakdown.Vector) { Vector: {{ FormatScore(result.ScoreBreakdown.Vector) }} }\n @if (result.ScoreBreakdown.FullText) { FTS: {{ FormatScore(result.ScoreBreakdown.FullText) }} }\n </span>\n </div>\n }\n </div>\n @if (ShowTags && result.Tags.length > 0) {\n <div class=\"detail-tags\">\n @for (tag of result.Tags; track tag) {\n <span class=\"result-card-tag\" [innerHTML]=\"HighlightMatch(tag)\"></span>\n }\n </div>\n }\n @if (GetResolvedLinks(result).length > 0) {\n <div class=\"detail-links\">\n @for (link of GetResolvedLinks(result); track link.Value) {\n @if (link.Type === 'URL') {\n <a [href]=\"link.Value\" target=\"_blank\" class=\"detail-link\" (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i>\n {{ TruncateUrl(link.Value) }}\n </a>\n } @else if (link.Type === 'Email') {\n <a [href]=\"'mailto:' + link.Value\" class=\"detail-link detail-link-email\" (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-envelope\"></i>\n {{ link.Value }}\n </a>\n }\n }\n </div>\n }\n <div class=\"detail-actions\">\n <button class=\"detail-open-btn\" (click)=\"OnOpenRecord(result, $event)\">\n @if (result.ResultType === 'storage-file') {\n <i class=\"fa-solid fa-external-link\"></i> Open File\n } @else {\n <i class=\"fa-solid fa-arrow-up-right-from-square\"></i> Open Record\n }\n </button>\n <button class=\"detail-similar-btn\" (click)=\"OnMoreLikeThis(result, $event)\">\n <i class=\"fa-solid fa-shuffle\"></i> See Similar Items\n </button>\n </div>\n </div>\n }\n </div>\n</ng-template>\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
2
|
+
import { IMetadataProvider } from '@memberjunction/core';
|
|
2
3
|
import { SearchRequest, SearchResponse, SearchResultItem, SearchResultGroup, SearchFilter } from './search-types';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
5
|
/** Recent search entry for history */
|
|
@@ -7,7 +8,14 @@ export interface RecentSearch {
|
|
|
7
8
|
Timestamp: Date;
|
|
8
9
|
ResultCount: number;
|
|
9
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Multi-provider note: callers under a non-default provider should set
|
|
13
|
+
* `service.Provider = component.ProviderToUse` before invoking any methods.
|
|
14
|
+
*/
|
|
10
15
|
export declare class SearchService {
|
|
16
|
+
private _provider;
|
|
17
|
+
get Provider(): IMetadataProvider;
|
|
18
|
+
set Provider(value: IMetadataProvider | null);
|
|
11
19
|
/** Current search response */
|
|
12
20
|
SearchResults$: BehaviorSubject<SearchResponse | null>;
|
|
13
21
|
/** Whether a search is in progress */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.service.d.ts","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"search.service.d.ts","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAA4B,MAAM,sBAAsB,CAAC;AASnF,OAAO,EACH,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EAGf,MAAM,gBAAgB,CAAC;;AA8BxB,sCAAsC;AACtC,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACvB;AASD;;;GAGG;AACH,qBACa,aAAa;IACtB,OAAO,CAAC,SAAS,CAAkC;IACnD,IAAW,QAAQ,IAAI,iBAAiB,CAEvC;IACD,IAAW,QAAQ,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,EAElD;IAED,8BAA8B;IACvB,cAAc,yCAAoD;IAEzE,sCAAsC;IAC/B,YAAY,2BAAuC;IAE1D,2EAA2E;IACpE,eAAe,kCAA2C;IAEjE,mBAAmB;IACZ,OAAO,kBAAyB;IAEvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAM;IACxC,OAAO,CAAC,oBAAoB,CAAS;IAErC,oFAAoF;IACpF,OAAO,CAAC,qBAAqB,CAAyC;IAEtE;;OAEG;IACU,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAuB3E;;;;OAIG;IACU,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,GAAE,MAAU,GAAG,OAAO,CAAC,cAAc,CAAC;IAoB1F,uCAAuC;IAChC,YAAY,IAAI,IAAI;IAI3B,yDAAyD;IAClD,mBAAmB,IAAI,IAAI;IAKlC;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,iBAAiB,EAAE;IA0BrE;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,YAAY,EAAE;IAShE,2CAA2C;IACpC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAIhD,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,qBAAqB;IAkC7B,OAAO,CAAC,mBAAmB;IAqB3B,OAAO,CAAC,cAAc;IAoBtB;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BhD,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,qBAAqB;IAa7B,iFAAiF;IACjF,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,mBAAmB;IAc3B;;OAEG;YACW,oBAAoB;IAwBlC,wFAAwF;IACxF,OAAO,CAAC,iCAAiC;IAsCzC,gEAAgE;IAChE,OAAO,CAAC,mBAAmB;IAuB3B,6DAA6D;IAC7D,OAAO,CAAC,kBAAkB;yCA7YjB,aAAa;6CAAb,aAAa;CAqazB"}
|
|
@@ -35,7 +35,18 @@ const FALLBACK_SOURCE_LABELS = {
|
|
|
35
35
|
};
|
|
36
36
|
/** User setting key for persisting recent searches */
|
|
37
37
|
const RECENT_SEARCHES_KEY = 'search.recentSearches';
|
|
38
|
+
/**
|
|
39
|
+
* Multi-provider note: callers under a non-default provider should set
|
|
40
|
+
* `service.Provider = component.ProviderToUse` before invoking any methods.
|
|
41
|
+
*/
|
|
38
42
|
export class SearchService {
|
|
43
|
+
_provider = null;
|
|
44
|
+
get Provider() {
|
|
45
|
+
return this._provider ?? Metadata.Provider;
|
|
46
|
+
}
|
|
47
|
+
set Provider(value) {
|
|
48
|
+
this._provider = value;
|
|
49
|
+
}
|
|
39
50
|
/** Current search response */
|
|
40
51
|
SearchResults$ = new BehaviorSubject(null);
|
|
41
52
|
/** Whether a search is in progress */
|
|
@@ -82,7 +93,7 @@ export class SearchService {
|
|
|
82
93
|
if (!query.trim()) {
|
|
83
94
|
return this.createEmptyResponse();
|
|
84
95
|
}
|
|
85
|
-
const provider =
|
|
96
|
+
const provider = this.Provider;
|
|
86
97
|
if (!(provider instanceof GraphQLDataProvider)) {
|
|
87
98
|
return this.createEmptyResponse('GraphQL provider not available');
|
|
88
99
|
}
|
|
@@ -247,9 +258,7 @@ export class SearchService {
|
|
|
247
258
|
if (event.event === MJEventType.LoggedIn) {
|
|
248
259
|
await StartupManager.Instance.Startup();
|
|
249
260
|
const engine = UserInfoEngine.Instance;
|
|
250
|
-
console.log('[SearchService] After Startup — engine.Loaded:', engine.Loaded, 'UserSettings count:', engine.UserSettings.length);
|
|
251
261
|
const json = engine.GetSetting(RECENT_SEARCHES_KEY);
|
|
252
|
-
console.log('[SearchService] GetSetting("' + RECENT_SEARCHES_KEY + '"):', json?.substring(0, 100));
|
|
253
262
|
if (json) {
|
|
254
263
|
const parsed = JSON.parse(json);
|
|
255
264
|
const searches = parsed.map(s => ({
|
|
@@ -316,7 +325,7 @@ export class SearchService {
|
|
|
316
325
|
if (!request.Query.trim()) {
|
|
317
326
|
return this.createEmptyResponse();
|
|
318
327
|
}
|
|
319
|
-
const provider =
|
|
328
|
+
const provider = this.Provider;
|
|
320
329
|
if (!(provider instanceof GraphQLDataProvider)) {
|
|
321
330
|
return this.createEmptyResponse('GraphQL provider not available');
|
|
322
331
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.service.js","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search service that connects to the UnifiedSearchService via GraphQL.\n *\n * Provides a reactive interface for executing searches, managing search history,\n * and transforming raw search responses into display-ready grouped results.\n */\n\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport { Metadata, StartupManager } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { MJEventType, MJGlobal } from '@memberjunction/global';\nimport {\n GraphQLSearchClient,\n GraphQLDataProvider,\n SearchClientResponse,\n SearchClientResultItem\n} from '@memberjunction/graphql-dataprovider';\nimport {\n SearchRequest,\n SearchResponse,\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchFilterOption,\n SearchProviderInfo\n} from './search-types';\n\n/** Default minimum relevance score threshold (0-1). Results below this are filtered out. */\nconst DEFAULT_MIN_SCORE = 0.35;\n\n/** Fallback icon mapping for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_ICONS: Record<string, string> = {\n 'entity': 'fa-solid fa-database',\n 'vector': 'fa-solid fa-brain',\n 'fulltext': 'fa-solid fa-magnifying-glass',\n 'content-item': 'fa-solid fa-file-lines',\n 'file': 'fa-solid fa-file',\n 'web-page': 'fa-solid fa-globe',\n 'storage': 'fa-solid fa-folder-open',\n};\n\n/** Fallback labels for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_LABELS: Record<string, string> = {\n 'entity': 'Database',\n 'vector': 'Semantic Search',\n 'fulltext': 'Full-Text Search',\n 'content-item': 'Content Items',\n 'file': 'Documents',\n 'web-page': 'Web Pages',\n 'storage': 'File Storage',\n};\n\n/** User setting key for persisting recent searches */\nconst RECENT_SEARCHES_KEY = 'search.recentSearches';\n\n/** Recent search entry for history */\nexport interface RecentSearch {\n Query: string;\n Timestamp: Date;\n ResultCount: number;\n}\n\n/** JSON-safe shape for persistence (Date → ISO string) */\ninterface RecentSearchJson {\n Query: string;\n Timestamp: string;\n ResultCount: number;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class SearchService {\n /** Current search response */\n public SearchResults$ = new BehaviorSubject<SearchResponse | null>(null);\n\n /** Whether a search is in progress */\n public IsSearching$ = new BehaviorSubject<boolean>(false);\n\n /** Recent search history (persisted via UserInfoEngine, max 20 entries) */\n public RecentSearches$ = new BehaviorSubject<RecentSearch[]>([]);\n\n /** Error stream */\n public Errors$ = new Subject<string>();\n\n private readonly maxRecentSearches = 20;\n private recentSearchesLoaded = false;\n\n /** Cached provider metadata keyed by SourceType, populated from search responses */\n private providersBySourceType = new Map<string, SearchProviderInfo>();\n\n /**\n * Execute a search request via the SearchKnowledge GraphQL mutation.\n */\n public async ExecuteSearch(request: SearchRequest): Promise<SearchResponse> {\n this.IsSearching$.next(true);\n const startTime = Date.now();\n\n try {\n const response = await this.executeGraphQLSearch(request);\n response.ElapsedMs = Date.now() - startTime;\n\n this.SearchResults$.next(response);\n this.addToRecentSearches(request.Query, response.TotalCount);\n\n return response;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Search failed';\n this.Errors$.next(errorMessage);\n const errorResponse = this.createEmptyResponse(errorMessage);\n this.SearchResults$.next(errorResponse);\n return errorResponse;\n } finally {\n this.IsSearching$.next(false);\n }\n }\n\n /**\n * Lightweight preview search for autocomplete/typeahead.\n * Does NOT update SearchResults$ or IsSearching$ observables,\n * and does NOT add to recent search history.\n */\n public async PreviewSearch(query: string, maxResults: number = 8): Promise<SearchResponse> {\n try {\n if (!query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = Metadata.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const clientResponse = await client.PreviewSearch(query, maxResults);\n return this.mapClientResponseToSearchResponse(clientResponse);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Preview search failed';\n return this.createEmptyResponse(errorMessage);\n }\n }\n\n /** Clear the current search results */\n public ClearResults(): void {\n this.SearchResults$.next(null);\n }\n\n /** Clear recent search history (memory and persisted) */\n public ClearRecentSearches(): void {\n this.RecentSearches$.next([]);\n this.persistRecentSearches([]);\n }\n\n /**\n * Group flat results by source type for display.\n */\n public GroupResults(results: SearchResultItem[]): SearchResultGroup[] {\n const groupMap = new Map<string, SearchResultItem[]>();\n\n for (const result of results) {\n const key = result.SourceType;\n const existing = groupMap.get(key);\n if (existing) {\n existing.push(result);\n } else {\n groupMap.set(key, [result]);\n }\n }\n\n return Array.from(groupMap.entries()).map(([sourceType, items]) => {\n // Priority: cached provider metadata > per-result metadata > fallback maps\n const cached = this.providersBySourceType.get(sourceType);\n return {\n Label: cached?.DisplayName ?? items[0]?.ProviderLabel ?? FALLBACK_SOURCE_LABELS[sourceType] ?? sourceType,\n Icon: cached?.Icon ?? items[0]?.ProviderIcon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle',\n SourceType: sourceType,\n Results: items,\n TotalCount: items.length\n };\n });\n }\n\n /**\n * Build filter facets from a set of results.\n */\n public BuildFilters(results: SearchResultItem[]): SearchFilter[] {\n return [\n this.buildSourceTypeFilter(results),\n this.buildEntityNameFilter(results),\n this.buildFileTypeFilter(results),\n this.buildTagFilter(results)\n ].filter(f => f.Options.length > 0); // Hide categories with no options\n }\n\n /** Get the icon for a given source type */\n public GetSourceIcon(sourceType: string): string {\n return this.providersBySourceType.get(sourceType)?.Icon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle';\n }\n\n private buildSourceTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n counts.set(r.SourceType, (counts.get(r.SourceType) ?? 0) + 1);\n }\n const options: SearchFilterOption[] = Array.from(counts.entries()).map(([type, count]) => {\n const cached = this.providersBySourceType.get(type);\n return {\n Label: cached?.DisplayName ?? FALLBACK_SOURCE_LABELS[type] ?? type,\n Value: type,\n Count: count,\n IsSelected: false,\n Icon: cached?.Icon ?? FALLBACK_SOURCE_ICONS[type]\n };\n });\n return { Category: 'Source', Options: options, MultiSelect: true };\n }\n\n private buildEntityNameFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n let fileCount = 0;\n for (const r of results) {\n if (r.ResultType === 'storage-file') {\n fileCount++;\n } else {\n counts.set(r.EntityName, (counts.get(r.EntityName) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([name, count]) => ({\n Label: name,\n Value: name,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-table'\n }));\n\n // Add a single \"Files\" entry for all storage file results\n if (fileCount > 0) {\n options.push({\n Label: 'Files',\n Value: '__storage-files__',\n Count: fileCount,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n });\n }\n\n return { Category: 'Entity', Options: options, MultiSelect: true };\n }\n\n private buildFileTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n if (r.ResultType !== 'storage-file') continue;\n const ext = r.Title?.split('.').pop()?.toUpperCase();\n if (ext && ext.length <= 6) {\n counts.set(ext, (counts.get(ext) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([ext, count]) => ({\n Label: ext,\n Value: ext,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n }));\n return { Category: 'File Type', Options: options, MultiSelect: true };\n }\n\n private buildTagFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n for (const tag of r.Tags) {\n counts.set(tag, (counts.get(tag) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15)\n .map(([tag, count]) => ({\n Label: tag,\n Value: tag,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-tag'\n }));\n return { Category: 'Tags', Options: options, MultiSelect: true };\n }\n\n /**\n * Load persisted recent searches from UserInfoEngine.\n * Safe to call multiple times — only loads once.\n */\n public async LoadRecentSearches(): Promise<void> {\n if (this.recentSearchesLoaded) return;\n\n try {\n MJGlobal.Instance.GetEventListener(true).subscribe(async (event) => {\n if (event.event === MJEventType.LoggedIn) {\n await StartupManager.Instance.Startup();\n\n const engine = UserInfoEngine.Instance;\n console.log('[SearchService] After Startup — engine.Loaded:', engine.Loaded, 'UserSettings count:', engine.UserSettings.length);\n\n const json = engine.GetSetting(RECENT_SEARCHES_KEY);\n console.log('[SearchService] GetSetting(\"' + RECENT_SEARCHES_KEY + '\"):', json?.substring(0, 100));\n\n if (json) {\n const parsed = JSON.parse(json) as RecentSearchJson[];\n const searches: RecentSearch[] = parsed.map(s => ({\n Query: s.Query,\n Timestamp: new Date(s.Timestamp),\n ResultCount: s.ResultCount\n }));\n this.RecentSearches$.next(searches);\n }\n }\n });\n } catch (err) {\n console.error('[SearchService] LoadRecentSearches error:', err);\n }\n this.recentSearchesLoaded = true;\n }\n\n private addToRecentSearches(query: string, resultCount: number): void {\n const current = this.RecentSearches$.value;\n const filtered = current.filter(s => s.Query !== query);\n const updated = [\n { Query: query, Timestamp: new Date(), ResultCount: resultCount },\n ...filtered\n ].slice(0, this.maxRecentSearches);\n this.RecentSearches$.next(updated);\n this.persistRecentSearches(updated);\n }\n\n private persistRecentSearches(searches: RecentSearch[]): void {\n try {\n const json: RecentSearchJson[] = searches.map(s => ({\n Query: s.Query,\n Timestamp: s.Timestamp.toISOString(),\n ResultCount: s.ResultCount\n }));\n UserInfoEngine.Instance.SetSettingDebounced(RECENT_SEARCHES_KEY, JSON.stringify(json));\n } catch {\n // Silently fail if UserInfoEngine not available\n }\n }\n\n /** Cache provider metadata by SourceType for use in GroupResults/BuildFilters */\n private cacheProviders(providers: SearchProviderInfo[]): void {\n for (const p of providers) {\n this.providersBySourceType.set(p.SourceType, p);\n }\n }\n\n private createEmptyResponse(errorMessage?: string): SearchResponse {\n return {\n Success: !errorMessage,\n Results: [],\n Groups: [],\n Filters: [],\n TotalCount: 0,\n ElapsedMs: 0,\n SourceCounts: { Vector: 0, FullText: 0, Entity: 0, Storage: 0 },\n Providers: [],\n ErrorMessage: errorMessage\n };\n }\n\n /**\n * Execute search via the GraphQLSearchClient.\n */\n private async executeGraphQLSearch(request: SearchRequest): Promise<SearchResponse> {\n if (!request.Query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = Metadata.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const filters = this.buildClientFilters(request);\n const minScore = request.MinScore ?? DEFAULT_MIN_SCORE;\n\n const clientResponse = await client.ExecuteSearch({\n Query: request.Query,\n MaxResults: request.MaxResults || 20,\n MinScore: minScore > 0 ? minScore : undefined,\n Filters: filters\n });\n\n return this.mapClientResponseToSearchResponse(clientResponse);\n }\n\n /** Convert a SearchClientResponse into the SearchResponse shape used by this service */\n private mapClientResponseToSearchResponse(clientResponse: SearchClientResponse): SearchResponse {\n if (!clientResponse.Success) {\n return this.createEmptyResponse(clientResponse.ErrorMessage ?? 'Search failed');\n }\n\n // Cache provider metadata for use in GroupResults/BuildFilters\n const providers: SearchProviderInfo[] = (clientResponse.Providers ?? []).map(p => ({\n ID: p.ID,\n Name: p.Name,\n DisplayName: p.DisplayName,\n Icon: p.Icon,\n SourceType: p.SourceType,\n Priority: p.Priority,\n }));\n this.cacheProviders(providers);\n\n const results: SearchResultItem[] = (clientResponse.Results ?? []).map(r => this.mapClientResultItem(r));\n\n const groups = this.GroupResults(results);\n const filters = this.BuildFilters(results);\n\n return {\n Success: true,\n Results: results,\n Groups: groups,\n Filters: filters,\n TotalCount: clientResponse.TotalCount,\n ElapsedMs: clientResponse.ElapsedMs,\n SourceCounts: {\n Vector: clientResponse.SourceCounts.Vector,\n FullText: clientResponse.SourceCounts.FullText,\n Entity: clientResponse.SourceCounts.Entity,\n Storage: clientResponse.SourceCounts.Storage\n },\n Providers: providers,\n };\n }\n\n /** Map a single SearchClientResultItem to a SearchResultItem */\n private mapClientResultItem(r: SearchClientResultItem): SearchResultItem {\n return {\n ID: r.ID,\n Title: r.RecordName || r.Title,\n Snippet: r.Snippet,\n EntityName: r.EntityName,\n RecordID: r.RecordID,\n SourceType: (r.SourceType as SearchResultItem['SourceType']) || 'entity',\n ResultType: r.ResultType,\n Score: r.Score,\n ScoreBreakdown: r.ScoreBreakdown ?? {},\n Tags: r.Tags ?? [],\n SourceIcon: r.EntityIcon || r.ProviderIcon || FALLBACK_SOURCE_ICONS[r.SourceType] || 'fa-solid fa-database',\n EntityIcon: r.EntityIcon,\n RecordName: r.RecordName,\n MatchedAt: new Date(r.MatchedAt),\n RawMetadata: r.RawMetadata,\n ProviderId: r.ProviderId,\n ProviderLabel: r.ProviderLabel,\n ProviderIcon: r.ProviderIcon,\n };\n }\n\n /** Build the client filters from active filter selections */\n private buildClientFilters(request: SearchRequest): { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } | undefined {\n if (!request.ActiveFilters || Object.keys(request.ActiveFilters).length === 0) {\n return undefined;\n }\n\n const result: { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } = {};\n\n const entityFilters = request.ActiveFilters['Entity'];\n if (entityFilters?.length) {\n result.EntityNames = entityFilters;\n }\n\n const sourceFilters = request.ActiveFilters['Source'];\n if (sourceFilters?.length) {\n result.SourceTypes = sourceFilters;\n }\n\n const tagFilters = request.ActiveFilters['Tags'];\n if (tagFilters?.length) {\n result.Tags = tagFilters;\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"search.service.js","sourceRoot":"","sources":["../../src/lib/search.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search service that connects to the UnifiedSearchService via GraphQL.\n *\n * Provides a reactive interface for executing searches, managing search history,\n * and transforming raw search responses into display-ready grouped results.\n */\n\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport { IMetadataProvider, Metadata, StartupManager } from '@memberjunction/core';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { MJEventType, MJGlobal } from '@memberjunction/global';\nimport {\n GraphQLSearchClient,\n GraphQLDataProvider,\n SearchClientResponse,\n SearchClientResultItem\n} from '@memberjunction/graphql-dataprovider';\nimport {\n SearchRequest,\n SearchResponse,\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchFilterOption,\n SearchProviderInfo\n} from './search-types';\n\n/** Default minimum relevance score threshold (0-1). Results below this are filtered out. */\nconst DEFAULT_MIN_SCORE = 0.35;\n\n/** Fallback icon mapping for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_ICONS: Record<string, string> = {\n 'entity': 'fa-solid fa-database',\n 'vector': 'fa-solid fa-brain',\n 'fulltext': 'fa-solid fa-magnifying-glass',\n 'content-item': 'fa-solid fa-file-lines',\n 'file': 'fa-solid fa-file',\n 'web-page': 'fa-solid fa-globe',\n 'storage': 'fa-solid fa-folder-open',\n};\n\n/** Fallback labels for source types (used when provider metadata is not available) */\nconst FALLBACK_SOURCE_LABELS: Record<string, string> = {\n 'entity': 'Database',\n 'vector': 'Semantic Search',\n 'fulltext': 'Full-Text Search',\n 'content-item': 'Content Items',\n 'file': 'Documents',\n 'web-page': 'Web Pages',\n 'storage': 'File Storage',\n};\n\n/** User setting key for persisting recent searches */\nconst RECENT_SEARCHES_KEY = 'search.recentSearches';\n\n/** Recent search entry for history */\nexport interface RecentSearch {\n Query: string;\n Timestamp: Date;\n ResultCount: number;\n}\n\n/** JSON-safe shape for persistence (Date → ISO string) */\ninterface RecentSearchJson {\n Query: string;\n Timestamp: string;\n ResultCount: number;\n}\n\n/**\n * Multi-provider note: callers under a non-default provider should set\n * `service.Provider = component.ProviderToUse` before invoking any methods.\n */\n@Injectable({ providedIn: 'root' })\nexport class SearchService {\n private _provider: IMetadataProvider | null = null;\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n /** Current search response */\n public SearchResults$ = new BehaviorSubject<SearchResponse | null>(null);\n\n /** Whether a search is in progress */\n public IsSearching$ = new BehaviorSubject<boolean>(false);\n\n /** Recent search history (persisted via UserInfoEngine, max 20 entries) */\n public RecentSearches$ = new BehaviorSubject<RecentSearch[]>([]);\n\n /** Error stream */\n public Errors$ = new Subject<string>();\n\n private readonly maxRecentSearches = 20;\n private recentSearchesLoaded = false;\n\n /** Cached provider metadata keyed by SourceType, populated from search responses */\n private providersBySourceType = new Map<string, SearchProviderInfo>();\n\n /**\n * Execute a search request via the SearchKnowledge GraphQL mutation.\n */\n public async ExecuteSearch(request: SearchRequest): Promise<SearchResponse> {\n this.IsSearching$.next(true);\n const startTime = Date.now();\n\n try {\n const response = await this.executeGraphQLSearch(request);\n response.ElapsedMs = Date.now() - startTime;\n\n this.SearchResults$.next(response);\n this.addToRecentSearches(request.Query, response.TotalCount);\n\n return response;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Search failed';\n this.Errors$.next(errorMessage);\n const errorResponse = this.createEmptyResponse(errorMessage);\n this.SearchResults$.next(errorResponse);\n return errorResponse;\n } finally {\n this.IsSearching$.next(false);\n }\n }\n\n /**\n * Lightweight preview search for autocomplete/typeahead.\n * Does NOT update SearchResults$ or IsSearching$ observables,\n * and does NOT add to recent search history.\n */\n public async PreviewSearch(query: string, maxResults: number = 8): Promise<SearchResponse> {\n try {\n if (!query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = this.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const clientResponse = await client.PreviewSearch(query, maxResults);\n return this.mapClientResponseToSearchResponse(clientResponse);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Preview search failed';\n return this.createEmptyResponse(errorMessage);\n }\n }\n\n /** Clear the current search results */\n public ClearResults(): void {\n this.SearchResults$.next(null);\n }\n\n /** Clear recent search history (memory and persisted) */\n public ClearRecentSearches(): void {\n this.RecentSearches$.next([]);\n this.persistRecentSearches([]);\n }\n\n /**\n * Group flat results by source type for display.\n */\n public GroupResults(results: SearchResultItem[]): SearchResultGroup[] {\n const groupMap = new Map<string, SearchResultItem[]>();\n\n for (const result of results) {\n const key = result.SourceType;\n const existing = groupMap.get(key);\n if (existing) {\n existing.push(result);\n } else {\n groupMap.set(key, [result]);\n }\n }\n\n return Array.from(groupMap.entries()).map(([sourceType, items]) => {\n // Priority: cached provider metadata > per-result metadata > fallback maps\n const cached = this.providersBySourceType.get(sourceType);\n return {\n Label: cached?.DisplayName ?? items[0]?.ProviderLabel ?? FALLBACK_SOURCE_LABELS[sourceType] ?? sourceType,\n Icon: cached?.Icon ?? items[0]?.ProviderIcon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle',\n SourceType: sourceType,\n Results: items,\n TotalCount: items.length\n };\n });\n }\n\n /**\n * Build filter facets from a set of results.\n */\n public BuildFilters(results: SearchResultItem[]): SearchFilter[] {\n return [\n this.buildSourceTypeFilter(results),\n this.buildEntityNameFilter(results),\n this.buildFileTypeFilter(results),\n this.buildTagFilter(results)\n ].filter(f => f.Options.length > 0); // Hide categories with no options\n }\n\n /** Get the icon for a given source type */\n public GetSourceIcon(sourceType: string): string {\n return this.providersBySourceType.get(sourceType)?.Icon ?? FALLBACK_SOURCE_ICONS[sourceType] ?? 'fa-solid fa-circle';\n }\n\n private buildSourceTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n counts.set(r.SourceType, (counts.get(r.SourceType) ?? 0) + 1);\n }\n const options: SearchFilterOption[] = Array.from(counts.entries()).map(([type, count]) => {\n const cached = this.providersBySourceType.get(type);\n return {\n Label: cached?.DisplayName ?? FALLBACK_SOURCE_LABELS[type] ?? type,\n Value: type,\n Count: count,\n IsSelected: false,\n Icon: cached?.Icon ?? FALLBACK_SOURCE_ICONS[type]\n };\n });\n return { Category: 'Source', Options: options, MultiSelect: true };\n }\n\n private buildEntityNameFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n let fileCount = 0;\n for (const r of results) {\n if (r.ResultType === 'storage-file') {\n fileCount++;\n } else {\n counts.set(r.EntityName, (counts.get(r.EntityName) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([name, count]) => ({\n Label: name,\n Value: name,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-table'\n }));\n\n // Add a single \"Files\" entry for all storage file results\n if (fileCount > 0) {\n options.push({\n Label: 'Files',\n Value: '__storage-files__',\n Count: fileCount,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n });\n }\n\n return { Category: 'Entity', Options: options, MultiSelect: true };\n }\n\n private buildFileTypeFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n if (r.ResultType !== 'storage-file') continue;\n const ext = r.Title?.split('.').pop()?.toUpperCase();\n if (ext && ext.length <= 6) {\n counts.set(ext, (counts.get(ext) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([ext, count]) => ({\n Label: ext,\n Value: ext,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-file'\n }));\n return { Category: 'File Type', Options: options, MultiSelect: true };\n }\n\n private buildTagFilter(results: SearchResultItem[]): SearchFilter {\n const counts = new Map<string, number>();\n for (const r of results) {\n for (const tag of r.Tags) {\n counts.set(tag, (counts.get(tag) ?? 0) + 1);\n }\n }\n const options: SearchFilterOption[] = Array.from(counts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15)\n .map(([tag, count]) => ({\n Label: tag,\n Value: tag,\n Count: count,\n IsSelected: false,\n Icon: 'fa-solid fa-tag'\n }));\n return { Category: 'Tags', Options: options, MultiSelect: true };\n }\n\n /**\n * Load persisted recent searches from UserInfoEngine.\n * Safe to call multiple times — only loads once.\n */\n public async LoadRecentSearches(): Promise<void> {\n if (this.recentSearchesLoaded) return;\n\n try {\n MJGlobal.Instance.GetEventListener(true).subscribe(async (event) => {\n if (event.event === MJEventType.LoggedIn) {\n await StartupManager.Instance.Startup();\n\n const engine = UserInfoEngine.Instance;\n\n const json = engine.GetSetting(RECENT_SEARCHES_KEY);\n\n if (json) {\n const parsed = JSON.parse(json) as RecentSearchJson[];\n const searches: RecentSearch[] = parsed.map(s => ({\n Query: s.Query,\n Timestamp: new Date(s.Timestamp),\n ResultCount: s.ResultCount\n }));\n this.RecentSearches$.next(searches);\n }\n }\n });\n } catch (err) {\n console.error('[SearchService] LoadRecentSearches error:', err);\n }\n this.recentSearchesLoaded = true;\n }\n\n private addToRecentSearches(query: string, resultCount: number): void {\n const current = this.RecentSearches$.value;\n const filtered = current.filter(s => s.Query !== query);\n const updated = [\n { Query: query, Timestamp: new Date(), ResultCount: resultCount },\n ...filtered\n ].slice(0, this.maxRecentSearches);\n this.RecentSearches$.next(updated);\n this.persistRecentSearches(updated);\n }\n\n private persistRecentSearches(searches: RecentSearch[]): void {\n try {\n const json: RecentSearchJson[] = searches.map(s => ({\n Query: s.Query,\n Timestamp: s.Timestamp.toISOString(),\n ResultCount: s.ResultCount\n }));\n UserInfoEngine.Instance.SetSettingDebounced(RECENT_SEARCHES_KEY, JSON.stringify(json));\n } catch {\n // Silently fail if UserInfoEngine not available\n }\n }\n\n /** Cache provider metadata by SourceType for use in GroupResults/BuildFilters */\n private cacheProviders(providers: SearchProviderInfo[]): void {\n for (const p of providers) {\n this.providersBySourceType.set(p.SourceType, p);\n }\n }\n\n private createEmptyResponse(errorMessage?: string): SearchResponse {\n return {\n Success: !errorMessage,\n Results: [],\n Groups: [],\n Filters: [],\n TotalCount: 0,\n ElapsedMs: 0,\n SourceCounts: { Vector: 0, FullText: 0, Entity: 0, Storage: 0 },\n Providers: [],\n ErrorMessage: errorMessage\n };\n }\n\n /**\n * Execute search via the GraphQLSearchClient.\n */\n private async executeGraphQLSearch(request: SearchRequest): Promise<SearchResponse> {\n if (!request.Query.trim()) {\n return this.createEmptyResponse();\n }\n\n const provider = this.Provider;\n if (!(provider instanceof GraphQLDataProvider)) {\n return this.createEmptyResponse('GraphQL provider not available');\n }\n\n const client = new GraphQLSearchClient(provider);\n const filters = this.buildClientFilters(request);\n const minScore = request.MinScore ?? DEFAULT_MIN_SCORE;\n\n const clientResponse = await client.ExecuteSearch({\n Query: request.Query,\n MaxResults: request.MaxResults || 20,\n MinScore: minScore > 0 ? minScore : undefined,\n Filters: filters\n });\n\n return this.mapClientResponseToSearchResponse(clientResponse);\n }\n\n /** Convert a SearchClientResponse into the SearchResponse shape used by this service */\n private mapClientResponseToSearchResponse(clientResponse: SearchClientResponse): SearchResponse {\n if (!clientResponse.Success) {\n return this.createEmptyResponse(clientResponse.ErrorMessage ?? 'Search failed');\n }\n\n // Cache provider metadata for use in GroupResults/BuildFilters\n const providers: SearchProviderInfo[] = (clientResponse.Providers ?? []).map(p => ({\n ID: p.ID,\n Name: p.Name,\n DisplayName: p.DisplayName,\n Icon: p.Icon,\n SourceType: p.SourceType,\n Priority: p.Priority,\n }));\n this.cacheProviders(providers);\n\n const results: SearchResultItem[] = (clientResponse.Results ?? []).map(r => this.mapClientResultItem(r));\n\n const groups = this.GroupResults(results);\n const filters = this.BuildFilters(results);\n\n return {\n Success: true,\n Results: results,\n Groups: groups,\n Filters: filters,\n TotalCount: clientResponse.TotalCount,\n ElapsedMs: clientResponse.ElapsedMs,\n SourceCounts: {\n Vector: clientResponse.SourceCounts.Vector,\n FullText: clientResponse.SourceCounts.FullText,\n Entity: clientResponse.SourceCounts.Entity,\n Storage: clientResponse.SourceCounts.Storage\n },\n Providers: providers,\n };\n }\n\n /** Map a single SearchClientResultItem to a SearchResultItem */\n private mapClientResultItem(r: SearchClientResultItem): SearchResultItem {\n return {\n ID: r.ID,\n Title: r.RecordName || r.Title,\n Snippet: r.Snippet,\n EntityName: r.EntityName,\n RecordID: r.RecordID,\n SourceType: (r.SourceType as SearchResultItem['SourceType']) || 'entity',\n ResultType: r.ResultType,\n Score: r.Score,\n ScoreBreakdown: r.ScoreBreakdown ?? {},\n Tags: r.Tags ?? [],\n SourceIcon: r.EntityIcon || r.ProviderIcon || FALLBACK_SOURCE_ICONS[r.SourceType] || 'fa-solid fa-database',\n EntityIcon: r.EntityIcon,\n RecordName: r.RecordName,\n MatchedAt: new Date(r.MatchedAt),\n RawMetadata: r.RawMetadata,\n ProviderId: r.ProviderId,\n ProviderLabel: r.ProviderLabel,\n ProviderIcon: r.ProviderIcon,\n };\n }\n\n /** Build the client filters from active filter selections */\n private buildClientFilters(request: SearchRequest): { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } | undefined {\n if (!request.ActiveFilters || Object.keys(request.ActiveFilters).length === 0) {\n return undefined;\n }\n\n const result: { EntityNames?: string[]; SourceTypes?: string[]; Tags?: string[] } = {};\n\n const entityFilters = request.ActiveFilters['Entity'];\n if (entityFilters?.length) {\n result.EntityNames = entityFilters;\n }\n\n const sourceFilters = request.ActiveFilters['Source'];\n if (sourceFilters?.length) {\n result.SourceTypes = sourceFilters;\n }\n\n const tagFilters = request.ActiveFilters['Tags'];\n if (tagFilters?.length) {\n result.Tags = tagFilters;\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-search",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.31.0",
|
|
4
4
|
"description": "MemberJunction: Reusable search overlay and results components - command palette / Spotlight style search",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -27,11 +27,12 @@
|
|
|
27
27
|
"@angular/forms": "21.1.3"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@memberjunction/core": "5.
|
|
31
|
-
"@memberjunction/
|
|
32
|
-
"@memberjunction/
|
|
33
|
-
"@memberjunction/
|
|
34
|
-
"@memberjunction/
|
|
30
|
+
"@memberjunction/core": "5.31.0",
|
|
31
|
+
"@memberjunction/ng-base-types": "5.31.0",
|
|
32
|
+
"@memberjunction/global": "5.31.0",
|
|
33
|
+
"@memberjunction/graphql-dataprovider": "5.31.0",
|
|
34
|
+
"@memberjunction/core-entities": "5.31.0",
|
|
35
|
+
"@memberjunction/ng-shared-generic": "5.31.0",
|
|
35
36
|
"rxjs": "^7.8.2",
|
|
36
37
|
"tslib": "^2.8.1"
|
|
37
38
|
},
|