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.
- package/application/files/root/.vscode/settings.json +6 -5
- package/application/files/root/eslint.config.mjs +10 -7
- package/application/files/src/app/app.config.ts +9 -1
- package/application/files/src/app/{app.component.ts → app.ts} +5 -5
- package/application/files/src/app/core/startup/startup.service.ts +17 -16
- package/application/files/src/app/layout/basic/{basic.component.ts → basic.ts} +18 -21
- package/application/files/src/app/layout/basic/widgets/{clear-storage.component.ts → clear-storage.ts} +5 -5
- package/application/files/src/app/layout/basic/widgets/fullscreen.ts +33 -0
- package/application/files/src/app/layout/basic/widgets/{i18n.component.ts → i18n.ts} +9 -13
- package/application/files/src/app/layout/basic/widgets/search.ts +98 -0
- package/application/files/src/app/layout/basic/widgets/{user.component.ts → user.ts} +4 -7
- package/application/files/src/app/layout/blank/{blank.component.ts → blank.ts} +2 -2
- package/application/files/src/app/layout/index.ts +3 -3
- package/application/files/src/app/layout/passport/{passport.component.ts → passport.ts} +6 -6
- package/application/files/src/app/routes/passport/routes.ts +2 -2
- package/application/files/src/app/routes/routes.ts +2 -2
- package/application/files/src/assets/color.less +295 -658
- package/application/files/src/assets/style.compact.css +1 -1
- package/application/files/src/assets/style.dark.css +1 -1
- package/application/files/src/main.ts +2 -2
- package/application/index.js +4 -4
- package/application/index.spec.ts +1 -1
- package/application/index.ts +4 -4
- package/ng-update/upgrade-rules/V21/index.js +1 -1
- package/ng-update/upgrade-rules/V21/index.js.map +1 -1
- package/ng-update/upgrade-rules/V21/index.ts +1 -1
- package/package.json +2 -2
- package/plugin/files/rtl/layout/basic/widgets/{rtl.component.ts → rtl.ts} +4 -8
- package/plugin/plugin.rtl.js +5 -5
- package/plugin/plugin.rtl.js.map +1 -1
- package/plugin/plugin.rtl.spec.ts +2 -2
- package/plugin/plugin.rtl.ts +5 -5
- package/utils/lib-versions.js +2 -2
- package/utils/lib-versions.ts +2 -2
- package/utils/versions.js +9 -10
- package/utils/versions.js.map +1 -1
- package/utils/versions.ts +9 -10
- package/application/files/src/app/layout/basic/widgets/fullscreen.component.ts +0 -32
- package/application/files/src/app/layout/basic/widgets/search.component.ts +0 -116
- /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": "
|
|
5
|
+
"source.fixAll.eslint": "always",
|
|
6
6
|
"source.fixAll.stylelint": "explicit"
|
|
7
7
|
},
|
|
8
|
+
"eslint.validate": ["typescript", "html"],
|
|
8
9
|
"[html]": {
|
|
9
|
-
"editor.formatOnSave":
|
|
10
|
-
"editor.defaultFormatter": "
|
|
10
|
+
"editor.formatOnSave": false,
|
|
11
|
+
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
|
11
12
|
},
|
|
12
13
|
"[typescript]": {
|
|
13
|
-
"editor.formatOnSave":
|
|
14
|
-
"editor.defaultFormatter": "
|
|
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
|
-
|
|
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 {
|
|
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,
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
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
|
|
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
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
HeaderSearch,
|
|
102
|
+
HeaderClearStorage,
|
|
103
|
+
HeaderFullScreen,
|
|
104
|
+
HeaderUser<% if (i18n) { %>,
|
|
105
|
+
HeaderI18n<% } %>
|
|
106
106
|
]
|
|
107
107
|
})
|
|
108
|
-
export class
|
|
109
|
-
|
|
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,
|
|
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
|
-
'
|
|
14
|
+
class: 'flex-1',
|
|
15
|
+
'(click)': '_click()'
|
|
15
16
|
},
|
|
16
17
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
17
18
|
imports: [NzIconModule, I18nPipe]
|
|
18
19
|
})
|
|
19
|
-
export class
|
|
20
|
+
export class HeaderClearStorage {
|
|
20
21
|
private readonly modalSrv = inject(NzModalService);
|
|
21
22
|
private readonly messageSrv = inject(NzMessageService);
|
|
22
23
|
|
|
23
|
-
|
|
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,
|
|
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
|
-
'
|
|
32
|
+
class: 'flex-1'
|
|
33
33
|
},
|
|
34
34
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
35
35
|
imports: [I18nPipe, NzDropdownModule, NzIconModule, NzMenuModule]
|
|
36
36
|
})
|
|
37
|
-
export class
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
42
|
+
/** Whether to display language text */
|
|
43
|
+
readonly showLangText = input(true, { transform: booleanAttribute });
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
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
|
|
43
|
-
|
|
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
|
-
'
|
|
8
|
+
class: 'alain-blank'
|
|
9
9
|
},
|
|
10
10
|
imports: [RouterOutlet]
|
|
11
11
|
})
|
|
12
|
-
export class
|
|
12
|
+
export class LayoutBlank {}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './basic/basic
|
|
2
|
-
export * from './blank/blank
|
|
3
|
-
export * from './passport/passport
|
|
1
|
+
export * from './basic/basic';
|
|
2
|
+
export * from './blank/blank';
|
|
3
|
+
export * from './passport/passport';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component,
|
|
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.
|
|
31
|
+
styleUrls: ['./passport.less'],
|
|
32
32
|
imports: [RouterOutlet<% if (i18n) { %>, HeaderI18nComponent<% } %>, GlobalFooterModule, NzIconModule]
|
|
33
33
|
})
|
|
34
|
-
export class
|
|
35
|
-
private
|
|
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
|
-
|
|
53
|
-
this.
|
|
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 {
|
|
8
|
+
import { LayoutPassport } from '../../layout';
|
|
9
9
|
|
|
10
10
|
export const routes: Routes = [
|
|
11
11
|
// passport
|
|
12
12
|
{
|
|
13
13
|
path: 'passport',
|
|
14
|
-
component:
|
|
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 {
|
|
6
|
+
import { LayoutBasic } from '../layout';
|
|
7
7
|
|
|
8
8
|
export const routes: Routes = [
|
|
9
9
|
{
|
|
10
10
|
path: '',
|
|
11
|
-
component:
|
|
11
|
+
component: LayoutBasic,
|
|
12
12
|
canActivate: [startPageGuard, authSimpleCanActivate],
|
|
13
13
|
canActivateChild: [authSimpleCanActivateChild],
|
|
14
14
|
data: {},
|