ng-alain 21.0.5 → 21.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/application/files/root/.vscode/settings.json +6 -5
  2. package/application/files/root/eslint.config.mjs +10 -7
  3. package/application/files/src/app/app.config.ts +9 -1
  4. package/application/files/src/app/{app.component.ts → app.ts} +5 -5
  5. package/application/files/src/app/core/startup/startup.service.ts +17 -16
  6. package/application/files/src/app/layout/basic/{basic.component.ts → basic.ts} +18 -21
  7. package/application/files/src/app/layout/basic/widgets/{clear-storage.component.ts → clear-storage.ts} +5 -5
  8. package/application/files/src/app/layout/basic/widgets/fullscreen.ts +33 -0
  9. package/application/files/src/app/layout/basic/widgets/{i18n.component.ts → i18n.ts} +9 -13
  10. package/application/files/src/app/layout/basic/widgets/search.ts +98 -0
  11. package/application/files/src/app/layout/basic/widgets/{user.component.ts → user.ts} +4 -7
  12. package/application/files/src/app/layout/blank/{blank.component.ts → blank.ts} +2 -2
  13. package/application/files/src/app/layout/index.ts +3 -3
  14. package/application/files/src/app/layout/passport/{passport.component.ts → passport.ts} +6 -6
  15. package/application/files/src/app/routes/passport/routes.ts +2 -2
  16. package/application/files/src/app/routes/routes.ts +2 -2
  17. package/application/files/src/assets/color.less +295 -658
  18. package/application/files/src/assets/style.compact.css +1 -1
  19. package/application/files/src/assets/style.dark.css +1 -1
  20. package/application/files/src/main.ts +2 -2
  21. package/application/index.js +4 -4
  22. package/application/index.spec.ts +1 -1
  23. package/application/index.ts +4 -4
  24. package/ng-update/upgrade-rules/V21/index.js +1 -1
  25. package/ng-update/upgrade-rules/V21/index.js.map +1 -1
  26. package/ng-update/upgrade-rules/V21/index.ts +1 -1
  27. package/package.json +2 -2
  28. package/plugin/files/rtl/layout/basic/widgets/{rtl.component.ts → rtl.ts} +4 -8
  29. package/plugin/plugin.rtl.js +5 -5
  30. package/plugin/plugin.rtl.js.map +1 -1
  31. package/plugin/plugin.rtl.spec.ts +2 -2
  32. package/plugin/plugin.rtl.ts +5 -5
  33. package/utils/lib-versions.js +2 -2
  34. package/utils/lib-versions.ts +2 -2
  35. package/utils/versions.js +9 -10
  36. package/utils/versions.js.map +1 -1
  37. package/utils/versions.ts +9 -10
  38. package/application/files/src/app/layout/basic/widgets/fullscreen.component.ts +0 -32
  39. package/application/files/src/app/layout/basic/widgets/search.component.ts +0 -116
  40. /package/application/files/src/app/layout/passport/{passport.component.less → passport.less} +0 -0
@@ -2,16 +2,17 @@
2
2
  "typescript.tsdk": "./node_modules/typescript/lib",
3
3
  "editor.formatOnSave": true,
4
4
  "editor.codeActionsOnSave": {
5
- "source.fixAll.eslint": "explicit",
5
+ "source.fixAll.eslint": "always",
6
6
  "source.fixAll.stylelint": "explicit"
7
7
  },
8
+ "eslint.validate": ["typescript", "html"],
8
9
  "[html]": {
9
- "editor.formatOnSave": true,
10
- "editor.defaultFormatter": "esbenp.prettier-vscode"
10
+ "editor.formatOnSave": false,
11
+ "editor.defaultFormatter": "dbaeumer.vscode-eslint"
11
12
  },
12
13
  "[typescript]": {
13
- "editor.formatOnSave": true,
14
- "editor.defaultFormatter": "esbenp.prettier-vscode",
14
+ "editor.formatOnSave": false,
15
+ "editor.defaultFormatter": "dbaeumer.vscode-eslint",
15
16
  },
