import { addEventListener, FiltersMap, ReportBI, withoutDefaults, } from '@wix/bex-core'; import { action } from 'mobx'; import { cairoCtaClicked, cairoFiltersPanelUsed, cairoManageViewActionSelected, cairoTryAgainClicked, cairoUndoClicked, cairoViewDeleted, cairoViewSaved, cairoViewSelected, cairoViewsUnsuccessfulUpdateInServer, wixPatternsClickOnViewDropdownSrc144Evid4, } from '@wix/bex-core/bi'; import { CollectionViewsState } from './CollectionViewsState'; import { PrivateView, ViewActionNameBI, ViewBase } from '../model'; import isEqual from 'lodash/isEqual'; export interface CollectionViewsStateBIReporterParams { reportBI: ReportBI; collectionViewState: CollectionViewsState; } export class CollectionViewsStateBIReporter { readonly collectionViewState: CollectionViewsState; readonly reportBI: ReportBI; constructor(params: CollectionViewsStateBIReporterParams) { this.collectionViewState = params.collectionViewState; this.reportBI = params.reportBI; } init() { const { reportBI, collectionViewState } = this; const { emitter, table, views } = collectionViewState; const disposers = [ addEventListener( views.events, 'beforeSelectView', action(() => { const previousViewName = views.currentView?.name; const previousFilters = JSON.stringify( table.collection.result.originQuery.filtersKey, ); const isFromSearchView = !!views.localSearchState.bi.events.listeners('afterSelectView') .length; views.events.once('afterSelectView', ({ view }) => { reportBI( withoutDefaults(cairoViewSelected)({ currentFilters: JSON.stringify( table.collection.result.originQuery.filtersKey, ), filteredListSize: table.collection.query.activeFiltersCount, newViewName: view.name, prevViewName: previousViewName, prevFilters: previousFilters, isPredefined: view.isPreset, isFromSearchView, isDefault: view.id === views.defaultViewId, }), ); }); }), ), addEventListener( emitter, 'openManageViewPopoverMenu', action(() => { reportBI( withoutDefaults(cairoFiltersPanelUsed)({ isOpened: true, feature: 'Manage Views', origin: 'Manage Views', }), ); const isRedesignEnabled = collectionViewState.table.container.internalExperiments?.enabled( 'specs.cairo.ViewsRedesign', ); if (isRedesignEnabled) { const viewId = views.currentView?.id; const { viewsWithoutCategory, categories } = views.localSearchState.categoriesWithViews; const flatViews = [ ...viewsWithoutCategory, ...categories.flatMap((c) => c.views), ]; const viewIndex = viewId ? flatViews.findIndex((v) => v.id === viewId) : undefined; reportBI( withoutDefaults(cairoCtaClicked)({ ctaName: 'more_actions', location: 'view_dropdown', itemId: viewId, itemIndex: viewIndex, }), ); } }), ), ]; return () => { disposers.forEach((disposer) => disposer()); }; } _getViewChanges(view1: ViewBase, view2: ViewBase) { const { queryCompareHelper } = this.collectionViewState; const changes = []; if (!isEqual(view1.sortDirections, view2.sortDirections)) { changes.push('Sorting'); } if ( queryCompareHelper.isColumnsChanged( view1.selectedColumns, view2.selectedColumns, ) ) { changes.push('Custom Columns'); } if (view1.filters?.search?.value !== view2.filters?.search?.value) { changes.push('Search'); } const { search: s1, ...filters1 } = view1.filters ?? {}; const { search: s2, ...filters2 } = view2.filters ?? {}; if (!isEqual(filters1, filters2)) { changes.push('Filters'); } return changes.join(','); } _saveViewBI( view: PrivateView, saveType: string, oldView?: PrivateView, ) { const { table } = this.collectionViewState; const selectedColumns = table.selectedColumns.value.filter( (col) => col.isSelected, ); this.reportBI( withoutDefaults(cairoViewSaved)({ ...table._commonDynamicBiParams(), saveType, prevName: oldView?.name, newViewName: view.name, isPredefined: view.isPreset, changedAttributes: this._getViewChanges(view, oldView ?? {}), numColumnsInView: selectedColumns.length ?? 0, numFiltersInView: table.collection.result.originQuery.search?.length ? table.collection.query.activeFiltersCount - 1 : table.collection.query.activeFiltersCount, searchQuery: table.collection.result.originQuery.search, viewFilters: JSON.stringify( table.collection.result.originQuery.nonPersistentFiltersKey, ), origin: 'MainToolbar', viewId: view.id, visibleColumnsOrder: selectedColumns.map((col) => col.id).join(','), isDefault: view.id === this.collectionViewState.views.defaultViewId, }), ); } _actionSelectedBI(actionIndex: number, actionName: ViewActionNameBI) { const { table, views } = this.collectionViewState; this.reportBI( withoutDefaults(cairoManageViewActionSelected)({ ...table._commonDynamicBiParams(), actionName, currentView: views.currentView?.id, actionIndex, numActions: 5, }), ); } saveViewChangesSelectedBI() { this._actionSelectedBI(1, 'view-save-changes'); } saveViewChangesBI(view: PrivateView, oldView?: PrivateView) { this._saveViewBI(view, 'save changes', oldView); } saveNewViewSelectedBI() { this._actionSelectedBI(2, 'view-save-new'); } saveNewViewBI(view: PrivateView) { this._saveViewBI(view, 'save as new view'); } deleteViewSelectedBI() { this._actionSelectedBI(5, 'view-delete'); } deleteViewBI(view: PrivateView) { const { table, views } = this.collectionViewState; this.reportBI( withoutDefaults(cairoViewDeleted)({ numFiltersInView: table.collection.result.originQuery.search?.length ? table.collection.query.activeFiltersCount - 1 : table.collection.query.activeFiltersCount, viewFilters: JSON.stringify(view.filters), viewName: view.name, viewId: view.id, wasSelected: true, isDefault: view.id === views.defaultViewId, }), ); } renameViewSelectedBI() { this._actionSelectedBI(3, 'view-rename'); } renameViewBI(view: PrivateView, oldName: string) { this._saveViewBI(view, 'rename', { ...view, name: oldName }); } setAsDefaultViewSelectedBI(isDefault: boolean) { this._actionSelectedBI( 4, isDefault ? 'view-set-as-default' : 'view-unset-as-default', ); } setAsDefaultViewBI(isDefault: boolean, view: PrivateView) { this._saveViewBI( view, isDefault ? 'set-as-default' : 'unset-as-default', view, ); } undoActionBI({ actionName, viewId, newName, }: { actionName: ViewActionNameBI; viewId: string; newName?: string; }) { const { views, queryCompareHelper } = this.collectionViewState; const view = views.getView(viewId); this.reportBI( withoutDefaults(cairoUndoClicked)({ actionName, viewId: view?.id, viewName: view?.name, viewNameApplied: newName ?? view?.name, changedAttributes: view && actionName === 'view-save-changes' ? this._getViewChanges( view, queryCompareHelper.currentViewBase ?? {}, ) : undefined, }), ); } tryAgainBI({ actionName }: { actionName: ViewActionNameBI }) { const { table } = this.collectionViewState; this.reportBI( withoutDefaults(cairoTryAgainClicked)({ actionName, isFromSearch: !!table.collection.result.originQuery.search, numOfWaitingUpdates: 1, }), ); } errorBI({ actionName, createdAt, viewId, }: { actionName: ViewActionNameBI; createdAt: number; viewId: string; }) { const { table } = this.collectionViewState; this.reportBI( withoutDefaults(cairoViewsUnsuccessfulUpdateInServer)({ actionName, errorType: 'Update Failed', timeFromEndAction: Date.now() - createdAt, numOfWaitingUpdates: 1, isFromSearch: !!table.collection.result.originQuery.search, viewId, }), ); } clickOnViewDropdownBI() { this.reportBI( withoutDefaults(wixPatternsClickOnViewDropdownSrc144Evid4)({}), ); } }