Skip to content

Commit

Permalink
Merge e98dbad into a4dd9d0
Browse files Browse the repository at this point in the history
  • Loading branch information
wosullivan committed Oct 2, 2020
2 parents a4dd9d0 + e98dbad commit b66b923
Show file tree
Hide file tree
Showing 8 changed files with 437 additions and 0 deletions.
96 changes: 96 additions & 0 deletions pages/top_queries.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, height=device-height" />
<title>Development</title>
<link rel="stylesheet" href="../css/CoveoFullSearch.css" />
<link rel="stylesheet" href="../css/CoveoJsSearchExtensions.css" />
<script class="coveo-script" src="../js/CoveoJsSearch.Lazy.js"></script>
<script class="coveo-script" src="../commonjs/CoveoJsSearchExtensions.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
Coveo.SearchEndpoint.configureSampleEndpointV2();
Coveo.init(document.body, {
TopQueries: {
suggestionQueryParams: {
count: 3,
searchHub: 'default',
},
},
});
});
</script>
</head>

<body id="search" class="CoveoSearchInterface" data-enable-history="true" style="padding: 1em;">
<span class="CoveoAnalytics"></span>
<div class="coveo-tab-section">
<a class="CoveoTab" data-id="All" data-caption="All Content"></a>
</div>
<div class="coveo-search-section">
<div class="CoveoSearchbox" data-enable-omnibox="true"></div>
</div>

<div class="CoveoTopQueries"></div>

<div class="coveo-facet-column">
<div class="CoveoFacet" data-title="Type" data-field="@objecttype" data-tab="All"></div>
<div class="CoveoFacet" data-title="FileType" data-field="@filetype" data-tab="All"></div>
<div class="CoveoFacet" data-title="Author" data-field="@author" data-tab="All"></div>
<div class="CoveoFacet" data-title="Year" data-field="@year" data-tab="All"></div>
<div class="CoveoFacet" data-title="Month" data-field="@month" data-tab="All"></div>
</div>
<div class="CoveoBreadcrumb"></div>
<div class="coveo-summary-section">
<span class="CoveoQuerySummary"></span>
<span class="CoveoQueryDuration"></span>
</div>
<div class="CoveoHiddenQuery"></div>
<div class="CoveoDidYouMean"></div>
<div class="CoveoErrorReport"></div>
<div class="CoveoResultList" data-layout="list" data-wait-animation="fade" data-auto-select-fields-to-include="true">
<script type="text/html" class="result-template">
<div class="coveo-result-frame">
<div class="CoveoResultActionsMenu">
<div class="CoveoCopyToClipboard2"></div>
<div class="CoveoQuickview"></div>
</div>
<div class="coveo-result-cell" style="vertical-align:top;text-align:center;width:32px;">
<span class="CoveoIcon" data-small="true" data-with-label="false"></span>
</div>
<div class="coveo-result-cell" style="vertical-align: top;padding-left: 16px;">
<div class="coveo-result-row" style="margin-top:0;">
<div class="coveo-result-cell" style="vertical-align:top;font-size:16px;">
<a class="CoveoResultLink"></a>
</div>
<div class="coveo-result-cell" style="width:120px;text-align:right;font-size:12px">
<div class="coveo-result-row">
<span class="CoveoFieldValue" data-field="@date" data-helper="date"></span>
</div>
</div>
</div>
<div class="coveo-result-row" style="margin-top:10px;">
<div class="coveo-result-cell">
<span class="CoveoExcerpt"></span>
</div>
</div>
<div class="coveo-result-row" style="margin-top:10px;">
<div class="coveo-result-cell">
<span class="CoveoFieldValue" data-field="@author" data-text-caption="Author" style="margin-right:30px;"></span>
<span class="CoveoFieldValue" data-field="@source" data-text-caption="Source" style="margin-right:30px;"></span>
<span class="CoveoFieldValue" data-field="@language" data-text-caption="Language" style="margin-right:30px;"></span>
<span class="CoveoFieldValue" data-field="@filetype" data-text-caption="File Type" style="margin-right:30px;"></span>
</div>
</div>
<div class="coveo-result-row" style="margin-top:10px;">
<div class="coveo-result-cell">
<div class="CoveoPrintableUri"></div>
</div>
</div>
</div>
</div>
</script>
</div>
</body>
</html>
1 change: 1 addition & 0 deletions src/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export { ResultsFilter } from './components/ResultsFilter/ResultsFilter';
export { ViewedByCustomer } from './components/ViewedByCustomer/ViewedByCustomer';
export { ResultAction } from './components/ResultAction/ResultAction';
export { CopyToClipboard } from './components/CopyToClipboard/CopyToClipboard';
export { TopQueries } from './components/TopQueries/TopQueries';
5 changes: 5 additions & 0 deletions src/components/TopQueries/Strings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Translation, Language } from '../../utils/translation';

Translation.register(Language.English, {
TopQueries_title: 'People also searched for',
});
31 changes: 31 additions & 0 deletions src/components/TopQueries/TopQueries.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@import '../../sass/Variables.scss';

