UNPKG

coveo-search-ui-extensions

Version:

Small generic components to extend the functionality of Coveo's Search UI framework.

287 lines 12.1 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { Component, Initialization, ComponentOptions, QueryEvents, l, get, ResultListEvents, ResultList, } from 'coveo-search-ui'; import { ResponsiveUserActions } from './ResponsiveUserActions'; import { arrowDown } from '../../utils/icons'; import { ClickedDocumentList } from './ClickedDocumentList'; import { QueryList } from './QueryList'; import { UserActivity } from './UserActivity'; import { UserProfileModel } from '../../Index'; import './Strings'; import { ViewedByCustomer } from '../ViewedByCustomer/ViewedByCustomer'; import { UserActionEvents } from './Events'; var ResultLayoutType; (function (ResultLayoutType) { ResultLayoutType["LIST"] = "list"; ResultLayoutType["TABLE"] = "table"; ResultLayoutType["CARD"] = "card"; })(ResultLayoutType || (ResultLayoutType = {})); /** * Display a panel that contains a summary of a user session and that also contains detailed information about user actions. */ export class UserActions extends Component { /** * Create an instance of the **UserActions** class. Initialize is needed the **UserProfileModel** and fetch user actions related to the **UserId**. * * @param element Element on which to bind the component. * @param options Initialization options of the component. * @param bindings Bindings of the Search-UI environment. */ constructor(element, options, bindings) { super(element, UserActions.ID, bindings); this.element = element; this.options = options; this.bindings = bindings; this.options = ComponentOptions.initComponentOptions(element, UserActions, options); if (!this.options.userId) { this.disable(); return; } if (this.options.viewedByCustomer) { this.showViewedByCustomer(); } this.tagViewsOfUser(); if (!options.hidden) { if (options.useResponsiveManager) { ResponsiveUserActions.init(this.root, this); } this.bind.onRootElement(QueryEvents.newQuery, () => this.hide()); this.hide(); } } /** * Collapse the panel. */ hide() { if (this.isOpened) { this.isOpened = false; get(this.root, UserProfileModel).deleteActions(this.options.userId); this.root.classList.remove(UserActions.USER_ACTION_OPENED); this.element.dispatchEvent(new CustomEvent(UserActions.Events.Hide)); } } /** * Open the panel. */ show() { return __awaiter(this, void 0, void 0, function* () { if (!this.isOpened) { this.isOpened = true; this.renderLoading(); this.element.dispatchEvent(new CustomEvent(UserActions.Events.Show)); this.bindings.usageAnalytics.logCustomEvent(UserActionEvents.open, {}, this.element); this.root.classList.add(UserActions.USER_ACTION_OPENED); try { const userActions = yield get(this.root, UserProfileModel).getActions(this.options.userId); if (userActions.length > 0) { this.render(); } else { this.renderNoActions(); } } catch (e) { if ((e === null || e === void 0 ? void 0 : e.statusCode) === 404) { this.renderEnablePrompt(); } else { this.renderNoActions(); } } } }); } /** * Toggle the visibility of the panel. */ toggle() { return __awaiter(this, void 0, void 0, function* () { if (this.isOpened) { this.hide(); } else { yield this.show(); } }); } buildAccordionHeader(title) { const div = document.createElement('div'); div.classList.add('coveo-accordion-header'); const headerTitle = document.createElement('div'); headerTitle.classList.add('coveo-accordion-header-title'); headerTitle.innerText = title; const arrow = document.createElement('div'); arrow.classList.add('coveo-arrow-down'); arrow.innerHTML = arrowDown; div.appendChild(headerTitle); div.appendChild(arrow); return div; } buildAccordion(title, elements) { const div = document.createElement('div'); div.classList.add('coveo-accordion'); const header = this.buildAccordionHeader(title); const foldable = document.createElement('div'); foldable.classList.add('coveo-accordion-foldable'); elements.forEach((el) => foldable.appendChild(el)); div.appendChild(header); div.appendChild(foldable); header.addEventListener('click', () => { if (div.classList.contains('coveo-folded')) { div.classList.remove('coveo-folded'); } else { div.classList.add('coveo-folded'); } }); return div; } buildCoveoElement(klass) { const el = document.createElement('div'); el.classList.add(`Coveo${klass.ID}`); return el; } /** * Initialize child Search-UI component and pass down critical options. * * @param element Parent element of each child that would be initialize. */ initializeSearchUIComponents(element) { const originalOptions = this.searchInterface.options.originalOptionsObject; Initialization.automaticallyCreateComponentsInside(element, { options: Object.assign(Object.assign({}, originalOptions), { QueryList: Object.assign(Object.assign({}, originalOptions.QueryList), { userId: this.options.userId }), ClickedDocumentList: Object.assign(Object.assign({}, originalOptions.ClickedDocumentList), { userId: this.options.userId }), UserActivity: Object.assign(Object.assign({}, originalOptions.UserActivity), { userId: this.options.userId }) }), bindings: this.bindings, }); } renderLoading() { this.element.innerHTML = ''; const loadingElement = document.createElement('div'); loadingElement.classList.add('coveo-loading-container'); loadingElement.innerHTML = ` <div role="status" class="slds-spinner slds-spinner--medium"> <span class="slds-assistive-text">Loading</span> <div class="slds-spinner__dot-a"></div> <div class="slds-spinner__dot-b"></div> </div>`; this.element.appendChild(loadingElement); } render() { const element = document.createElement('div'); const summarySection = this.buildAccordion(this.options.summaryLabel, [ this.buildCoveoElement(ClickedDocumentList), this.buildCoveoElement(QueryList), ]); summarySection.classList.add(`coveo-summary`); const detailsSection = this.buildAccordion(this.options.activityLabel, [this.buildCoveoElement(UserActivity)]); detailsSection.classList.add('coveo-details'); element.appendChild(summarySection); element.appendChild(detailsSection); this.initializeSearchUIComponents(element); this.element.innerHTML = ''; this.element.appendChild(element); } renderNoActions() { const messageContainer = document.createElement('div'); messageContainer.classList.add('coveo-no-actions'); messageContainer.innerHTML = ` <div class="coveo-user-actions-title">${l(UserActions.ID)}</div> <p>${l(UserActions.ID + '_no_actions_title')}.</p> <div> <span>${l(UserActions.ID + '_no_actions_causes_title')}</span> <ul class="coveo-no-actions-causes"> <li>${l(UserActions.ID + '_no_actions_cause_not_associated')}.</li> <li>${l(UserActions.ID + '_no_actions_cause_case_too_old')}.</li> </ul> </div> <p>${l(UserActions.ID + '_no_actions_contact_admin')}.</p> `; this.element.innerHTML = ''; this.element.appendChild(messageContainer); } renderEnablePrompt() { const messageContainer = document.createElement('div'); messageContainer.classList.add('coveo-no-actions'); messageContainer.innerHTML = ` <div class="coveo-user-actions-title">${l(UserActions.ID)}</div> <p>${l(UserActions.ID + '_no_actions_cause_not_enabled')}.</p> <p>${l(UserActions.ID + '_no_actions_contact_admin')}.</p> `; this.element.innerHTML = ''; this.element.appendChild(messageContainer); } showViewedByCustomer() { this.bind.onRootElement(ResultListEvents.newResultDisplayed, (args) => { if (Boolean(args.item.getElementsByClassName('CoveoViewedByCustomer').length)) { return; } if (this.inferResultListLayout() !== ResultLayoutType.TABLE) { const resultLastRow = '.coveo-result-row:last-child'; args.item .querySelector(resultLastRow) .parentNode.appendChild(ViewedByCustomer.getViewedByCustomerResultRowDom(this.bindings, args.result)); } }); } tagViewsOfUser() { Coveo.$$(this.root).on('buildingQuery', (e, args) => { try { args.queryBuilder.userActions = { tagViewsOfUser: this.options.userId, }; } catch (e) { this.logger.warn("CreatedBy Email wasn't found", e); } }); } inferResultListLayout() { const resultLists = this.root.querySelectorAll(`${Component.computeSelectorForType(ResultList.ID)}:not(.coveo-hidden)`); const resultListLayoutTypes = [ResultLayoutType.CARD, ResultLayoutType.TABLE, ResultLayoutType.LIST]; if (resultLists.length > 0 && resultListLayoutTypes.indexOf(resultLists[0].dataset.layout) !== -1) { return resultLists[0].dataset.layout; } return ResultLayoutType.LIST; } } /** * Identifier of the Search-UI component. */ UserActions.ID = 'UserActions'; UserActions.Events = { Hide: 'userActionsPanelHide', Show: 'userActionsPanelShow', }; /** * Default initialization options of the **UserActions** class. */ UserActions.options = { userId: ComponentOptions.buildStringOption({ required: true }), buttonLabel: ComponentOptions.buildStringOption({ defaultValue: 'User Actions', }), summaryLabel: ComponentOptions.buildStringOption({ defaultValue: 'Session Summary', }), activityLabel: ComponentOptions.buildStringOption({ defaultValue: 'User Activity Timeline', }), viewedByCustomer: ComponentOptions.buildBooleanOption({ defaultValue: true, }), hidden: ComponentOptions.buildBooleanOption({ defaultValue: false, }), useResponsiveManager: ComponentOptions.buildBooleanOption({ defaultValue: true, }), }; UserActions.USER_ACTION_OPENED = 'coveo-user-actions-opened'; Initialization.registerAutoCreateComponent(UserActions); //# sourceMappingURL=UserActions.js.map