All files / src/embed search.ts

100% Statements 28/28
93.33% Branches 14/15
100% Functions 4/4
100% Lines 28/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                  3x 3x 3x                                       3x             7x 7x               7x 7x 1x   7x 1x     7x                             7x 7x 7x 5x   7x 4x     7x   7x 7x 7x 7x     7x                         7x   7x 7x   7x      
/**
 * Copyright (c) 2021
 *
 * Embed search or a saved answer
 *
 * @summary Search embed
 * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
 */
 
import { DataSourceVisualMode, DOMSelector, Param } from '../types';
import { getQueryParamString } from '../utils';
import { ViewConfig, TsEmbed } from './base';
 
export interface SearchViewConfig extends ViewConfig {
    collapseDataSources?: boolean;
    hideDataSources?: boolean;
    hideResults?: boolean;
    enableSearchAssist?: boolean;
    disabledActions?: string[];
    disabledActionReason?: string;
}
 
export interface SearchRenderOptions {
    dataSources?: string[];
    searchQuery?: string;
    answerId?: string;
}
 
/**
 * Embed ThoughtSpot search
 */
export class SearchEmbed extends TsEmbed {
    /**
     * The view configuration for the embedded ThoughtSpot search
     */
    private viewConfig: SearchViewConfig;
 
    constructor(domSelector: DOMSelector, viewConfig: SearchViewConfig) {
        super(domSelector);
        this.viewConfig = viewConfig;
    }
 
    /**
     * Get the state of the data sources panel that the embedded
     * ThoughtSpot search will be initialized with
     */
    private getDataSourceMode() {
        let dataSourceMode = DataSourceVisualMode.Expanded;
        if (this.viewConfig.collapseDataSources === true) {
            dataSourceMode = DataSourceVisualMode.Collapsed;
        }
        if (this.viewConfig.hideDataSources === true) {
            dataSourceMode = DataSourceVisualMode.Hidden;
        }
 
        return dataSourceMode;
    }
 
    /**
     * Construct the URL of the embedded ThoughtSpot search to be
     * loaded in the iframe
     * @param answerId The GUID of a saved answer
     * @param dataSources A list of data source GUIDs
     * @param searchQuery A search query to be fired on load
     */
    private getIFrameSrc(
        answerId: string,
        dataSources?: string[],
        searchQuery?: string,
    ) {
        const answerPath = answerId ? `saved-answer/${answerId}` : 'answer';
        const queryParams = {};
        if (dataSources && dataSources.length) {
            queryParams[Param.DataSources] = JSON.stringify(dataSources);
        }
        if (searchQuery) {
            queryParams[Param.SearchQuery] = searchQuery;
        }
 
        queryParams[Param.DataSourceMode] = this.getDataSourceMode();
 
        let query = '';
        const queryParamsString = getQueryParamString(queryParams);
        Eif (queryParamsString) {
            query = `?${queryParamsString}`;
        }
 
        return `${this.getEmbedBasePath()}/${answerPath}${query}`;
    }
 
    /**
     * Render ThoughtSpot search
     * @param renderOptions An object specifying the list of dataSources,
     * searchQuery and answerId (for loading a saved answer)
     */
    public render({
        dataSources,
        searchQuery,
        answerId,
    }: SearchRenderOptions = {}): SearchEmbed {
        super.render();
 
        const src = this.getIFrameSrc(answerId, dataSources, searchQuery);
        this.renderIFrame(src, this.viewConfig.frameParams);
 
        return this;
    }
}