import { View, ViewsDTO } from '../model'; import { WixPatternsMonitor, FiltersMap, DataCapsule, WixPatternsContainer, } from '@wix/bex-core'; export interface ViewsServiceParams { readonly viewsStorage: DataCapsule; readonly defaultViewStorage: DataCapsule; readonly fqdn: string; readonly monitor: WixPatternsMonitor; readonly errorHandler: WixPatternsContainer['errorHandler']; readonly translate: WixPatternsContainer['translate']; } export interface AppSettingsViewsSchema { views: { hiddenPresetIds?: Record; list?: Record | null | undefined>; }; } export class ViewsService { readonly viewsStorage; readonly defaultViewStorage; readonly fqdn; readonly monitor; readonly errorHandler; readonly translate; constructor(params: ViewsServiceParams) { this.viewsStorage = params.viewsStorage; this.defaultViewStorage = params.defaultViewStorage; this.fqdn = params.fqdn; this.monitor = params.monitor; this.errorHandler = params.errorHandler; this.translate = params.translate; } async migrateFromLocalStorage() { const { viewsStorage, fqdn } = this; try { await ( viewsStorage as { migrateItem?: (key: string) => unknown } ).migrateItem?.(fqdn); } catch (e) { this.monitor.reportError({ error: e, }); } } async fetchViews(): Promise | null> { const { viewsStorage, fqdn, errorHandler } = this; const data = await errorHandler.withErrorHandler( () => viewsStorage .getItem | null | undefined>(fqdn) .catch((e) => { if ( (e as Record | undefined)?.message === 'Key was not found in capsule' ) { return null; } throw e; }), {}, ); if (data?.views == null) { return null; } const { list, hiddenPresetIds } = data.views; return { views: list && Object.values(list) .filter((view): view is View => view != null) .sort( (a, b) => new Date(a.createdAt ?? 0).valueOf() - new Date(b.createdAt ?? 0).valueOf(), ), hiddenPresetIds: hiddenPresetIds && Object.values(hiddenPresetIds).filter((id): id is string => id != null), }; } async fetchDefaultViewId(): Promise { const { defaultViewStorage, fqdn, errorHandler } = this; const data = await errorHandler.withErrorHandler( () => defaultViewStorage .getItem<{ id: string } | string | null | undefined>( `${fqdn}.defaultViewId`, ) .catch((e) => { if ( (e as Record | undefined)?.message === 'Key was not found in capsule' ) { return null; } throw e; }), {}, ); return typeof data === 'string' ? data : data?.id ?? null; } async saveView(view: View, props?: { isRename?: boolean }) { const { viewsStorage, fqdn, errorHandler, translate: t } = this; await errorHandler.withErrorHandler( () => viewsStorage.setItem | null | undefined>( fqdn, { views: { list: { [view.id]: { ...view, createdAt: new Date().toISOString(), }, }, }, }, ), {}, { statusCodesOverrides: { INTERNAL: () => ({ message: props?.isRename ? t('cairo.manageView.Rename.error.toast') : t('cairo.manageView.saveView.error.toast'), }), }, }, ); } async deleteView(view: View) { const { viewsStorage, fqdn, errorHandler, translate: t } = this; await errorHandler.withErrorHandler( () => viewsStorage.setItem | null | undefined>( fqdn, { views: { list: { [view.id]: null, }, }, }, ), {}, { statusCodesOverrides: { INTERNAL: () => ({ message: t('cairo.manageView.Delete.CTA.error.toast'), }), }, }, ); } async updateHiddenPreset(idToDelete: string) { const { viewsStorage, fqdn, errorHandler, translate: t } = this; await errorHandler.withErrorHandler( () => viewsStorage.setItem | null | undefined>( fqdn, { views: { hiddenPresetIds: { [idToDelete]: idToDelete, }, }, }, ), {}, { statusCodesOverrides: { INTERNAL: () => ({ message: t('cairo.manageView.Delete.CTA.error.toast'), }), }, }, ); } async updateDefaultView(view?: View) { const { defaultViewStorage, fqdn, errorHandler, translate: t } = this; await errorHandler.withErrorHandler( async () => { const defaultViewKey = `${fqdn}.defaultViewId`; if (view != null) { await defaultViewStorage.setItem<{ id: string } | null | undefined>( defaultViewKey, { id: view.id, }, ); } else { await defaultViewStorage.removeItem(defaultViewKey); } }, {}, { statusCodesOverrides: { INTERNAL: view ? () => ({ message: t('cairo.manageView.setAsDefault.error.toast', { viewName: view.name, }), }) : undefined, }, }, ); } }