From 9ccd807a55b433229480f5dcb01b9951fba0a2f1 Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Sat, 15 Aug 2026 04:04:32 +0400 Subject: [PATCH] feat: editable new-order poll interval in admin settings Co-Authored-By: Claude Sonnet 5 --- .../pages/admin-settings-page.component.html | 19 +++++++++ .../admin-settings-page.component.spec.ts | 42 +++++++++++++++++++ .../pages/admin-settings-page.component.ts | 11 +++++ src/app/i18n/en.ts | 4 ++ src/app/i18n/hy.ts | 4 ++ src/app/i18n/ru.ts | 4 ++ src/app/i18n/translations.ts | 4 ++ 7 files changed, 88 insertions(+) create mode 100644 src/app/features/admin/settings/pages/admin-settings-page.component.spec.ts diff --git a/src/app/features/admin/settings/pages/admin-settings-page.component.html b/src/app/features/admin/settings/pages/admin-settings-page.component.html index 00ba29e..6b415fa 100644 --- a/src/app/features/admin/settings/pages/admin-settings-page.component.html +++ b/src/app/features/admin/settings/pages/admin-settings-page.component.html @@ -32,4 +32,23 @@ {{ 'adminSettings.currencyRatesSaved' | translate }} + +
+

{{ 'adminSettings.notificationInterval' | translate }}

+

{{ 'adminSettings.notificationIntervalExplain' | translate }}

