barneo-search-widget-lib
Version:
Библиотека для поиска по каталогу Barneo на Vue 3
358 lines (327 loc) • 10.6 kB
text/typescript
import type { BarneoConfig, DEFAULT_CONFIG } from "../types/config";
import { SearchApiService } from "../services/api";
import { AnalyticsService } from "../modules/analytics/services/AnalyticsService";
/**
* Глобальный менеджер конфигурации Barneo Search Library
*/
export class BarneoConfigManager {
private static instance: BarneoConfigManager;
private config: BarneoConfig = {} as BarneoConfig;
private apiService: SearchApiService | null = null;
private analyticsService: AnalyticsService | null = null;
private constructor(config?: Partial<BarneoConfig>) {
// Инициализируем конфигурацию синхронно
this.initializeWithConfig(config);
}
private initializeWithConfig(config?: Partial<BarneoConfig>) {
// Используем базовую конфигурацию по умолчанию
const defaultConfig: BarneoConfig = {
api: {
baseUrl: "https://api.search.ensi.cloud",
token: "95246bb090387d5c92186f1b6d25cc72",
customerId: "4",
locationId: "1",
// apiVersion не указан по умолчанию
},
searchWidget: {
placeholder: "Найти товары",
debounceMs: 300,
minSearchLength: 2,
darkMode: false,
focusMode: false,
showClearButton: true,
},
filtersWidget: {
maxValuesPerFilter: 5,
debounceMs: 300,
darkMode: false,
},
productsWidget: {
itemsPerPage: 20,
mobileItemWidth: 140,
desktopItemWidth: 250,
darkMode: false,
showPagination: true,
showTotalCount: true,
},
sortWidget: {
darkMode: false,
defaultSort: "relevance",
},
};
// Объединяем с переданной конфигурацией
this.config = this.mergeConfig(defaultConfig, config || {});
this.initializeApiService();
this.initializeAnalyticsService();
}
/**
* Получить единственный экземпляр менеджера конфигурации
*/
public static getInstance(
config?: Partial<BarneoConfig>
): BarneoConfigManager {
if (!BarneoConfigManager.instance) {
BarneoConfigManager.instance = new BarneoConfigManager(config);
}
return BarneoConfigManager.instance;
}
/**
* Инициализировать конфигурацию (для использования в Nuxt/Vue приложении)
*/
public static initialize(
config?: Partial<BarneoConfig>
): BarneoConfigManager {
return BarneoConfigManager.getInstance(config);
}
/**
* Получить текущую конфигурацию
*/
public getConfig(): BarneoConfig {
return this.config;
}
/**
* Получить конфигурацию API
*/
public getApiConfig() {
return this.config.api;
}
/**
* Получить конфигурацию поискового виджета
*/
public getSearchWidgetConfig() {
return this.config.searchWidget || {};
}
/**
* Получить конфигурацию виджета фильтров
*/
public getFiltersWidgetConfig() {
return this.config.filtersWidget || {};
}
/**
* Получить конфигурацию виджета товаров
*/
public getProductsWidgetConfig() {
return this.config.productsWidget || {};
}
/**
* Получить конфигурацию виджета сортировки
*/
public getSortWidgetConfig() {
return this.config.sortWidget || {};
}
/**
* Получить API сервис
*/
public getApiService(): SearchApiService {
if (!this.apiService) {
this.initializeApiService();
}
return this.apiService!;
}
/**
* Получить сервис аналитики
*/
public getAnalyticsService(): AnalyticsService {
if (!this.analyticsService) {
this.initializeAnalyticsService();
}
return this.analyticsService!;
}
/**
* Обновить всю конфигурацию
*/
public updateConfig(newConfig: Partial<BarneoConfig>): void {
this.config = this.mergeConfig(this.config, newConfig);
this.initializeApiService();
this.initializeAnalyticsService();
}
/**
* Обновить конфигурацию API
*/
public updateApiConfig(apiConfig: Partial<BarneoConfig["api"]>): void {
this.config.api = { ...this.config.api, ...apiConfig };
this.initializeApiService();
this.initializeAnalyticsService();
}
/**
* Обновить конфигурацию поискового виджета
*/
public updateSearchWidgetConfig(
searchConfig: Partial<BarneoConfig["searchWidget"]>
): void {
this.config.searchWidget = {
...this.config.searchWidget,
...searchConfig,
};
}
/**
* Обновить конфигурацию виджета фильтров
*/
public updateFiltersWidgetConfig(
filtersConfig: Partial<BarneoConfig["filtersWidget"]>
): void {
this.config.filtersWidget = {
...this.config.filtersWidget,
...filtersConfig,
};
}
/**
* Обновить конфигурацию виджета товаров
*/
public updateProductsWidgetConfig(
productsConfig: Partial<BarneoConfig["productsWidget"]>
): void {
this.config.productsWidget = {
...this.config.productsWidget,
...productsConfig,
};
}
/**
* Обновить конфигурацию виджета сортировки
*/
public updateSortWidgetConfig(
sortConfig: Partial<BarneoConfig["sortWidget"]>
): void {
this.config.sortWidget = {
...this.config.sortWidget,
...sortConfig,
};
}
/**
* Сбросить конфигурацию к значениям по умолчанию
*/
public async resetConfig(): Promise<void> {
this.config = {
api: {
baseUrl: "https://api.search.ensi.cloud",
token: "95246bb090387d5c92186f1b6d25cc72",
customerId: "4",
locationId: "1",
apiVersion: "v1",
},
searchWidget: {
placeholder: "Найти товары",
debounceMs: 300,
minSearchLength: 2,
darkMode: false,
focusMode: false,
showClearButton: true,
},
filtersWidget: {
maxValuesPerFilter: 5,
debounceMs: 300,
darkMode: false,
},
productsWidget: {
itemsPerPage: 20,
mobileItemWidth: 140,
desktopItemWidth: 250,
darkMode: false,
showPagination: true,
showTotalCount: true,
},
sortWidget: {
darkMode: false,
defaultSort: "relevance",
},
};
this.initializeApiService();
this.initializeAnalyticsService();
}
/**
* Объединить конфигурации
*/
private mergeConfig(
defaultConfig: BarneoConfig,
userConfig: Partial<BarneoConfig>
): BarneoConfig {
return {
api: { ...defaultConfig.api, ...userConfig.api },
searchWidget: {
...defaultConfig.searchWidget,
...userConfig.searchWidget,
},
filtersWidget: {
...defaultConfig.filtersWidget,
...userConfig.filtersWidget,
},
productsWidget: {
...defaultConfig.productsWidget,
...userConfig.productsWidget,
},
sortWidget: {
...defaultConfig.sortWidget,
...userConfig.sortWidget,
},
};
}
/**
* Инициализировать API сервис
*/
private initializeApiService(): void {
this.apiService = new SearchApiService(this.config.api);
}
/**
* Инициализировать сервис аналитики
*/
private initializeAnalyticsService(): void {
this.analyticsService = new AnalyticsService({
baseUrl: this.config.api.baseUrl,
token: this.config.api.token,
customerId: this.config.api.customerId,
locationId: this.config.api.locationId,
apiVersion: this.config.api.apiVersion,
});
}
/**
* Vue плагин
*/
install(app: any, config?: Partial<BarneoConfig>) {
if (config) {
this.updateConfig(config);
}
app.provide("barneoConfig", this.config);
app.provide("barneoApiService", this.getApiService());
app.provide("barneoAnalyticsService", this.getAnalyticsService());
app.provide("barneoConfigManager", this);
// Добавляем глобальный доступ для использования вне Vue контекста
if (typeof window !== "undefined") {
(window as any).__barneoConfigManager = this;
}
}
}
/**
* Vue плагин для Barneo Search Library
*/
export const BarneoConfigPlugin = {
install(app: any, config?: Partial<BarneoConfig>) {
const manager = BarneoConfigManager.getInstance(config);
manager.install(app, config);
},
};
/**
* Composable для использования конфигурации
*/
export function useBarneoConfig() {
const configManager = BarneoConfigManager.getInstance();
return {
config: configManager.getConfig(),
apiService: configManager.getApiService(),
analyticsService: configManager.getAnalyticsService(),
searchWidgetConfig: configManager.getSearchWidgetConfig(),
filtersWidgetConfig: configManager.getFiltersWidgetConfig(),
productsWidgetConfig: configManager.getProductsWidgetConfig(),
sortWidgetConfig: configManager.getSortWidgetConfig(),
updateConfig: configManager.updateConfig.bind(configManager),
updateApiConfig: configManager.updateApiConfig.bind(configManager),
updateSearchWidgetConfig:
configManager.updateSearchWidgetConfig.bind(configManager),
updateFiltersWidgetConfig:
configManager.updateFiltersWidgetConfig.bind(configManager),
updateProductsWidgetConfig:
configManager.updateProductsWidgetConfig.bind(configManager),
updateSortWidgetConfig:
configManager.updateSortWidgetConfig.bind(configManager),
resetConfig: configManager.resetConfig.bind(configManager),
};
}