Skip to content

Commit

Permalink
feat: add provideAlainConfig (#1689)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk committed Nov 10, 2023
1 parent d1ed91e commit b9e0fad
Show file tree
Hide file tree
Showing 23 changed files with 99 additions and 62 deletions.
6 changes: 3 additions & 3 deletions docs/global-config.en-US.md
Expand Up @@ -10,19 +10,19 @@ We add support of **global configuration** to many components. You can define th

## How to Use?

If you want to provide default configurations to some components, you should provide an object that implements the interface **AlainConfig** with the injection token **ALAIN_CONFIG**, in the root module (in another word, to the root injector). Like this:
If you want to provide default configurations to some components, please use `provideAlainConfig` function. object providing implements interface `AlainConfig` For example:

```typescript
// global-config.module.ts
import { AlainConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainConfig } from '@delon/util/config';

const alainConfig: AlainConfig = {
st: { ps: 3 },
};

@NgModule({
providers: [
{ provide: ALAIN_CONFIG, useValue: alainConfig },
provideAlainConfig(alainConfig)
],
})
export class GlobalConfigModule {}
Expand Down
6 changes: 3 additions & 3 deletions docs/global-config.zh-CN.md
Expand Up @@ -10,19 +10,19 @@ type: Dev

## 如何使用

想要为某些组件提供默认配置项,请在根注入器中根据注入令牌 `ALAIN_CONFIG` 提供一个符合 `AlainConfig` 接口的对象,例如:
想要为某些组件提供默认配置项,可以使用 `provideAlainConfig` 函数,转入一个符合 `AlainConfig` 接口的对象,例如:

```typescript
// global-config.module.ts
import { AlainConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainConfig } from '@delon/util/config';

const alainConfig: AlainConfig = {
st: { ps: 3 },
};

@NgModule({
providers: [
{ provide: ALAIN_CONFIG, useValue: alainConfig },
provideAlainConfig(alainConfig)
],
})
export class GlobalConfigModule {}
Expand Down
2 changes: 1 addition & 1 deletion docs/ssr.md
Expand Up @@ -77,7 +77,7 @@ export class AuthStorageStore implements IStore {

```diff
const alainProvides = [
{ provide: ALAIN_CONFIG, useValue: alainConfig },
provideAlainConfig(alainConfig)
+ { provide: DA_STORE_TOKEN, useClass: AuthStorageStore },
];
```
Expand Down
16 changes: 3 additions & 13 deletions packages/abc/st/test/st-sort.spec.ts
@@ -1,6 +1,6 @@
import { ComponentFixture, fakeAsync } from '@angular/core/testing';

import { AlainConfig, ALAIN_CONFIG } from '@delon/util/config';
import { provideAlainConfig } from '@delon/util/config';
import { NzSafeAny } from 'ng-zorro-antd/core/types';

import { PageObject, TestComponent, genModule } from './base.spec';
Expand Down Expand Up @@ -100,25 +100,15 @@ describe('abc: st-sort', () => {
it('should default is mulit sorting', () => {
page = genModule(TestComponent, {
minColumn: true,
providers: [
{
provide: ALAIN_CONFIG,
useValue: { st: { multiSort: { global: true } } } as AlainConfig
}
],
providers: [provideAlainConfig({ st: { multiSort: { global: true } } })],
createComp: true
})!;
expect(page.comp.multiSort).not.toBeUndefined();
});
it('should default non-mulit sorting', () => {
page = genModule(TestComponent, {
minColumn: true,
providers: [
{
provide: ALAIN_CONFIG,
useValue: { st: { multiSort: { global: false } } } as AlainConfig
}
],
providers: [provideAlainConfig({ st: { multiSort: { global: false } } })],
createComp: true
})!;
expect(page.comp.multiSort).toBeUndefined();
Expand Down
4 changes: 2 additions & 2 deletions packages/auth/src/token/base.interceptor.spec.ts
Expand Up @@ -17,7 +17,7 @@ import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable, throwError, catchError } from 'rxjs';

import { AlainAuthConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainAuthConfig, provideAlainConfig } from '@delon/util/config';

import { AuthReferrer, DA_SERVICE_TOKEN, ITokenModel, ITokenService } from './interface';
import { SimpleInterceptor } from './simple/simple.interceptor';
Expand Down Expand Up @@ -81,7 +81,7 @@ describe('auth: base.interceptor', () => {
imports: [HttpClientTestingModule, RouterTestingModule.withRoutes([]), DelonAuthModule],
providers: [
{ provide: DOCUMENT, useValue: MockDoc },
{ provide: ALAIN_CONFIG, useValue: { auth: options } },
provideAlainConfig({ auth: options }),
{
provide: HTTP_INTERCEPTORS,
useClass: SimpleInterceptor,
Expand Down
4 changes: 2 additions & 2 deletions packages/auth/src/token/jwt/jwt.interceptor.spec.ts
Expand Up @@ -5,7 +5,7 @@ import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { of, catchError } from 'rxjs';

import { AlainAuthConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainAuthConfig, provideAlainConfig } from '@delon/util/config';

import { JWTInterceptor } from './jwt.interceptor';
import { JWTTokenModel } from './jwt.model';
Expand Down Expand Up @@ -41,7 +41,7 @@ describe('auth: jwt.interceptor', () => {
DelonAuthModule
],
providers: [
{ provide: ALAIN_CONFIG, useValue: { auth: options } },
provideAlainConfig({ auth: options }),
{ provide: HTTP_INTERCEPTORS, useClass: JWTInterceptor, multi: true }
]
});
Expand Down
4 changes: 2 additions & 2 deletions packages/auth/src/token/simple/simple.interceptor.spec.ts
Expand Up @@ -7,7 +7,7 @@ import { DefaultUrlSerializer, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable } from 'rxjs';

import { AlainAuthConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainAuthConfig, provideAlainConfig } from '@delon/util/config';

import { SimpleInterceptor } from './simple.interceptor';
import { SimpleTokenModel } from './simple.model';
Expand Down Expand Up @@ -58,7 +58,7 @@ describe('auth: simple.interceptor', () => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule.withRoutes([]), DelonAuthModule],
providers: [
{ provide: ALAIN_CONFIG, useValue: { auth: options } },
provideAlainConfig({ auth: options }),
{ provide: Router, useValue: mockRouter },
{
provide: HTTP_INTERCEPTORS,
Expand Down
4 changes: 2 additions & 2 deletions packages/cache/src/cache.spec.ts
Expand Up @@ -5,7 +5,7 @@ import { Type } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { firstValueFrom, Observable, of, filter } from 'rxjs';

import { AlainCacheConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainCacheConfig, provideAlainConfig } from '@delon/util/config';

import { DelonCacheModule } from './cache.module';
import { CacheService } from './cache.service';
Expand Down Expand Up @@ -39,7 +39,7 @@ describe('cache: service', () => {
function genModule(options?: AlainCacheConfig): void {
const providers: any[] = [];
if (options) {
providers.push({ provide: ALAIN_CONFIG, useValue: { cache: options } });
providers.push(provideAlainConfig({ cache: options }));
}
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, DelonCacheModule],
Expand Down
6 changes: 3 additions & 3 deletions packages/chart/docs/getting-started.en-US.md
Expand Up @@ -29,7 +29,7 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
{ provide: ALAIN_CONFIG, useValue: alainConfig }
provideAlainConfig(alainConfig)
]
};
}
Expand Down Expand Up @@ -105,9 +105,9 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
{ provide: ALAIN_CONFIG, useValue: alainConfig }
provideAlainConfig(alainConfig)
]
};
}
}
```
```
4 changes: 2 additions & 2 deletions packages/chart/docs/getting-started.zh-CN.md
Expand Up @@ -41,7 +41,7 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
{ provide: ALAIN_CONFIG, useValue: alainConfig }
provideAlainConfig(alainConfig)
]
};
}
Expand Down Expand Up @@ -117,7 +117,7 @@ export class DelonModule {
return {
ngModule: DelonModule,
providers: [
{ provide: ALAIN_CONFIG, useValue: alainConfig }
provideAlainConfig(alainConfig)
]
};
}
Expand Down
4 changes: 2 additions & 2 deletions packages/mock/src/mock.interceptor.spec.ts
Expand Up @@ -18,7 +18,7 @@ import { Observable, lastValueFrom, map, of } from 'rxjs';

import * as Mock from 'mockjs';

import { AlainMockConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainMockConfig, provideAlainConfig } from '@delon/util/config';

import { MockRequest } from './interface';
import { DelonMockModule } from './mock.module';
Expand Down Expand Up @@ -81,7 +81,7 @@ describe('mock: interceptor', () => {
]),
DelonMockModule.forRoot({ data })
].concat(imports),
providers: ([{ provide: ALAIN_CONFIG, useValue: { mock: options } }] as any[]).concat(providers || [])
providers: ([provideAlainConfig({ mock: options })] as any[]).concat(providers || [])
});
http = TestBed.inject<HttpClient>(HttpClient);
httpMock = TestBed.inject(HttpTestingController as Type<HttpTestingController>);
Expand Down
4 changes: 2 additions & 2 deletions packages/mock/src/mock.service.spec.ts
Expand Up @@ -3,7 +3,7 @@ import { TestBed } from '@angular/core/testing';