+
+ +
+
+ + {{ 'adminSettings.notificationIntervalSaved' | translate }} +
+
diff --git a/src/app/features/admin/settings/pages/admin-settings-page.component.spec.ts b/src/app/features/admin/settings/pages/admin-settings-page.component.spec.ts new file mode 100644 index 0000000..32859cb --- /dev/null +++ b/src/app/features/admin/settings/pages/admin-settings-page.component.spec.ts @@ -0,0 +1,42 @@ +import { TestBed } from '@angular/core/testing'; +import { provideRouter } from '@angular/router'; +import { signal } from '@angular/core'; +import { AdminSettingsPageComponent } from './admin-settings-page.component'; +import { AdminOrderWatcherService } from '../../shell/services/admin-order-watcher.service'; + +describe('AdminSettingsPageComponent notification interval', () => { + let watcherStub: { + intervalMs: ReturnType>; + setIntervalSeconds: jasmine.Spy; + }; + + beforeEach(() => { + watcherStub = { + intervalMs: signal(15000), + setIntervalSeconds: jasmine.createSpy('setIntervalSeconds'), + }; + + TestBed.configureTestingModule({ + imports: [AdminSettingsPageComponent], + providers: [ + provideRouter([]), + { provide: AdminOrderWatcherService, useValue: watcherStub }, + ], + }); + }); + + it('initializes the draft from the current interval in seconds', () => { + const fixture = TestBed.createComponent(AdminSettingsPageComponent); + expect(fixture.componentInstance.notificationIntervalSecondsDraft()).toBe(15); + }); + + it('saveNotificationInterval calls setIntervalSeconds with the draft value', () => { + const fixture = TestBed.createComponent(AdminSettingsPageComponent); + const component = fixture.componentInstance; + + component.notificationIntervalSecondsDraft.set(30); + component.saveNotificationInterval(); + + expect(watcherStub.setIntervalSeconds).toHaveBeenCalledWith(30); + }); +}); diff --git a/src/app/features/admin/settings/pages/admin-settings-page.component.ts b/src/app/features/admin/settings/pages/admin-settings-page.component.ts index da46840..b32a6a4 100644 --- a/src/app/features/admin/settings/pages/admin-settings-page.component.ts +++ b/src/app/features/admin/settings/pages/admin-settings-page.component.ts @@ -6,6 +6,7 @@ import { TranslatePipe } from '../../../../i18n/translate.pipe'; import { ToggleComponent } from '../../../../shared/ui/toggle/toggle.component'; import { CurrencyRatesService } from '../../../../services/currency-rates.service'; import { LanguageService } from '../../../../services/language.service'; +import { AdminOrderWatcherService } from '../../shell/services/admin-order-watcher.service'; const SAVED_MESSAGE_DURATION_MS = 2000; @@ -25,6 +26,16 @@ export class AdminSettingsPageComponent { readonly rateDrafts = signal>({ ...this.currencyRates.rates() }); readonly showSavedMessage = signal(false); + readonly orderWatcher = inject(AdminOrderWatcherService); + readonly notificationIntervalSecondsDraft = signal(Math.round(this.orderWatcher.intervalMs() / 1000)); + readonly showNotificationIntervalSaved = signal(false); + + saveNotificationInterval(): void { + this.orderWatcher.setIntervalSeconds(this.notificationIntervalSecondsDraft()); + this.showNotificationIntervalSaved.set(true); + setTimeout(() => this.showNotificationIntervalSaved.set(false), SAVED_MESSAGE_DURATION_MS); + } + onCompactToggle(compact: boolean): void { this.preferences.setDensity(compact ? 'compact' : 'comfortable'); } diff --git a/src/app/i18n/en.ts b/src/app/i18n/en.ts index fd7f88e..d543aac 100644 --- a/src/app/i18n/en.ts +++ b/src/app/i18n/en.ts @@ -1951,6 +1951,10 @@ export const en: Translations = { currencyRatesExplain: 'Rates relative to 1 RUB, used to convert storefront prices while the backend does not return prices per currency.', currencyRatesSave: 'Save rates', currencyRatesSaved: 'Rates saved', + notificationInterval: 'New-order check interval (seconds)', + notificationIntervalExplain: 'How often the admin panel polls for new orders to show a notification.', + notificationIntervalSave: 'Save interval', + notificationIntervalSaved: 'Interval saved', }, adminAnalytics: { topProductsEmptyTitle: 'No product sales in this period', diff --git a/src/app/i18n/hy.ts b/src/app/i18n/hy.ts index 144e43d..68ff444 100644 --- a/src/app/i18n/hy.ts +++ b/src/app/i18n/hy.ts @@ -1946,6 +1946,10 @@ export const hy: Translations = { currencyRatesExplain: 'Փոխարժեքներ՝ 1 RUB-ի նկատմամբ, օգտագործվում են կայքի գները փոխարկելու համար, քանի դեռ բեքենդը գներ չի վերադարձնում ըստ արժույթի։', currencyRatesSave: 'Պահպանել փոխարժեքները', currencyRatesSaved: 'Փոխարժեքները պահպանվեցին', + notificationInterval: 'Նոր պատվերների ստուգման ինտերվալ (վրկ)', + notificationIntervalExplain: 'Որքան հաճախ է ադմին վահանակը ստուգում նոր պատվերներ ծանուցման համար։', + notificationIntervalSave: 'Պահպանել ինտերվալը', + notificationIntervalSaved: 'Ինտերվալը պահպանվեց', }, adminAnalytics: { topProductsEmptyTitle: 'Այս ժամանակահատվածում ապրանքների վաճառք չկա', diff --git a/src/app/i18n/ru.ts b/src/app/i18n/ru.ts index 4a2a39f..a2963a9 100644 --- a/src/app/i18n/ru.ts +++ b/src/app/i18n/ru.ts @@ -1946,6 +1946,10 @@ export const ru: Translations = { currencyRatesExplain: 'Курсы относительно 1 RUB, используются для конвертации цен на сайте, пока бэкенд не возвращает цены в разных валютах.', currencyRatesSave: 'Сохранить курсы', currencyRatesSaved: 'Курсы сохранены', + notificationInterval: 'Интервал проверки новых заказов (сек)', + notificationIntervalExplain: 'Как часто админ-панель проверяет новые заказы для уведомления.', + notificationIntervalSave: 'Сохранить интервал', + notificationIntervalSaved: 'Интервал сохранён', }, adminAnalytics: { topProductsEmptyTitle: 'Нет продаж товаров за этот период', diff --git a/src/app/i18n/translations.ts b/src/app/i18n/translations.ts index 59f93a2..4227d80 100644 --- a/src/app/i18n/translations.ts +++ b/src/app/i18n/translations.ts @@ -1959,6 +1959,10 @@ export interface Translations { currencyRatesExplain: string; currencyRatesSave: string; currencyRatesSaved: string; + notificationInterval: string; + notificationIntervalExplain: string; + notificationIntervalSave: string; + notificationIntervalSaved: string; }; adminAnalytics: { topProductsEmptyTitle: string;