diff --git a/docs/concepts/configuration.md b/docs/concepts/configuration.md index f33f703dd6..71f85c6ced 100644 --- a/docs/concepts/configuration.md +++ b/docs/concepts/configuration.md @@ -128,7 +128,7 @@ To access these properties we provide the [`StatePropertiesService`](../../src/a ICM provides a Configurations REST resource - `/configurations` - that is supposed to provide all relevant runtime configurations that can be defined in the ICM back office and are required to configure a REST client as well. This includes service configurations, locales, basket preferences, etc. -The ICM configurations information can be accessed through the [`getServerConfigParameter`](../../src/app/core/store/general/server-config/server-config.selectors.ts) selector. +The ICM configurations information can be accessed through the [`getServerConfigParameter`](../../src/app/core/store/core/server-config/server-config.selectors.ts) selector. ## ICM Endpoint Configuration diff --git a/e2e/cypress/integration/pages/meta-data.module.ts b/e2e/cypress/integration/pages/meta-data.module.ts index 13233b7339..a8c18df7e6 100644 --- a/e2e/cypress/integration/pages/meta-data.module.ts +++ b/e2e/cypress/integration/pages/meta-data.module.ts @@ -11,7 +11,7 @@ export class MetaDataModule { 'og:image': /.*og-image-default.*/, 'og:type': 'website', 'og:locale': 'en_US', - 'og:locale:alternate': ['de_DE', 'fr_FR'], + 'og:locale:alternate': ['fr_FR', 'de_DE'], }; meta(key: string) { @@ -29,7 +29,7 @@ export class MetaDataModule { } private checkStrategy(val: string | RegExp | string[]) { - return typeof val === 'string' ? 'equal' : Array.isArray(val) ? 'deep.equal' : 'match'; + return typeof val === 'string' ? 'equal' : Array.isArray(val) ? 'include.members' : 'match'; } check(expect: { title?: string; url?: RegExp; description?: string; [key: string]: string | RegExp }) { diff --git a/src/app/core/facades/app.facade.ts b/src/app/core/facades/app.facade.ts index d0f687fa6f..ac0b9919e4 100644 --- a/src/app/core/facades/app.facade.ts +++ b/src/app/core/facades/app.facade.ts @@ -13,11 +13,11 @@ import { } from 'ish-core/store/core/configuration'; import { businessError, getGeneralError, getGeneralErrorType } from 'ish-core/store/core/error'; import { selectPath } from 'ish-core/store/core/router'; +import { getServerConfigParameter } from 'ish-core/store/core/server-config'; import { getBreadcrumbData, getHeaderType, getWrapperClass, isStickyHeader } from 'ish-core/store/core/viewconf'; import { getLoggedInCustomer } from 'ish-core/store/customer/user'; import { getAllCountries, loadCountries } from 'ish-core/store/general/countries'; import { getRegionsByCountryCode, loadRegions } from 'ish-core/store/general/regions'; -import { getServerConfigParameter } from 'ish-core/store/general/server-config'; @Injectable({ providedIn: 'root' }) export class AppFacade { diff --git a/src/app/core/facades/checkout.facade.ts b/src/app/core/facades/checkout.facade.ts index 3d0cce69a5..916ea6f52e 100644 --- a/src/app/core/facades/checkout.facade.ts +++ b/src/app/core/facades/checkout.facade.ts @@ -8,6 +8,7 @@ import { Attribute } from 'ish-core/models/attribute/attribute.model'; import { LineItemUpdate } from 'ish-core/models/line-item-update/line-item-update.model'; import { PaymentInstrument } from 'ish-core/models/payment-instrument/payment-instrument.model'; import { selectRouteData } from 'ish-core/store/core/router'; +import { getServerConfigParameter } from 'ish-core/store/core/server-config'; import { getAllAddresses } from 'ish-core/store/customer/addresses'; import { addPromotionCodeToBasket, @@ -47,7 +48,6 @@ import { } from 'ish-core/store/customer/basket'; import { getOrdersError, getSelectedOrder } from 'ish-core/store/customer/orders'; import { getLoggedInUser } from 'ish-core/store/customer/user'; -import { getServerConfigParameter } from 'ish-core/store/general/server-config'; import { whenFalsy, whenTruthy } from 'ish-core/utils/operators'; // tslint:disable:member-ordering diff --git a/src/app/core/services/api/api.service.spec.ts b/src/app/core/services/api/api.service.spec.ts index 2b1fd7ebfd..ea466d1f32 100644 --- a/src/app/core/services/api/api.service.spec.ts +++ b/src/app/core/services/api/api.service.spec.ts @@ -525,7 +525,7 @@ describe('Api Service', () => { TestBed.configureTestingModule({ // https://angular.io/guide/http#testing-http-requests imports: [ - CoreStoreModule.forTesting(['configuration']), + CoreStoreModule.forTesting(['configuration', 'serverConfig']), CustomerStoreModule.forTesting('user'), HttpClientTestingModule, ], diff --git a/src/app/core/store/core/configuration/configuration.effects.spec.ts b/src/app/core/store/core/configuration/configuration.effects.spec.ts index a0f0e64bfe..6471e25f13 100644 --- a/src/app/core/store/core/configuration/configuration.effects.spec.ts +++ b/src/app/core/store/core/configuration/configuration.effects.spec.ts @@ -22,7 +22,10 @@ describe('Configuration Effects', () => { translateServiceMock = mock(TranslateService); TestBed.configureTestingModule({ - imports: [BrowserTransferStateModule, CoreStoreModule.forTesting(['configuration'], [ConfigurationEffects])], + imports: [ + BrowserTransferStateModule, + CoreStoreModule.forTesting(['configuration', 'serverConfig'], [ConfigurationEffects]), + ], providers: [ { provide: TranslateService, useFactory: () => instance(translateServiceMock) }, provideMockActions(() => actions$), diff --git a/src/app/core/store/core/configuration/configuration.integration.spec.ts b/src/app/core/store/core/configuration/configuration.integration.spec.ts index b5e79f11c8..29159a55a4 100644 --- a/src/app/core/store/core/configuration/configuration.integration.spec.ts +++ b/src/app/core/store/core/configuration/configuration.integration.spec.ts @@ -35,7 +35,11 @@ describe('Configuration Integration', () => { declarations: [DummyComponent], imports: [ BrowserTransferStateModule, - CoreStoreModule.forTesting(['router', 'configuration'], [ConfigurationEffects], [configurationMeta]), + CoreStoreModule.forTesting( + ['router', 'configuration', 'serverConfig'], + [ConfigurationEffects], + [configurationMeta] + ), RouterTestingModule.withRoutes([ { path: 'home', component: DummyComponent, canActivate: [ConfigurationGuard] }, ]), diff --git a/src/app/core/store/core/configuration/configuration.reducer.ts b/src/app/core/store/core/configuration/configuration.reducer.ts index a6e4d4d1b6..9492b081fe 100644 --- a/src/app/core/store/core/configuration/configuration.reducer.ts +++ b/src/app/core/store/core/configuration/configuration.reducer.ts @@ -17,6 +17,7 @@ export interface ConfigurationState { identityProviders?: { [id: string]: { type?: string; [key: string]: unknown } }; features?: string[]; theme?: string; + defaultLocale?: string; locales?: Locale[]; lang?: string; // not synced via state transfer @@ -31,6 +32,7 @@ const initialState: ConfigurationState = { application: undefined, features: undefined, theme: undefined, + defaultLocale: environment.defaultLocale, locales: environment.locales, lang: undefined, _deviceType: environment.defaultDeviceType, diff --git a/src/app/core/store/core/configuration/configuration.selectors.spec.ts b/src/app/core/store/core/configuration/configuration.selectors.spec.ts index d3f28fce5c..376e918398 100644 --- a/src/app/core/store/core/configuration/configuration.selectors.spec.ts +++ b/src/app/core/store/core/configuration/configuration.selectors.spec.ts @@ -1,6 +1,8 @@ import { TestBed } from '@angular/core/testing'; +import { Locale } from 'ish-core/models/locale/locale.model'; import { CoreStoreModule } from 'ish-core/store/core/core-store.module'; +import { loadServerConfigSuccess } from 'ish-core/store/core/server-config'; import { StoreWithSnapshots, provideStoreSnapshots } from 'ish-core/utils/dev/ngrx-testing'; import { applyConfiguration } from './configuration.actions'; @@ -21,7 +23,7 @@ describe('Configuration Selectors', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [CoreStoreModule.forTesting(['configuration'])], + imports: [CoreStoreModule.forTesting(['configuration', 'serverConfig'])], providers: [provideStoreSnapshots()], }); @@ -106,4 +108,109 @@ describe('Configuration Selectors', () => { `); }); }); + + describe('after setting default locales', () => { + beforeEach(() => { + store$.dispatch( + applyConfiguration({ + locales: [ + { lang: 'de_DE' }, + { lang: 'en_US' }, + { lang: 'fr_BE' }, + { lang: 'nl_BE' }, + { lang: 'no_NO' }, + { lang: 'zh_CN' }, + ] as Locale[], + }) + ); + }); + + describe('without ICM server configuration', () => { + it('should choose the internal default Locale when no ICM is available', () => { + store$.dispatch( + applyConfiguration({ + ...store$.state.configuration, + defaultLocale: 'en_US', + }) + ); + expect(getCurrentLocale(store$.state)).toMatchInlineSnapshot(` + Object { + "lang": "en_US", + } + `); + }); + + it('should choose the first locale when no ICM or internal configuration is available', () => { + store$.dispatch( + applyConfiguration({ + ...store$.state.configuration, + defaultLocale: undefined, + }) + ); + expect(getCurrentLocale(store$.state)).toMatchInlineSnapshot(` + Object { + "lang": "de_DE", + } + `); + }); + + it.each` + requested | chosen + ${'de_DE'} | ${'de_DE'} + ${'no_NO'} | ${'no_NO'} + ${'nl_BE'} | ${'nl_BE'} + ${'zh_CN'} | ${'zh_CN'} + ${'nl_NL'} | ${'de_DE'} + `('should choose $chosen when $requested is requested', ({ requested, chosen }) => { + store$.dispatch(applyConfiguration({ lang: requested, defaultLocale: undefined })); + expect(getCurrentLocale(store$.state)?.lang).toEqual(chosen); + }); + }); + + describe('with ICM server configuration', () => { + beforeEach(() => { + store$.dispatch( + loadServerConfigSuccess({ + config: { + general: { + defaultLocale: 'en_US', + locales: ['en_US', 'de_DE', 'fr_BE', 'nl_BE', 'fr_FR'], + }, + }, + }) + ); + }); + + it('should filter available locales for matching ICM server locales', () => { + expect(getAvailableLocales(store$.state)?.map(l => l.lang)).toMatchInlineSnapshot(` + Array [ + "en_US", + "de_DE", + "fr_BE", + "nl_BE", + ] + `); + }); + + it('should choose the ICM configured default locale when ICM configuration is available', () => { + expect(getCurrentLocale(store$.state)).toMatchInlineSnapshot(` + Object { + "lang": "en_US", + } + `); + }); + + it.each` + requested | chosen + ${'de_DE'} | ${'de_DE'} + ${'no_NO'} | ${'en_US'} + ${'nl_BE'} | ${'nl_BE'} + ${'zh_CN'} | ${'en_US'} + ${'nl_NL'} | ${'en_US'} + `('should choose $chosen when $requested is requested', ({ requested, chosen }) => { + store$.dispatch(applyConfiguration({ lang: requested })); + expect(getCurrentLocale(store$.state)?.lang).toEqual(chosen); + }); + }); + }); }); diff --git a/src/app/core/store/core/configuration/configuration.selectors.ts b/src/app/core/store/core/configuration/configuration.selectors.ts index f34d2d83ed..5fd0920771 100644 --- a/src/app/core/store/core/configuration/configuration.selectors.ts +++ b/src/app/core/store/core/configuration/configuration.selectors.ts @@ -2,6 +2,7 @@ import { createSelector, createSelectorFactory, resultMemoize } from '@ngrx/stor import { isEqual } from 'lodash-es'; import { getCoreState } from 'ish-core/store/core/core-store'; +import { getServerConfigParameter } from 'ish-core/store/core/server-config'; import { ConfigurationState } from './configuration.reducer'; @@ -33,14 +34,44 @@ export const getFeatures = createSelector(getConfigurationState, state => state. export const getTheme = createSelector(getConfigurationState, state => state.theme); -export const getAvailableLocales = createSelector(getConfigurationState, state => state.locales); +const defaultLocale = createSelector(getConfigurationState, state => state.defaultLocale); + +/** + * locales configured in environment.ts + */ +const internalLocales = createSelector(getConfigurationState, state => state.locales); + +/** + * environment.ts locales filtered by locales configured in ICM + * + * TODO: available locales should not be filtered by local environment, + * if no locale is available, then a default configured locale from environment.ts should be loaded as fallback + */ +export const getAvailableLocales = createSelector( + internalLocales, + getServerConfigParameter('general.locales'), + (configured, activated) => + activated?.length ? activated.map(lang => configured?.find(l => l.lang === lang)).filter(x => !!x) : configured +); + +const internalRequestedLocale = createSelector(getConfigurationState, state => state.lang); /** * selects the current locale if set. If not returns the first available locale + * tries to find requested locale, + * falls back to ICM configured default locale if no match is found, + * and finally falls back to first available locale if none is configured */ export const getCurrentLocale = createSelector( - getConfigurationState, - state => state.locales.find(l => l.lang === state.lang) || state.locales[0] + getAvailableLocales, + internalRequestedLocale, + defaultLocale, + getServerConfigParameter('general.defaultLocale'), + (available, requested, internalDefaultLocale, configuredDefault) => + available?.find(l => l.lang === requested) ?? + available?.find(l => l.lang === configuredDefault) ?? + available?.find(l => l.lang === internalDefaultLocale) ?? + available?.[0] ); export const getDeviceType = createSelector(getConfigurationState, state => state._deviceType); diff --git a/src/app/core/store/core/core-store.module.ts b/src/app/core/store/core/core-store.module.ts index 6095e69291..355fdf3f89 100644 --- a/src/app/core/store/core/core-store.module.ts +++ b/src/app/core/store/core/core-store.module.ts @@ -17,6 +17,8 @@ import { ErrorEffects } from './error/error.effects'; import { errorReducer } from './error/error.reducer'; import { MessagesEffects } from './messages/messages.effects'; import { CustomRouterSerializer } from './router/router.serializer'; +import { ServerConfigEffects } from './server-config/server-config.effects'; +import { serverConfigReducer } from './server-config/server-config.reducer'; import { ViewconfEffects } from './viewconf/viewconf.effects'; import { viewconfReducer } from './viewconf/viewconf.reducer'; @@ -25,9 +27,10 @@ const coreReducers: ActionReducerMap = { error: errorReducer, viewconf: viewconfReducer, configuration: configurationReducer, + serverConfig: serverConfigReducer, }; -const coreEffects = [ErrorEffects, ViewconfEffects, ConfigurationEffects, MessagesEffects]; +const coreEffects = [ErrorEffects, ViewconfEffects, ConfigurationEffects, MessagesEffects, ServerConfigEffects]; const coreMetaReducers: MetaReducer[] = [ ngrxStateTransferMeta, diff --git a/src/app/core/store/core/core-store.ts b/src/app/core/store/core/core-store.ts index 8325bd7fff..8782f1a2c8 100644 --- a/src/app/core/store/core/core-store.ts +++ b/src/app/core/store/core/core-store.ts @@ -6,12 +6,14 @@ import { ErrorState } from 'ish-core/store/core/error/error.reducer'; import { ViewconfState } from 'ish-core/store/core/viewconf/viewconf.reducer'; import { RouterState } from './router/router.reducer'; +import { ServerConfigState } from './server-config/server-config.reducer'; export interface CoreState { router: RouterReducerState; error: ErrorState; viewconf: ViewconfState; configuration: ConfigurationState; + serverConfig: ServerConfigState; } export const getCoreState: Selector = state => state; diff --git a/src/app/core/store/general/server-config/index.ts b/src/app/core/store/core/server-config/index.ts similarity index 100% rename from src/app/core/store/general/server-config/index.ts rename to src/app/core/store/core/server-config/index.ts diff --git a/src/app/core/store/general/server-config/server-config.actions.ts b/src/app/core/store/core/server-config/server-config.actions.ts similarity index 100% rename from src/app/core/store/general/server-config/server-config.actions.ts rename to src/app/core/store/core/server-config/server-config.actions.ts diff --git a/src/app/core/store/general/server-config/server-config.effects.spec.ts b/src/app/core/store/core/server-config/server-config.effects.spec.ts similarity index 95% rename from src/app/core/store/general/server-config/server-config.effects.spec.ts rename to src/app/core/store/core/server-config/server-config.effects.spec.ts index ac5820be36..9bcbf26c01 100644 --- a/src/app/core/store/general/server-config/server-config.effects.spec.ts +++ b/src/app/core/store/core/server-config/server-config.effects.spec.ts @@ -8,7 +8,6 @@ import { instance, mock, when } from 'ts-mockito'; import { ConfigurationService } from 'ish-core/services/configuration/configuration.service'; import { CoreStoreModule } from 'ish-core/store/core/core-store.module'; -import { GeneralStoreModule } from 'ish-core/store/general/general-store.module'; import { makeHttpError } from 'ish-core/utils/dev/api-service-utils'; import { StoreWithSnapshots, provideStoreSnapshots } from 'ish-core/utils/dev/ngrx-testing'; import { routerTestNavigationAction } from 'ish-core/utils/dev/routing'; @@ -25,7 +24,7 @@ describe('Server Config Effects', () => { when(configurationServiceMock.getServerConfiguration()).thenReturn(of({})); TestBed.configureTestingModule({ - imports: [CoreStoreModule.forTesting([], [ServerConfigEffects]), GeneralStoreModule.forTesting('serverConfig')], + imports: [CoreStoreModule.forTesting(['serverConfig'], [ServerConfigEffects])], providers: [ provideStoreSnapshots(), { provide: ConfigurationService, useFactory: () => instance(configurationServiceMock) }, diff --git a/src/app/core/store/general/server-config/server-config.effects.ts b/src/app/core/store/core/server-config/server-config.effects.ts similarity index 100% rename from src/app/core/store/general/server-config/server-config.effects.ts rename to src/app/core/store/core/server-config/server-config.effects.ts diff --git a/src/app/core/store/general/server-config/server-config.reducer.ts b/src/app/core/store/core/server-config/server-config.reducer.ts similarity index 100% rename from src/app/core/store/general/server-config/server-config.reducer.ts rename to src/app/core/store/core/server-config/server-config.reducer.ts diff --git a/src/app/core/store/general/server-config/server-config.selectors.spec.ts b/src/app/core/store/core/server-config/server-config.selectors.spec.ts similarity index 93% rename from src/app/core/store/general/server-config/server-config.selectors.spec.ts rename to src/app/core/store/core/server-config/server-config.selectors.spec.ts index c3aa7de0e2..e476813a7c 100644 --- a/src/app/core/store/general/server-config/server-config.selectors.spec.ts +++ b/src/app/core/store/core/server-config/server-config.selectors.spec.ts @@ -1,7 +1,6 @@ import { TestBed } from '@angular/core/testing'; import { CoreStoreModule } from 'ish-core/store/core/core-store.module'; -import { GeneralStoreModule } from 'ish-core/store/general/general-store.module'; import { StoreWithSnapshots, provideStoreSnapshots } from 'ish-core/utils/dev/ngrx-testing'; import { loadServerConfigSuccess } from './server-config.actions'; @@ -12,7 +11,7 @@ describe('Server Config Selectors', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [CoreStoreModule.forTesting(), GeneralStoreModule.forTesting('serverConfig')], + imports: [CoreStoreModule.forTesting(['serverConfig'])], providers: [provideStoreSnapshots()], }); diff --git a/src/app/core/store/general/server-config/server-config.selectors.ts b/src/app/core/store/core/server-config/server-config.selectors.ts similarity index 76% rename from src/app/core/store/general/server-config/server-config.selectors.ts rename to src/app/core/store/core/server-config/server-config.selectors.ts index 24a9636d1c..14eaf5dcc6 100644 --- a/src/app/core/store/general/server-config/server-config.selectors.ts +++ b/src/app/core/store/core/server-config/server-config.selectors.ts @@ -1,8 +1,8 @@ import { createSelector } from '@ngrx/store'; -import { getGeneralState } from 'ish-core/store/general/general-store'; +import { getCoreState } from 'ish-core/store/core/core-store'; -const getServerConfigState = createSelector(getGeneralState, state => state.serverConfig); +const getServerConfigState = createSelector(getCoreState, state => state.serverConfig); const getServerConfig = createSelector(getServerConfigState, state => state._config); diff --git a/src/app/core/store/customer/basket/basket-validation.effects.spec.ts b/src/app/core/store/customer/basket/basket-validation.effects.spec.ts index 35c6ba4477..ef0e59b772 100644 --- a/src/app/core/store/customer/basket/basket-validation.effects.spec.ts +++ b/src/app/core/store/customer/basket/basket-validation.effects.spec.ts @@ -12,10 +12,9 @@ import { BasketValidation } from 'ish-core/models/basket-validation/basket-valid import { Product } from 'ish-core/models/product/product.model'; import { BasketService } from 'ish-core/services/basket/basket.service'; import { CoreStoreModule } from 'ish-core/store/core/core-store.module'; +import { loadServerConfigSuccess } from 'ish-core/store/core/server-config'; import { CustomerStoreModule } from 'ish-core/store/customer/customer-store.module'; import { createOrder } from 'ish-core/store/customer/orders'; -import { GeneralStoreModule } from 'ish-core/store/general/general-store.module'; -import { loadServerConfigSuccess } from 'ish-core/store/general/server-config'; import { loadProductSuccess } from 'ish-core/store/shopping/products'; import { makeHttpError } from 'ish-core/utils/dev/api-service-utils'; import { BasketMockData } from 'ish-core/utils/dev/basket-mock-data'; @@ -50,9 +49,8 @@ describe('Basket Validation Effects', () => { TestBed.configureTestingModule({ declarations: [DummyComponent], imports: [ - CoreStoreModule.forTesting(), + CoreStoreModule.forTesting(['serverConfig']), CustomerStoreModule.forTesting('user', 'basket'), - GeneralStoreModule.forTesting('serverConfig'), RouterTestingModule.withRoutes([ { path: 'checkout', children: [{ path: 'address', component: DummyComponent }] }, { path: 'checkout', children: [{ path: 'review', component: DummyComponent }] }, diff --git a/src/app/core/store/customer/basket/basket-validation.effects.ts b/src/app/core/store/customer/basket/basket-validation.effects.ts index 620f48f8ce..b7a8376b6e 100644 --- a/src/app/core/store/customer/basket/basket-validation.effects.ts +++ b/src/app/core/store/customer/basket/basket-validation.effects.ts @@ -12,8 +12,8 @@ import { BasketValidationScopeType, } from 'ish-core/models/basket-validation/basket-validation.model'; import { BasketService } from 'ish-core/services/basket/basket.service'; +import { getServerConfigParameter } from 'ish-core/store/core/server-config'; import { createOrder } from 'ish-core/store/customer/orders'; -import { getServerConfigParameter } from 'ish-core/store/general/server-config'; import { loadProduct } from 'ish-core/store/shopping/products'; import { mapErrorToAction, mapToPayload, mapToPayloadProperty, whenTruthy } from 'ish-core/utils/operators'; diff --git a/src/app/core/store/customer/customer-store.spec.ts b/src/app/core/store/customer/customer-store.spec.ts index 18d99974d3..40f343f294 100644 --- a/src/app/core/store/customer/customer-store.spec.ts +++ b/src/app/core/store/customer/customer-store.spec.ts @@ -31,7 +31,6 @@ import { CoreStoreModule } from 'ish-core/store/core/core-store.module'; import { CustomerStoreModule } from 'ish-core/store/customer/customer-store.module'; import { loginUser } from 'ish-core/store/customer/user'; import { UserEffects } from 'ish-core/store/customer/user/user.effects'; -import { GeneralStoreModule } from 'ish-core/store/general/general-store.module'; import { loadProductSuccess } from 'ish-core/store/shopping/products'; import { ShoppingStoreModule } from 'ish-core/store/shopping/shopping-store.module'; import { CookiesService } from 'ish-core/utils/cookies/cookies.service'; @@ -157,9 +156,8 @@ describe('Customer Store', () => { TestBed.configureTestingModule({ declarations: [DummyComponent], imports: [ - CoreStoreModule.forTesting(['configuration'], [UserEffects]), + CoreStoreModule.forTesting(['configuration', 'serverConfig'], [UserEffects]), CustomerStoreModule, - GeneralStoreModule.forTesting('serverConfig'), RouterTestingModule.withRoutes([ { path: 'account', diff --git a/src/app/core/store/customer/user/user.selectors.spec.ts b/src/app/core/store/customer/user/user.selectors.spec.ts index 2226d20083..9c9c06a6d0 100644 --- a/src/app/core/store/customer/user/user.selectors.spec.ts +++ b/src/app/core/store/customer/user/user.selectors.spec.ts @@ -6,9 +6,8 @@ import { PaymentMethod } from 'ish-core/models/payment-method/payment-method.mod import { Product } from 'ish-core/models/product/product.model'; import { User } from 'ish-core/models/user/user.model'; import { CoreStoreModule } from 'ish-core/store/core/core-store.module'; +import { loadServerConfigSuccess } from 'ish-core/store/core/server-config'; import { CustomerStoreModule } from 'ish-core/store/customer/customer-store.module'; -import { GeneralStoreModule } from 'ish-core/store/general/general-store.module'; -import { loadServerConfigSuccess } from 'ish-core/store/general/server-config'; import { loadProductSuccess } from 'ish-core/store/shopping/products'; import { makeHttpError } from 'ish-core/utils/dev/api-service-utils'; import { StoreWithSnapshots, provideStoreSnapshots } from 'ish-core/utils/dev/ngrx-testing'; @@ -42,11 +41,7 @@ describe('User Selectors', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ - CoreStoreModule.forTesting(['configuration']), - CustomerStoreModule.forTesting('user'), - GeneralStoreModule.forTesting('serverConfig'), - ], + imports: [CoreStoreModule.forTesting(['configuration', 'serverConfig']), CustomerStoreModule.forTesting('user')], providers: [provideStoreSnapshots()], }); diff --git a/src/app/core/store/customer/user/user.selectors.ts b/src/app/core/store/customer/user/user.selectors.ts index 3e327ce645..02f399eb51 100644 --- a/src/app/core/store/customer/user/user.selectors.ts +++ b/src/app/core/store/customer/user/user.selectors.ts @@ -1,7 +1,7 @@ import { createSelector } from '@ngrx/store'; +import { getServerConfigParameter } from 'ish-core/store/core/server-config'; import { getCustomerState } from 'ish-core/store/customer/customer-store'; -import { getServerConfigParameter } from 'ish-core/store/general/server-config'; const getUserState = createSelector(getCustomerState, state => state.user); diff --git a/src/app/core/store/general/general-store.module.ts b/src/app/core/store/general/general-store.module.ts index b30f384bc2..8a143c653f 100644 --- a/src/app/core/store/general/general-store.module.ts +++ b/src/app/core/store/general/general-store.module.ts @@ -10,17 +10,14 @@ import { countriesReducer } from './countries/countries.reducer'; import { GeneralState } from './general-store'; import { RegionsEffects } from './regions/regions.effects'; import { regionsReducer } from './regions/regions.reducer'; -import { ServerConfigEffects } from './server-config/server-config.effects'; -import { serverConfigReducer } from './server-config/server-config.reducer'; const generalReducers: ActionReducerMap = { countries: countriesReducer, regions: regionsReducer, contact: contactReducer, - serverConfig: serverConfigReducer, }; -const generalEffects = [ContactEffects, CountriesEffects, RegionsEffects, ServerConfigEffects]; +const generalEffects = [ContactEffects, CountriesEffects, RegionsEffects]; @NgModule({ imports: [EffectsModule.forFeature(generalEffects), StoreModule.forFeature('general', generalReducers)], diff --git a/src/app/core/store/general/general-store.ts b/src/app/core/store/general/general-store.ts index 5f3919b159..4753dfbbc0 100644 --- a/src/app/core/store/general/general-store.ts +++ b/src/app/core/store/general/general-store.ts @@ -3,13 +3,11 @@ import { createFeatureSelector } from '@ngrx/store'; import { ContactState } from './contact/contact.reducer'; import { CountriesState } from './countries/countries.reducer'; import { RegionsState } from './regions/regions.reducer'; -import { ServerConfigState } from './server-config/server-config.reducer'; export interface GeneralState { countries: CountriesState; regions: RegionsState; contact: ContactState; - serverConfig: ServerConfigState; } export const getGeneralState = createFeatureSelector('general'); diff --git a/src/app/core/store/shopping/shopping-store.spec.ts b/src/app/core/store/shopping/shopping-store.spec.ts index 6c0e9cdb53..d21d1d6bcf 100644 --- a/src/app/core/store/shopping/shopping-store.spec.ts +++ b/src/app/core/store/shopping/shopping-store.spec.ts @@ -977,7 +977,7 @@ describe('Shopping Store', () => { categories: tree(A.123,A.123.456) @ngrx/router-store/cancel: routerState: {"url":"","params":{},"queryParams":{},"data":{}} - storeState: {"configuration":{"locales":[3],"_deviceType":"mobile"},"sho... + storeState: {"configuration":{"defaultLocale":"en_US","locales":[3],"_de... event: {"id":1,"url":"/category/A.123.456/product/P3"} @ngrx/router-store/request: routerState: {"url":"","params":{},"queryParams":{},"data":{}} @@ -1026,7 +1026,7 @@ describe('Shopping Store', () => { error: {"name":"HttpErrorResponse","message":"error loading categor... @ngrx/router-store/cancel: routerState: {"url":"","params":{},"queryParams":{},"data":{}} - storeState: {"configuration":{"locales":[3],"_deviceType":"mobile"},"sho... + storeState: {"configuration":{"defaultLocale":"en_US","locales":[3],"_de... event: {"id":1,"url":"/category/A.123.XXX"} @ngrx/router-store/request: routerState: {"url":"","params":{},"queryParams":{},"data":{}} diff --git a/src/app/extensions/captcha/facades/captcha.facade.ts b/src/app/extensions/captcha/facades/captcha.facade.ts index ba5a96980a..d5135a1e42 100644 --- a/src/app/extensions/captcha/facades/captcha.facade.ts +++ b/src/app/extensions/captcha/facades/captcha.facade.ts @@ -3,7 +3,7 @@ import { Store, select } from '@ngrx/store'; import { Observable } from 'rxjs'; import { filter, map, switchMap, switchMapTo } from 'rxjs/operators'; -import { getServerConfigParameter } from 'ish-core/store/general/server-config'; +import { getServerConfigParameter } from 'ish-core/store/core/server-config'; import { whenTruthy } from 'ish-core/utils/operators'; export type CaptchaTopic = diff --git a/src/environments/environment.model.ts b/src/environments/environment.model.ts index 221f5b3b83..89fef0cee5 100644 --- a/src/environments/environment.model.ts +++ b/src/environments/environment.model.ts @@ -74,6 +74,8 @@ export interface Environment { // default device type used for initial page responses defaultDeviceType: DeviceType; + defaultLocale?: string; + // configuration of the available locales - hard coded for now locales: Locale[]; @@ -117,6 +119,7 @@ export const ENVIRONMENT_DEFAULTS: Environment = { productListingItemsPerPage: 9, defaultProductListingViewType: 'grid', defaultDeviceType: 'mobile', + defaultLocale: 'en_US', locales: [ { lang: 'en_US', currency: 'USD', value: 'en', displayName: 'English', displayLong: 'English (United States)' }, { lang: 'de_DE', currency: 'EUR', value: 'de', displayName: 'German', displayLong: 'German (Germany)' },