import * as Mock from 'mockjs';

import { AlainMockConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainMockConfig, provideAlainConfig } from '@delon/util/config';

import { MockOptions, MockRequest, MockRule } from './interface';
import { MockService } from './mock.service';
Expand Down Expand Up @@ -32,7 +32,7 @@ describe('mock: service', () => {
function genModule(options: AlainMockConfig, mockOptions?: MockOptions): void {
TestBed.configureTestingModule({
imports: [DelonMockModule.forRoot(mockOptions)],
providers: [{ provide: ALAIN_CONFIG, useValue: { mock: options } }]
providers: [provideAlainConfig({ mock: options })]
});
srv = TestBed.inject<MockService>(MockService);
spyOn(console, 'log');
Expand Down
4 changes: 2 additions & 2 deletions packages/theme/src/services/http/http.spec.ts
Expand Up @@ -5,7 +5,7 @@ import { Type } from '@angular/core';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { of, catchError } from 'rxjs';

import { AlainThemeHttpClientConfig, ALAIN_CONFIG } from '@delon/util/config';
import { AlainThemeHttpClientConfig, provideAlainConfig } from '@delon/util/config';
import { deepCopy } from '@delon/util/other';
import { NzSafeAny } from 'ng-zorro-antd/core/types';

Expand All @@ -24,7 +24,7 @@ describe('theme: http.client', () => {
function createModule(config?: AlainThemeHttpClientConfig): void {
const providers: any[] = [_HttpClient];
if (config) {
providers.push({ provide: ALAIN_CONFIG, useValue: { themeHttp: config } });
providers.push(provideAlainConfig({ themeHttp: config }));
}
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
Expand Down
6 changes: 3 additions & 3 deletions packages/theme/src/services/i18n/i18n.spec.ts
Expand Up @@ -4,7 +4,7 @@ import { By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';

import { AlainConfig, ALAIN_CONFIG } from '@delon/util/config';
import { provideAlainConfig } from '@delon/util/config';

import { AlainI18NService, ALAIN_I18N_TOKEN } from './i18n';
import { alainI18nCanActivate, alainI18nCanActivateChild } from './i18n-url.guard';
Expand Down Expand Up @@ -70,7 +70,7 @@ describe('theme: i18n', () => {
TestBed.configureTestingModule({
imports: [AlainThemeModule],
declarations: [TestComponent],
providers: [{ provide: ALAIN_CONFIG, useValue: { themeI18n: { interpolation: ['#', '#'] } } as AlainConfig }]
providers: [provideAlainConfig({ themeI18n: { interpolation: ['#', '#'] } })]
});
fixture = TestBed.createComponent(TestComponent);
srv = fixture.debugElement.injector.get(ALAIN_I18N_TOKEN);
Expand Down Expand Up @@ -137,7 +137,7 @@ describe('theme: i18n', () => {
])
],
declarations: [TestComponent],
providers: [{ provide: ALAIN_CONFIG, useValue: { themeI18n: { paramNameOfUrlGuard: 'lang' } } as AlainConfig }]
providers: [provideAlainConfig({ themeI18n: { paramNameOfUrlGuard: 'lang' } })]
});
fixture = TestBed.createComponent(TestComponent);
srv = fixture.debugElement.injector.get(ALAIN_I18N_TOKEN);
Expand Down
2 changes: 1 addition & 1 deletion packages/theme/src/services/settings/index.en-US.md
Expand Up @@ -54,7 +54,7 @@ Support add the configuration of `ALAIN_SETTING_KEYS` via the `global-config.mod

```diff
const alainProvides = [
{ provide: ALAIN_CONFIG, useValue: alainConfig },
provideAlainConfig(alainConfig),
+ {
+ provide: ALAIN_SETTING_KEYS,
+ useValue: {
Expand Down
4 changes: 2 additions & 2 deletions packages/theme/src/services/settings/index.zh-CN.md
Expand Up @@ -54,7 +54,7 @@ type: Service

```diff
const alainProvides = [
{ provide: ALAIN_CONFIG, useValue: alainConfig },
provideAlainConfig(alainConfig),
+ {
+ provide: ALAIN_SETTING_KEYS,
+ useValue: {
Expand All @@ -64,4 +64,4 @@ type: Service
+ },
+ },
];
```
```
13 changes: 2 additions & 11 deletions packages/util/array/array.service.spec.ts
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { TestBed } from '@angular/core/testing';

import { AlainConfig, ALAIN_CONFIG } from '@delon/util/config';
import { provideAlainConfig } from '@delon/util/config';
import { deepCopy } from '@delon/util/other';
import { NzTreeBaseService, NzTreeNode } from 'ng-zorro-antd/core/tree';

Expand Down Expand Up @@ -230,16 +230,7 @@ describe('utils: array', () => {
describe('[config]', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: ALAIN_CONFIG,
useValue: {
utilArray: {
idMapName: 'ID'
}
} as AlainConfig
}
]
providers: [provideAlainConfig({ utilArray: { idMapName: 'ID' } })]
});
srv = TestBed.inject<ArrayService>(ArrayService);
});
Expand Down
6 changes: 5 additions & 1 deletion packages/util/config/config.types.ts
@@ -1,4 +1,4 @@
import { InjectionToken } from '@angular/core';
import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';

import {
AlainCellConfig,
Expand Down Expand Up @@ -72,3 +72,7 @@ export const ALAIN_CONFIG = new InjectionToken<AlainConfig>('alain-config', {
export function ALAIN_CONFIG_FACTORY(): AlainConfig {
return {};
}

export function provideAlainConfig(config: AlainConfig): EnvironmentProviders {
return makeEnvironmentProviders([{ provide: ALAIN_CONFIG, useValue: config }]);
}
8 changes: 8 additions & 0 deletions schematics/ng-update/upgrade-rules/v17/index.spec.ts
Expand Up @@ -63,4 +63,12 @@ describe('Schematic: ng-update: v17Rule', () => {
const content = tree.readContent(globalConfigPath);
expect(content).not.toContain(`AlainThemeModule.forRoot()`);
});

it('#replaceProvideAlainConfig', async () => {
const globalConfigPath = '/projects/foo/src/app/global-config.module.ts';
tree.create(globalConfigPath, `const alainProvides = [{ provide: ALAIN_CONFIG, useValue: alainConfig }];`);
await runMigration();
const content = tree.readContent(globalConfigPath);
expect(content).toContain(`provideAlainConfig(alainConfig)`);
});
});
9 changes: 8 additions & 1 deletion schematics/ng-update/upgrade-rules/v17/index.ts
Expand Up @@ -3,6 +3,7 @@ import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';

import { autoRegisterFormWidgets } from './autoRegisterFormWidgets';
import { removeAlainThemeModuleForRoot } from './removeAlainThemeModuleForRoot';
import { replaceProvideConfig } from './replaceProvideConfig';
import { logFinished, logInfo, logWarn } from '../../../utils';
import { UpgradeMainVersions } from '../../../utils/versions';

Expand Down Expand Up @@ -30,6 +31,12 @@ export function v17Rule(): Rule {
return async (tree: Tree, context: SchematicContext) => {
UpgradeMainVersions(tree);
logInfo(context, `Upgrade dependency version number`);
return chain([removeAlainThemeModuleForRoot(), autoRegisterFormWidgets(), qr(), finished()]);
return chain([
removeAlainThemeModuleForRoot(),
autoRegisterFormWidgets(),
replaceProvideConfig(),
qr(),
finished()
]);
};
}

0 comments on commit b9e0fad

Please sign in to comment.