16
17
  "[markdown]": {
17
18
  "editor.formatOnSave": false
@@ -15,12 +15,7 @@ export default defineConfig(
15
15
  '.*/',
16
16
  'dist/',
17
17
  'coverage/',
18
- 'junit/',
19
- 'ng-alain/',
20
- 'schematics/**/files/**/*',
21
- 'src/dist/**/*',
22
- 'src/templates/**/*',
23
- 'src/app/routes/gen/**/*'
18
+ 'junit/'
24
19
  ]
25
20
  },
26
21
  {
@@ -135,7 +130,15 @@ export default defineConfig(
135
130
  // ...angular.configs.templateAccessibility,
136
131
  ],
137
132
  rules: {
138
- "prettier/prettier": ["error"],
133
+ 'prettier/prettier': [
134
+ 'error',
135
+ {
136
+ parser: 'angular'
137
+ },
138
+ {
139
+ usePrettierrc: true
140
+ }
141
+ ],
139
142
  "@angular-eslint/template/eqeqeq": "off",
140
143
  "@angular-eslint/template/prefer-self-closing-tags": "error"
141
144
  }
@@ -1,6 +1,12 @@
1
1
  import { provideHttpClient, withInterceptors } from '@angular/common/http';
2
2
  import { default as ngLang } from '@angular/common/locales/zh';
3
- import { ApplicationConfig, EnvironmentProviders, Provider } from '@angular/core';
3
+ import {
4
+ ApplicationConfig,
5
+ EnvironmentProviders,
6
+ provideBrowserGlobalErrorListeners,
7
+ Provider,
8
+ provideZonelessChangeDetection
9
+ } from '@angular/core';
4
10
  import { provideRouter, withComponentInputBinding, withViewTransitions, withInMemoryScrolling, withHashLocation, RouterFeatures } from '@angular/router';
5
11
  import { <% if (i18n) { %>I18NService, <% } %>defaultInterceptor, provideStartup } from '@core';
6
12
  import { provideCellWidgets } from '@delon/abc/cell';
@@ -43,6 +49,8 @@ const routerFeatures: RouterFeatures[] = [
43
49
  if (environment.useHash) routerFeatures.push(withHashLocation());
44
50
 
45
51
  const providers: Array<Provider | EnvironmentProviders> = [
52
+ provideBrowserGlobalErrorListeners(),
53
+ provideZonelessChangeDetection(),
46
54
  provideHttpClient(withInterceptors([...(environment.interceptorFns ?? []), authSimpleInterceptor, defaultInterceptor])),
47
55
  provideRouter(routes, ...routerFeatures),<% if (reuseTab) { %>
48
56
  provideReuseTabConfig(),<% } %>
@@ -1,4 +1,4 @@
1
- import { Component, OnInit, inject } from '@angular/core';
1
+ import { Component, inject } from '@angular/core';
2
2
  import { NavigationEnd, NavigationError, RouteConfigLoadStart, Router, RouterOutlet } from '@angular/router';
3
3
  import { TitleService, VERSION as VERSION_ALAIN, stepPreloader } from '@delon/theme';
4
4
  import { environment } from '@env/environment';
@@ -14,16 +14,16 @@ import { VERSION as VERSION_ZORRO } from 'ng-zorro-antd/version';
14
14
  '[attr.ng-zorro-version]': 'ngZorroVersion'
15
15
  }
16
16
  })