$title-font-size: 1.1em;
$default-padding: 6px;

.CoveoTopQueries {
border: $default-border;
border-radius: $border-radius;
max-width: 500px;

h2 {
margin: 0;
padding: $default-padding;
background-color: $grey-3;
font-size: $title-font-size;
color: $color-greyish-teal-blue;
}

ul {
margin: 0;
padding: 0;
list-style-type: none;
}

li {
margin: 0;
border-top: $default-border;
padding: $default-padding;
padding-left: 20px;
}
}
123 changes: 123 additions & 0 deletions src/components/TopQueries/TopQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import {
Component,
ComponentOptions,
IAnalyticsActionCause,
IComponentBindings,
Initialization,
IQuerySuggestRequest,
l,
IQuerySuggestResponse,
IAnalyticsNoMeta,
} from 'coveo-search-ui';
import './Strings';

export interface ITopQueriesOptions {
/**
* The parameters sent to the suggestion query.
* The component uses this information to get better suggestions
* In most cases, the q attribute should be set to ''
*/
suggestionQueryParams?: IQuerySuggestRequest;
/**
* The displayed title over the suggestions
*/
title?: string;
/**
* Specifies the handler called when a suggestion is clicked.
*
* Default executes a search query using the suggestion
*
* This option must be set in JavaScript when initializing the component.
*/
onClick?: (expression: string, component: TopQueries) => void;
}

/**
* The TopQueries component suggests the top searched queries in the specific context and links the search results of the suggestions to the user
*/
export class TopQueries extends Component {
static ID = 'TopQueries';

/**
* The possible options for the TopQueries component
* @componentOptions
*/
static options: ITopQueriesOptions = {
suggestionQueryParams: ComponentOptions.buildJsonOption<IQuerySuggestRequest>({ defaultValue: { q: '' } }),
title: ComponentOptions.buildStringOption({ defaultValue: l('TopQueries_title') }),
onClick: ComponentOptions.buildCustomOption((s) => null, {
defaultValue: (expression: string, component: TopQueries) => {
component.usageAnalytics.logSearchEvent<IAnalyticsNoMeta>(TopQueries.topQueriesClickActionCause, {});
component.queryStateModel.set('q', expression);
component.queryController.executeQuery({ origin: component });
},
}),
};

public static topQueriesClickActionCause: IAnalyticsActionCause = {
name: 'topQueriesClick',
type: 'interface',
};

private listElem: HTMLUListElement;

/**
* Construct a TopQueries component.
* @param element The HTML element bound to this component.
* @param options The options that can be provided to this component.
* @param bindings The bindings, or environment within which this component exists.
*/
constructor(public element: HTMLElement, public options: ITopQueriesOptions, public bindings?: IComponentBindings) {
super(element, TopQueries.ID, bindings);
this.options = ComponentOptions.initComponentOptions(element, TopQueries, options);

const titleElem = document.createElement('h2');
titleElem.innerHTML = options.title;

this.listElem = document.createElement('ul');

this.element.appendChild(titleElem);
this.element.appendChild(this.listElem);

this.updateTopQueries();
}

public async updateTopQueries(suggestionQueryParams: IQuerySuggestRequest = this.options.suggestionQueryParams): Promise<void> {
this.show();

let suggestions: IQuerySuggestResponse;
try {
suggestions = await this.queryController.getEndpoint().getQuerySuggest(suggestionQueryParams);
} catch (err) {
console.error(`Failed to fetch query suggestions: ${err}`);
this.hide();
return;
}

if (!suggestions?.completions?.length || suggestions.completions.length == 0) {
// Hide the widget if there are no query suggestions or data format is invalid
this.hide();
} else {
suggestions.completions.forEach((completion) => {
const li = document.createElement('li');
const a = document.createElement('a');
a.classList.add('coveo-link');
a.addEventListener('click', () => this.options.onClick(completion.expression, this));
a.innerHTML = completion.expression;

li.appendChild(a);
this.listElem.appendChild(li);
});
}
}

private hide(): void {
this.element.classList.add('coveo-hidden');
}

private show(): void {
this.element.classList.remove('coveo-hidden');
}
}

Initialization.registerAutoCreateComponent(TopQueries);
1 change: 1 addition & 0 deletions src/sass/Index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
@import '../components/UserActions/UserActions.scss';
@import '../components/ViewedByCustomer/ViewedByCustomer.scss';
@import './ResultActionMenu.scss';
@import '../components/TopQueries/TopQueries.scss';
3 changes: 3 additions & 0 deletions src/sass/Variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ $lynch: #5d7289;
$bali-hai: #8097aa;
$nepal: #94a9bf;
$heather: #b5c4cf;
$color-greyish-teal-blue: #1d4f76;

// Grey Palette
$grey-5: #b5c4cf;
Expand All @@ -25,3 +26,5 @@ $calypso: #316084;
$tangerine: #ef9700;

$icon-container-size: 24px;
$default-border: 1px solid $grey-5;
$border-radius: 2px;
Loading

0 comments on commit b66b923

Please sign in to comment.