coveo-search-ui
Version:
Coveo JavaScript Search Framework
217 lines (188 loc) • 6.68 kB
text/typescript
import { loadAgGridLibrary } from './AgGrid';
import { first, map, each, flatten, find } from 'underscore';
import agGridModule = require('ag-grid/main');
import { Dom, $$, StringUtils, StreamHighlightUtils } from '../../UtilsModules';
import { IQueryResult } from '../../rest/QueryResult';
import { IResultsComponentBindings } from '../Base/ResultsComponentBindings';
import ResultListModule = require('../ResultList/ResultList');
import { ResultLink } from '../ResultLink/ResultLink';
import { IComponentBindings } from '../Base/ComponentBindings';
declare const agGrid: typeof agGridModule;
export interface ITableDataSource extends agGridModule.ColDef {
content?: any;
width?: number;
children?: Record<string, ITableDataSource>[];
cellRenderer?: new () => agGridModule.ICellRendererComp;
}
export const defaultGridOptions: agGridModule.GridOptions = {
domLayout: 'autoHeight',
enableColResize: true,
rowHeight: 100,
enableRangeSelection: true,
suppressRowClickSelection: true,
suppressCellSelection: true,
defaultColDef: {
width: 100
},
enableSorting: true,
autoSizePadding: 10
};
export class TableBuilder {
private gridOptions: agGridModule.GridOptions | undefined;
public async build(sources: Record<string, ITableDataSource>[], table: Dom, gridOptions = defaultGridOptions) {
const firstData = first(sources) || {};
const mapToAgGridFormat = (value: agGridModule.ColDef & agGridModule.ColGroupDef, key: string): any => {
if (value.children) {
return {
field: key,
headerName: key,
marryChildren: true,
children: flatten(
value.children.map((child: any) => {
return map(child, mapToAgGridFormat);
})
)
};
} else {
return {
field: key,
headerName: key,
...value
};
}
};
const columnDefs = map(firstData as any, mapToAgGridFormat) as agGridModule.ColDef[];
const rowData = map(sources, source => {
const merged: any = {};
const extractContent = (value: ITableDataSource & agGridModule.ColGroupDef, key: string) => {
if (value.content) {
merged[key] = value.content;
} else if (value.children) {
each(value.children, (child: any) => {
each(child, extractContent);
});
}
};
each(source, extractContent as any);
return merged;
});
this.gridOptions = {
...defaultGridOptions,
columnDefs,
rowData,
...gridOptions
};
await loadAgGridLibrary();
const grid = new agGrid.Grid(table.el, this.gridOptions);
return { grid, gridOptions: this.gridOptions };
}
public static thumbnailCell(result: IQueryResult, bindings: IComponentBindings): Record<string, ITableDataSource> {
return {
Document: {
content: { result, bindings },
cellRenderer: ThumbnailHtmlRenderer,
width: 550,
getQuickFilterText: (params: agGridModule.GetQuickFilterTextParams) => {
return '';
}
}
};
}
}
export class ThumbnailHtmlRenderer implements agGridModule.ICellRendererComp {
private element: any | undefined;
private currentFilter: string | undefined;
public init(params?: { value: { result: IQueryResult; bindings: IComponentBindings }; api: any }) {
if (params) {
this.element = params.value;
this.currentFilter = params.api.filterManager.quickFilter;
}
}
public getGui(): HTMLElement {
const cell = $$('div', { className: 'coveo-relevance-inspector-thumbnail-cell' });
if (this.element) {
const thumbnail = this.thumbnail(this.element.result, this.element.bindings);
cell.append(thumbnail.el);
} else {
cell.append($$('p', undefined, '-- NULL --').el);
}
return cell.el;
}
private thumbnail(result: IQueryResult, bindings: IResultsComponentBindings) {
let dom: Dom;
if (bindings && result) {
const resultLists = bindings.searchInterface.getComponents('ResultList') as ResultListModule.ResultList[];
const firstActiveResultList = find(resultLists, resultList => !resultList.disabled);
if (firstActiveResultList) {
dom = $$('div', {
className: 'coveo-relevance-inspector-result-thumbnail'
});
firstActiveResultList.buildResult(result).then(builtResult => {
dom.append(builtResult);
});
} else {
dom = $$('a', {
className: 'CoveoResultLink'
});
new ResultLink(dom.el, { alwaysOpenInNewWindow: true }, bindings, result);
}
if (this.currentFilter) {
this.highlightSearch(dom.el, this.currentFilter);
}
} else {
dom = $$('div', undefined, '-- NULL --');
}
return dom;
}
public refresh(params: any): boolean {
return true;
}
private highlightSearch(elementToSearch: HTMLElement, search: string) {
let asHTMLElement: HTMLElement = elementToSearch;
if (asHTMLElement != null && asHTMLElement.innerText != null) {
const match = asHTMLElement.innerText.split(new RegExp('(?=' + StringUtils.regexEncode(search) + ')', 'gi'));
asHTMLElement.innerHTML = '';
match.forEach(value => {
const regex = new RegExp('(' + StringUtils.regexEncode(search) + ')', 'i');
const group = value.match(regex);
let span;
if (group != null) {
span = $$('span', {
className: 'coveo-relevance-inspector-highlight'
});
span.text(group[1]);
asHTMLElement.appendChild(span.el);
span = $$('span');
span.text(value.substr(group[1].length));
asHTMLElement.appendChild(span.el);
} else {
span = $$('span');
span.text(value);
asHTMLElement.appendChild(span.el);
}
});
}
}
}
export class GenericHtmlRenderer implements agGridModule.ICellRendererComp {
private element: string | undefined;
private currentFilter: string | undefined;
public init(params?: any) {
if (params && params.api) {
this.element = params.value;
this.currentFilter = params.api.filterManager.quickFilter;
}
}
public getGui(): HTMLElement {
if (this.element && this.currentFilter) {
return $$('div', undefined, StreamHighlightUtils.highlightStreamHTML(this.element, { Precision: ['precision'] }, {})).el;
} else if (this.element) {
return $$('div', undefined, this.element).el;
} else {
return $$('div', undefined, '-- NULL --').el;
}
}
public refresh(params: any): boolean {
return true;
}
}