17
- export class AppComponent implements OnInit {
17
+ export class App {
18
18
  private readonly router = inject(Router);
19
19
  private readonly titleSrv = inject(TitleService);
20
20
  private readonly modalSrv = inject(NzModalService);
21
- ngAlainVersion = VERSION_ALAIN.full;
22
- ngZorroVersion = VERSION_ZORRO.full;
21
+ protected ngAlainVersion = VERSION_ALAIN.full;
22
+ protected ngZorroVersion = VERSION_ZORRO.full;
23
23
 
24
24
  private donePreloader = stepPreloader();
25
25
 
26
- ngOnInit(): void {
26
+ constructor() {
27
27
  let configLoad = false;
28
28
  this.router.events.subscribe(ev => {
29
29
  if (ev instanceof RouteConfigLoadStart) {
@@ -1,4 +1,4 @@
1
- import { APP_INITIALIZER, Injectable, Provider, inject } from '@angular/core';
1
+ import { EnvironmentProviders, Injectable, Provider, inject, provideAppInitializer } from '@angular/core';
2
2
  import { Router } from '@angular/router';
3
3
  import { HttpClient } from '@angular/common/http';
4
4
  import { DA_SERVICE_TOKEN } from '@delon/auth';
@@ -12,15 +12,16 @@ import type { NzSafeAny } from 'ng-zorro-antd/core/types';
12
12
  * Used for application startup
13
13
  * Generally used to get the basic data of the application, like: Menu Data, User Data, etc.
14
14
  */
15
- export function provideStartup(): Provider[] {
15
+ export function provideStartup(): Array<Provider | EnvironmentProviders> {
16
16
  return [
17
17
  StartupService,
18
- {
19
- provide: APP_INITIALIZER,
20
- useFactory: (startupService: StartupService) => () => startupService.load(),
21
- deps: [StartupService],
22
- multi: true
23
- }
18
+ provideAppInitializer(() => {
19
+ const initializerFn = (
20
+ (startupService: StartupService) => () =>
21
+ startupService.load()
22
+ )(inject(StartupService));
23
+ return initializerFn();
24
+ })
24
25
  ];
25
26
  }
26
27
 
@@ -44,6 +45,14 @@ export class StartupService {
44
45
  })
45
46
  );
46
47
 
48
+ load(): Observable<void> {
49
+ // http
50
+ // return this.viaHttp();
51
+ // mock: Don’t use it in a production environment. ViaMock is just to simulate some data to make the scaffolding work normally
52
+ // mock:请勿在生产环境中这么使用,viaMock 单纯只是为了模拟一些数据使脚手架一开始能正常运行
53
+ return <% if (i18n) { %>this.viaMockI18n();<% } else { %>this.viaMock();<% } %>
54
+ }
55
+
47
56
  private handleAppData(res: NzSafeAny): void {
48
57
  // Application information: including site name, description, year
49
58
  this.settingService.setApp(res.app);
@@ -129,12 +138,4 @@ export class StartupService {
129
138
 
130
139
  return of(void 0);
131
140
  }
132
-
133
- load(): Observable<void> {
134
- // http
135
- // return this.viaHttp();
136
- // mock: Don’t use it in a production environment. ViaMock is just to simulate some data to make the scaffolding work normally
137
- // mock:请勿在生产环境中这么使用,viaMock 单纯只是为了模拟一些数据使脚手架一开始能正常运行
138
- return <% if (i18n) { %>this.viaMockI18n();<% } else { %>this.viaMock();<% } %>
139
- }
140
141
  }
@@ -1,4 +1,4 @@
1
- import { Component, inject } from '@angular/core';
1
+ import { Component, inject, signal } from '@angular/core';
2
2
  import { RouterLink, RouterOutlet } from '@angular/router';
3
3
  import { I18nPipe, SettingsService, User } from '@delon/theme';
4
4
  import { LayoutDefaultModule, LayoutDefaultOptions } from '@delon/theme/layout-default';
@@ -11,11 +11,11 @@ import { NzDropdownModule } from 'ng-zorro-antd/dropdown';
11
11
  import { NzIconModule } from 'ng-zorro-antd/icon';
12
12
  import { NzMenuModule } from 'ng-zorro-antd/menu';
13
13
 
14
- import { HeaderClearStorageComponent } from './widgets/clear-storage.component';
15
- import { HeaderFullScreenComponent } from './widgets/fullscreen.component';
16
- import { HeaderSearchComponent } from './widgets/search.component';
17
- import { HeaderUserComponent } from './widgets/user.component';<% if (i18n) { %>
18
- import { HeaderI18nComponent } from './widgets/i18n.component';<% } %>
14
+ import { HeaderClearStorage } from './widgets/clear-storage';
15
+ import { HeaderFullScreen } from './widgets/fullscreen';
16
+ import { HeaderSearch } from './widgets/search';
17
+ import { HeaderUser } from './widgets/user';<% if (i18n) { %>
18
+ import { HeaderI18n } from './widgets/i18n';<% } %>
19
19
 
20
20
  @Component({
21
21
  selector: 'layout-basic',
@@ -32,12 +32,12 @@ import { HeaderI18nComponent } from './widgets/i18n.component';<% } %>
32
32
  </a>
33
33
  </layout-default-header-item>
34
34
  <layout-default-header-item direction="left" hidden="pc">
35
- <div layout-default-header-item-trigger (click)="searchToggleStatus = !searchToggleStatus">
35
+ <div layout-default-header-item-trigger (click)="searchToggleStatus.set(!searchToggleStatus())">
36
36
  <nz-icon nzType="search" />
37
37
  </div>
38
38
  </layout-default-header-item>
39
39
  <layout-default-header-item direction="middle">
40
- <header-search class="alain-default__search" [toggleChange]="searchToggleStatus" />
40
+ <header-search [(toggleChange)]="searchToggleStatus" />
41
41
  </layout-default-header-item>
42
42
  <layout-default-header-item direction="right" hidden="mobile">
43
43
  <div layout-default-header-item-trigger nz-dropdown [nzDropdownMenu]="settingsMenu" nzTrigger="click" nzPlacement="bottomRight">
@@ -98,22 +98,19 @@ import { HeaderI18nComponent } from './widgets/i18n.component';<% } %>
98
98
  NzMenuModule,
99
99
  NzDropdownModule,
100
100
  NzAvatarModule,
101
- HeaderSearchComponent,
102
- HeaderClearStorageComponent,
103
- HeaderFullScreenComponent,
104
- HeaderUserComponent<% if (i18n) { %>,
105
- HeaderI18nComponent<% } %>
101
+ HeaderSearch,
102
+ HeaderClearStorage,
103
+ HeaderFullScreen,
104
+ HeaderUser<% if (i18n) { %>,
105
+ HeaderI18n<% } %>
106
106
  ]
107
107
  })
108
- export class LayoutBasicComponent {
109
- private readonly settings = inject(SettingsService);
110
- options: LayoutDefaultOptions = {
108
+ export class LayoutBasic {
109
+ readonly user = inject(SettingsService).user;
110
+ protected options: LayoutDefaultOptions = {
111
111
  logoExpanded: `./assets/logo-full.svg`,
112
112
  logoCollapsed: `./assets/logo.svg`
113
113
  };
114
- searchToggleStatus = false;
115
- showSettingDrawer = !environment.production;
116
- get user(): User {
117
- return this.settings.user;
118
- }
114
+ protected searchToggleStatus = signal(false);
115
+ protected showSettingDrawer = !environment.production;
119
116
  }
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, HostListener, inject } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2
2
  import { I18nPipe } from '@delon/theme';
3
3
  import { NzIconModule } from 'ng-zorro-antd/icon';
4
4
  import { NzMessageService } from 'ng-zorro-antd/message';
@@ -11,17 +11,17 @@ import { NzModalService } from 'ng-zorro-antd/modal';
11
11
  {{ 'menu.clear.local.storage' | i18n }}
12
12
  `,
13
13
  host: {
14
- '[class.flex-1]': 'true'
14
+ class: 'flex-1',
15
+ '(click)': '_click()'
15
16
  },
16
17
  changeDetection: ChangeDetectionStrategy.OnPush,
17
18
  imports: [NzIconModule, I18nPipe]
18
19
  })
19
- export class HeaderClearStorageComponent {
20
+ export class HeaderClearStorage {
20
21
  private readonly modalSrv = inject(NzModalService);
21
22
  private readonly messageSrv = inject(NzMessageService);
22
23
 
23
- @HostListener('click')
24
- _click(): void {
24
+ protected _click(): void {
25
25
  this.modalSrv.confirm({
26
26
  nzTitle: 'Make sure clear all local storage?',
27
27
  nzOnOk: () => {
@@ -0,0 +1,33 @@
1
+ import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
2
+ import { I18nPipe } from '@delon/theme';
3
+ import { NzIconModule } from 'ng-zorro-antd/icon';
4
+ import screenfull from 'screenfull';
5
+
6
+ @Component({
7
+ selector: 'header-fullscreen',
8
+ template: `
9
+ @let s = status();
10
+ <nz-icon [nzType]="s ? 'fullscreen-exit' : 'fullscreen'" />
11
+ {{ (s ? 'menu.fullscreen.exit' : 'menu.fullscreen') | i18n }}
12
+ `,
13
+ host: {
14
+ class: 'flex-1',
15
+ '(window:resize)': '_resize()',
16
+ '(click)': '_click()'
17
+ },
18
+ changeDetection: ChangeDetectionStrategy.OnPush,
19
+ imports: [NzIconModule, I18nPipe]
20
+ })
21
+ export class HeaderFullScreen {
22
+ protected status = signal(false);
23
+
24
+ protected _resize(): void {
25
+ this.status.set(screenfull.isFullscreen);
26
+ }
27
+
28
+ protected _click(): void {
29
+ if (screenfull.isEnabled) {
30
+ screenfull.toggle();
31
+ }
32
+ }
33
+ }
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, Input, booleanAttribute, inject, DOCUMENT } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, booleanAttribute, inject, DOCUMENT, input } from '@angular/core';
2
2
  import { I18NService } from '@core';
3
3
  import { ALAIN_I18N_TOKEN, I18nPipe, SettingsService } from '@delon/theme';
4
4
  import { NzDropdownModule } from 'ng-zorro-antd/dropdown';
@@ -8,7 +8,7 @@ import { NzMenuModule } from 'ng-zorro-antd/menu';
8
8
  @Component({
9
9
  selector: 'header-i18n',
10
10
  template: `
11
- @if (showLangText) {
11
+ @if (showLangText()) {
12
12
  <div nz-dropdown [nzDropdownMenu]="langMenu" nzPlacement="bottomRight">
13
13
  <nz-icon nzType="global" />
14
14
  {{ 'menu.lang' | i18n }}
@@ -29,27 +29,23 @@ import { NzMenuModule } from 'ng-zorro-antd/menu';
29
29
  </nz-dropdown-menu>
30
30
  `,
31
31
  host: {
32
- '[class.flex-1]': 'true'
32
+ class: 'flex-1'
33
33
  },
34
34
  changeDetection: ChangeDetectionStrategy.OnPush,
35
35
  imports: [I18nPipe, NzDropdownModule, NzIconModule, NzMenuModule]
36
36
  })
37
- export class HeaderI18nComponent {
37
+ export class HeaderI18n {
38
38
  private readonly settings = inject(SettingsService);
39
39
  private readonly i18n = inject<I18NService>(ALAIN_I18N_TOKEN);
40
40
  private readonly doc = inject(DOCUMENT);
41
- /** Whether to display language text */
42
- @Input({ transform: booleanAttribute }) showLangText = true;
43
41
 
44
- get langs(): Array<{ code: string; text: string; abbr: string }> {
45
- return this.i18n.getLangs();
46
- }
42
+ /** Whether to display language text */
43
+ readonly showLangText = input(true, { transform: booleanAttribute });
47
44
 
48
- get curLangCode(): string {
49
- return this.settings.layout.lang;
50
- }
45
+ protected readonly langs = this.i18n.getLangs();
46
+ protected readonly curLangCode = this.settings.layout.lang;
51
47
 
52
- change(lang: string): void {
48
+ protected change(lang: string): void {
53
49
  const spinEl = this.doc.createElement('div');
54
50
  spinEl.setAttribute('class', `page-loading ant-spin ant-spin-lg ant-spin-spinning`);
55
51
  spinEl.innerHTML = `<span class="ant-spin-dot ant-spin-dot-spin"><i></i><i></i><i></i><i></i></span>`;
@@ -0,0 +1,98 @@
1
+ import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, afterNextRender, effect, inject, model, signal } from '@angular/core';
2
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
+ import { HotkeyDirective } from '@delon/abc/hotkey';
4
+ import { I18nPipe } from '@delon/theme';
5
+ import { NzAutocompleteModule } from 'ng-zorro-antd/auto-complete';
6
+ import { NzIconModule } from 'ng-zorro-antd/icon';
7
+ import { NzInputModule } from 'ng-zorro-antd/input';
8
+ import { BehaviorSubject, debounceTime, delay, distinctUntilChanged, filter, tap } from 'rxjs';
9
+
10
+ @Component({
11
+ selector: 'header-search',
12
+ template: `
13
+ <nz-input-wrapper>
14
+ <nz-icon nzInputPrefix [nzType]="focus() ? 'arrow-down' : 'search'" />
15
+ @if (loading()) {
16
+ <nz-icon nzInputSuffix nzType="loading" />
17
+ }
18
+ <input
19
+ type="text"
20
+ nz-input
21
+ [nzAutocomplete]="auto"
22
+ (input)="search($event)"
23
+ (focus)="qFocus()"
24
+ (blur)="qBlur()"
25
+ hotkey="F1"
26
+ [attr.placeholder]="'menu.search.placeholder' | i18n"
27
+ />
28
+ </nz-input-wrapper>
29
+ <nz-autocomplete nzBackfill #auto>
30
+ @for (i of options(); track $index) {
31
+ <nz-auto-option [nzValue]="i">{{ i }}</nz-auto-option>
32
+ }
33
+ </nz-autocomplete>
34
+ `,
35
+ host: {
36
+ class: 'alain-default__search',
37
+ '[class.alain-default__search-focus]': 'focus()',
38
+ '[class.alain-default__search-toggled]': 'searchToggled()'
39
+ },
40
+ changeDetection: ChangeDetectionStrategy.OnPush,
41
+ imports: [I18nPipe, NzInputModule, NzIconModule, NzAutocompleteModule, HotkeyDirective]
42
+ })
43
+ export class HeaderSearch {
44
+ private readonly el = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;
45
+ private readonly d$ = inject(DestroyRef);
46
+ private readonly search$ = new BehaviorSubject('');
47
+ protected options = signal<string[]>([]);
48
+ protected loading = signal(false);
49
+ protected focus = signal(false);
50
+ protected searchToggled = signal(false);
51
+
52
+ readonly toggleChange = model(false);
53
+
54
+ constructor() {
55
+ afterNextRender(() => {
56
+ this.search$
57
+ .pipe(
58
+ debounceTime(500),
59
+ distinctUntilChanged(),
60
+ filter(value => value.length > 0),
61
+ tap(() => this.loading.set(true)),
62
+ delay(500), // Mock http
63
+ takeUntilDestroyed(this.d$)
64
+ )
65
+ .subscribe(value => {
66
+ this.loading.set(false);
67
+ this.options.set(value ? [value, value + value, value + value + value] : []);
68
+ });
69
+ });
70
+
71
+ effect(() => {
72
+ const v = this.searchToggled();
73
+ if (v == null) return;
74
+
75
+ this.searchToggled.set(v);
76
+ this.focus.set(v);
77
+ const ipt = this.el.querySelector<HTMLInputElement>('.ant-input');
78
+ if (v && ipt) {
79
+ ipt.focus();
80
+ }
81
+ });
82
+ }
83
+
84
+ protected qFocus(): void {
85
+ this.focus.set(true);
86
+ }
87
+
88
+ protected qBlur(): void {
89
+ this.focus.set(false);
90
+ this.searchToggled.set(false);
91
+ this.options.set([]);
92
+ this.toggleChange.set(false);
93
+ }
94
+
95
+ protected search(ev: Event): void {
96
+ this.search$.next((ev.target as HTMLInputElement).value);
97
+ }
98
+ }
@@ -1,7 +1,7 @@
1
1
  import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
2
2
  import { Router, RouterLink } from '@angular/router';
3
3
  import { DA_SERVICE_TOKEN } from '@delon/auth';
4
- import { I18nPipe, SettingsService, User } from '@delon/theme';
4
+ import { I18nPipe, SettingsService } from '@delon/theme';
5
5
  import { NzAvatarModule } from 'ng-zorro-antd/avatar';
6
6
  import { NzDropdownModule } from 'ng-zorro-antd/dropdown';
7
7
  import { NzIconModule } from 'ng-zorro-antd/icon';
@@ -39,15 +39,12 @@ import { NzMenuModule } from 'ng-zorro-antd/menu';
39
39
  changeDetection: ChangeDetectionStrategy.OnPush,
40
40
  imports: [RouterLink, NzDropdownModule, NzMenuModule, NzIconModule, I18nPipe, NzAvatarModule]
41
41
  })
42
- export class HeaderUserComponent {
43
- private readonly settings = inject(SettingsService);
42
+ export class HeaderUser {
43
+ protected readonly user = inject(SettingsService).user;
44
44
  private readonly router = inject(Router);
45
45
  private readonly tokenService = inject(DA_SERVICE_TOKEN);
46
- get user(): User {
47
- return this.settings.user;
48
- }
49
46
 
50
- logout(): void {
47
+ protected logout(): void {
51
48
  this.tokenService.clear();
52
49
  this.router.navigateByUrl(this.tokenService.login_url!);
53
50
  }
@@ -5,8 +5,8 @@ import { RouterOutlet } from '@angular/router';
5
5
  selector: 'layout-blank',
6
6
  template: `<router-outlet />`,
7
7
  host: {
8
- '[class.alain-blank]': 'true'
8
+ class: 'alain-blank'
9
9
  },
10
10
  imports: [RouterOutlet]
11
11
  })
12
- export class LayoutBlankComponent {}
12
+ export class LayoutBlank {}
@@ -1,3 +1,3 @@
1
- export * from './basic/basic.component';
2
- export * from './blank/blank.component';
3
- export * from './passport/passport.component';
1
+ export * from './basic/basic';
2
+ export * from './blank/blank';
3
+ export * from './passport/passport';
@@ -1,4 +1,4 @@
1
- import { Component, OnInit, inject } from '@angular/core';
1
+ import { Component, inject } from '@angular/core';
2
2
  import { RouterOutlet } from '@angular/router';
3
3
  import { GlobalFooterModule } from '@delon/abc/global-footer';
4
4
  import { DA_SERVICE_TOKEN } from '@delon/auth';
@@ -28,11 +28,11 @@ import { HeaderI18nComponent } from '../basic/widgets/i18n.component';<% } %>
28
28
  </div>
29
29
  </div>
30
30
  `,
31
- styleUrls: ['./passport.component.less'],
31
+ styleUrls: ['./passport.less'],
32
32
  imports: [RouterOutlet<% if (i18n) { %>, HeaderI18nComponent<% } %>, GlobalFooterModule, NzIconModule]
33
33
  })
34
- export class LayoutPassportComponent implements OnInit {
35
- private tokenService = inject(DA_SERVICE_TOKEN);
34
+ export class LayoutPassport {
35
+ private tokenSrv = inject(DA_SERVICE_TOKEN);
36
36
 
37
37
  links = [
38
38
  {
@@ -49,7 +49,7 @@ export class LayoutPassportComponent implements OnInit {
49
49
  }
50
50
  ];
51
51
 
52
- ngOnInit(): void {
53
- this.tokenService.clear();
52
+ constructor() {
53
+ this.tokenSrv.clear();
54
54
  }
55
55
  }
@@ -5,13 +5,13 @@ import { UserLockComponent } from './lock/lock.component';
5
5
  import { UserLoginComponent } from './login/login.component';
6
6
  import { UserRegisterComponent } from './register/register.component';
7
7
  import { UserRegisterResultComponent } from './register-result/register-result.component';
8
- import { LayoutPassportComponent } from '../../layout';
8
+ import { LayoutPassport } from '../../layout';
9
9
 
10
10
  export const routes: Routes = [
11
11
  // passport
12
12
  {
13
13
  path: 'passport',
14
- component: LayoutPassportComponent,
14
+ component: LayoutPassport,
15
15
  children: [
16
16
  {
17
17
  path: 'login',
@@ -3,12 +3,12 @@ import { startPageGuard } from '@core';
3
3
  import { authSimpleCanActivate, authSimpleCanActivateChild } from '@delon/auth';
4
4
 
5
5
  import { DashboardComponent } from './dashboard/dashboard.component';
6
- import { LayoutBasicComponent } from '../layout';
6
+ import { LayoutBasic } from '../layout';
7
7
 
8
8
  export const routes: Routes = [
9
9
  {
10
10
  path: '',
11
- component: LayoutBasicComponent,
11
+ component: LayoutBasic,
12
12
  canActivate: [startPageGuard, authSimpleCanActivate],
13
13
  canActivateChild: [authSimpleCanActivateChild],
14
14
  data: {},