@kuzntsv/uikit 0.21.37 → 1.0.1
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/fesm2022/kuzntsv-uikit-interceptors.mjs +174 -0
- package/fesm2022/kuzntsv-uikit-interceptors.mjs.map +1 -0
- package/fesm2022/kuzntsv-uikit-ui.mjs +1810 -0
- package/fesm2022/kuzntsv-uikit-ui.mjs.map +1 -0
- package/fesm2022/kuzntsv-uikit.mjs +166 -2119
- package/fesm2022/kuzntsv-uikit.mjs.map +1 -1
- package/package.json +9 -1
- package/types/kuzntsv-uikit-interceptors.d.ts +11 -0
- package/types/kuzntsv-uikit-ui.d.ts +783 -0
- package/types/kuzntsv-uikit.d.ts +105 -918
- package/assets/_navbar-theme.scss +0 -25
|
@@ -1,153 +1,79 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
2
|
+
import { InjectionToken, Injectable, inject, signal, DestroyRef } from '@angular/core';
|
|
3
|
+
import { HttpContextToken, HttpHeaders, HttpClient } from '@angular/common/http';
|
|
4
|
+
import { Subject } from 'rxjs';
|
|
5
|
+
import { UIKIT_CONFIG as UIKIT_CONFIG$1 } from 'src/config';
|
|
6
|
+
import { Router } from '@angular/router';
|
|
7
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
8
|
+
import { UIKIT_NOTIFICATION_TOKEN as UIKIT_NOTIFICATION_TOKEN$1 } from 'src/models';
|
|
9
9
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
10
|
-
import * as i1 from '@angular/forms';
|
|
11
|
-
import { FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule, NgControl } from '@angular/forms';
|
|
12
|
-
import { MatButton, MatIconButton, MatAnchor } from '@angular/material/button';
|
|
13
|
-
import { MatCard, MatCardHeader, MatCardTitle, MatCardContent } from '@angular/material/card';
|
|
14
|
-
import { MatFormField, MatLabel, MatError, MatSuffix, MatHint } from '@angular/material/form-field';
|
|
15
|
-
import { MatIcon } from '@angular/material/icon';
|
|
16
|
-
import { MatInput } from '@angular/material/input';
|
|
17
|
-
import { map, debounceTime, distinctUntilChanged, startWith as startWith$1 } from 'rxjs/operators';
|
|
18
|
-
import { MatDivider } from '@angular/material/divider';
|
|
19
|
-
import { MatMenu, MatMenuTrigger, MatMenuItem, MatMenuContent } from '@angular/material/menu';
|
|
20
|
-
import { MatToolbar } from '@angular/material/toolbar';
|
|
21
|
-
import * as i1$1 from '@angular/material/tooltip';
|
|
22
|
-
import { MatTooltip, MatTooltipModule } from '@angular/material/tooltip';
|
|
23
|
-
import { MAT_DIALOG_DATA, MatDialogRef, MatDialogTitle, MatDialogContent, MatDialogActions, MatDialogClose, MatDialog, MatDialogConfig } from '@angular/material/dialog';
|
|
24
|
-
import { DomSanitizer } from '@angular/platform-browser';
|
|
25
|
-
import { ENTER, COMMA } from '@angular/cdk/keycodes';
|
|
26
|
-
import { AsyncPipe } from '@angular/common';
|
|
27
|
-
import * as i2 from '@angular/material/autocomplete';
|
|
28
|
-
import { MatAutocompleteModule, MatOption } from '@angular/material/autocomplete';
|
|
29
|
-
import * as i3 from '@angular/material/chips';
|
|
30
|
-
import { MatChipsModule } from '@angular/material/chips';
|
|
31
|
-
import { MAT_DATE_LOCALE, MAT_DATE_FORMATS, MatOption as MatOption$1, MatOptgroup } from '@angular/material/core';
|
|
32
|
-
import { MatDateRangeInput, MatStartDate, MatEndDate, MatDatepickerToggle, MatDateRangePicker } from '@angular/material/datepicker';
|
|
33
|
-
import 'moment/locale/ru';
|
|
34
|
-
import moment from 'moment';
|
|
35
|
-
import * as i3$1 from '@angular/cdk/scrolling';
|
|
36
|
-
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
37
|
-
import { MatSelect, MatFormField as MatFormField$1, MatLabel as MatLabel$1 } from '@angular/material/select';
|
|
38
|
-
import { SelectionModel } from '@angular/cdk/collections';
|
|
39
|
-
import { MatCheckbox } from '@angular/material/checkbox';
|
|
40
|
-
import { MatPaginator } from '@angular/material/paginator';
|
|
41
|
-
import { MatSort, MatSortHeader } from '@angular/material/sort';
|
|
42
|
-
import { MatTableDataSource, MatTable, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell, MatNoDataRow, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow, MatFooterRowDef, MatFooterRow, MatFooterCellDef, MatFooterCell, MatTableModule } from '@angular/material/table';
|
|
43
10
|
|
|
44
|
-
|
|
45
|
-
cdRef = inject(ChangeDetectorRef);
|
|
46
|
-
ngAfterViewInit() {
|
|
47
|
-
this.cdRef.detectChanges();
|
|
48
|
-
}
|
|
49
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ProgressSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
50
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: ProgressSpinnerComponent, isStandalone: true, selector: "ngx-uik-loader", ngImport: i0, template: `
|
|
51
|
-
<div class="loading-indicator" mat-dialog-content>
|
|
52
|
-
<mat-progress-spinner mode="indeterminate">
|
|
53
|
-
</mat-progress-spinner>
|
|
54
|
-
</div>
|
|
55
|
-
`, isInline: true, styles: [".loading-indicator{position:fixed;z-index:999;height:2em;width:2em;overflow:initial;margin:auto;inset:0}.loading-indicator:before{content:\"\";display:block;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0000004d}\n"], dependencies: [{ kind: "component", type: MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
56
|
-
}
|
|
57
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ProgressSpinnerComponent, decorators: [{
|
|
58
|
-
type: Component,
|
|
59
|
-
args: [{ selector: 'ngx-uik-loader', template: `
|
|
60
|
-
<div class="loading-indicator" mat-dialog-content>
|
|
61
|
-
<mat-progress-spinner mode="indeterminate">
|
|
62
|
-
</mat-progress-spinner>
|
|
63
|
-
</div>
|
|
64
|
-
`, changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatProgressSpinner], styles: [".loading-indicator{position:fixed;z-index:999;height:2em;width:2em;overflow:initial;margin:auto;inset:0}.loading-indicator:before{content:\"\";display:block;position:fixed;top:0;left:0;width:100%;height:100%;background-color:#0000004d}\n"] }]
|
|
65
|
-
}] });
|
|
11
|
+
const UIKIT_CONFIG = new InjectionToken('UIKIT_CONFIG');
|
|
66
12
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (!this.overlayRef?.hasAttached()) {
|
|
78
|
-
this.overlayRef?.attach(spinnerOverlayPortal);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
hide() {
|
|
83
|
-
if (this.overlayRef) {
|
|
84
|
-
this.overlayRef.detach();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
88
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LoaderService, providedIn: 'root' });
|
|
89
|
-
}
|
|
90
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LoaderService, decorators: [{
|
|
91
|
-
type: Injectable,
|
|
92
|
-
args: [{
|
|
93
|
-
providedIn: 'root'
|
|
94
|
-
}]
|
|
95
|
-
}] });
|
|
13
|
+
// Токен, в который мы будем передавать строку-идентификатор нужного API
|
|
14
|
+
// По умолчанию пустая строка означает "использовать дефолтное (основное) API"
|
|
15
|
+
const API_NAME = new HttpContextToken(() => '');
|
|
16
|
+
// Иногда внутри сервиса нужно сделать один специфический запрос (например, стянуть публичный JSON-файл конфигурации), не добавляя его глобально в publicUrls.
|
|
17
|
+
// Используя подход с HttpContext, мы можем добавить в библиотеку маркер пропуска авторизации:
|
|
18
|
+
// А в коде приложения вызывать так:
|
|
19
|
+
// this.http.get('/assets/config.json', {
|
|
20
|
+
// context: new HttpContext().set(BYPASS_AUTH, true)
|
|
21
|
+
// });
|
|
22
|
+
const BYPASS_AUTH = new HttpContextToken(() => false);
|
|
96
23
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
success(message, duration = this.duration) {
|
|
109
|
-
this.openSnackBar(message, 'Закрыть', duration);
|
|
110
|
-
}
|
|
111
|
-
info(message, duration = this.duration) {
|
|
112
|
-
this.openSnackBar(message, 'Закрыть', duration);
|
|
113
|
-
}
|
|
114
|
-
helper(message, duration = this.duration) {
|
|
115
|
-
this.openSnackBar(message, 'Закрыть', duration);
|
|
116
|
-
}
|
|
117
|
-
warning(message, duration = this.duration) {
|
|
118
|
-
this.openSnackBar(message, 'Закрыть', duration);
|
|
119
|
-
}
|
|
120
|
-
error(message, duration = this.duration) {
|
|
121
|
-
this.openSnackBar(message, 'Закрыть', duration);
|
|
24
|
+
;
|
|
25
|
+
|
|
26
|
+
const UIKIT_NOTIFICATION_TOKEN = new InjectionToken('UikitNotificationToken');
|
|
27
|
+
|
|
28
|
+
class AuthEventService {
|
|
29
|
+
authErrorSource = new Subject();
|
|
30
|
+
// Стрим для прослушивания ошибок (экспортируется наружу)
|
|
31
|
+
authError$ = this.authErrorSource.asObservable();
|
|
32
|
+
// Метод для генерации события (вызовется в интерцепторе)
|
|
33
|
+
notify401() {
|
|
34
|
+
this.authErrorSource.next();
|
|
122
35
|
}
|
|
123
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
124
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
36
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AuthEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
37
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AuthEventService, providedIn: 'root' });
|
|
125
38
|
}
|
|
126
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
39
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AuthEventService, decorators: [{
|
|
127
40
|
type: Injectable,
|
|
128
|
-
args: [{
|
|
129
|
-
providedIn: 'root'
|
|
130
|
-
}]
|
|
41
|
+
args: [{ providedIn: 'root' }]
|
|
131
42
|
}] });
|
|
132
43
|
|
|
133
|
-
class
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
44
|
+
class RoleService {
|
|
45
|
+
// Вычисление разрешений по ролям
|
|
46
|
+
// Роль для скрытия элементов.
|
|
47
|
+
hideRole = 'HIDE';
|
|
48
|
+
/** Проверка массива ролей */
|
|
49
|
+
hasRoles(roles, checkRoles) {
|
|
50
|
+
if (roles) {
|
|
51
|
+
for (const checkRole of checkRoles) {
|
|
52
|
+
if (roles.find(role => (role === checkRole || role === 'ADMIN'))) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
/** Элемент скрывается, если у пользователя нет ни одной роли из перереданных в "roles"
|
|
60
|
+
или в списке "roles" есть роль "hideRole". */
|
|
61
|
+
isHideElement(roles, checkRoles) {
|
|
62
|
+
if (!roles || roles.length === 0)
|
|
63
|
+
return false;
|
|
64
|
+
if (roles.indexOf(this.hideRole) !== -1)
|
|
65
|
+
return true;
|
|
66
|
+
for (const role of roles) {
|
|
67
|
+
if (role && (role.length !== 0) && this.hasRoles(checkRoles, [role])) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
145
70
|
}
|
|
71
|
+
return true;
|
|
146
72
|
}
|
|
147
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
148
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
73
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RoleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
74
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RoleService, providedIn: 'root' });
|
|
149
75
|
}
|
|
150
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
76
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RoleService, decorators: [{
|
|
151
77
|
type: Injectable,
|
|
152
78
|
args: [{
|
|
153
79
|
providedIn: 'root'
|
|
@@ -181,13 +107,10 @@ class User {
|
|
|
181
107
|
*/
|
|
182
108
|
class UserService {
|
|
183
109
|
user;
|
|
110
|
+
config = inject(UIKIT_CONFIG$1);
|
|
184
111
|
constructor() {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
this.user = new User();
|
|
190
|
-
}
|
|
112
|
+
const saved = localStorage.getItem(this.config.auth.userStorageKey);
|
|
113
|
+
this.user = saved ? JSON.parse(saved) : new User();
|
|
191
114
|
}
|
|
192
115
|
get dept() {
|
|
193
116
|
return this.user?.depart;
|
|
@@ -198,12 +121,12 @@ class UserService {
|
|
|
198
121
|
}
|
|
199
122
|
/** Изменить данные пользователя в localStorage */
|
|
200
123
|
set userData(user) {
|
|
201
|
-
|
|
202
|
-
this.
|
|
124
|
+
this.user = user;
|
|
125
|
+
localStorage.setItem(this.config.auth.userStorageKey, JSON.stringify(user));
|
|
203
126
|
}
|
|
204
127
|
/** Удаляет данные о пользователе из localStorage. */
|
|
205
128
|
removeUser() {
|
|
206
|
-
localStorage.removeItem(
|
|
129
|
+
localStorage.removeItem(this.config.auth.userStorageKey);
|
|
207
130
|
}
|
|
208
131
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: UserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
209
132
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: UserService, providedIn: 'root' });
|
|
@@ -215,192 +138,117 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
215
138
|
}]
|
|
216
139
|
}], ctorParameters: () => [] });
|
|
217
140
|
|
|
218
|
-
//
|
|
141
|
+
// interface RefreshResponse {
|
|
142
|
+
// accessToken: string;
|
|
143
|
+
// refreshToken: string;
|
|
144
|
+
// }
|
|
219
145
|
class AuthService {
|
|
220
|
-
// Указываем какой сервер использовать
|
|
221
|
-
baseRoute = 'mainApi/';
|
|
222
|
-
// Хранит доступные пользователю действия
|
|
223
|
-
permissions = ['VIEW'];
|
|
224
|
-
defaultRoles = [];
|
|
225
146
|
// Хранит роли пользователя
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
147
|
+
_roles = signal([], ...(ngDevMode ? [{ debugName: "_roles" }] : []));
|
|
148
|
+
// Состояние авторизации
|
|
149
|
+
_loggedIn = signal(false, ...(ngDevMode ? [{ debugName: "_loggedIn" }] : []));
|
|
150
|
+
roles = this._roles.asReadonly();
|
|
151
|
+
loggedIn = this._loggedIn.asReadonly();
|
|
231
152
|
defaultHeader = {
|
|
232
|
-
headers: new HttpHeaders().set('content-type', 'application/x-www-form-urlencoded')
|
|
153
|
+
headers: new HttpHeaders().set('content-type', 'application/x-www-form-urlencoded'),
|
|
233
154
|
};
|
|
234
|
-
|
|
235
|
-
http = inject(HttpClient);
|
|
236
|
-
router = inject(Router);
|
|
237
|
-
console = inject(LogService);
|
|
238
|
-
alertService = inject(AlertService);
|
|
155
|
+
notificationService = inject(UIKIT_NOTIFICATION_TOKEN$1);
|
|
239
156
|
userService = inject(UserService);
|
|
157
|
+
eventService = inject(AuthEventService);
|
|
158
|
+
destroyRef = inject(DestroyRef);
|
|
159
|
+
http = inject(HttpClient);
|
|
160
|
+
config = inject(UIKIT_CONFIG$1);
|
|
161
|
+
// Внедряем роутер опционально, чтобы библиотека не падала, если роутера нет в приложении
|
|
162
|
+
router = inject(Router, { optional: true });
|
|
240
163
|
constructor() {
|
|
241
|
-
this.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
/** Проверка разрешений */
|
|
252
|
-
hasPermission(authPermission) {
|
|
253
|
-
return !!(this.permissions &&
|
|
254
|
-
this.permissions.find(permission => permission === authPermission));
|
|
255
|
-
}
|
|
256
|
-
/** Проверка ролей */
|
|
257
|
-
hasRole(roles, checkRole) {
|
|
258
|
-
if (roles) {
|
|
259
|
-
return !!roles.find(role => (role === checkRole || role === 'ADMIN'));
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
return false;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
/** Проверка массива ролей */
|
|
266
|
-
hasRoles(roles, checkRoles) {
|
|
267
|
-
if (roles) {
|
|
268
|
-
for (const checkRole of checkRoles) {
|
|
269
|
-
if (roles.find(role => (role === checkRole || role === 'ADMIN'))) {
|
|
270
|
-
return true;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
/** Элемент скрывается, если у пользователя нет ни одной роли из перереданных в "roles"
|
|
277
|
-
или в списке "roles" есть роль "hideRole". */
|
|
278
|
-
isHideElement(roles, checkRoles) {
|
|
279
|
-
if (!roles || roles.length === 0)
|
|
280
|
-
return false;
|
|
281
|
-
if (roles.indexOf(this.hideRole) !== -1)
|
|
282
|
-
return true;
|
|
283
|
-
for (const role of roles) {
|
|
284
|
-
if (role && (role.length !== 0) && this.hasRole(checkRoles, role)) {
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return true;
|
|
164
|
+
if (this.userService.userData?.roleList)
|
|
165
|
+
this._roles.set(this.userService.userData?.roleList);
|
|
166
|
+
this._loggedIn.set(!!this.userService.userData && !!this.userService.userData.token);
|
|
167
|
+
// Слушаем шину событий: если интерцептор поймал 401, сбрасываем сессию
|
|
168
|
+
this.eventService.authError$
|
|
169
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
170
|
+
.subscribe(() => {
|
|
171
|
+
this.logout();
|
|
172
|
+
});
|
|
289
173
|
}
|
|
290
|
-
// /** Сменить роль без side эффекта */
|
|
291
|
-
// public changeRole(role: string) {
|
|
292
|
-
// this.roles$.next([role]);
|
|
293
|
-
// }
|
|
294
|
-
// /** Сменить роли без side эффекта */
|
|
295
|
-
// public changeRoles(roles: string[]) {
|
|
296
|
-
// this.roles$.next(roles);
|
|
297
|
-
// }
|
|
298
174
|
/** Запрос авторизации */
|
|
299
|
-
login(username, password, idCas,
|
|
175
|
+
login(username, password, idCas, onErrorFn) {
|
|
300
176
|
const passwordEncoded = encodeURIComponent(password);
|
|
301
177
|
let body = `username=${username}&password=${passwordEncoded}`;
|
|
302
178
|
if (idCas) {
|
|
303
179
|
body += `&idcas=${idCas}`;
|
|
304
180
|
}
|
|
305
|
-
|
|
306
|
-
body
|
|
307
|
-
}
|
|
308
|
-
this.http.post(this.baseRoute + 'jwt', body, this.defaultHeader)
|
|
181
|
+
this.http
|
|
182
|
+
.post(this.config.auth.loginRoute + 'jwt', body, this.defaultHeader)
|
|
309
183
|
.subscribe({
|
|
310
|
-
next: data => {
|
|
311
|
-
this.successLoginAction(data
|
|
312
|
-
this.
|
|
184
|
+
next: (data) => {
|
|
185
|
+
this.successLoginAction(data);
|
|
186
|
+
this.notificationService.success('Успешная авторизация');
|
|
313
187
|
},
|
|
314
188
|
error: (error) => {
|
|
315
|
-
|
|
316
|
-
this.
|
|
189
|
+
console.log(error);
|
|
190
|
+
this.notificationService.error('Ошибка при авторизации: ' + error, 0);
|
|
317
191
|
if (onErrorFn) {
|
|
318
192
|
onErrorFn();
|
|
319
193
|
}
|
|
320
|
-
}
|
|
194
|
+
},
|
|
321
195
|
});
|
|
322
196
|
}
|
|
323
197
|
/** Aвторизация по пропуску */
|
|
324
|
-
loginByPermit(permit, idCas
|
|
198
|
+
loginByPermit(permit, idCas) {
|
|
325
199
|
let body = `permit=${permit}`;
|
|
326
200
|
if (idCas) {
|
|
327
201
|
body += `&idcas=${idCas}`;
|
|
328
202
|
}
|
|
329
|
-
|
|
330
|
-
body
|
|
331
|
-
}
|
|
332
|
-
return this.http.post(this.baseRoute + 'jwt', body, this.defaultHeader)
|
|
203
|
+
return this.http
|
|
204
|
+
.post(this.config.auth.loginRoute + 'jwt', body, this.defaultHeader)
|
|
333
205
|
.subscribe({
|
|
334
206
|
next: (data) => {
|
|
335
|
-
this.successLoginAction(data
|
|
336
|
-
this.
|
|
207
|
+
this.successLoginAction(data);
|
|
208
|
+
this.notificationService.success('Успешная авторизация');
|
|
337
209
|
},
|
|
338
210
|
error: (error) => {
|
|
339
|
-
|
|
340
|
-
this.
|
|
341
|
-
}
|
|
211
|
+
console.log(error);
|
|
212
|
+
this.notificationService.error('Ошибка при авторизации: ' + error, 0);
|
|
213
|
+
},
|
|
342
214
|
});
|
|
343
215
|
}
|
|
344
|
-
|
|
345
|
-
logout(returnUrl = '') {
|
|
216
|
+
logout() {
|
|
346
217
|
// Убирает(удаляет) пользователя из локального хранилища когда он разлогинивается
|
|
347
218
|
this.userService.removeUser();
|
|
348
|
-
|
|
349
|
-
//
|
|
350
|
-
this.
|
|
351
|
-
//
|
|
352
|
-
if (
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
219
|
+
this._loggedIn.set(false);
|
|
220
|
+
// localStorage.removeItem(this.config.auth.userStorageKey);
|
|
221
|
+
// localStorage.removeItem(this.config.auth.refreshTokenStorageKey);
|
|
222
|
+
// ЛОГИКА СОХРАНЕНИЯ URL ПРИ РАЗЛОГИНЕ (Ваш улучшенный кусок кода)
|
|
223
|
+
if (this.router) {
|
|
224
|
+
const currentUrl = this.router.url;
|
|
225
|
+
// Проверяем, не находимся ли мы уже на странице логина, чтобы избежать зацикливания
|
|
226
|
+
if (currentUrl.includes(this.config.auth.loginRoute)) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
// Безопасное формирование query-параметров через Router
|
|
230
|
+
this.router.navigate([this.config.auth.loginRoute], {
|
|
231
|
+
queryParams: { returnUrl: encodeURIComponent(currentUrl) },
|
|
232
|
+
});
|
|
358
233
|
}
|
|
359
234
|
}
|
|
360
|
-
// Получить роли пользователя
|
|
361
|
-
getRoles() {
|
|
362
|
-
return this.http.get(this.baseRoute + 'jwt/webroles');
|
|
363
|
-
}
|
|
364
|
-
// /** Инициализация ролей */
|
|
365
|
-
// private initRole() {
|
|
366
|
-
// if (this.hasRole(this.roles$.getValue(), this.defaultRole)) {
|
|
367
|
-
// this.roleService.getRoles().subscribe({
|
|
368
|
-
// next: (data: string[]) => {
|
|
369
|
-
// this.roles$.next(data['Roles']);
|
|
370
|
-
// },
|
|
371
|
-
// error: (error: any) => {
|
|
372
|
-
// this.console.log(error);
|
|
373
|
-
// this.alert.error('Ошибка при получении списка ролей пользователя: ' + error);
|
|
374
|
-
// }
|
|
375
|
-
// });
|
|
376
|
-
// }
|
|
377
|
-
// }
|
|
378
235
|
/** При успешной авторизации */
|
|
379
|
-
successLoginAction(user
|
|
236
|
+
successLoginAction(user) {
|
|
380
237
|
this.userService.userData = user;
|
|
381
|
-
this.
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
this.router.navigate([url], { queryParams: params });
|
|
396
|
-
}
|
|
397
|
-
else {
|
|
398
|
-
this.router.navigate([decodeUrl]);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
else {
|
|
402
|
-
// не указан целевой маршрут, переход на главную
|
|
403
|
-
this.router.navigate(['']);
|
|
238
|
+
this._loggedIn.set(true);
|
|
239
|
+
this._roles.set(this.userService.userData.roleList);
|
|
240
|
+
// ЛОГИКА ВОЗВРАТА ПОСЛЕ УСПЕШНОГО ЛОГИНА
|
|
241
|
+
if (this.router) {
|
|
242
|
+
// Извлекаем returnUrl из текущего query-параметра текущего маршрута
|
|
243
|
+
const currentUrlTree = this.router.parseUrl(this.router.url);
|
|
244
|
+
const returnUrl = currentUrlTree.queryParamMap.get('returnUrl');
|
|
245
|
+
if (returnUrl) {
|
|
246
|
+
// Декодируем и перенаправляем пользователя туда, где он был
|
|
247
|
+
this.router.navigateByUrl(decodeURIComponent(returnUrl));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
// Если returnUrl нет, идем на главную
|
|
251
|
+
this.router.navigate(['/']);
|
|
404
252
|
}
|
|
405
253
|
}
|
|
406
254
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
@@ -408,1849 +256,48 @@ class AuthService {
|
|
|
408
256
|
}
|
|
409
257
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AuthService, decorators: [{
|
|
410
258
|
type: Injectable,
|
|
411
|
-
args: [{
|
|
412
|
-
providedIn: 'root'
|
|
413
|
-
}]
|
|
414
|
-
}], ctorParameters: () => [] });
|
|
415
|
-
|
|
416
|
-
class LoginFormComponent {
|
|
417
|
-
pending = input(false, ...(ngDevMode ? [{ debugName: "pending" }] : []));
|
|
418
|
-
errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
|
|
419
|
-
submitted = output();
|
|
420
|
-
hide = true;
|
|
421
|
-
form = new FormGroup({
|
|
422
|
-
username: new FormControl('', [Validators.required]),
|
|
423
|
-
password: new FormControl('', [Validators.required]),
|
|
424
|
-
});
|
|
425
|
-
constructor() {
|
|
426
|
-
effect(() => {
|
|
427
|
-
if (this.pending()) {
|
|
428
|
-
this.form.disable();
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
this.form.enable();
|
|
432
|
-
}
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
submit() {
|
|
436
|
-
if (this.form.valid) {
|
|
437
|
-
this.submitted.emit(this.form.value);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LoginFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
441
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: LoginFormComponent, isStandalone: true, selector: "ngx-uik-login-form", inputs: { pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { submitted: "submitted" }, ngImport: i0, template: "<mat-card appearance=\"outlined\">\r\n <mat-card-header>\r\n <mat-card-title>\r\n \u0410\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u044F\r\n </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\">\r\n <p>\r\n <mat-form-field>\r\n <mat-label>\u0418\u043C\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F</mat-label>\r\n <input type=\"text\" pattern=\"[A-Za-z]{1,}.[A-Za-z]{1,}.[A-Za-z]*\"\r\n matInput\r\n autocomplete=\"on\"\r\n name=\"login-form-username\"\r\n placeholder=\"\u0418\u043C\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F\"\r\n formControlName=\"username\">\r\n @if (form.controls['username'].hasError('pattern')) {\r\n <mat-error>\r\n \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043C\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 (\u041F\u0440\u0438\u043C\u0435\u0440: a.p.petrov)\r\n </mat-error>\r\n }\r\n @if (form.controls['username'].hasError('required')) {\r\n <mat-error>\r\n \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0437\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u044D\u0442\u043E \u043F\u043E\u043B\u0435\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </p>\r\n\r\n <p>\r\n <mat-form-field>\r\n <mat-label>\u041F\u0430\u0440\u043E\u043B\u044C</mat-label>\r\n <input [type]=\"hide ? 'password' : 'text'\" matInput placeholder=\"\u041F\u0430\u0440\u043E\u043B\u044C\" formControlName=\"password\">\r\n <mat-icon class=\"watcher\" matSuffix (mousedown)=\"hide=false\" (mouseup)=\"hide=true\"\r\n >{{ hide ? 'visibility_off' : 'visibility'}}</mat-icon>\r\n @if (form.controls['password'].hasError('required')) {\r\n <mat-error>\r\n \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0437\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u044D\u0442\u043E \u043F\u043E\u043B\u0435\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </p>\r\n\r\n @if (errorMessage()) {\r\n <p class=\"loginError\">\r\n {{ errorMessage() }}\r\n </p>\r\n }\r\n\r\n <p class=\"loginButtons\">\r\n <button type=\"submit\" mat-button mat-stroked-button color=\"primary\" [disabled]=\"pending()\">\u0412\u043E\u0439\u0442\u0438</button>\r\n </p>\r\n\r\n </form>\r\n </mat-card-content>\r\n </mat-card>\r\n", styles: [":host{display:flex;justify-content:center;margin:32px 0}.mat-mdc-form-field{width:100%;min-width:300px}mat-card-header{justify-content:center}mat-card-content{font-size:16px}.loginError{padding:16px;width:300px;color:#fff;background-color:red}.loginButtons{display:flex;flex-direction:row;justify-content:flex-end}.watcher{cursor:default}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }] });
|
|
442
|
-
}
|
|
443
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LoginFormComponent, decorators: [{
|
|
444
|
-
type: Component,
|
|
445
|
-
args: [{ selector: 'ngx-uik-login-form', imports: [MatCard, MatCardHeader, MatCardTitle, MatCardContent, FormsModule, ReactiveFormsModule, MatFormField,
|
|
446
|
-
MatLabel, MatInput, MatError, MatIcon, MatSuffix, MatButton], template: "<mat-card appearance=\"outlined\">\r\n <mat-card-header>\r\n <mat-card-title>\r\n \u0410\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u044F\r\n </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <form [formGroup]=\"form\" (ngSubmit)=\"submit()\">\r\n <p>\r\n <mat-form-field>\r\n <mat-label>\u0418\u043C\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F</mat-label>\r\n <input type=\"text\" pattern=\"[A-Za-z]{1,}.[A-Za-z]{1,}.[A-Za-z]*\"\r\n matInput\r\n autocomplete=\"on\"\r\n name=\"login-form-username\"\r\n placeholder=\"\u0418\u043C\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F\"\r\n formControlName=\"username\">\r\n @if (form.controls['username'].hasError('pattern')) {\r\n <mat-error>\r\n \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043C\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 (\u041F\u0440\u0438\u043C\u0435\u0440: a.p.petrov)\r\n </mat-error>\r\n }\r\n @if (form.controls['username'].hasError('required')) {\r\n <mat-error>\r\n \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0437\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u044D\u0442\u043E \u043F\u043E\u043B\u0435\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </p>\r\n\r\n <p>\r\n <mat-form-field>\r\n <mat-label>\u041F\u0430\u0440\u043E\u043B\u044C</mat-label>\r\n <input [type]=\"hide ? 'password' : 'text'\" matInput placeholder=\"\u041F\u0430\u0440\u043E\u043B\u044C\" formControlName=\"password\">\r\n <mat-icon class=\"watcher\" matSuffix (mousedown)=\"hide=false\" (mouseup)=\"hide=true\"\r\n >{{ hide ? 'visibility_off' : 'visibility'}}</mat-icon>\r\n @if (form.controls['password'].hasError('required')) {\r\n <mat-error>\r\n \u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u0437\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u044D\u0442\u043E \u043F\u043E\u043B\u0435\r\n </mat-error>\r\n }\r\n </mat-form-field>\r\n </p>\r\n\r\n @if (errorMessage()) {\r\n <p class=\"loginError\">\r\n {{ errorMessage() }}\r\n </p>\r\n }\r\n\r\n <p class=\"loginButtons\">\r\n <button type=\"submit\" mat-button mat-stroked-button color=\"primary\" [disabled]=\"pending()\">\u0412\u043E\u0439\u0442\u0438</button>\r\n </p>\r\n\r\n </form>\r\n </mat-card-content>\r\n </mat-card>\r\n", styles: [":host{display:flex;justify-content:center;margin:32px 0}.mat-mdc-form-field{width:100%;min-width:300px}mat-card-header{justify-content:center}mat-card-content{font-size:16px}.loginError{padding:16px;width:300px;color:#fff;background-color:red}.loginButtons{display:flex;flex-direction:row;justify-content:flex-end}.watcher{cursor:default}\n"] }]
|
|
447
|
-
}], ctorParameters: () => [], propDecorators: { pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], submitted: [{ type: i0.Output, args: ["submitted"] }] } });
|
|
448
|
-
|
|
449
|
-
class PermitFormComponent {
|
|
450
|
-
hidy = viewChild('hidy', ...(ngDevMode ? [{ debugName: "hidy" }] : []));
|
|
451
|
-
submitted = output();
|
|
452
|
-
mouseHandling(event) {
|
|
453
|
-
this.hidy()?.nativeElement.focus();
|
|
454
|
-
}
|
|
455
|
-
ngOnInit() {
|
|
456
|
-
// Обнуляем значение Input
|
|
457
|
-
const hidy = this.hidy();
|
|
458
|
-
if (hidy) {
|
|
459
|
-
hidy.nativeElement.value = null;
|
|
460
|
-
hidy.nativeElement.focus();
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Поле ввода
|
|
465
|
-
*
|
|
466
|
-
* @param событие нажатия на клавишу
|
|
467
|
-
*/
|
|
468
|
-
onKeydown(event) {
|
|
469
|
-
if (event.key === 'Enter') {
|
|
470
|
-
const permit = this.hidy()?.nativeElement.value;
|
|
471
|
-
if (permit) {
|
|
472
|
-
this.submitted.emit(permit);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: PermitFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
477
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.0", type: PermitFormComponent, isStandalone: true, selector: "ngx-uik-permit-form", outputs: { submitted: "submitted" }, host: { listeners: { "document:mouseup": "mouseHandling($event)" } }, viewQueries: [{ propertyName: "hidy", first: true, predicate: ["hidy"], descendants: true, isSignal: true }], ngImport: i0, template: "<mat-card appearance=\"outlined\">\r\n <mat-card-header>\r\n <mat-card-title>\r\n \u041F\u0440\u0438\u043B\u043E\u0436\u0438\u0442\u0435 \u043F\u0440\u043E\u043F\u0443\u0441\u043A\r\n </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <div class=\"permit\"></div>\r\n </mat-card-content>\r\n</mat-card>\r\n<input #hidy class=\"hidy\" type=\"text\" (keydown)=\"onKeydown($event)\"/>", styles: [":host{display:flex;justify-content:center;margin:32px 0}.mat-mdc-form-field{width:100%;min-width:300px}mat-card-title,mat-card-content{display:flex;justify-content:center}mat-card-content{font-size:16px}div.permit{border:none;width:300px;background-size:300px;height:180px}div.permit button div{margin-bottom:200px;color:#000;font-size:34px}input.hidy{opacity:0;position:absolute;left:-200px;top:-200px}\n"], dependencies: [{ kind: "component", type: MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "directive", type: MatCardContent, selector: "mat-card-content" }] });
|
|
478
|
-
}
|
|
479
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: PermitFormComponent, decorators: [{
|
|
480
|
-
type: Component,
|
|
481
|
-
args: [{ selector: 'ngx-uik-permit-form', imports: [MatCard, MatCardHeader, MatCardTitle, MatCardContent], template: "<mat-card appearance=\"outlined\">\r\n <mat-card-header>\r\n <mat-card-title>\r\n \u041F\u0440\u0438\u043B\u043E\u0436\u0438\u0442\u0435 \u043F\u0440\u043E\u043F\u0443\u0441\u043A\r\n </mat-card-title>\r\n </mat-card-header>\r\n <mat-card-content>\r\n <div class=\"permit\"></div>\r\n </mat-card-content>\r\n</mat-card>\r\n<input #hidy class=\"hidy\" type=\"text\" (keydown)=\"onKeydown($event)\"/>", styles: [":host{display:flex;justify-content:center;margin:32px 0}.mat-mdc-form-field{width:100%;min-width:300px}mat-card-title,mat-card-content{display:flex;justify-content:center}mat-card-content{font-size:16px}div.permit{border:none;width:300px;background-size:300px;height:180px}div.permit button div{margin-bottom:200px;color:#000;font-size:34px}input.hidy{opacity:0;position:absolute;left:-200px;top:-200px}\n"] }]
|
|
482
|
-
}], propDecorators: { hidy: [{ type: i0.ViewChild, args: ['hidy', { isSignal: true }] }], submitted: [{ type: i0.Output, args: ["submitted"] }], mouseHandling: [{
|
|
483
|
-
type: HostListener,
|
|
484
|
-
args: ['document:mouseup', ['$event']]
|
|
485
|
-
}] } });
|
|
486
|
-
|
|
487
|
-
class LoginPageComponent {
|
|
488
|
-
pending = false;
|
|
489
|
-
error = '';
|
|
490
|
-
isKiosk = false;
|
|
491
|
-
/** Идентификатор АС */
|
|
492
|
-
idCas = 0;
|
|
493
|
-
/** Подписка на Идентификатор АС */
|
|
494
|
-
sub;
|
|
495
|
-
/** Url страницы, с которой был переход (после входа вернет на неё) */
|
|
496
|
-
returnUrl = '';
|
|
497
|
-
authService = inject(AuthService);
|
|
498
|
-
route = inject(ActivatedRoute);
|
|
499
|
-
loaderService = inject(LoaderService);
|
|
500
|
-
constructor() {
|
|
501
|
-
this.sub = this.route.data.subscribe(data => {
|
|
502
|
-
this.idCas = data['idCas'];
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
ngOnInit() {
|
|
506
|
-
if (localStorage.getItem('id_human') || localStorage.getItem('kiosk-keyboard-layout')) {
|
|
507
|
-
// this.isKiosk = true;
|
|
508
|
-
}
|
|
509
|
-
this.route.queryParams.subscribe(params => {
|
|
510
|
-
this.returnUrl = params['returnUrl'];
|
|
511
|
-
//console.log('constructor this.returnUrl = ', this.returnUrl);
|
|
512
|
-
//this.returnUrl = this.returnUrl.slice(this.returnUrl.lastIndexOf('returnUrl=') + 'returnUrl='.length);
|
|
513
|
-
//console.log('constructor NEW this.returnUrl = ', this.returnUrl);
|
|
514
|
-
});
|
|
515
|
-
}
|
|
516
|
-
ngOnDestroy() {
|
|
517
|
-
this.sub.unsubscribe();
|
|
518
|
-
}
|
|
519
|
-
onSubmitError() {
|
|
520
|
-
return () => {
|
|
521
|
-
this.pending = false;
|
|
522
|
-
this.loaderService.hide();
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
onSubmit($event) {
|
|
526
|
-
this.loaderService.show();
|
|
527
|
-
this.pending = true;
|
|
528
|
-
this.authService.login($event.username, $event.password, this.idCas, this.returnUrl, this.onSubmitError());
|
|
529
|
-
}
|
|
530
|
-
onSubmitPermit($event) {
|
|
531
|
-
const permit = $event;
|
|
532
|
-
this.authService.loginByPermit(permit, this.idCas, this.returnUrl);
|
|
533
|
-
}
|
|
534
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LoginPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
535
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: LoginPageComponent, isStandalone: true, selector: "ngx-uik-login-page", ngImport: i0, template: "@if (!isKiosk) {\r\n <ngx-uik-login-form\r\n (submitted)=\"onSubmit($event)\"\r\n [pending]=\"pending\"\r\n [errorMessage]=\"error\">\r\n </ngx-uik-login-form>\r\n }\r\n @if (isKiosk) {\r\n <ngx-uik-permit-form\r\n (submitted)=\"onSubmitPermit($event)\"\r\n >\r\n </ngx-uik-permit-form>\r\n }", styles: [""], dependencies: [{ kind: "component", type: LoginFormComponent, selector: "ngx-uik-login-form", inputs: ["pending", "errorMessage"], outputs: ["submitted"] }, { kind: "component", type: PermitFormComponent, selector: "ngx-uik-permit-form", outputs: ["submitted"] }] });
|
|
536
|
-
}
|
|
537
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LoginPageComponent, decorators: [{
|
|
538
|
-
type: Component,
|
|
539
|
-
args: [{ selector: 'ngx-uik-login-page', imports: [LoginFormComponent, PermitFormComponent], template: "@if (!isKiosk) {\r\n <ngx-uik-login-form\r\n (submitted)=\"onSubmit($event)\"\r\n [pending]=\"pending\"\r\n [errorMessage]=\"error\">\r\n </ngx-uik-login-form>\r\n }\r\n @if (isKiosk) {\r\n <ngx-uik-permit-form\r\n (submitted)=\"onSubmitPermit($event)\"\r\n >\r\n </ngx-uik-permit-form>\r\n }" }]
|
|
259
|
+
args: [{ providedIn: 'root' }]
|
|
540
260
|
}], ctorParameters: () => [] });
|
|
541
261
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DisableIfUnauthorizedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
554
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: DisableIfUnauthorizedDirective, isStandalone: true, selector: "[ngxUikDisableIfUnauthorized]", inputs: { permission: { classPropertyName: "permission", publicName: "ngxUikDisableIfUnauthorized", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
555
|
-
}
|
|
556
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DisableIfUnauthorizedDirective, decorators: [{
|
|
557
|
-
type: Directive,
|
|
558
|
-
args: [{
|
|
559
|
-
selector: '[ngxUikDisableIfUnauthorized]',
|
|
560
|
-
standalone: true
|
|
561
|
-
}]
|
|
562
|
-
}], ctorParameters: () => [], propDecorators: { permission: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngxUikDisableIfUnauthorized", required: false }] }] } });
|
|
563
|
-
|
|
564
|
-
class HideIfUnauthorizedDirective {
|
|
565
|
-
permission = input(undefined, { ...(ngDevMode ? { debugName: "permission" } : {}), alias: 'ngxUikHideIfUnauthorized' });
|
|
566
|
-
el = inject(ElementRef);
|
|
567
|
-
authService = inject(AuthService);
|
|
568
|
-
ngOnInit() {
|
|
569
|
-
if (this.permission() && !this.authService.hasPermission(this.permission())) {
|
|
570
|
-
this.el.nativeElement.style.display = 'none';
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: HideIfUnauthorizedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
574
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: HideIfUnauthorizedDirective, isStandalone: true, selector: "[ngxUikHideIfUnauthorized]", inputs: { permission: { classPropertyName: "permission", publicName: "ngxUikHideIfUnauthorized", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
575
|
-
}
|
|
576
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: HideIfUnauthorizedDirective, decorators: [{
|
|
577
|
-
type: Directive,
|
|
578
|
-
args: [{
|
|
579
|
-
selector: '[ngxUikHideIfUnauthorized]',
|
|
580
|
-
standalone: true
|
|
581
|
-
}]
|
|
582
|
-
}], propDecorators: { permission: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngxUikHideIfUnauthorized", required: false }] }] } });
|
|
583
|
-
|
|
584
|
-
class DisableIfRoleDirective {
|
|
585
|
-
role = input('', { ...(ngDevMode ? { debugName: "role" } : {}), alias: 'ngxUikDisableIfRole' });
|
|
586
|
-
userRoles = signal([], ...(ngDevMode ? [{ debugName: "userRoles" }] : []));
|
|
587
|
-
el = inject(ElementRef);
|
|
588
|
-
authService = inject(AuthService);
|
|
589
|
-
constructor() {
|
|
590
|
-
effect(() => {
|
|
591
|
-
if (!this.authService.hasRole(this.userRoles(), this.role())) {
|
|
592
|
-
this.el.nativeElement.disabled = true;
|
|
593
|
-
}
|
|
594
|
-
else {
|
|
595
|
-
this.el.nativeElement.disabled = false;
|
|
596
|
-
}
|
|
262
|
+
// Сервис для вывода сообщений(ошибки, успеха)
|
|
263
|
+
class NotificationService {
|
|
264
|
+
// eslint-disable-next-line no-magic-numbers
|
|
265
|
+
duration = 5000;
|
|
266
|
+
_snackBar = inject(MatSnackBar);
|
|
267
|
+
openSnackBar(message, action, duration = this.duration) {
|
|
268
|
+
this._snackBar.open(message, action, {
|
|
269
|
+
duration,
|
|
270
|
+
panelClass: ['red-snackbar'],
|
|
597
271
|
});
|
|
598
272
|
}
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
this.authService.roles$.subscribe((userRoles) => {
|
|
602
|
-
this.userRoles.set(userRoles);
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DisableIfRoleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
607
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.0", type: DisableIfRoleDirective, isStandalone: true, selector: "[ngxUikDisableIfRole]", inputs: { role: { classPropertyName: "role", publicName: "ngxUikDisableIfRole", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
608
|
-
}
|
|
609
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DisableIfRoleDirective, decorators: [{
|
|
610
|
-
type: Directive,
|
|
611
|
-
args: [{
|
|
612
|
-
selector: '[ngxUikDisableIfRole]',
|
|
613
|
-
standalone: true
|
|
614
|
-
}]
|
|
615
|
-
}], ctorParameters: () => [], propDecorators: { role: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngxUikDisableIfRole", required: false }] }] } });
|
|
616
|
-
|
|
617
|
-
class HideIfRoleNotDirective {
|
|
618
|
-
roles = input([], { ...(ngDevMode ? { debugName: "roles" } : {}), alias: 'ngxUikHideIfRoleNot' });
|
|
619
|
-
userRoles = signal([], ...(ngDevMode ? [{ debugName: "userRoles" }] : []));
|
|
620
|
-
el = inject(ElementRef);
|
|
621
|
-
authService = inject(AuthService);
|
|
622
|
-
constructor() {
|
|
623
|
-
effect(() => {
|
|
624
|
-
if (this.userRoles() && this.userRoles().length > 0) {
|
|
625
|
-
// Элемент скрывается, если у пользователя нет ни одной роли из перереданных в "roles"
|
|
626
|
-
// или в списке "roles" есть роль "hideRole".
|
|
627
|
-
const isHide = this.authService.isHideElement(this.roles(), this.userRoles());
|
|
628
|
-
if (isHide) {
|
|
629
|
-
this.el.nativeElement.style.display = 'none';
|
|
630
|
-
}
|
|
631
|
-
else {
|
|
632
|
-
this.el.nativeElement.style.display = 'inherit';
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
});
|
|
273
|
+
success(message, duration = this.duration) {
|
|
274
|
+
this.openSnackBar(message, 'Закрыть', duration);
|
|
636
275
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
this.authService.roles$.subscribe((userRoles) => {
|
|
640
|
-
this.userRoles.set(userRoles);
|
|
641
|
-
});
|
|
642
|
-
}
|
|
276
|
+
info(message, duration = this.duration) {
|
|
277
|
+
this.openSnackBar(message, 'Закрыть', duration);
|
|
643
278
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
}
|
|
647
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: HideIfRoleNotDirective, decorators: [{
|
|
648
|
-
type: Directive,
|
|
649
|
-
args: [{
|
|
650
|
-
selector: '[ngxUikHideIfRoleNot]',
|
|
651
|
-
standalone: true
|
|
652
|
-
}]
|
|
653
|
-
}], ctorParameters: () => [], propDecorators: { roles: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngxUikHideIfRoleNot", required: false }] }] } });
|
|
654
|
-
|
|
655
|
-
class AuthGuardService {
|
|
656
|
-
auth = inject(AuthService);
|
|
657
|
-
router = inject(Router);
|
|
658
|
-
canActivate(route, state) {
|
|
659
|
-
const isLogin = this.auth.loggedIn$.value;
|
|
660
|
-
if (!isLogin) {
|
|
661
|
-
console.log('state.url =', state.url);
|
|
662
|
-
// Если не зарегистрирован вернуть в форму авторизации
|
|
663
|
-
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
|
|
664
|
-
}
|
|
665
|
-
return isLogin;
|
|
279
|
+
helper(message, duration = this.duration) {
|
|
280
|
+
this.openSnackBar(message, 'Закрыть', duration);
|
|
666
281
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
}
|
|
670
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AuthGuardService, decorators: [{
|
|
671
|
-
type: Injectable,
|
|
672
|
-
args: [{
|
|
673
|
-
providedIn: 'root'
|
|
674
|
-
}]
|
|
675
|
-
}] });
|
|
676
|
-
const authGuard = (route, state) => inject(AuthGuardService).canActivate(route, state);
|
|
677
|
-
|
|
678
|
-
class RoleGuardService {
|
|
679
|
-
roles = [];
|
|
680
|
-
authService = inject(AuthService);
|
|
681
|
-
router = inject(Router);
|
|
682
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
683
|
-
canActivate(route, state) {
|
|
684
|
-
this.roles = route.data['roles'];
|
|
685
|
-
return this.authService.roles$.pipe(map((userRoles) => this.authService.hasRoles(userRoles, this.roles)));
|
|
282
|
+
warning(message, duration = this.duration) {
|
|
283
|
+
this.openSnackBar(message, 'Закрыть', duration);
|
|
686
284
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
}
|
|
690
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RoleGuardService, decorators: [{
|
|
691
|
-
type: Injectable,
|
|
692
|
-
args: [{
|
|
693
|
-
providedIn: 'root'
|
|
694
|
-
}]
|
|
695
|
-
}] });
|
|
696
|
-
const roleGuard = (route, state) => inject(RoleGuardService).canActivate(route, state);
|
|
697
|
-
|
|
698
|
-
// Вычисление разрешений на модули по ролям
|
|
699
|
-
class RoleService {
|
|
700
|
-
// Указываем какой сервер использовать
|
|
701
|
-
baseRoute = 'mainApi/';
|
|
702
|
-
http = inject(HttpClient);
|
|
703
|
-
// Получить роли пользователя
|
|
704
|
-
getRoles() {
|
|
705
|
-
return this.http.get(this.baseRoute + 'jwt/webroles');
|
|
285
|
+
error(message, duration = this.duration) {
|
|
286
|
+
this.openSnackBar(message, 'Закрыть', duration);
|
|
706
287
|
}
|
|
707
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
708
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
288
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
289
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NotificationService, providedIn: 'root' });
|
|
709
290
|
}
|
|
710
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type:
|
|
291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NotificationService, decorators: [{
|
|
711
292
|
type: Injectable,
|
|
712
293
|
args: [{
|
|
713
294
|
providedIn: 'root'
|
|
714
295
|
}]
|
|
715
296
|
}] });
|
|
716
297
|
|
|
717
|
-
class BaseToolbarService {
|
|
718
|
-
baseRoute = 'BaseToolbar';
|
|
719
|
-
constructor() { }
|
|
720
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseToolbarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
721
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseToolbarService, providedIn: 'root' });
|
|
722
|
-
}
|
|
723
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseToolbarService, decorators: [{
|
|
724
|
-
type: Injectable,
|
|
725
|
-
args: [{
|
|
726
|
-
providedIn: 'root'
|
|
727
|
-
}]
|
|
728
|
-
}], ctorParameters: () => [] });
|
|
729
|
-
|
|
730
|
-
class BaseToolbarComponent {
|
|
731
|
-
rolesNewBtn = input([], ...(ngDevMode ? [{ debugName: "rolesNewBtn" }] : []));
|
|
732
|
-
rolesEditBtn = input([], ...(ngDevMode ? [{ debugName: "rolesEditBtn" }] : []));
|
|
733
|
-
rolesRemoveBtn = input([], ...(ngDevMode ? [{ debugName: "rolesRemoveBtn" }] : []));
|
|
734
|
-
rolesCopyBtn = input([], ...(ngDevMode ? [{ debugName: "rolesCopyBtn" }] : []));
|
|
735
|
-
rolesExcelBtn = input([], ...(ngDevMode ? [{ debugName: "rolesExcelBtn" }] : []));
|
|
736
|
-
rolesCsvBtn = input([], ...(ngDevMode ? [{ debugName: "rolesCsvBtn" }] : []));
|
|
737
|
-
rolesPdfBtn = input([], ...(ngDevMode ? [{ debugName: "rolesPdfBtn" }] : []));
|
|
738
|
-
rolesPrintBtn = input([], ...(ngDevMode ? [{ debugName: "rolesPrintBtn" }] : []));
|
|
739
|
-
rolesRefreshBtn = input([], ...(ngDevMode ? [{ debugName: "rolesRefreshBtn" }] : []));
|
|
740
|
-
rolesClearBtn = input([], ...(ngDevMode ? [{ debugName: "rolesClearBtn" }] : []));
|
|
741
|
-
newBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "newBtnDisabled" }] : []));
|
|
742
|
-
editBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "editBtnDisabled" }] : []));
|
|
743
|
-
removeBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "removeBtnDisabled" }] : []));
|
|
744
|
-
copyBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "copyBtnDisabled" }] : []));
|
|
745
|
-
excelBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "excelBtnDisabled" }] : []));
|
|
746
|
-
csvBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "csvBtnDisabled" }] : []));
|
|
747
|
-
pdfBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "pdfBtnDisabled" }] : []));
|
|
748
|
-
printBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "printBtnDisabled" }] : []));
|
|
749
|
-
refreshBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "refreshBtnDisabled" }] : []));
|
|
750
|
-
clearBtnDisabled = input(false, ...(ngDevMode ? [{ debugName: "clearBtnDisabled" }] : []));
|
|
751
|
-
newBtnTooltip = input('Добавить', ...(ngDevMode ? [{ debugName: "newBtnTooltip" }] : []));
|
|
752
|
-
editBtnTooltip = input('Изменить', ...(ngDevMode ? [{ debugName: "editBtnTooltip" }] : []));
|
|
753
|
-
removeBtnTooltip = input('Удалить', ...(ngDevMode ? [{ debugName: "removeBtnTooltip" }] : []));
|
|
754
|
-
copyBtnTooltip = input('Скопировать', ...(ngDevMode ? [{ debugName: "copyBtnTooltip" }] : []));
|
|
755
|
-
excelBtnTooltip = input('Экспортировать в Excel', ...(ngDevMode ? [{ debugName: "excelBtnTooltip" }] : []));
|
|
756
|
-
csvBtnTooltip = input('Экспортировать в Csv', ...(ngDevMode ? [{ debugName: "csvBtnTooltip" }] : []));
|
|
757
|
-
pdfBtnTooltip = input('Экспортировать в Pdf', ...(ngDevMode ? [{ debugName: "pdfBtnTooltip" }] : []));
|
|
758
|
-
printBtnTooltip = input('Печатать', ...(ngDevMode ? [{ debugName: "printBtnTooltip" }] : []));
|
|
759
|
-
refreshBtnTooltip = input('Обновить данные', ...(ngDevMode ? [{ debugName: "refreshBtnTooltip" }] : []));
|
|
760
|
-
clearBtnTooltip = input('Очистить фильтр', ...(ngDevMode ? [{ debugName: "clearBtnTooltip" }] : []));
|
|
761
|
-
/** Список элементов контекстного меню. */
|
|
762
|
-
newBtnOpt = input([], ...(ngDevMode ? [{ debugName: "newBtnOpt" }] : []));
|
|
763
|
-
clickedNewBtn = output();
|
|
764
|
-
clickedEditBtn = output();
|
|
765
|
-
clickedRemoveBtn = output();
|
|
766
|
-
clickedCopyBtn = output();
|
|
767
|
-
clickedExcelBtn = output();
|
|
768
|
-
clickedCsvBtn = output();
|
|
769
|
-
clickedPdfBtn = output();
|
|
770
|
-
clickedPrintBtn = output();
|
|
771
|
-
clickedRefreshBtn = output();
|
|
772
|
-
clickedClearBtn = output();
|
|
773
|
-
// DI
|
|
774
|
-
authService = inject(AuthService);
|
|
775
|
-
userRoles = [];
|
|
776
|
-
subscription = new Subscription();
|
|
777
|
-
ngOnInit() {
|
|
778
|
-
// получить права пользователя
|
|
779
|
-
const subs = this.authService.roles$.subscribe((userRoles) => {
|
|
780
|
-
this.userRoles = userRoles;
|
|
781
|
-
});
|
|
782
|
-
this.subscription.add(subs);
|
|
783
|
-
}
|
|
784
|
-
ngOnDestroy() {
|
|
785
|
-
if (this.subscription)
|
|
786
|
-
this.subscription.unsubscribe();
|
|
787
|
-
}
|
|
788
|
-
isShow(roles) {
|
|
789
|
-
//console.log(roles, this.userRoles);
|
|
790
|
-
return !this.authService.isHideElement(roles, this.userRoles);
|
|
791
|
-
}
|
|
792
|
-
onNewClick() {
|
|
793
|
-
this.clickedNewBtn.emit();
|
|
794
|
-
}
|
|
795
|
-
onEditClick() {
|
|
796
|
-
this.clickedEditBtn.emit();
|
|
797
|
-
}
|
|
798
|
-
onRemoveClick() {
|
|
799
|
-
this.clickedRemoveBtn.emit();
|
|
800
|
-
}
|
|
801
|
-
onCopyClick() {
|
|
802
|
-
this.clickedCopyBtn.emit();
|
|
803
|
-
}
|
|
804
|
-
onExcelClick() {
|
|
805
|
-
this.clickedExcelBtn.emit();
|
|
806
|
-
}
|
|
807
|
-
onCsvClick() {
|
|
808
|
-
this.clickedCsvBtn.emit();
|
|
809
|
-
}
|
|
810
|
-
onPdfClick() {
|
|
811
|
-
this.clickedPdfBtn.emit();
|
|
812
|
-
}
|
|
813
|
-
onPrintClick() {
|
|
814
|
-
this.clickedPrintBtn.emit();
|
|
815
|
-
}
|
|
816
|
-
onRefreshGridClick() {
|
|
817
|
-
this.clickedRefreshBtn.emit();
|
|
818
|
-
}
|
|
819
|
-
onClearClick() {
|
|
820
|
-
this.clickedClearBtn.emit();
|
|
821
|
-
}
|
|
822
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
823
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: BaseToolbarComponent, isStandalone: true, selector: "ngx-uik-base-toolbar", inputs: { rolesNewBtn: { classPropertyName: "rolesNewBtn", publicName: "rolesNewBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesEditBtn: { classPropertyName: "rolesEditBtn", publicName: "rolesEditBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesRemoveBtn: { classPropertyName: "rolesRemoveBtn", publicName: "rolesRemoveBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesCopyBtn: { classPropertyName: "rolesCopyBtn", publicName: "rolesCopyBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesExcelBtn: { classPropertyName: "rolesExcelBtn", publicName: "rolesExcelBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesCsvBtn: { classPropertyName: "rolesCsvBtn", publicName: "rolesCsvBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesPdfBtn: { classPropertyName: "rolesPdfBtn", publicName: "rolesPdfBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesPrintBtn: { classPropertyName: "rolesPrintBtn", publicName: "rolesPrintBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesRefreshBtn: { classPropertyName: "rolesRefreshBtn", publicName: "rolesRefreshBtn", isSignal: true, isRequired: false, transformFunction: null }, rolesClearBtn: { classPropertyName: "rolesClearBtn", publicName: "rolesClearBtn", isSignal: true, isRequired: false, transformFunction: null }, newBtnDisabled: { classPropertyName: "newBtnDisabled", publicName: "newBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, editBtnDisabled: { classPropertyName: "editBtnDisabled", publicName: "editBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, removeBtnDisabled: { classPropertyName: "removeBtnDisabled", publicName: "removeBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, copyBtnDisabled: { classPropertyName: "copyBtnDisabled", publicName: "copyBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, excelBtnDisabled: { classPropertyName: "excelBtnDisabled", publicName: "excelBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, csvBtnDisabled: { classPropertyName: "csvBtnDisabled", publicName: "csvBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, pdfBtnDisabled: { classPropertyName: "pdfBtnDisabled", publicName: "pdfBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, printBtnDisabled: { classPropertyName: "printBtnDisabled", publicName: "printBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, refreshBtnDisabled: { classPropertyName: "refreshBtnDisabled", publicName: "refreshBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, clearBtnDisabled: { classPropertyName: "clearBtnDisabled", publicName: "clearBtnDisabled", isSignal: true, isRequired: false, transformFunction: null }, newBtnTooltip: { classPropertyName: "newBtnTooltip", publicName: "newBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, editBtnTooltip: { classPropertyName: "editBtnTooltip", publicName: "editBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, removeBtnTooltip: { classPropertyName: "removeBtnTooltip", publicName: "removeBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, copyBtnTooltip: { classPropertyName: "copyBtnTooltip", publicName: "copyBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, excelBtnTooltip: { classPropertyName: "excelBtnTooltip", publicName: "excelBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, csvBtnTooltip: { classPropertyName: "csvBtnTooltip", publicName: "csvBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, pdfBtnTooltip: { classPropertyName: "pdfBtnTooltip", publicName: "pdfBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, printBtnTooltip: { classPropertyName: "printBtnTooltip", publicName: "printBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, refreshBtnTooltip: { classPropertyName: "refreshBtnTooltip", publicName: "refreshBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, clearBtnTooltip: { classPropertyName: "clearBtnTooltip", publicName: "clearBtnTooltip", isSignal: true, isRequired: false, transformFunction: null }, newBtnOpt: { classPropertyName: "newBtnOpt", publicName: "newBtnOpt", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickedNewBtn: "clickedNewBtn", clickedEditBtn: "clickedEditBtn", clickedRemoveBtn: "clickedRemoveBtn", clickedCopyBtn: "clickedCopyBtn", clickedExcelBtn: "clickedExcelBtn", clickedCsvBtn: "clickedCsvBtn", clickedPdfBtn: "clickedPdfBtn", clickedPrintBtn: "clickedPrintBtn", clickedRefreshBtn: "clickedRefreshBtn", clickedClearBtn: "clickedClearBtn" }, providers: [
|
|
824
|
-
BaseToolbarService
|
|
825
|
-
], ngImport: i0, template: "<mat-toolbar>\r\n @if (isShow(rolesNewBtn())) {\r\n @if (newBtnOpt() && newBtnOpt().length > 0) {\r\n <button [disabled]=\"newBtnDisabled()\" [matMenuTriggerFor]=\"menuNewBtn\"\r\n mat-icon-button [matTooltip]=\"newBtnTooltip()\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n <mat-menu #menuNewBtn=\"matMenu\">\r\n @for (menuItem of newBtnOpt(); track menuItem) {\r\n @if (menuItem.title === '-' && !(menuItem.hideFn ? menuItem.hideFn(\"\") : menuItem.hide)) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (menuItem.title !== '-' && !(menuItem.hideFn ? menuItem.hideFn(\"\") : menuItem.hide)) {\r\n <button mat-menu-item\r\n (click)=\"menuItem.onClickFn ? menuItem.onClickFn('') : ''\"\r\n [disabled]=\"menuItem.disabledFn ? menuItem.disabledFn('') : menuItem.disabled\">\r\n @if (menuItem.icon) {\r\n <mat-icon>{{menuItem.icon}}</mat-icon>\r\n }\r\n {{ menuItem.title }}\r\n </button>\r\n }\r\n }\r\n </mat-menu>\r\n } \r\n @else {\r\n <button [disabled]=\"newBtnDisabled()\" (click)=\"onNewClick()\"\r\n mat-icon-button routerLink=\"new\" routerLinkActive=\"active\" [matTooltip]=\"newBtnTooltip()\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n }\r\n\r\n @if (isShow(rolesEditBtn())) {\r\n <button [disabled]=\"editBtnDisabled()\" (click)=\"onEditClick()\"\r\n mat-icon-button routerLink=\"edit\" color=\"primary\" routerLinkActive=\"active\" [matTooltip]=\"editBtnTooltip()\">\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesRemoveBtn())) {\r\n <button [disabled]=\"removeBtnDisabled()\" (click)=\"onRemoveClick()\"\r\n mat-icon-button routerLink=\"delete\" color=\"warn\" routerLinkActive=\"active\" [matTooltip]=\"removeBtnTooltip()\">\r\n <mat-icon>remove</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesCopyBtn())) {\r\n <button [disabled]=\"copyBtnDisabled()\" (click)=\"onCopyClick()\"\r\n mat-icon-button routerLink=\"delete\" routerLinkActive=\"active\" [matTooltip]=\"copyBtnTooltip()\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesExcelBtn())) {\r\n <button [disabled]=\"excelBtnDisabled()\" (click)=\"onExcelClick()\"\r\n mat-icon-button routerLink=\"excel\" routerLinkActive=\"active\" [matTooltip]=\"excelBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">explicit</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesCsvBtn())) {\r\n <button [disabled]=\"csvBtnDisabled()\" (click)=\"onCsvClick()\"\r\n mat-icon-button routerLink=\"csv\" routerLinkActive=\"active\" [matTooltip]=\"csvBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">download</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesPdfBtn())) {\r\n <button [disabled]=\"pdfBtnDisabled()\" (click)=\"onPdfClick()\"\r\n mat-icon-button routerLink=\"pdf\" routerLinkActive=\"active\" [matTooltip]=\"pdfBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">picture_as_pdf</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesPrintBtn())) {\r\n <button [disabled]=\"printBtnDisabled()\" (click)=\"onPrintClick()\"\r\n mat-icon-button routerLink=\"print\" routerLinkActive=\"active\" [matTooltip]=\"printBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">print_outline</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesRefreshBtn())) {\r\n <button [disabled]=\"refreshBtnDisabled()\" (click)=\"onRefreshGridClick()\"\r\n mat-icon-button routerLink=\"refresh\" routerLinkActive=\"active\" [matTooltip]=\"refreshBtnTooltip()\">\r\n <mat-icon>refresh</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesClearBtn())) {\r\n <button [disabled]=\"clearBtnDisabled()\" (click)=\"onClearClick()\"\r\n mat-icon-button routerLink=\"clear\" routerLinkActive=\"active\" [matTooltip]=\"clearBtnTooltip()\">\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n }\r\n</mat-toolbar>\r\n", styles: [""], dependencies: [{ kind: "component", type: MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }] });
|
|
826
|
-
}
|
|
827
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseToolbarComponent, decorators: [{
|
|
828
|
-
type: Component,
|
|
829
|
-
args: [{ selector: 'ngx-uik-base-toolbar', imports: [MatToolbar, MatIconButton, MatTooltip, MatIcon, MatMenu, MatDivider, MatMenuTrigger, MatMenuItem], providers: [
|
|
830
|
-
BaseToolbarService
|
|
831
|
-
], template: "<mat-toolbar>\r\n @if (isShow(rolesNewBtn())) {\r\n @if (newBtnOpt() && newBtnOpt().length > 0) {\r\n <button [disabled]=\"newBtnDisabled()\" [matMenuTriggerFor]=\"menuNewBtn\"\r\n mat-icon-button [matTooltip]=\"newBtnTooltip()\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n <mat-menu #menuNewBtn=\"matMenu\">\r\n @for (menuItem of newBtnOpt(); track menuItem) {\r\n @if (menuItem.title === '-' && !(menuItem.hideFn ? menuItem.hideFn(\"\") : menuItem.hide)) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (menuItem.title !== '-' && !(menuItem.hideFn ? menuItem.hideFn(\"\") : menuItem.hide)) {\r\n <button mat-menu-item\r\n (click)=\"menuItem.onClickFn ? menuItem.onClickFn('') : ''\"\r\n [disabled]=\"menuItem.disabledFn ? menuItem.disabledFn('') : menuItem.disabled\">\r\n @if (menuItem.icon) {\r\n <mat-icon>{{menuItem.icon}}</mat-icon>\r\n }\r\n {{ menuItem.title }}\r\n </button>\r\n }\r\n }\r\n </mat-menu>\r\n } \r\n @else {\r\n <button [disabled]=\"newBtnDisabled()\" (click)=\"onNewClick()\"\r\n mat-icon-button routerLink=\"new\" routerLinkActive=\"active\" [matTooltip]=\"newBtnTooltip()\">\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n }\r\n }\r\n\r\n @if (isShow(rolesEditBtn())) {\r\n <button [disabled]=\"editBtnDisabled()\" (click)=\"onEditClick()\"\r\n mat-icon-button routerLink=\"edit\" color=\"primary\" routerLinkActive=\"active\" [matTooltip]=\"editBtnTooltip()\">\r\n <mat-icon>edit</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesRemoveBtn())) {\r\n <button [disabled]=\"removeBtnDisabled()\" (click)=\"onRemoveClick()\"\r\n mat-icon-button routerLink=\"delete\" color=\"warn\" routerLinkActive=\"active\" [matTooltip]=\"removeBtnTooltip()\">\r\n <mat-icon>remove</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesCopyBtn())) {\r\n <button [disabled]=\"copyBtnDisabled()\" (click)=\"onCopyClick()\"\r\n mat-icon-button routerLink=\"delete\" routerLinkActive=\"active\" [matTooltip]=\"copyBtnTooltip()\">\r\n <mat-icon>content_copy</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesExcelBtn())) {\r\n <button [disabled]=\"excelBtnDisabled()\" (click)=\"onExcelClick()\"\r\n mat-icon-button routerLink=\"excel\" routerLinkActive=\"active\" [matTooltip]=\"excelBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">explicit</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesCsvBtn())) {\r\n <button [disabled]=\"csvBtnDisabled()\" (click)=\"onCsvClick()\"\r\n mat-icon-button routerLink=\"csv\" routerLinkActive=\"active\" [matTooltip]=\"csvBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">download</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesPdfBtn())) {\r\n <button [disabled]=\"pdfBtnDisabled()\" (click)=\"onPdfClick()\"\r\n mat-icon-button routerLink=\"pdf\" routerLinkActive=\"active\" [matTooltip]=\"pdfBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">picture_as_pdf</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesPrintBtn())) {\r\n <button [disabled]=\"printBtnDisabled()\" (click)=\"onPrintClick()\"\r\n mat-icon-button routerLink=\"print\" routerLinkActive=\"active\" [matTooltip]=\"printBtnTooltip()\">\r\n <mat-icon class=\"material-icons-outlined\">print_outline</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesRefreshBtn())) {\r\n <button [disabled]=\"refreshBtnDisabled()\" (click)=\"onRefreshGridClick()\"\r\n mat-icon-button routerLink=\"refresh\" routerLinkActive=\"active\" [matTooltip]=\"refreshBtnTooltip()\">\r\n <mat-icon>refresh</mat-icon>\r\n </button>\r\n }\r\n @if (isShow(rolesClearBtn())) {\r\n <button [disabled]=\"clearBtnDisabled()\" (click)=\"onClearClick()\"\r\n mat-icon-button routerLink=\"clear\" routerLinkActive=\"active\" [matTooltip]=\"clearBtnTooltip()\">\r\n <mat-icon>clear</mat-icon>\r\n </button>\r\n }\r\n</mat-toolbar>\r\n" }]
|
|
832
|
-
}], propDecorators: { rolesNewBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesNewBtn", required: false }] }], rolesEditBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesEditBtn", required: false }] }], rolesRemoveBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesRemoveBtn", required: false }] }], rolesCopyBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesCopyBtn", required: false }] }], rolesExcelBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesExcelBtn", required: false }] }], rolesCsvBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesCsvBtn", required: false }] }], rolesPdfBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesPdfBtn", required: false }] }], rolesPrintBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesPrintBtn", required: false }] }], rolesRefreshBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesRefreshBtn", required: false }] }], rolesClearBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "rolesClearBtn", required: false }] }], newBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "newBtnDisabled", required: false }] }], editBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "editBtnDisabled", required: false }] }], removeBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeBtnDisabled", required: false }] }], copyBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyBtnDisabled", required: false }] }], excelBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "excelBtnDisabled", required: false }] }], csvBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "csvBtnDisabled", required: false }] }], pdfBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "pdfBtnDisabled", required: false }] }], printBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "printBtnDisabled", required: false }] }], refreshBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshBtnDisabled", required: false }] }], clearBtnDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearBtnDisabled", required: false }] }], newBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "newBtnTooltip", required: false }] }], editBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "editBtnTooltip", required: false }] }], removeBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeBtnTooltip", required: false }] }], copyBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyBtnTooltip", required: false }] }], excelBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "excelBtnTooltip", required: false }] }], csvBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "csvBtnTooltip", required: false }] }], pdfBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "pdfBtnTooltip", required: false }] }], printBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "printBtnTooltip", required: false }] }], refreshBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshBtnTooltip", required: false }] }], clearBtnTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearBtnTooltip", required: false }] }], newBtnOpt: [{ type: i0.Input, args: [{ isSignal: true, alias: "newBtnOpt", required: false }] }], clickedNewBtn: [{ type: i0.Output, args: ["clickedNewBtn"] }], clickedEditBtn: [{ type: i0.Output, args: ["clickedEditBtn"] }], clickedRemoveBtn: [{ type: i0.Output, args: ["clickedRemoveBtn"] }], clickedCopyBtn: [{ type: i0.Output, args: ["clickedCopyBtn"] }], clickedExcelBtn: [{ type: i0.Output, args: ["clickedExcelBtn"] }], clickedCsvBtn: [{ type: i0.Output, args: ["clickedCsvBtn"] }], clickedPdfBtn: [{ type: i0.Output, args: ["clickedPdfBtn"] }], clickedPrintBtn: [{ type: i0.Output, args: ["clickedPrintBtn"] }], clickedRefreshBtn: [{ type: i0.Output, args: ["clickedRefreshBtn"] }], clickedClearBtn: [{ type: i0.Output, args: ["clickedClearBtn"] }] } });
|
|
833
|
-
|
|
834
|
-
var Action;
|
|
835
|
-
(function (Action) {
|
|
836
|
-
Action["Add"] = "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435";
|
|
837
|
-
Action["Edit"] = "\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435";
|
|
838
|
-
})(Action || (Action = {}));
|
|
839
|
-
|
|
840
|
-
class AvatarService {
|
|
841
|
-
baseRoute = 'common/human/';
|
|
842
|
-
http = inject(HttpClient);
|
|
843
|
-
getAvatarById(idHuman) {
|
|
844
|
-
return this.http.get(this.baseRoute + idHuman + '/avatar', { responseType: 'arraybuffer' });
|
|
845
|
-
}
|
|
846
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AvatarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
847
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AvatarService, providedIn: 'root' });
|
|
848
|
-
}
|
|
849
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: AvatarService, decorators: [{
|
|
850
|
-
type: Injectable,
|
|
851
|
-
args: [{
|
|
852
|
-
providedIn: 'root'
|
|
853
|
-
}]
|
|
854
|
-
}] });
|
|
855
|
-
|
|
856
|
-
class LocalStorageService {
|
|
857
|
-
constructor() { }
|
|
858
|
-
saveData(key, value) {
|
|
859
|
-
localStorage.setItem(key, value);
|
|
860
|
-
}
|
|
861
|
-
getData(key) {
|
|
862
|
-
return localStorage.getItem(key);
|
|
863
|
-
}
|
|
864
|
-
removeData(key) {
|
|
865
|
-
localStorage.removeItem(key);
|
|
866
|
-
}
|
|
867
|
-
clearData() {
|
|
868
|
-
localStorage.clear();
|
|
869
|
-
}
|
|
870
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LocalStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
871
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LocalStorageService, providedIn: 'root' });
|
|
872
|
-
}
|
|
873
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: LocalStorageService, decorators: [{
|
|
874
|
-
type: Injectable,
|
|
875
|
-
args: [{
|
|
876
|
-
providedIn: 'root'
|
|
877
|
-
}]
|
|
878
|
-
}], ctorParameters: () => [] });
|
|
879
|
-
|
|
880
|
-
class ExportService {
|
|
881
|
-
// Экспорт в CSV
|
|
882
|
-
exportCSV(data, filename = 'data', arrHeader, newHeaders) {
|
|
883
|
-
const csvData = this.convertToCSV(data, arrHeader, newHeaders);
|
|
884
|
-
console.log(csvData);
|
|
885
|
-
const blob = new Blob(['\ufeff' + csvData], { type: 'text/csv;charset=utf-8;' });
|
|
886
|
-
const dwldLink = document.createElement('a');
|
|
887
|
-
const url = URL.createObjectURL(blob);
|
|
888
|
-
const isSafariBrowser = navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Chrome') === -1;
|
|
889
|
-
if (isSafariBrowser) { //if Safari open in new window to save file with random filename.
|
|
890
|
-
dwldLink.setAttribute('target', '_blank');
|
|
891
|
-
}
|
|
892
|
-
dwldLink.setAttribute('href', url);
|
|
893
|
-
dwldLink.setAttribute('download', filename + '.csv');
|
|
894
|
-
dwldLink.style.visibility = 'hidden';
|
|
895
|
-
document.body.appendChild(dwldLink);
|
|
896
|
-
dwldLink.click();
|
|
897
|
-
document.body.removeChild(dwldLink);
|
|
898
|
-
}
|
|
899
|
-
convertToCSV(objArray, headerList, newHeaders) {
|
|
900
|
-
const array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
|
|
901
|
-
let str = '';
|
|
902
|
-
let row = 'S.No,';
|
|
903
|
-
for (const index in newHeaders) {
|
|
904
|
-
if (Object.prototype.hasOwnProperty.call(newHeaders, index)) {
|
|
905
|
-
row += newHeaders[index] + ',';
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
row = row.slice(0, -1);
|
|
909
|
-
str += row + '\r\n';
|
|
910
|
-
for (let i = 0; i < array.length; i++) {
|
|
911
|
-
let line = (i + 1) + '';
|
|
912
|
-
for (const index in headerList) {
|
|
913
|
-
if (Object.prototype.hasOwnProperty.call(newHeaders, index)) {
|
|
914
|
-
const head = headerList[index];
|
|
915
|
-
line += ',' + array[i][head];
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
str += line + '\r\n';
|
|
919
|
-
}
|
|
920
|
-
return str;
|
|
921
|
-
}
|
|
922
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ExportService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
923
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ExportService, providedIn: 'root' });
|
|
924
|
-
}
|
|
925
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ExportService, decorators: [{
|
|
926
|
-
type: Injectable,
|
|
927
|
-
args: [{
|
|
928
|
-
providedIn: 'root'
|
|
929
|
-
}]
|
|
930
|
-
}] });
|
|
931
|
-
|
|
932
|
-
class SseService {
|
|
933
|
-
zone = inject(NgZone);
|
|
934
|
-
eventSource = null;
|
|
935
|
-
isConnected = false;
|
|
936
|
-
constructor() { }
|
|
937
|
-
createSseEventSource(baseUrl, user, topic) {
|
|
938
|
-
const subject = new ReplaySubject(1);
|
|
939
|
-
// Close any existing connection
|
|
940
|
-
this.closeSseEventSource();
|
|
941
|
-
const topicUri = topic.getTopic(baseUrl, user);
|
|
942
|
-
// environment.sse_url
|
|
943
|
-
this.eventSource = new EventSource(topicUri
|
|
944
|
-
//, {withCredentials: true}
|
|
945
|
-
);
|
|
946
|
-
if (this.eventSource) {
|
|
947
|
-
this.isConnected = true;
|
|
948
|
-
// Listen for messages
|
|
949
|
-
this.eventSource.onmessage = (event) => {
|
|
950
|
-
console.log(event);
|
|
951
|
-
const messageData = JSON.parse(event.data);
|
|
952
|
-
this.zone.run(() => {
|
|
953
|
-
subject.next(messageData);
|
|
954
|
-
});
|
|
955
|
-
};
|
|
956
|
-
this.eventSource.onopen = () => {
|
|
957
|
-
console.log('SSE connection opened.');
|
|
958
|
-
};
|
|
959
|
-
// Process error
|
|
960
|
-
this.eventSource.onerror = (error) => {
|
|
961
|
-
console.error('SSE error:', error);
|
|
962
|
-
this.reconnectOnError(baseUrl, user, topic, subject);
|
|
963
|
-
};
|
|
964
|
-
}
|
|
965
|
-
return subject.asObservable();
|
|
966
|
-
}
|
|
967
|
-
reconnectOnError(baseUrl, user, topic, subject) {
|
|
968
|
-
this.closeSseEventSource();
|
|
969
|
-
if (this.isConnected)
|
|
970
|
-
return; // Prevent duplicate connections
|
|
971
|
-
console.log('Reconnecting to SSE in 1 second...');
|
|
972
|
-
setTimeout(() => {
|
|
973
|
-
this.zone.run(() => {
|
|
974
|
-
this.createSseEventSource(baseUrl, user, topic).subscribe(subject);
|
|
975
|
-
});
|
|
976
|
-
}, 1000);
|
|
977
|
-
}
|
|
978
|
-
closeSseEventSource() {
|
|
979
|
-
if (this.eventSource) {
|
|
980
|
-
this.eventSource.close();
|
|
981
|
-
this.eventSource = null;
|
|
982
|
-
this.isConnected = false;
|
|
983
|
-
console.log('SSE Connection closed');
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SseService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
987
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SseService, providedIn: 'root' });
|
|
988
|
-
}
|
|
989
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SseService, decorators: [{
|
|
990
|
-
type: Injectable,
|
|
991
|
-
args: [{
|
|
992
|
-
providedIn: 'root'
|
|
993
|
-
}]
|
|
994
|
-
}], ctorParameters: () => [] });
|
|
995
|
-
|
|
996
|
-
class BaseEditClass {
|
|
997
|
-
/** Сервис индикатор загрузки. */
|
|
998
|
-
loaderService = inject(LoaderService);
|
|
999
|
-
/** Сервис уведомлений. */
|
|
1000
|
-
alertService = inject(AlertService);
|
|
1001
|
-
/** Объект для отписки (вызывается метод unsubscribe при уничтожении компонента). */
|
|
1002
|
-
subscription = new Subscription();
|
|
1003
|
-
ngOnDestroy() {
|
|
1004
|
-
this.subscription.unsubscribe();
|
|
1005
|
-
}
|
|
1006
|
-
onNoClick(event) {
|
|
1007
|
-
this.dialogRef?.close(null);
|
|
1008
|
-
event.preventDefault(); // иначе сработает onSubmit
|
|
1009
|
-
}
|
|
1010
|
-
onSubmit() {
|
|
1011
|
-
if (this.form) {
|
|
1012
|
-
if (this.form.valid) {
|
|
1013
|
-
if (this.dialogData)
|
|
1014
|
-
Object.keys(this.form.controls).forEach(controlName => this.dialogData.entity[controlName] = this.form?.controls[controlName].value);
|
|
1015
|
-
this.dialogRef?.close(this.dialogData);
|
|
1016
|
-
}
|
|
1017
|
-
else {
|
|
1018
|
-
Object.keys(this.form.controls).forEach(controlName => this.form?.controls[controlName].markAsTouched());
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
formActionIsAdd() {
|
|
1023
|
-
return this.dialogData?.action === Action.Add;
|
|
1024
|
-
}
|
|
1025
|
-
formActionIsEdit() {
|
|
1026
|
-
return this.dialogData?.action === Action.Edit;
|
|
1027
|
-
}
|
|
1028
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseEditClass, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1029
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: BaseEditClass, isStandalone: true, ngImport: i0 });
|
|
1030
|
-
}
|
|
1031
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseEditClass, decorators: [{
|
|
1032
|
-
type: Directive
|
|
1033
|
-
}] });
|
|
1034
|
-
|
|
1035
|
-
var EntityAction;
|
|
1036
|
-
(function (EntityAction) {
|
|
1037
|
-
EntityAction["Init"] = "\u0418\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F";
|
|
1038
|
-
EntityAction["Add"] = "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0435";
|
|
1039
|
-
EntityAction["Edit"] = "\u0418\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435";
|
|
1040
|
-
EntityAction["Delete"] = "\u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435";
|
|
1041
|
-
})(EntityAction || (EntityAction = {}));
|
|
1042
|
-
|
|
1043
|
-
class BaseFilterClass {
|
|
1044
|
-
/** Сервис для работы с LocalStorage. */
|
|
1045
|
-
localStorageService = inject(LocalStorageService);
|
|
1046
|
-
/** Сервис индикатор загрузки. */
|
|
1047
|
-
loaderService = inject(LoaderService);
|
|
1048
|
-
/** Сервис уведомлений. */
|
|
1049
|
-
alertService = inject(AlertService);
|
|
1050
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1051
|
-
defaultDebounceTime = 500;
|
|
1052
|
-
/** Объект для отписки (вызывается метод unsubscribe при уничтожении компонента). */
|
|
1053
|
-
subscription = new Subscription();
|
|
1054
|
-
constructor() {
|
|
1055
|
-
}
|
|
1056
|
-
ngOnDestroy() {
|
|
1057
|
-
this.subscription.unsubscribe();
|
|
1058
|
-
}
|
|
1059
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseFilterClass, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1060
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: BaseFilterClass, isStandalone: true, ngImport: i0 });
|
|
1061
|
-
}
|
|
1062
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseFilterClass, decorators: [{
|
|
1063
|
-
type: Directive
|
|
1064
|
-
}], ctorParameters: () => [] });
|
|
1065
|
-
|
|
1066
|
-
class BaseNavBarMenuClass {
|
|
1067
|
-
subscription = new Subscription();
|
|
1068
|
-
router = inject(Router);
|
|
1069
|
-
ngOnDestroy() {
|
|
1070
|
-
if (this.subscription)
|
|
1071
|
-
this.subscription.unsubscribe();
|
|
1072
|
-
}
|
|
1073
|
-
/** Нажата средняя кнопка (открыть ссылку в новой вкладке). */
|
|
1074
|
-
onMiddleClick(event, baseUrl, menu) {
|
|
1075
|
-
// 1 - Auxiliary button pressed (usually the middle button)
|
|
1076
|
-
if (event.button === 1) {
|
|
1077
|
-
// event.preventDefault();
|
|
1078
|
-
menu.closeMenu();
|
|
1079
|
-
const urlTree = this.router.serializeUrl(this.router.createUrlTree([baseUrl]));
|
|
1080
|
-
window.open(urlTree, '_blank');
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseNavBarMenuClass, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1084
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: BaseNavBarMenuClass, isStandalone: true, ngImport: i0 });
|
|
1085
|
-
}
|
|
1086
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseNavBarMenuClass, decorators: [{
|
|
1087
|
-
type: Directive
|
|
1088
|
-
}] });
|
|
1089
|
-
|
|
1090
|
-
class DialogComponent {
|
|
1091
|
-
data = inject(MAT_DIALOG_DATA);
|
|
1092
|
-
dialogRef = inject((MatDialogRef));
|
|
1093
|
-
constructor() {
|
|
1094
|
-
if (!this.data.title) {
|
|
1095
|
-
this.data.title = 'Подтверждение';
|
|
1096
|
-
}
|
|
1097
|
-
if (!this.data.btnNoTitle) {
|
|
1098
|
-
this.data.btnNoTitle = 'Нет';
|
|
1099
|
-
}
|
|
1100
|
-
if (!this.data.btnYesTitle) {
|
|
1101
|
-
this.data.btnYesTitle = 'Да';
|
|
1102
|
-
}
|
|
1103
|
-
}
|
|
1104
|
-
onNoClick() {
|
|
1105
|
-
this.dialogRef.close();
|
|
1106
|
-
}
|
|
1107
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1108
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: DialogComponent, isStandalone: true, selector: "ngx-uik-dialog", ngImport: i0, template: "<h1 mat-dialog-title>{{ data.title }}</h1>\r\n<div mat-dialog-content>\r\n <div style=\"white-space: pre-line\">{{ data.message }}</div>\r\n</div>\r\n<div mat-dialog-actions align=\"end\">\r\n <button mat-raised-button (click)=\"onNoClick()\" cdkFocusInitial>{{ data.btnNoTitle }}</button>\r\n <button mat-raised-button color=\"warn\" [mat-dialog-close]=\"data.id\">{{ data.btnYesTitle }}</button>\r\n</div>\r\n\r\n", styles: [""], dependencies: [{ kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }] });
|
|
1109
|
-
}
|
|
1110
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DialogComponent, decorators: [{
|
|
1111
|
-
type: Component,
|
|
1112
|
-
args: [{ selector: 'ngx-uik-dialog', imports: [MatDialogTitle, MatDialogContent, MatDialogActions, MatButton, MatDialogClose], template: "<h1 mat-dialog-title>{{ data.title }}</h1>\r\n<div mat-dialog-content>\r\n <div style=\"white-space: pre-line\">{{ data.message }}</div>\r\n</div>\r\n<div mat-dialog-actions align=\"end\">\r\n <button mat-raised-button (click)=\"onNoClick()\" cdkFocusInitial>{{ data.btnNoTitle }}</button>\r\n <button mat-raised-button color=\"warn\" [mat-dialog-close]=\"data.id\">{{ data.btnYesTitle }}</button>\r\n</div>\r\n\r\n" }]
|
|
1113
|
-
}], ctorParameters: () => [] });
|
|
1114
|
-
|
|
1115
|
-
class BasePageClass {
|
|
1116
|
-
dialog = inject(MatDialog);
|
|
1117
|
-
/** Данные для табличного компонента. */
|
|
1118
|
-
data = signal([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
1119
|
-
/** Количество записей по фильтру. */
|
|
1120
|
-
length = signal(0, ...(ngDevMode ? [{ debugName: "length" }] : []));
|
|
1121
|
-
entityService;
|
|
1122
|
-
entityType;
|
|
1123
|
-
entityEditComponent;
|
|
1124
|
-
extraData;
|
|
1125
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1126
|
-
defaultPageIndex = 0;
|
|
1127
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1128
|
-
defaultPageSize = 10;
|
|
1129
|
-
dialogEditWidth = 'auto';
|
|
1130
|
-
dialogRemoveWidth = '400px';
|
|
1131
|
-
routeAddress = '';
|
|
1132
|
-
/** Сообщение при удалении записи(й). */
|
|
1133
|
-
removalMessage = '';
|
|
1134
|
-
/** Заголовок страницы. */
|
|
1135
|
-
pageTitle = '';
|
|
1136
|
-
/**
|
|
1137
|
-
* Создание записи: вызывается перед открытием диалога.
|
|
1138
|
-
*/
|
|
1139
|
-
beforeOpenDialogOnNewEvent;
|
|
1140
|
-
/**
|
|
1141
|
-
* Редактирование записи: вызывается перед открытием диалога.
|
|
1142
|
-
*/
|
|
1143
|
-
beforeOpenDialogOnEditEvent;
|
|
1144
|
-
/**
|
|
1145
|
-
* Создание записи: вызывается перед сохранением объекта.
|
|
1146
|
-
*/
|
|
1147
|
-
beforeSaveOnNewEvent;
|
|
1148
|
-
/**
|
|
1149
|
-
* Редактирование записи: вызывается перед сохранением объекта.
|
|
1150
|
-
*/
|
|
1151
|
-
beforeSaveOnEditEvent;
|
|
1152
|
-
/**
|
|
1153
|
-
* Создание записи: вызывается после сохранения объекта.
|
|
1154
|
-
*/
|
|
1155
|
-
afterSaveOnNewEvent;
|
|
1156
|
-
/**
|
|
1157
|
-
* Редактирование записи: вызывается после сохранения объекта.
|
|
1158
|
-
*/
|
|
1159
|
-
afterSaveOnEditEvent;
|
|
1160
|
-
editorRoles = [];
|
|
1161
|
-
executeRoles = [];
|
|
1162
|
-
/** Список ролей, для которых скрыть элемент. */
|
|
1163
|
-
hideRoles = ['HIDE'];
|
|
1164
|
-
/** Загрузка данных. */
|
|
1165
|
-
loadData$ = new Subject();
|
|
1166
|
-
/** Загрузка количества записей. */
|
|
1167
|
-
loadLength$ = new Subject();
|
|
1168
|
-
/** Очистка фильтра. */
|
|
1169
|
-
clearFilter$ = new Subject();
|
|
1170
|
-
/** Очистка фильтра (для очистки присвоить пустой объект '{}'). */
|
|
1171
|
-
clearFilter = null;
|
|
1172
|
-
/** Разрешен выбор нескольких строк. */
|
|
1173
|
-
allowMultiSelect = false;
|
|
1174
|
-
/** Выбранные строки в таблице. */
|
|
1175
|
-
selected = [];
|
|
1176
|
-
/** Состояние сортировки, пагинации. */
|
|
1177
|
-
tableState;
|
|
1178
|
-
/** Доступность кнопки "Изменить". */
|
|
1179
|
-
editBtnDisabled = true;
|
|
1180
|
-
/** Доступность кнопки "Удалить". */
|
|
1181
|
-
removeBtnDisabled = true;
|
|
1182
|
-
/** Разрешено ли отправлять событие rowDoubleClicked при двойном щелчке мышью. */
|
|
1183
|
-
dblClickedEventEnable = true;
|
|
1184
|
-
// Список элементов контекстного меню.
|
|
1185
|
-
opt = [];
|
|
1186
|
-
// DI
|
|
1187
|
-
router = inject(Router);
|
|
1188
|
-
/** Сервис для работы с LocalStorage. */
|
|
1189
|
-
localStorageService = inject(LocalStorageService);
|
|
1190
|
-
/** Сервис индикатор загрузки. */
|
|
1191
|
-
loaderService = inject(LoaderService);
|
|
1192
|
-
/** Сервис уведомлений. */
|
|
1193
|
-
alertService = inject(AlertService);
|
|
1194
|
-
/** Объект для отписки (вызывается метод unsubscribe при уничтожении компонента). */
|
|
1195
|
-
subscription = new Subscription();
|
|
1196
|
-
constructor() {
|
|
1197
|
-
this.tableState = {
|
|
1198
|
-
sortActive: this.localStorageService.getData(this.constructor.name + 'SortActive') || '',
|
|
1199
|
-
sortDirection: (this.localStorageService.getData(this.constructor.name + 'SortDirection') || ''),
|
|
1200
|
-
pageIndex: Number(this.localStorageService.getData(this.constructor.name + 'PageIndex')) || this.defaultPageIndex,
|
|
1201
|
-
pageSize: Number(this.localStorageService.getData(this.constructor.name + 'PageSize')) || this.defaultPageSize
|
|
1202
|
-
};
|
|
1203
|
-
}
|
|
1204
|
-
ngOnDestroy() {
|
|
1205
|
-
this.subscription.unsubscribe();
|
|
1206
|
-
}
|
|
1207
|
-
subscribeToLoadData(fnGetData, fnGetCount, fnMapEntity) {
|
|
1208
|
-
// отменять стримы, созданные ранее
|
|
1209
|
-
const subs = this.loadData$
|
|
1210
|
-
.pipe(tap(() => this.loaderService.show()), switchMap(() => fnGetData()), map$1(v => fnMapEntity ? v.map(fnMapEntity()) : v))
|
|
1211
|
-
.subscribe({
|
|
1212
|
-
next: (response) => {
|
|
1213
|
-
this.data.set(response);
|
|
1214
|
-
this.loaderService.hide();
|
|
1215
|
-
},
|
|
1216
|
-
error: (error) => {
|
|
1217
|
-
this.loaderService.hide();
|
|
1218
|
-
console.log(error);
|
|
1219
|
-
this.alertService.error('Произошла ошибка: ' + error, 0);
|
|
1220
|
-
}
|
|
1221
|
-
});
|
|
1222
|
-
this.subscription?.add(subs);
|
|
1223
|
-
const subs2 = this.loadLength$
|
|
1224
|
-
.pipe(switchMap(() => fnGetCount()))
|
|
1225
|
-
.subscribe({
|
|
1226
|
-
next: (response) => {
|
|
1227
|
-
this.length.set(response);
|
|
1228
|
-
},
|
|
1229
|
-
error: (error) => {
|
|
1230
|
-
console.log(error);
|
|
1231
|
-
this.alertService.error('Произошла ошибка: ' + error, 0);
|
|
1232
|
-
}
|
|
1233
|
-
});
|
|
1234
|
-
this.subscription?.add(subs2);
|
|
1235
|
-
// загрузить данные и количество записей
|
|
1236
|
-
this.loadData$.next(null);
|
|
1237
|
-
this.loadLength$.next(null);
|
|
1238
|
-
}
|
|
1239
|
-
onPageChange(pageState) {
|
|
1240
|
-
this.tableState.pageIndex = pageState.pageIndex;
|
|
1241
|
-
this.tableState.pageSize = pageState.pageSize;
|
|
1242
|
-
this.localStorageService.saveData(this.constructor.name + 'PageIndex', pageState.pageIndex.toString());
|
|
1243
|
-
this.localStorageService.saveData(this.constructor.name + 'PageSize', pageState.pageSize.toString());
|
|
1244
|
-
this.loadData$.next(null);
|
|
1245
|
-
this.loadLength$.next(null);
|
|
1246
|
-
}
|
|
1247
|
-
onSortChange(sortState) {
|
|
1248
|
-
this.tableState.sortActive = sortState.sortActive;
|
|
1249
|
-
this.tableState.sortDirection = sortState.sortDirection;
|
|
1250
|
-
this.localStorageService.saveData(this.constructor.name + 'SortActive', sortState.sortActive);
|
|
1251
|
-
this.localStorageService.saveData(this.constructor.name + 'SortDirection', sortState.sortDirection);
|
|
1252
|
-
this.loadData$.next(null);
|
|
1253
|
-
this.loadLength$.next(null);
|
|
1254
|
-
}
|
|
1255
|
-
entityFactory(type) {
|
|
1256
|
-
return new type();
|
|
1257
|
-
}
|
|
1258
|
-
/** Событие изменение выбранных записей. */
|
|
1259
|
-
onSelectionChange(selected) {
|
|
1260
|
-
this.selected = selected;
|
|
1261
|
-
this.editBtnDisabledUpdate(this.selected);
|
|
1262
|
-
this.removeBtnDisabledUpdate(this.selected);
|
|
1263
|
-
}
|
|
1264
|
-
/** Обновление доступности кнопки "Изменить" - вызывается при изменении выбранных записей. */
|
|
1265
|
-
editBtnDisabledUpdate(selected) {
|
|
1266
|
-
this.editBtnDisabled = !(selected && selected.length === 1);
|
|
1267
|
-
}
|
|
1268
|
-
/** Обновление доступности кнопки "Удалить" - вызывается при изменении выбранных записей. */
|
|
1269
|
-
removeBtnDisabledUpdate(selected) {
|
|
1270
|
-
this.removeBtnDisabled = !(selected && selected.length > 0);
|
|
1271
|
-
}
|
|
1272
|
-
/** Событие двойной клик. */
|
|
1273
|
-
onRowDoubleClicked() {
|
|
1274
|
-
this.editEvent();
|
|
1275
|
-
}
|
|
1276
|
-
/** Событие создание. */
|
|
1277
|
-
newEvent() {
|
|
1278
|
-
if (this.entityEditComponent) {
|
|
1279
|
-
const data = { action: Action.Add, entity: new this.entityType(null) };
|
|
1280
|
-
// Назначить значения полей объекта перед открытием диалога.
|
|
1281
|
-
if (this.beforeOpenDialogOnNewEvent) {
|
|
1282
|
-
this.beforeOpenDialogOnNewEvent(data.entity, data.extraData);
|
|
1283
|
-
}
|
|
1284
|
-
// Открытие окна
|
|
1285
|
-
const dialogRef = this.openDialog(this.entityEditComponent, data, this.dialog);
|
|
1286
|
-
// Обработка закрытия окна
|
|
1287
|
-
const subs = dialogRef.afterClosed().subscribe((result) => {
|
|
1288
|
-
// Проверка результата
|
|
1289
|
-
if (result && result.entity && (Object.keys(result.entity).length !== 0)) {
|
|
1290
|
-
// Дополнительные действия перед сохранением объекта.
|
|
1291
|
-
if (this.beforeSaveOnNewEvent)
|
|
1292
|
-
this.beforeSaveOnNewEvent(result.entity, result.extraData);
|
|
1293
|
-
const subs = this.entityService.newObject(result.entity)
|
|
1294
|
-
.subscribe({
|
|
1295
|
-
next: (obj) => {
|
|
1296
|
-
// Дополнительные действия после сохранения объекта.
|
|
1297
|
-
if (this.afterSaveOnNewEvent) {
|
|
1298
|
-
const callback = () => {
|
|
1299
|
-
this.refreshEvent();
|
|
1300
|
-
this.alertService.success('Запись добавлена.');
|
|
1301
|
-
};
|
|
1302
|
-
this.afterSaveOnNewEvent(callback.bind(this), obj, result.extraData);
|
|
1303
|
-
}
|
|
1304
|
-
else {
|
|
1305
|
-
this.refreshEvent();
|
|
1306
|
-
this.alertService.success('Запись добавлена.');
|
|
1307
|
-
}
|
|
1308
|
-
},
|
|
1309
|
-
error: (error) => {
|
|
1310
|
-
console.log('error', error);
|
|
1311
|
-
this.alertService.error('Произошла ошибка при добавлении записи: ' + error, 0);
|
|
1312
|
-
}
|
|
1313
|
-
});
|
|
1314
|
-
this.subscription.add(subs);
|
|
1315
|
-
}
|
|
1316
|
-
});
|
|
1317
|
-
this.subscription.add(subs);
|
|
1318
|
-
// Закрытие окна по нажатию Escape
|
|
1319
|
-
const subs2 = dialogRef.keydownEvents().subscribe((event) => {
|
|
1320
|
-
if (event.key === 'Escape') {
|
|
1321
|
-
dialogRef.close(null);
|
|
1322
|
-
}
|
|
1323
|
-
});
|
|
1324
|
-
this.subscription.add(subs2);
|
|
1325
|
-
}
|
|
1326
|
-
else {
|
|
1327
|
-
this.alertService.warning('Действие не доступно.');
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
/** Событие редактирование. */
|
|
1331
|
-
editEvent() {
|
|
1332
|
-
if (this.selected && this.selected.length === 1) {
|
|
1333
|
-
if (this.entityEditComponent) {
|
|
1334
|
-
const data = { action: Action.Edit, entity: this.selected[0] };
|
|
1335
|
-
// Назначить значения полей объекта перед открытием диалога.
|
|
1336
|
-
if (this.beforeOpenDialogOnEditEvent) {
|
|
1337
|
-
this.beforeOpenDialogOnEditEvent(data.entity, data.extraData);
|
|
1338
|
-
}
|
|
1339
|
-
// Открытие окна
|
|
1340
|
-
const dialogRef = this.openDialog(this.entityEditComponent, data, this.dialog);
|
|
1341
|
-
// Обработка закрытия окна
|
|
1342
|
-
const subs = dialogRef.afterClosed().subscribe((result) => {
|
|
1343
|
-
// Проверка результата
|
|
1344
|
-
if (result && result.entity && (Object.keys(result.entity).length !== 0)) {
|
|
1345
|
-
// Дополнительные действия перед сохранением объекта.
|
|
1346
|
-
if (this.beforeSaveOnEditEvent)
|
|
1347
|
-
this.beforeSaveOnEditEvent(result.entity, result.extraData);
|
|
1348
|
-
const subs = this.entityService.editObject(result.entity)
|
|
1349
|
-
.subscribe({
|
|
1350
|
-
next: () => {
|
|
1351
|
-
// Дополнительные действия после сохранения объекта.
|
|
1352
|
-
if (this.afterSaveOnEditEvent) {
|
|
1353
|
-
const callback = () => {
|
|
1354
|
-
this.refreshEvent();
|
|
1355
|
-
this.alertService.success('Запись изменена.');
|
|
1356
|
-
};
|
|
1357
|
-
this.afterSaveOnEditEvent(callback.bind(this), result.entity, result.extraData);
|
|
1358
|
-
}
|
|
1359
|
-
else {
|
|
1360
|
-
this.refreshEvent();
|
|
1361
|
-
this.alertService.success('Запись изменена.');
|
|
1362
|
-
}
|
|
1363
|
-
},
|
|
1364
|
-
error: (error) => {
|
|
1365
|
-
console.log('error', error);
|
|
1366
|
-
this.alertService.error('Произошла ошибка при изменении записи: ' + error, 0);
|
|
1367
|
-
}
|
|
1368
|
-
});
|
|
1369
|
-
this.subscription.add(subs);
|
|
1370
|
-
}
|
|
1371
|
-
});
|
|
1372
|
-
this.subscription.add(subs);
|
|
1373
|
-
// Закрытие окна по нажатию Escape
|
|
1374
|
-
const subs2 = dialogRef.keydownEvents().subscribe((event) => {
|
|
1375
|
-
if (event.key === 'Escape') {
|
|
1376
|
-
dialogRef.close(null);
|
|
1377
|
-
}
|
|
1378
|
-
});
|
|
1379
|
-
this.subscription.add(subs2);
|
|
1380
|
-
}
|
|
1381
|
-
else {
|
|
1382
|
-
this.alertService.warning('Действие не доступно.');
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
/** Событие удаление. */
|
|
1387
|
-
removeEvent() {
|
|
1388
|
-
// если выбрана запись(и)
|
|
1389
|
-
if (this.selected && this.selected.length > 0) {
|
|
1390
|
-
const dialogRef = this.openDialogRemoveConfirm(this.removalMessage);
|
|
1391
|
-
if (dialogRef) {
|
|
1392
|
-
const subs = dialogRef.afterClosed().subscribe((result) => {
|
|
1393
|
-
// при подтверждении возвращается 'delete'
|
|
1394
|
-
if (result === 'delete') {
|
|
1395
|
-
// готовим объект с запросами на удаление
|
|
1396
|
-
const sourcesObject = {};
|
|
1397
|
-
this.selected.forEach((item, index) => sourcesObject['obj' + index] = this.entityService.deleteObject(item));
|
|
1398
|
-
// ждем, когда выполнятся все запросы
|
|
1399
|
-
const subs = forkJoin(sourcesObject)
|
|
1400
|
-
.subscribe({
|
|
1401
|
-
next: () => {
|
|
1402
|
-
this.refreshEvent();
|
|
1403
|
-
this.alertService.success('Выбранные записи удалены.');
|
|
1404
|
-
},
|
|
1405
|
-
error: (error) => {
|
|
1406
|
-
console.log('error', error);
|
|
1407
|
-
this.alertService.error('Произошла ошибка при удалении записи: ' + error, 0);
|
|
1408
|
-
}
|
|
1409
|
-
});
|
|
1410
|
-
this.subscription.add(subs);
|
|
1411
|
-
}
|
|
1412
|
-
});
|
|
1413
|
-
this.subscription.add(subs);
|
|
1414
|
-
// Закрытие окна по нажатию Escape
|
|
1415
|
-
const subs2 = dialogRef.keydownEvents().subscribe((event) => {
|
|
1416
|
-
if (event.key === 'Escape') {
|
|
1417
|
-
dialogRef.close(null);
|
|
1418
|
-
}
|
|
1419
|
-
});
|
|
1420
|
-
this.subscription.add(subs2);
|
|
1421
|
-
}
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
/** Событие обновления данных. */
|
|
1425
|
-
refreshEvent() {
|
|
1426
|
-
this.loadData$.next(null);
|
|
1427
|
-
this.loadLength$.next(null);
|
|
1428
|
-
}
|
|
1429
|
-
/** Событие очистки фильтра. */
|
|
1430
|
-
clearEvent() {
|
|
1431
|
-
this.clearFilter$.next(null);
|
|
1432
|
-
this.clearFilter = {};
|
|
1433
|
-
}
|
|
1434
|
-
/** Изменение сообщения об удалении. */
|
|
1435
|
-
onRemovalMessageChange(message) {
|
|
1436
|
-
this.removalMessage = message;
|
|
1437
|
-
}
|
|
1438
|
-
/** Изменение заголовка страницы. */
|
|
1439
|
-
onPageTitleChange(title) {
|
|
1440
|
-
this.pageTitle = title;
|
|
1441
|
-
}
|
|
1442
|
-
openDialog(entityComponent, data, dialog) {
|
|
1443
|
-
// create dialog config
|
|
1444
|
-
const dialogConfig = new MatDialogConfig();
|
|
1445
|
-
dialogConfig.disableClose = true;
|
|
1446
|
-
dialogConfig.autoFocus = true;
|
|
1447
|
-
dialogConfig.width = this.dialogEditWidth;
|
|
1448
|
-
dialogConfig.data = data;
|
|
1449
|
-
dialogConfig.panelClass = this.entityType.name + '-edit-dialog';
|
|
1450
|
-
// return dialog
|
|
1451
|
-
return dialog.open(entityComponent, dialogConfig);
|
|
1452
|
-
}
|
|
1453
|
-
openDialogRemoveConfirm(removalMessage) {
|
|
1454
|
-
let message = 'Вы хотите удалить ';
|
|
1455
|
-
message += removalMessage ?
|
|
1456
|
-
removalMessage :
|
|
1457
|
-
this.allowMultiSelect ? `выбранные записи (${this.selected.length})?` : 'выбранную запись?';
|
|
1458
|
-
return this.dialog.open(DialogComponent, {
|
|
1459
|
-
width: this.dialogRemoveWidth,
|
|
1460
|
-
data: {
|
|
1461
|
-
id: 'delete',
|
|
1462
|
-
title: 'Подтверждение',
|
|
1463
|
-
message: message,
|
|
1464
|
-
btnNoTitle: 'Отмена',
|
|
1465
|
-
btnYesTitle: 'Удалить'
|
|
1466
|
-
}
|
|
1467
|
-
});
|
|
1468
|
-
}
|
|
1469
|
-
// contextMenu: При щелчке ПКМ открыть в новой вкладке.
|
|
1470
|
-
onMiddleButton(baseUrl, queryParamName, queryParamValue) {
|
|
1471
|
-
return ($event, item, contextMenu) => {
|
|
1472
|
-
// Нажата средняя кнопка (в новой вкладке).
|
|
1473
|
-
// 1 - Auxiliary button pressed (usually the middle button)
|
|
1474
|
-
if ($event.button === 1) {
|
|
1475
|
-
//$event.preventDefault();
|
|
1476
|
-
contextMenu.closeMenu();
|
|
1477
|
-
// Converts the route into a string that can be used
|
|
1478
|
-
// with the window.open() function
|
|
1479
|
-
const url = this.router.serializeUrl(queryParamName && queryParamValue ?
|
|
1480
|
-
this.router.createUrlTree([baseUrl], { queryParams: { [queryParamName]: item[queryParamValue] } })
|
|
1481
|
-
: this.router.createUrlTree([baseUrl]));
|
|
1482
|
-
window.open(url, '_blank');
|
|
1483
|
-
}
|
|
1484
|
-
};
|
|
1485
|
-
}
|
|
1486
|
-
// Action в таблице: При щелчке ПКМ открыть в новой вкладке.
|
|
1487
|
-
onActionMiddleButton(baseUrl, queryParamName, queryParamValue) {
|
|
1488
|
-
return ($event, item) => {
|
|
1489
|
-
// Нажата средняя кнопка (в новой вкладке).
|
|
1490
|
-
// 1 - Auxiliary button pressed (usually the middle button)
|
|
1491
|
-
if ($event.button === 1) {
|
|
1492
|
-
//$event.preventDefault();
|
|
1493
|
-
// Converts the route into a string that can be used
|
|
1494
|
-
// with the window.open() function
|
|
1495
|
-
const url = this.router.serializeUrl(queryParamName && queryParamValue ?
|
|
1496
|
-
this.router.createUrlTree([baseUrl], { queryParams: { [queryParamName]: item[queryParamValue] } })
|
|
1497
|
-
: this.router.createUrlTree([baseUrl]));
|
|
1498
|
-
window.open(url, '_blank');
|
|
1499
|
-
}
|
|
1500
|
-
};
|
|
1501
|
-
}
|
|
1502
|
-
dateToString(date) {
|
|
1503
|
-
return date ? (new Date(date)).toLocaleString('ru-RU', { timeZone: 'Europe/Samara' }) : null; // MSK+01
|
|
1504
|
-
}
|
|
1505
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BasePageClass, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1506
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: BasePageClass, isStandalone: true, ngImport: i0 });
|
|
1507
|
-
}
|
|
1508
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BasePageClass, decorators: [{
|
|
1509
|
-
type: Directive
|
|
1510
|
-
}], ctorParameters: () => [] });
|
|
1511
|
-
|
|
1512
|
-
class BaseServiceClass {
|
|
1513
|
-
countRoute = 'count';
|
|
1514
|
-
pageIndexParam = 'page';
|
|
1515
|
-
pageSizeParam = 'limit';
|
|
1516
|
-
sortColumnParam = 'column';
|
|
1517
|
-
directionParam = 'direction';
|
|
1518
|
-
http = inject(HttpClient);
|
|
1519
|
-
getObjects() {
|
|
1520
|
-
return this.http.get(this.baseRoute)
|
|
1521
|
-
.pipe(map(data => data.map(item => new this.entityType(item).deserialize(item))));
|
|
1522
|
-
}
|
|
1523
|
-
getObject(id) {
|
|
1524
|
-
return this.http.get(this.baseRoute + id)
|
|
1525
|
-
.pipe(map(data => new this.entityType(data).deserialize(data)));
|
|
1526
|
-
}
|
|
1527
|
-
getCount() {
|
|
1528
|
-
return this.http.get(this.baseRoute + this.countRoute);
|
|
1529
|
-
}
|
|
1530
|
-
getObjectsByPaging(pageIndex, pageSize, sortColumn, direction) {
|
|
1531
|
-
const params = this.getParams(pageIndex, pageSize, sortColumn, direction);
|
|
1532
|
-
return this.http.get(this.baseRoute, { params })
|
|
1533
|
-
.pipe(map(data => data.map(item => new this.entityType(item).deserialize(item))));
|
|
1534
|
-
}
|
|
1535
|
-
newObject(entity) {
|
|
1536
|
-
return this.http.post(this.baseRoute, entity);
|
|
1537
|
-
}
|
|
1538
|
-
editObject(entity) {
|
|
1539
|
-
return this.http.put(this.baseRoute + entity.id, entity);
|
|
1540
|
-
}
|
|
1541
|
-
deleteObject(entity) {
|
|
1542
|
-
return this.http.delete(this.baseRoute + entity.id);
|
|
1543
|
-
}
|
|
1544
|
-
getParams(pageIndex, pageSize, sortColumn, direction) {
|
|
1545
|
-
let params = new HttpParams();
|
|
1546
|
-
if (pageIndex + 1)
|
|
1547
|
-
// переход от индекса к номеру страницы
|
|
1548
|
-
params = params.append(this.pageIndexParam, pageIndex + 1);
|
|
1549
|
-
if (pageSize)
|
|
1550
|
-
params = params.append(this.pageSizeParam, pageSize);
|
|
1551
|
-
if (sortColumn)
|
|
1552
|
-
params = params.append(this.sortColumnParam, sortColumn);
|
|
1553
|
-
if (direction)
|
|
1554
|
-
params = params.append(this.directionParam, direction);
|
|
1555
|
-
return params;
|
|
1556
|
-
}
|
|
1557
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseServiceClass, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1558
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseServiceClass, providedIn: 'root' });
|
|
1559
|
-
}
|
|
1560
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseServiceClass, decorators: [{
|
|
1561
|
-
type: Injectable,
|
|
1562
|
-
args: [{
|
|
1563
|
-
providedIn: 'root'
|
|
1564
|
-
}]
|
|
1565
|
-
}] });
|
|
1566
|
-
|
|
1567
|
-
class SetValueDirective {
|
|
1568
|
-
ngControl = inject(NgControl);
|
|
1569
|
-
set setValue(val) {
|
|
1570
|
-
this.ngControl.control?.setValue(val, { emitEvent: false });
|
|
1571
|
-
}
|
|
1572
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SetValueDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1573
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: SetValueDirective, isStandalone: true, selector: "[setValue]", inputs: { setValue: "setValue" }, ngImport: i0 });
|
|
1574
|
-
}
|
|
1575
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SetValueDirective, decorators: [{
|
|
1576
|
-
type: Directive,
|
|
1577
|
-
args: [{
|
|
1578
|
-
selector: "[setValue]"
|
|
1579
|
-
}]
|
|
1580
|
-
}], propDecorators: { setValue: [{
|
|
1581
|
-
type: Input
|
|
1582
|
-
}] } });
|
|
1583
|
-
|
|
1584
|
-
class RedirectGuard {
|
|
1585
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1586
|
-
canActivate(route, state) {
|
|
1587
|
-
console.log(route.data['externalUrl']);
|
|
1588
|
-
window.location.href = route.data['externalUrl'];
|
|
1589
|
-
return true;
|
|
1590
|
-
}
|
|
1591
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RedirectGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1592
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RedirectGuard, providedIn: 'root' });
|
|
1593
|
-
}
|
|
1594
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: RedirectGuard, decorators: [{
|
|
1595
|
-
type: Injectable,
|
|
1596
|
-
args: [{
|
|
1597
|
-
providedIn: 'root'
|
|
1598
|
-
}]
|
|
1599
|
-
}] });
|
|
1600
|
-
|
|
1601
|
-
class SecUser {
|
|
1602
|
-
id = 0;
|
|
1603
|
-
login = '';
|
|
1604
|
-
fio = '';
|
|
1605
|
-
dept = 0;
|
|
1606
|
-
tabnum = 0;
|
|
1607
|
-
userView;
|
|
1608
|
-
constructor(init) {
|
|
1609
|
-
if (init) {
|
|
1610
|
-
Object.assign(this, init);
|
|
1611
|
-
}
|
|
1612
|
-
else {
|
|
1613
|
-
this.id = 0;
|
|
1614
|
-
this.login = '';
|
|
1615
|
-
this.dept = 0;
|
|
1616
|
-
this.tabnum = 0;
|
|
1617
|
-
this.fio = '';
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
deserialize(input) {
|
|
1621
|
-
Object.assign(this, input);
|
|
1622
|
-
return this;
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
class SafePipe {
|
|
1627
|
-
sanitizer = inject(DomSanitizer);
|
|
1628
|
-
transform(url) {
|
|
1629
|
-
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
|
|
1630
|
-
}
|
|
1631
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SafePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1632
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: SafePipe, isStandalone: true, name: "safe" });
|
|
1633
|
-
}
|
|
1634
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: SafePipe, decorators: [{
|
|
1635
|
-
type: Pipe,
|
|
1636
|
-
args: [{
|
|
1637
|
-
name: 'safe'
|
|
1638
|
-
}]
|
|
1639
|
-
}] });
|
|
1640
|
-
|
|
1641
|
-
class TimePipe {
|
|
1642
|
-
transform(value) {
|
|
1643
|
-
// const hour = Math.abs(value) >= 60 ? Math.round(value / 60) + 'ч.' : '';
|
|
1644
|
-
// const minute = ' ' + Math.abs(value % 60) + 'м.';
|
|
1645
|
-
// return value === 0 ? '0' : hour + ' ' + minute;
|
|
1646
|
-
const hour = Math.abs(value) >= 60 ? Math.floor(Math.abs(value) / 60).toString().padStart(2, '0') : '00';
|
|
1647
|
-
const minute = Math.abs(value % 60).toString().padStart(2, '0');
|
|
1648
|
-
const time = hour + ':' + minute;
|
|
1649
|
-
return value < 0 ? '-' + time : time;
|
|
1650
|
-
}
|
|
1651
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TimePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1652
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: TimePipe, isStandalone: true, name: "time" });
|
|
1653
|
-
}
|
|
1654
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TimePipe, decorators: [{
|
|
1655
|
-
type: Pipe,
|
|
1656
|
-
args: [{
|
|
1657
|
-
name: 'time'
|
|
1658
|
-
}]
|
|
1659
|
-
}] });
|
|
1660
|
-
|
|
1661
|
-
class TruncatePipe {
|
|
1662
|
-
// Usage:
|
|
1663
|
-
// {{ str | truncate:[20] }} // or
|
|
1664
|
-
// {{ str | truncate:[20, '...'] }} // or|
|
|
1665
|
-
transform(value, args) {
|
|
1666
|
-
const limit = args.length > 0 ? parseInt(args[0], 10) : 20;
|
|
1667
|
-
const trail = args.length > 1 ? args[1] : '...';
|
|
1668
|
-
return value.length > limit ? value.substring(0, limit) + trail : value;
|
|
1669
|
-
}
|
|
1670
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TruncatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
1671
|
-
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: TruncatePipe, isStandalone: true, name: "truncate" });
|
|
1672
|
-
}
|
|
1673
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TruncatePipe, decorators: [{
|
|
1674
|
-
type: Pipe,
|
|
1675
|
-
args: [{
|
|
1676
|
-
name: 'truncate'
|
|
1677
|
-
}]
|
|
1678
|
-
}] });
|
|
1679
|
-
|
|
1680
|
-
class BaseMatChipComponent {
|
|
1681
|
-
// Все элементы
|
|
1682
|
-
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
1683
|
-
// Выбранные элементы, ключи (ChipItem.value)
|
|
1684
|
-
selectedItemsInput = input([], ...(ngDevMode ? [{ debugName: "selectedItemsInput" }] : []));
|
|
1685
|
-
// Заголовок
|
|
1686
|
-
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
1687
|
-
// Событие изменения выбранных элементов
|
|
1688
|
-
selectedItemsChange = output();
|
|
1689
|
-
input = viewChild('input', ...(ngDevMode ? [{ debugName: "input" }] : []));
|
|
1690
|
-
separatorKeysCodes = [ENTER, COMMA];
|
|
1691
|
-
inputCtrl = new FormControl();
|
|
1692
|
-
filteredItems$;
|
|
1693
|
-
selectedItems = [];
|
|
1694
|
-
constructor() {
|
|
1695
|
-
effect(() => {
|
|
1696
|
-
if (this.items().length > 0) {
|
|
1697
|
-
this.filteredItems$ = this.inputCtrl.valueChanges.pipe(startWith(null), map(item => (item ? this._filter(item) : this.items().slice())));
|
|
1698
|
-
}
|
|
1699
|
-
});
|
|
1700
|
-
effect(() => {
|
|
1701
|
-
if (this.selectedItemsInput())
|
|
1702
|
-
this.selectedItems = this.items().filter(s => this.selectedItemsInput().includes(s.value));
|
|
1703
|
-
});
|
|
1704
|
-
}
|
|
1705
|
-
remove(value) {
|
|
1706
|
-
this.selectedItems = [...this.selectedItems];
|
|
1707
|
-
const index = this.selectedItems.map(i => i.value).indexOf(value);
|
|
1708
|
-
if (index >= 0) {
|
|
1709
|
-
this.selectedItems.splice(index, 1);
|
|
1710
|
-
this.selectedItemsChange.emit(this.selectedItems.map(i => i.value));
|
|
1711
|
-
}
|
|
1712
|
-
}
|
|
1713
|
-
selected(event) {
|
|
1714
|
-
this.selectedItems = [...this.selectedItems];
|
|
1715
|
-
const item = this.items().find(s => s.value == event.option.value);
|
|
1716
|
-
if (item) {
|
|
1717
|
-
this.selectedItems.push(item);
|
|
1718
|
-
}
|
|
1719
|
-
this.selectedItemsChange.emit(this.selectedItems.map(i => i.value));
|
|
1720
|
-
const inputValue = this.input();
|
|
1721
|
-
if (inputValue)
|
|
1722
|
-
inputValue.nativeElement.value = '';
|
|
1723
|
-
this.inputCtrl.setValue(null);
|
|
1724
|
-
}
|
|
1725
|
-
_filter(value) {
|
|
1726
|
-
const filterValue = value.toLowerCase();
|
|
1727
|
-
return this.items().filter(item => item.viewValue.toLowerCase().includes(filterValue));
|
|
1728
|
-
}
|
|
1729
|
-
onCloseClick($event) {
|
|
1730
|
-
$event.stopPropagation();
|
|
1731
|
-
this.selectedItemsChange.emit([]);
|
|
1732
|
-
}
|
|
1733
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseMatChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1734
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: BaseMatChipComponent, isStandalone: true, selector: "ngx-uik-chip-input-autocomplete", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsInput: { classPropertyName: "selectedItemsInput", publicName: "selectedItemsInput", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsChange: "selectedItemsChange" }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "<mat-form-field class=\"chip-list\" appearance=\"fill\">\r\n <mat-label>{{ title() }}</mat-label>\r\n <mat-chip-grid #chipList aria-label=\"'\u0412\u044B\u0431\u043E\u0440 '+title()\">\r\n @for (item of selectedItems; track item) {\r\n <mat-chip-row color=\"primary\"\r\n (removed)=\"remove(item.value)\">\r\n {{ item.viewValue }}\r\n <button matChipRemove>\r\n <mat-icon>cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n }\r\n </mat-chip-grid>\r\n <input\r\n #input\r\n [placeholder]=\"'\u0412\u0432\u0435\u0434\u0438\u0442\u0435 '+title()+'...'\"\r\n [formControl]=\"inputCtrl\"\r\n [matAutocomplete]=\"auto\"\r\n [matChipInputFor]=\"chipList\"\r\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\r\n >\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\r\n @for (item of filteredItems$ | async; track item) {\r\n <mat-option [value]=\"item.value\"\r\n [disabled]=\"selectedItemsInput()?.includes(item.value)\">\r\n {{ item.viewValue }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n @if (selectedItems.length > 0) {\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onCloseClick($event)\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n</mat-form-field>\r\n", styles: [".chip-list{width:100%}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i3.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i3.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled", "readonly", "matChipInputDisabledInteractive"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i3.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i3.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "pipe", type: AsyncPipe, name: "async" }] });
|
|
1735
|
-
}
|
|
1736
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseMatChipComponent, decorators: [{
|
|
1737
|
-
type: Component,
|
|
1738
|
-
args: [{ selector: 'ngx-uik-chip-input-autocomplete', imports: [MatFormField, AsyncPipe, FormsModule, ReactiveFormsModule, MatAutocompleteModule, MatIcon, MatOption,
|
|
1739
|
-
MatChipsModule, MatLabel], template: "<mat-form-field class=\"chip-list\" appearance=\"fill\">\r\n <mat-label>{{ title() }}</mat-label>\r\n <mat-chip-grid #chipList aria-label=\"'\u0412\u044B\u0431\u043E\u0440 '+title()\">\r\n @for (item of selectedItems; track item) {\r\n <mat-chip-row color=\"primary\"\r\n (removed)=\"remove(item.value)\">\r\n {{ item.viewValue }}\r\n <button matChipRemove>\r\n <mat-icon>cancel</mat-icon>\r\n </button>\r\n </mat-chip-row>\r\n }\r\n </mat-chip-grid>\r\n <input\r\n #input\r\n [placeholder]=\"'\u0412\u0432\u0435\u0434\u0438\u0442\u0435 '+title()+'...'\"\r\n [formControl]=\"inputCtrl\"\r\n [matAutocomplete]=\"auto\"\r\n [matChipInputFor]=\"chipList\"\r\n [matChipInputSeparatorKeyCodes]=\"separatorKeysCodes\"\r\n >\r\n <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\r\n @for (item of filteredItems$ | async; track item) {\r\n <mat-option [value]=\"item.value\"\r\n [disabled]=\"selectedItemsInput()?.includes(item.value)\">\r\n {{ item.viewValue }}\r\n </mat-option>\r\n }\r\n </mat-autocomplete>\r\n @if (selectedItems.length > 0) {\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onCloseClick($event)\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n</mat-form-field>\r\n", styles: [".chip-list{width:100%}\n"] }]
|
|
1740
|
-
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], selectedItemsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemsInput", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], selectedItemsChange: [{ type: i0.Output, args: ["selectedItemsChange"] }], input: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
1741
|
-
|
|
1742
|
-
function dateFormat(date) {
|
|
1743
|
-
if (date)
|
|
1744
|
-
return moment(date).format("YYYY-MM-DD");
|
|
1745
|
-
else
|
|
1746
|
-
return '';
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
// See the Moment.js docs for the meaning of these formats:
|
|
1750
|
-
// https://momentjs.com/docs/#/displaying/format/
|
|
1751
|
-
const MY_FORMATS = {
|
|
1752
|
-
parse: {
|
|
1753
|
-
dateInput: 'DD.MM.YYYY',
|
|
1754
|
-
},
|
|
1755
|
-
display: {
|
|
1756
|
-
dateInput: 'DD.MM.YYYY',
|
|
1757
|
-
monthYearLabel: 'MMM YYYY',
|
|
1758
|
-
dateA11yLabel: 'LL',
|
|
1759
|
-
monthYearA11yLabel: 'MMMM YYYY',
|
|
1760
|
-
},
|
|
1761
|
-
};
|
|
1762
|
-
|
|
1763
|
-
class DateRangeInputComponent {
|
|
1764
|
-
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
1765
|
-
dateRange = input({ begin: '', end: '' }, ...(ngDevMode ? [{ debugName: "dateRange" }] : []));
|
|
1766
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1767
|
-
minDate = input(new Date(2020, 0, 1), ...(ngDevMode ? [{ debugName: "minDate" }] : []));
|
|
1768
|
-
clearInput = input(null, ...(ngDevMode ? [{ debugName: "clearInput" }] : []));
|
|
1769
|
-
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
1770
|
-
dateRangeChange = output();
|
|
1771
|
-
form = new FormGroup({
|
|
1772
|
-
begin: new FormControl(),
|
|
1773
|
-
end: new FormControl(),
|
|
1774
|
-
});
|
|
1775
|
-
subscription = new Subscription();
|
|
1776
|
-
constructor() {
|
|
1777
|
-
effect(() => {
|
|
1778
|
-
if (this.clearInput())
|
|
1779
|
-
this.form.reset();
|
|
1780
|
-
});
|
|
1781
|
-
effect(() => {
|
|
1782
|
-
const value = this.dateRange();
|
|
1783
|
-
if (this.form) {
|
|
1784
|
-
this.form.controls['begin'].setValue(value.begin ? new Date(value.begin) : null);
|
|
1785
|
-
this.form.controls['end'].setValue(value.end ? new Date(value.begin) : null);
|
|
1786
|
-
}
|
|
1787
|
-
this.dateRangeChange.emit(this.rangeToDateDateRange(this.form.value));
|
|
1788
|
-
});
|
|
1789
|
-
}
|
|
1790
|
-
ngOnInit() {
|
|
1791
|
-
if (this.required()) {
|
|
1792
|
-
this.form.controls['begin'].addValidators(Validators.required);
|
|
1793
|
-
this.form.controls['end'].addValidators(Validators.required);
|
|
1794
|
-
}
|
|
1795
|
-
// подписка на изменение периода
|
|
1796
|
-
this.form.valueChanges
|
|
1797
|
-
.pipe(
|
|
1798
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1799
|
-
debounceTime(500), distinctUntilChanged())
|
|
1800
|
-
.subscribe({
|
|
1801
|
-
next: range => {
|
|
1802
|
-
if (this.required()) {
|
|
1803
|
-
if (range.begin && range.end) {
|
|
1804
|
-
this.dateRangeChange.emit(this.rangeToDateDateRange(range));
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
else {
|
|
1808
|
-
this.dateRangeChange.emit(this.rangeToDateDateRange(range));
|
|
1809
|
-
}
|
|
1810
|
-
}
|
|
1811
|
-
});
|
|
1812
|
-
}
|
|
1813
|
-
ngOnDestroy() {
|
|
1814
|
-
if (this.subscription)
|
|
1815
|
-
this.subscription.unsubscribe();
|
|
1816
|
-
}
|
|
1817
|
-
rangeToDateDateRange(range) {
|
|
1818
|
-
return {
|
|
1819
|
-
begin: range.begin ? dateFormat(range.begin) : '',
|
|
1820
|
-
end: range.end ? dateFormat(range.end) : ''
|
|
1821
|
-
};
|
|
1822
|
-
}
|
|
1823
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DateRangeInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1824
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: DateRangeInputComponent, isStandalone: true, selector: "ngx-uik-date-range-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, dateRange: { classPropertyName: "dateRange", publicName: "dateRange", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, clearInput: { classPropertyName: "clearInput", publicName: "clearInput", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateRangeChange: "dateRangeChange" }, providers: [
|
|
1825
|
-
{ provide: MAT_DATE_LOCALE, useValue: 'ru' },
|
|
1826
|
-
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
|
|
1827
|
-
], ngImport: i0, template: "<mat-form-field appearance=\"fill\">\r\n <mat-label>{{label()}}</mat-label>\r\n <mat-date-range-input\r\n [rangePicker]=\"picker\"\r\n [formGroup]=\"form\"\r\n [min]=\"minDate()\">\r\n <input matStartDate formControlName=\"begin\" placeholder=\"\u0414\u0430\u0442\u0430 \u043D\u0430\u0447\u0430\u043B\u0430\">\r\n <input matEndDate formControlName=\"end\" placeholder=\"\u0414\u0430\u0442\u0430 \u043E\u043A\u043E\u043D\u0447\u0430\u043D\u0438\u044F\">\r\n </mat-date-range-input>\r\n <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\r\n <mat-date-range-picker #picker></mat-date-range-picker>\r\n <mat-error>\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0435\u0440\u0438\u043E\u0434</mat-error>\r\n</mat-form-field>\r\n\r\n", styles: ["mat-form-field{margin-right:16px}\n"], dependencies: [{ kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "component", type: MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: MatStartDate, selector: "input[matStartDate]", outputs: ["dateChange", "dateInput"] }, { kind: "directive", type: MatEndDate, selector: "input[matEndDate]", outputs: ["dateChange", "dateInput"] }, { kind: "component", type: MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }] });
|
|
1828
|
-
}
|
|
1829
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: DateRangeInputComponent, decorators: [{
|
|
1830
|
-
type: Component,
|
|
1831
|
-
args: [{ selector: 'ngx-uik-date-range-input', imports: [MatFormField, MatLabel, MatDateRangeInput, FormsModule, ReactiveFormsModule, MatStartDate, MatEndDate,
|
|
1832
|
-
MatDatepickerToggle, MatSuffix, MatDateRangePicker, MatError], providers: [
|
|
1833
|
-
{ provide: MAT_DATE_LOCALE, useValue: 'ru' },
|
|
1834
|
-
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
|
|
1835
|
-
], template: "<mat-form-field appearance=\"fill\">\r\n <mat-label>{{label()}}</mat-label>\r\n <mat-date-range-input\r\n [rangePicker]=\"picker\"\r\n [formGroup]=\"form\"\r\n [min]=\"minDate()\">\r\n <input matStartDate formControlName=\"begin\" placeholder=\"\u0414\u0430\u0442\u0430 \u043D\u0430\u0447\u0430\u043B\u0430\">\r\n <input matEndDate formControlName=\"end\" placeholder=\"\u0414\u0430\u0442\u0430 \u043E\u043A\u043E\u043D\u0447\u0430\u043D\u0438\u044F\">\r\n </mat-date-range-input>\r\n <mat-datepicker-toggle matIconSuffix [for]=\"picker\"></mat-datepicker-toggle>\r\n <mat-date-range-picker #picker></mat-date-range-picker>\r\n <mat-error>\u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u043F\u0435\u0440\u0438\u043E\u0434</mat-error>\r\n</mat-form-field>\r\n\r\n", styles: ["mat-form-field{margin-right:16px}\n"] }]
|
|
1836
|
-
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], dateRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateRange", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], clearInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearInput", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], dateRangeChange: [{ type: i0.Output, args: ["dateRangeChange"] }] } });
|
|
1837
|
-
|
|
1838
|
-
var DialogAction;
|
|
1839
|
-
(function (DialogAction) {
|
|
1840
|
-
DialogAction["Add"] = "\u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C";
|
|
1841
|
-
DialogAction["Edit"] = "\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C";
|
|
1842
|
-
DialogAction["Delete"] = "\u0423\u0434\u0430\u043B\u0438\u0442\u044C";
|
|
1843
|
-
DialogAction["None"] = "";
|
|
1844
|
-
})(DialogAction || (DialogAction = {}));
|
|
1845
|
-
|
|
1846
|
-
class NavBarComponent extends BaseNavBarMenuClass {
|
|
1847
|
-
/** Видимость панели, когда loggedIn === false. */
|
|
1848
|
-
visibleOnLogout = input(false, ...(ngDevMode ? [{ debugName: "visibleOnLogout" }] : []));
|
|
1849
|
-
/** Видимость аватара. */
|
|
1850
|
-
visibleAvatar = input(true, ...(ngDevMode ? [{ debugName: "visibleAvatar" }] : []));
|
|
1851
|
-
/** Видимость кнопки "Выйти". */
|
|
1852
|
-
visibleLogoutBtn = input(true, ...(ngDevMode ? [{ debugName: "visibleLogoutBtn" }] : []));
|
|
1853
|
-
/** Признак, что пользователь авторизован. */
|
|
1854
|
-
loggedIn = input(false, ...(ngDevMode ? [{ debugName: "loggedIn" }] : []));
|
|
1855
|
-
/** ФИО пользователя. */
|
|
1856
|
-
fioUser = input('', ...(ngDevMode ? [{ debugName: "fioUser" }] : []));
|
|
1857
|
-
/** Всплывающая подсказка о пользователе. */
|
|
1858
|
-
userTooltip = input('', ...(ngDevMode ? [{ debugName: "userTooltip" }] : []));
|
|
1859
|
-
/** URL аватара */
|
|
1860
|
-
avatarURL = input('', ...(ngDevMode ? [{ debugName: "avatarURL" }] : []));
|
|
1861
|
-
/** Нажата кнопка "Выйти". */
|
|
1862
|
-
logout = output();
|
|
1863
|
-
dialog = inject(MatDialog);
|
|
1864
|
-
constructor() {
|
|
1865
|
-
super();
|
|
1866
|
-
}
|
|
1867
|
-
onLogout() {
|
|
1868
|
-
this.logout.emit(this.router.url);
|
|
1869
|
-
}
|
|
1870
|
-
openDialog() {
|
|
1871
|
-
const dialogRef = this.dialog.open(DialogComponent, {
|
|
1872
|
-
width: '400px',
|
|
1873
|
-
data: {
|
|
1874
|
-
id: 'logout',
|
|
1875
|
-
title: 'Подтверждение',
|
|
1876
|
-
message: 'Вы хотите выйти?',
|
|
1877
|
-
btnNoTitle: 'Отмена',
|
|
1878
|
-
btnYesTitle: 'Выйти'
|
|
1879
|
-
}
|
|
1880
|
-
});
|
|
1881
|
-
const subs = dialogRef.afterClosed().subscribe((id) => {
|
|
1882
|
-
if (id) {
|
|
1883
|
-
this.onLogout();
|
|
1884
|
-
}
|
|
1885
|
-
});
|
|
1886
|
-
this.subscription.add(subs);
|
|
1887
|
-
}
|
|
1888
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NavBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1889
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: NavBarComponent, isStandalone: true, selector: "ngx-uik-navbar", inputs: { visibleOnLogout: { classPropertyName: "visibleOnLogout", publicName: "visibleOnLogout", isSignal: true, isRequired: false, transformFunction: null }, visibleAvatar: { classPropertyName: "visibleAvatar", publicName: "visibleAvatar", isSignal: true, isRequired: false, transformFunction: null }, visibleLogoutBtn: { classPropertyName: "visibleLogoutBtn", publicName: "visibleLogoutBtn", isSignal: true, isRequired: false, transformFunction: null }, loggedIn: { classPropertyName: "loggedIn", publicName: "loggedIn", isSignal: true, isRequired: false, transformFunction: null }, fioUser: { classPropertyName: "fioUser", publicName: "fioUser", isSignal: true, isRequired: false, transformFunction: null }, userTooltip: { classPropertyName: "userTooltip", publicName: "userTooltip", isSignal: true, isRequired: false, transformFunction: null }, avatarURL: { classPropertyName: "avatarURL", publicName: "avatarURL", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logout: "logout" }, usesInheritance: true, ngImport: i0, template: "@if (visibleOnLogout() || loggedIn()) {\r\n <nav class=\"ngx-uik-navbar-header\">\r\n \r\n <ng-content></ng-content>\r\n\r\n <div class=\"flex-spacer\"></div>\r\n \r\n @if (visibleAvatar() && (loggedIn() === false || !avatarURL)) {\r\n <mat-icon [matTooltip]=\"userTooltip()\">account_circle</mat-icon>\r\n }\r\n @if (visibleAvatar() && loggedIn() && avatarURL()) {\r\n <img\r\n class=\"user-photo\"\r\n [src]=\"avatarURL() | safe\"\r\n loading=\"lazy\"\r\n [alt]=\"fioUser()\"\r\n [matTooltip]=\"userTooltip()\">\r\n }\r\n\r\n <span class = \"user-name\" [matTooltip]=\"userTooltip()\">\r\n {{ fioUser() }}\r\n </span>\r\n\r\n @if (visibleLogoutBtn()) {\r\n <a mat-button class=\"pm-button\" (click)=\"openDialog()\">\u0412\u044B\u0439\u0442\u0438 <mat-icon>logout</mat-icon></a>\r\n }\r\n </nav>\r\n}", styles: [".ngx-uik-navbar-header{display:flex;flex-wrap:wrap;align-items:center;padding:8px 16px}.flex-spacer{flex-grow:1}.user-name{margin-left:8px;line-height:1rem;white-space:normal}.user-photo{border-radius:50%;width:32px;height:32px;margin-right:10px}.mat-mdc-button{color:#fff!important;padding-left:16px!important;padding-right:16px!important}.mdc-button{letter-spacing:normal}\n"], dependencies: [{ kind: "component", type: MatAnchor, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: SafePipe, name: "safe" }] });
|
|
1890
|
-
}
|
|
1891
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NavBarComponent, decorators: [{
|
|
1892
|
-
type: Component,
|
|
1893
|
-
args: [{ selector: 'ngx-uik-navbar', imports: [MatAnchor, MatIcon, MatTooltip, SafePipe], template: "@if (visibleOnLogout() || loggedIn()) {\r\n <nav class=\"ngx-uik-navbar-header\">\r\n \r\n <ng-content></ng-content>\r\n\r\n <div class=\"flex-spacer\"></div>\r\n \r\n @if (visibleAvatar() && (loggedIn() === false || !avatarURL)) {\r\n <mat-icon [matTooltip]=\"userTooltip()\">account_circle</mat-icon>\r\n }\r\n @if (visibleAvatar() && loggedIn() && avatarURL()) {\r\n <img\r\n class=\"user-photo\"\r\n [src]=\"avatarURL() | safe\"\r\n loading=\"lazy\"\r\n [alt]=\"fioUser()\"\r\n [matTooltip]=\"userTooltip()\">\r\n }\r\n\r\n <span class = \"user-name\" [matTooltip]=\"userTooltip()\">\r\n {{ fioUser() }}\r\n </span>\r\n\r\n @if (visibleLogoutBtn()) {\r\n <a mat-button class=\"pm-button\" (click)=\"openDialog()\">\u0412\u044B\u0439\u0442\u0438 <mat-icon>logout</mat-icon></a>\r\n }\r\n </nav>\r\n}", styles: [".ngx-uik-navbar-header{display:flex;flex-wrap:wrap;align-items:center;padding:8px 16px}.flex-spacer{flex-grow:1}.user-name{margin-left:8px;line-height:1rem;white-space:normal}.user-photo{border-radius:50%;width:32px;height:32px;margin-right:10px}.mat-mdc-button{color:#fff!important;padding-left:16px!important;padding-right:16px!important}.mdc-button{letter-spacing:normal}\n"] }]
|
|
1894
|
-
}], ctorParameters: () => [], propDecorators: { visibleOnLogout: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleOnLogout", required: false }] }], visibleAvatar: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleAvatar", required: false }] }], visibleLogoutBtn: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleLogoutBtn", required: false }] }], loggedIn: [{ type: i0.Input, args: [{ isSignal: true, alias: "loggedIn", required: false }] }], fioUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "fioUser", required: false }] }], userTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "userTooltip", required: false }] }], avatarURL: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarURL", required: false }] }], logout: [{ type: i0.Output, args: ["logout"] }] } });
|
|
1895
|
-
|
|
1896
|
-
class NotFoundComponent {
|
|
1897
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1898
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.0", type: NotFoundComponent, isStandalone: true, selector: "ngx-uik-not-found", ngImport: i0, template: "<div class=\"center\">\r\n <h3 class=\"mat-display-1\">\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u0430</h3>\r\n</div>\r\n", styles: [".center{display:flex;justify-content:center;margin:3rem}\n"] });
|
|
1899
|
-
}
|
|
1900
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: NotFoundComponent, decorators: [{
|
|
1901
|
-
type: Component,
|
|
1902
|
-
args: [{ selector: 'ngx-uik-not-found', standalone: true, template: "<div class=\"center\">\r\n <h3 class=\"mat-display-1\">\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D\u0430</h3>\r\n</div>\r\n", styles: [".center{display:flex;justify-content:center;margin:3rem}\n"] }]
|
|
1903
|
-
}] });
|
|
1904
|
-
|
|
1905
|
-
class BaseSelectAutocompleteWithVsComponent {
|
|
1906
|
-
// https://stackblitz.com/edit/autocomplete-with-virtual-scroll-dc9u2g
|
|
1907
|
-
// Все элементы
|
|
1908
|
-
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : []));
|
|
1909
|
-
// Выбранный элемент (входной параметр)
|
|
1910
|
-
selectedItemInput = input(undefined, ...(ngDevMode ? [{ debugName: "selectedItemInput" }] : []));
|
|
1911
|
-
// Заголовок
|
|
1912
|
-
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
1913
|
-
// Видимость
|
|
1914
|
-
isVisible = input(true, ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
|
|
1915
|
-
// Обязательность
|
|
1916
|
-
isRequired = input(false, ...(ngDevMode ? [{ debugName: "isRequired" }] : []));
|
|
1917
|
-
// Доступность
|
|
1918
|
-
isDisabled = input(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
1919
|
-
// Доступность
|
|
1920
|
-
width = input('200', ...(ngDevMode ? [{ debugName: "width" }] : []));
|
|
1921
|
-
// Выбранный элемент
|
|
1922
|
-
selectedItem = linkedSignal(() => this.selectedItemInput(), ...(ngDevMode ? [{ debugName: "selectedItem" }] : []));
|
|
1923
|
-
// Событие изменения выбранного элемента
|
|
1924
|
-
selectedItemChange = output();
|
|
1925
|
-
height = '200px';
|
|
1926
|
-
// input элемент
|
|
1927
|
-
inputCtrl = new FormControl();
|
|
1928
|
-
// отфильтрованные (отображаемые) элементы
|
|
1929
|
-
filteredItems = [];
|
|
1930
|
-
subscription = new Subscription();
|
|
1931
|
-
constructor() {
|
|
1932
|
-
effect(() => {
|
|
1933
|
-
console.log('ITEMS =', this.items());
|
|
1934
|
-
//this.filteredItems = this.items();
|
|
1935
|
-
console.log('selectedItem =', this.selectedItemInput());
|
|
1936
|
-
if (this.items().length > 0) {
|
|
1937
|
-
console.log('filteredItems SET');
|
|
1938
|
-
this.setFileredItems(this.items());
|
|
1939
|
-
this.inputCtrl.setValue(this.selectedItemInput());
|
|
1940
|
-
}
|
|
1941
|
-
});
|
|
1942
|
-
}
|
|
1943
|
-
ngOnInit() {
|
|
1944
|
-
// Listen for changes to the input
|
|
1945
|
-
const subs = this.inputCtrl.valueChanges
|
|
1946
|
-
.pipe(startWith$1(''),
|
|
1947
|
-
// eslint-disable-next-line no-magic-numbers
|
|
1948
|
-
debounceTime(500), distinctUntilChanged(),
|
|
1949
|
-
// Note: If the option value is bound to object, after selecting the option
|
|
1950
|
-
// Note: the value will change from string to {}. We want to perform search
|
|
1951
|
-
// Note: only when the type is string (no match)
|
|
1952
|
-
//filter(q => typeof q === 'string'),
|
|
1953
|
-
//tap((v) => console.log('v=', v)),
|
|
1954
|
-
map((value) => {
|
|
1955
|
-
// Filter the options
|
|
1956
|
-
console.log('typeof value =', typeof value);
|
|
1957
|
-
if (typeof value === 'undefined') {
|
|
1958
|
-
this.setFileredItems(this.items());
|
|
1959
|
-
}
|
|
1960
|
-
else {
|
|
1961
|
-
if (typeof value !== 'object') {
|
|
1962
|
-
console.log('v1=', value);
|
|
1963
|
-
this.setFileredItems(this.items()
|
|
1964
|
-
.filter(option => option.viewValue.toLowerCase().includes(value.toLowerCase())));
|
|
1965
|
-
}
|
|
1966
|
-
else {
|
|
1967
|
-
// typeof value === 'object'
|
|
1968
|
-
console.log('v2=', value);
|
|
1969
|
-
if (value) {
|
|
1970
|
-
// this.predmet = value;
|
|
1971
|
-
this.setFileredItems(this.items()
|
|
1972
|
-
.filter((option) => option.viewValue.toLowerCase().includes(value.viewValue.toLowerCase())));
|
|
1973
|
-
console.log('v3=', value);
|
|
1974
|
-
}
|
|
1975
|
-
else {
|
|
1976
|
-
this.setFileredItems(this.items());
|
|
1977
|
-
console.log('v4=', value);
|
|
1978
|
-
}
|
|
1979
|
-
}
|
|
1980
|
-
}
|
|
1981
|
-
}))
|
|
1982
|
-
.subscribe();
|
|
1983
|
-
this.subscription.add(subs);
|
|
1984
|
-
if (this.isDisabled()) {
|
|
1985
|
-
this.inputCtrl.disable();
|
|
1986
|
-
}
|
|
1987
|
-
else {
|
|
1988
|
-
this.inputCtrl.enable();
|
|
1989
|
-
}
|
|
1990
|
-
}
|
|
1991
|
-
ngOnDestroy() {
|
|
1992
|
-
if (this.subscription)
|
|
1993
|
-
this.subscription.unsubscribe();
|
|
1994
|
-
}
|
|
1995
|
-
onSelectedItemChange(item) {
|
|
1996
|
-
console.log("onSelectedItemChange, item=", item);
|
|
1997
|
-
this.selectedItem.set(item);
|
|
1998
|
-
this.selectedItemChange.emit(item);
|
|
1999
|
-
}
|
|
2000
|
-
onClearClick($event) {
|
|
2001
|
-
$event.stopPropagation();
|
|
2002
|
-
this.inputCtrl.setValue('');
|
|
2003
|
-
}
|
|
2004
|
-
displayWithFn(lookup) {
|
|
2005
|
-
return lookup ? lookup.viewValue : null;
|
|
2006
|
-
}
|
|
2007
|
-
setFileredItems(items) {
|
|
2008
|
-
this.filteredItems = items;
|
|
2009
|
-
// Recompute how big the viewport should be.
|
|
2010
|
-
// eslint-disable-next-line no-magic-numbers
|
|
2011
|
-
if (items.length < 4) {
|
|
2012
|
-
// eslint-disable-next-line no-magic-numbers
|
|
2013
|
-
this.height = items.length * 50 + 'px';
|
|
2014
|
-
}
|
|
2015
|
-
else {
|
|
2016
|
-
this.height = '200px';
|
|
2017
|
-
}
|
|
2018
|
-
console.log('update filteredItems =', this.filteredItems);
|
|
2019
|
-
}
|
|
2020
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseSelectAutocompleteWithVsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2021
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: BaseSelectAutocompleteWithVsComponent, isStandalone: true, selector: "ngx-uik-select-autocomplete-with-vs", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, selectedItemInput: { classPropertyName: "selectedItemInput", publicName: "selectedItemInput", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, isVisible: { classPropertyName: "isVisible", publicName: "isVisible", isSignal: true, isRequired: false, transformFunction: null }, isRequired: { classPropertyName: "isRequired", publicName: "isRequired", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemChange: "selectedItemChange" }, ngImport: i0, template: "@if (isVisible()) {\r\n <mat-form-field [style.width.px]=\"width()\">\r\n <mat-label>{{ title() }}</mat-label>\r\n <input type=\"text\"\r\n [placeholder]=title()\r\n aria-label=\"Number\"\r\n matInput\r\n (ngModelChange)=\"onSelectedItemChange($event)\"\r\n [formControl]=\"inputCtrl\"\r\n [matAutocomplete]=\"auto\"\r\n [required]=\"isRequired() ? 'required' : ''\"\r\n >\r\n @if (!isDisabled && selectedItem()) {\r\n <button mat-button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onClearClick($event)\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n <mat-autocomplete #auto=\"matAutocomplete\" [displayWith]=\"displayWithFn\" showPanel=\"true\">\r\n <cdk-virtual-scroll-viewport class=\"autocomplete-test-viewport\" [style.height]=\"height\" itemSize=\"25\">\r\n <mat-option *cdkVirtualFor=\"let option of filteredItems\" [value]=\"option\" class=\"autocomplete-item\">\r\n {{option.viewValue}}\r\n </mat-option>\r\n </cdk-virtual-scroll-viewport>\r\n </mat-autocomplete>\r\n @if (inputCtrl.invalid) {\r\n <mat-error>\u0412\u0432\u0435\u0434\u0438\u0442\u0435 {{title()}}</mat-error>\r\n }\r\n @if (!inputCtrl.value) {\r\n <mat-hint>\u041D\u0430\u0447\u043D\u0438\u0442\u0435 \u0432\u0432\u043E\u0434\u0438\u0442\u044C ...</mat-hint>\r\n }\r\n </mat-form-field>\r\n}", styles: ["mat-form-field{margin-right:12px}.autocomplete-item{height:50px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i2.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i2.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i3$1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i3$1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i3$1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }] });
|
|
2022
|
-
}
|
|
2023
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseSelectAutocompleteWithVsComponent, decorators: [{
|
|
2024
|
-
type: Component,
|
|
2025
|
-
args: [{ selector: 'ngx-uik-select-autocomplete-with-vs', imports: [FormsModule, ReactiveFormsModule, MatAutocompleteModule, MatHint, MatError, MatOption, MatIcon,
|
|
2026
|
-
MatFormField, ScrollingModule, MatInput, MatLabel], template: "@if (isVisible()) {\r\n <mat-form-field [style.width.px]=\"width()\">\r\n <mat-label>{{ title() }}</mat-label>\r\n <input type=\"text\"\r\n [placeholder]=title()\r\n aria-label=\"Number\"\r\n matInput\r\n (ngModelChange)=\"onSelectedItemChange($event)\"\r\n [formControl]=\"inputCtrl\"\r\n [matAutocomplete]=\"auto\"\r\n [required]=\"isRequired() ? 'required' : ''\"\r\n >\r\n @if (!isDisabled && selectedItem()) {\r\n <button mat-button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onClearClick($event)\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n <mat-autocomplete #auto=\"matAutocomplete\" [displayWith]=\"displayWithFn\" showPanel=\"true\">\r\n <cdk-virtual-scroll-viewport class=\"autocomplete-test-viewport\" [style.height]=\"height\" itemSize=\"25\">\r\n <mat-option *cdkVirtualFor=\"let option of filteredItems\" [value]=\"option\" class=\"autocomplete-item\">\r\n {{option.viewValue}}\r\n </mat-option>\r\n </cdk-virtual-scroll-viewport>\r\n </mat-autocomplete>\r\n @if (inputCtrl.invalid) {\r\n <mat-error>\u0412\u0432\u0435\u0434\u0438\u0442\u0435 {{title()}}</mat-error>\r\n }\r\n @if (!inputCtrl.value) {\r\n <mat-hint>\u041D\u0430\u0447\u043D\u0438\u0442\u0435 \u0432\u0432\u043E\u0434\u0438\u0442\u044C ...</mat-hint>\r\n }\r\n </mat-form-field>\r\n}", styles: ["mat-form-field{margin-right:12px}.autocomplete-item{height:50px}\n"] }]
|
|
2027
|
-
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], selectedItemInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemInput", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], isVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "isVisible", required: false }] }], isRequired: [{ type: i0.Input, args: [{ isSignal: true, alias: "isRequired", required: false }] }], isDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDisabled", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], selectedItemChange: [{ type: i0.Output, args: ["selectedItemChange"] }] } });
|
|
2028
|
-
|
|
2029
|
-
class BaseSelectWithGroupComponent {
|
|
2030
|
-
// Все группы
|
|
2031
|
-
groups = input([], ...(ngDevMode ? [{ debugName: "groups" }] : []));
|
|
2032
|
-
// Выбранные элементы, ключи (BaseSelectItem.value)
|
|
2033
|
-
selectedItems = input([], ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
|
|
2034
|
-
// Заголовок
|
|
2035
|
-
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
2036
|
-
// Событие изменения выбранных элементов
|
|
2037
|
-
selectedItemsChange = output();
|
|
2038
|
-
separatorKeysCodes = [ENTER, COMMA];
|
|
2039
|
-
control = new FormControl([]);
|
|
2040
|
-
constructor() {
|
|
2041
|
-
effect(() => {
|
|
2042
|
-
if (this.groups().length > 0) {
|
|
2043
|
-
this.control.setValue(this.selectedItems().map(i => Number(i)));
|
|
2044
|
-
}
|
|
2045
|
-
});
|
|
2046
|
-
}
|
|
2047
|
-
selectionChange($event) {
|
|
2048
|
-
this.selectedItemsChange.emit($event.value.map((i) => i.toString()));
|
|
2049
|
-
}
|
|
2050
|
-
onClearClick($event) {
|
|
2051
|
-
$event.stopPropagation();
|
|
2052
|
-
// this.control.setValue('');
|
|
2053
|
-
this.selectedItemsChange.emit([]);
|
|
2054
|
-
}
|
|
2055
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseSelectWithGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2056
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: BaseSelectWithGroupComponent, isStandalone: true, selector: "ngx-uik-select-with-group", inputs: { groups: { classPropertyName: "groups", publicName: "groups", isSignal: true, isRequired: false, transformFunction: null }, selectedItems: { classPropertyName: "selectedItems", publicName: "selectedItems", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsChange: "selectedItemsChange" }, ngImport: i0, template: "<mat-form-field class=\"select-with-group\" appearance=\"fill\">\r\n <mat-label>{{ title() }}</mat-label>\r\n <mat-select [formControl]=\"control\" (selectionChange)=\"selectionChange($event)\" multiple>\r\n @for (group of groups(); track group) {\r\n <mat-optgroup [label]=\"group.name\">\r\n @for (item of group.items; track item) {\r\n <mat-option [value]=\"item.value\" >\r\n {{item.viewValue}}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }\r\n\r\n </mat-select>\r\n @if (control.value && control.value!.length > 0) {\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onClearClick($event)\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n</mat-form-field>\r\n", styles: [".select-with-group{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatOption$1, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatFormField$1, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel$1, selector: "mat-label" }] });
|
|
2057
|
-
}
|
|
2058
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseSelectWithGroupComponent, decorators: [{
|
|
2059
|
-
type: Component,
|
|
2060
|
-
args: [{ selector: 'ngx-uik-select-with-group', imports: [FormsModule, ReactiveFormsModule, MatIcon, MatOption$1, MatOptgroup, MatSelect, MatFormField$1, MatLabel$1], template: "<mat-form-field class=\"select-with-group\" appearance=\"fill\">\r\n <mat-label>{{ title() }}</mat-label>\r\n <mat-select [formControl]=\"control\" (selectionChange)=\"selectionChange($event)\" multiple>\r\n @for (group of groups(); track group) {\r\n <mat-optgroup [label]=\"group.name\">\r\n @for (item of group.items; track item) {\r\n <mat-option [value]=\"item.value\" >\r\n {{item.viewValue}}\r\n </mat-option>\r\n }\r\n </mat-optgroup>\r\n }\r\n\r\n </mat-select>\r\n @if (control.value && control.value!.length > 0) {\r\n <button matSuffix mat-icon-button aria-label=\"Clear\" (click)=\"onClearClick($event)\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n }\r\n</mat-form-field>\r\n", styles: [".select-with-group{width:100%}\n"] }]
|
|
2061
|
-
}], ctorParameters: () => [], propDecorators: { groups: [{ type: i0.Input, args: [{ isSignal: true, alias: "groups", required: false }] }], selectedItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItems", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], selectedItemsChange: [{ type: i0.Output, args: ["selectedItemsChange"] }] } });
|
|
2062
|
-
|
|
2063
|
-
class TableComponent {
|
|
2064
|
-
/** Отображаемые данные. */
|
|
2065
|
-
data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
|
|
2066
|
-
/** Количество записей. */
|
|
2067
|
-
length = input(0, ...(ngDevMode ? [{ debugName: "length" }] : []));
|
|
2068
|
-
/** Настройки колонок. */
|
|
2069
|
-
columnOptions = input([], ...(ngDevMode ? [{ debugName: "columnOptions" }] : []));
|
|
2070
|
-
/** Состояние сортировки, пагинации. */
|
|
2071
|
-
tableState = input.required(...(ngDevMode ? [{ debugName: "tableState" }] : []));
|
|
2072
|
-
/** Разрешен выбор нескольких строк. */
|
|
2073
|
-
allowMultiSelect = input(false, ...(ngDevMode ? [{ debugName: "allowMultiSelect" }] : []));
|
|
2074
|
-
/** Список элементов контекстного меню. */
|
|
2075
|
-
opt = input([], ...(ngDevMode ? [{ debugName: "opt" }] : []));
|
|
2076
|
-
/** Отправка события rowDoubleClicked (при двойном щелчке мышью) отключена. */
|
|
2077
|
-
rowDblClickedDisable = input(false, ...(ngDevMode ? [{ debugName: "rowDblClickedDisable" }] : []));
|
|
2078
|
-
/** Отображать строку с итогом. */
|
|
2079
|
-
footer = input(false, ...(ngDevMode ? [{ debugName: "footer" }] : []));
|
|
2080
|
-
/** Изменение страницы. */
|
|
2081
|
-
pageStateChange = output();
|
|
2082
|
-
/** Изменение сортировки. */
|
|
2083
|
-
sortStateChange = output();
|
|
2084
|
-
/** Изменение выбранных записей. */
|
|
2085
|
-
selectionChange = output();
|
|
2086
|
-
/** Двойной щелчек ЛКМ*/
|
|
2087
|
-
rowDoubleClicked = output();
|
|
2088
|
-
sort = viewChild(MatSort, ...(ngDevMode ? [{ debugName: "sort" }] : []));
|
|
2089
|
-
paginator = viewChild(MatPaginator, ...(ngDevMode ? [{ debugName: "paginator" }] : []));
|
|
2090
|
-
contextMenu = viewChild(MatMenuTrigger, ...(ngDevMode ? [{ debugName: "contextMenu" }] : []));
|
|
2091
|
-
pageState = linkedSignal(() => {
|
|
2092
|
-
return { pageIndex: this.tableState().pageIndex, pageSize: this.tableState().pageSize };
|
|
2093
|
-
}, ...(ngDevMode ? [{ debugName: "pageState" }] : []));
|
|
2094
|
-
sortState = linkedSignal(() => {
|
|
2095
|
-
return { sortActive: this.tableState().sortActive, sortDirection: this.tableState().sortDirection };
|
|
2096
|
-
}, ...(ngDevMode ? [{ debugName: "sortState" }] : []));
|
|
2097
|
-
/** Выбранная строка, для которого будет показываться меню при нажатии правой кнопки мыши. */
|
|
2098
|
-
itemForMenu;
|
|
2099
|
-
/** Позиция в которой отображается контекстное меню. */
|
|
2100
|
-
contextMenuPosition = { x: '0px', y: '0px' };
|
|
2101
|
-
// eslint-disable-next-line no-magic-numbers
|
|
2102
|
-
defaultPageIndex = 0;
|
|
2103
|
-
// eslint-disable-next-line no-magic-numbers
|
|
2104
|
-
defaultPageSize = 10;
|
|
2105
|
-
/** Источник данных для отображения. */
|
|
2106
|
-
dataSource = new MatTableDataSource();
|
|
2107
|
-
/** Выбранные записи. */
|
|
2108
|
-
selection = new SelectionModel();
|
|
2109
|
-
/** Список отображаемых колонок (формируется из @columnOptions). */
|
|
2110
|
-
displayedColumns;
|
|
2111
|
-
subscription = new Subscription();
|
|
2112
|
-
constructor() {
|
|
2113
|
-
effect(() => {
|
|
2114
|
-
this.dataSource.data = this.data();
|
|
2115
|
-
// сохранить выделенные строки, если они все еще есть в данных
|
|
2116
|
-
const selected = this.selection.selected;
|
|
2117
|
-
this.selection.clear();
|
|
2118
|
-
this.data().filter(v => selected.map(s => JSON.stringify(s)).includes(JSON.stringify(v))).map(d => {
|
|
2119
|
-
this.selection.select(d);
|
|
2120
|
-
});
|
|
2121
|
-
});
|
|
2122
|
-
}
|
|
2123
|
-
ngOnInit() {
|
|
2124
|
-
this.displayedColumns = ['select'].concat(this.columnOptions()?.filter(c => !c.hide).map((item) => item.name) || []);
|
|
2125
|
-
// пересоздаем, т.к. параметр allowMultiSelect появляется только сейчас
|
|
2126
|
-
this.selection = new SelectionModel(this.allowMultiSelect());
|
|
2127
|
-
}
|
|
2128
|
-
ngOnDestroy() {
|
|
2129
|
-
if (this.subscription)
|
|
2130
|
-
this.subscription.unsubscribe();
|
|
2131
|
-
}
|
|
2132
|
-
ngAfterViewInit() {
|
|
2133
|
-
// подписи элементов управления пагинатора (MatPaginatorIntl)
|
|
2134
|
-
const paginator = this.paginator();
|
|
2135
|
-
if (paginator) {
|
|
2136
|
-
paginator._intl.itemsPerPageLabel = 'Записей на странице';
|
|
2137
|
-
paginator._intl.firstPageLabel = 'Первая страница';
|
|
2138
|
-
paginator._intl.previousPageLabel = 'Предыдущая страница';
|
|
2139
|
-
paginator._intl.nextPageLabel = 'Следующая страница';
|
|
2140
|
-
paginator._intl.lastPageLabel = 'Последняя страница';
|
|
2141
|
-
// изменение пагинации
|
|
2142
|
-
const subs = paginator.page.subscribe(page => {
|
|
2143
|
-
const pageState = {
|
|
2144
|
-
pageIndex: page.pageIndex,
|
|
2145
|
-
pageSize: page.pageSize
|
|
2146
|
-
};
|
|
2147
|
-
this.pageState.set(pageState);
|
|
2148
|
-
this.pageStateChange.emit(pageState);
|
|
2149
|
-
});
|
|
2150
|
-
this.subscription.add(subs);
|
|
2151
|
-
}
|
|
2152
|
-
// изменение сортировки
|
|
2153
|
-
const sortValue = this.sort();
|
|
2154
|
-
if (sortValue) {
|
|
2155
|
-
const subs = sortValue.sortChange
|
|
2156
|
-
.subscribe(sort => {
|
|
2157
|
-
const sortState = {
|
|
2158
|
-
sortActive: sort.active,
|
|
2159
|
-
sortDirection: sort.direction
|
|
2160
|
-
};
|
|
2161
|
-
this.sortState.set(sortState);
|
|
2162
|
-
this.sortStateChange.emit(sortState);
|
|
2163
|
-
});
|
|
2164
|
-
this.subscription.add(subs);
|
|
2165
|
-
}
|
|
2166
|
-
// изменение выбранных записей
|
|
2167
|
-
if (this.selection) {
|
|
2168
|
-
const subs = this.selection.changed.subscribe(change => {
|
|
2169
|
-
this.selectionChange.emit(change.source.selected);
|
|
2170
|
-
});
|
|
2171
|
-
this.subscription.add(subs);
|
|
2172
|
-
}
|
|
2173
|
-
}
|
|
2174
|
-
/** Whether the number of selected elements matches the total number of rows. */
|
|
2175
|
-
isAllSelected() {
|
|
2176
|
-
const numSelected = this.selection.selected.length;
|
|
2177
|
-
const numRows = this.dataSource.data.length;
|
|
2178
|
-
return numSelected === numRows;
|
|
2179
|
-
}
|
|
2180
|
-
/** Selects all rows if they are not all selected; otherwise clear selection. */
|
|
2181
|
-
masterToggle() {
|
|
2182
|
-
console.log(this.selection.isMultipleSelection());
|
|
2183
|
-
if (this.isAllSelected()) {
|
|
2184
|
-
this.selection.clear();
|
|
2185
|
-
}
|
|
2186
|
-
else {
|
|
2187
|
-
this.dataSource.data.forEach(row => this.selection.select(row));
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
/** При щелчке по строке. */
|
|
2191
|
-
onRowClicked(row) {
|
|
2192
|
-
// выделение строки при щелчке по строке
|
|
2193
|
-
if (this.selection.isSelected(row)) {
|
|
2194
|
-
this.selection.deselect(row);
|
|
2195
|
-
}
|
|
2196
|
-
else {
|
|
2197
|
-
this.selection.select(row);
|
|
2198
|
-
}
|
|
2199
|
-
}
|
|
2200
|
-
/** При двойном щелчке по строке. */
|
|
2201
|
-
onRowDblClicked(row) {
|
|
2202
|
-
// выделение строки при двойном щелчке по строке
|
|
2203
|
-
this.selection.clear();
|
|
2204
|
-
this.selection.select(row);
|
|
2205
|
-
if (!this.rowDblClickedDisable())
|
|
2206
|
-
this.rowDoubleClicked.emit(row);
|
|
2207
|
-
}
|
|
2208
|
-
/** При вызове контекстного меню. */
|
|
2209
|
-
onContextMenu(event, itemForMenu) {
|
|
2210
|
-
if (this.opt() && this.opt().length === 0) {
|
|
2211
|
-
// если нет пунктов меню, то не показываем меню
|
|
2212
|
-
return;
|
|
2213
|
-
}
|
|
2214
|
-
event.preventDefault();
|
|
2215
|
-
this.itemForMenu = itemForMenu;
|
|
2216
|
-
this.contextMenuPosition.x = event.clientX + 'px';
|
|
2217
|
-
this.contextMenuPosition.y = event.clientY + 'px';
|
|
2218
|
-
// как это (menuData) использовать в шаблоне не понятно, поэтому использую this.itemForMenu
|
|
2219
|
-
// https://www.concretepage.com/angular-material/passing-data-to-mat-menu-angular-material
|
|
2220
|
-
const contextMenu = this.contextMenu();
|
|
2221
|
-
if (contextMenu) {
|
|
2222
|
-
contextMenu.menuData = { itemForMenu };
|
|
2223
|
-
contextMenu.menu?.focusFirstItem('mouse');
|
|
2224
|
-
contextMenu.openMenu();
|
|
2225
|
-
}
|
|
2226
|
-
}
|
|
2227
|
-
getTotal(columnName) {
|
|
2228
|
-
const arr = this.dataSource.data
|
|
2229
|
-
.filter(t => typeof t[columnName] === 'number')
|
|
2230
|
-
.map(t => t[columnName]);
|
|
2231
|
-
if (arr.length === 0)
|
|
2232
|
-
return '';
|
|
2233
|
-
else
|
|
2234
|
-
return arr.reduce((acc, value) => acc + value, 0);
|
|
2235
|
-
}
|
|
2236
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2237
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TableComponent, isStandalone: true, selector: "ngx-uik-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: false, transformFunction: null }, columnOptions: { classPropertyName: "columnOptions", publicName: "columnOptions", isSignal: true, isRequired: false, transformFunction: null }, tableState: { classPropertyName: "tableState", publicName: "tableState", isSignal: true, isRequired: true, transformFunction: null }, allowMultiSelect: { classPropertyName: "allowMultiSelect", publicName: "allowMultiSelect", isSignal: true, isRequired: false, transformFunction: null }, opt: { classPropertyName: "opt", publicName: "opt", isSignal: true, isRequired: false, transformFunction: null }, rowDblClickedDisable: { classPropertyName: "rowDblClickedDisable", publicName: "rowDblClickedDisable", isSignal: true, isRequired: false, transformFunction: null }, footer: { classPropertyName: "footer", publicName: "footer", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageStateChange: "pageStateChange", sortStateChange: "sortStateChange", selectionChange: "selectionChange", rowDoubleClicked: "rowDoubleClicked" }, viewQueries: [{ propertyName: "sort", first: true, predicate: MatSort, descendants: true, isSignal: true }, { propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true, isSignal: true }, { propertyName: "contextMenu", first: true, predicate: MatMenuTrigger, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"component-container\">\r\n <div class=\"table-container\">\r\n <table mat-table [dataSource]=\"dataSource\"\r\n matSort\r\n [matSortActive]=\"sortState().sortActive || ''\"\r\n [matSortDirection]=\"sortState().sortDirection\"\r\n matSortDisableClear>\r\n\r\n <!-- \u0412\u044B\u0431\u043E\u0440 \u0441\u0442\u0440\u043E\u043A\u0438 Column -->\r\n <ng-container matColumnDef=\"select\">\r\n <th mat-header-cell *matHeaderCellDef>\r\n @if (allowMultiSelect()) {\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\r\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\r\n </mat-checkbox>\r\n }\r\n </th>\r\n <td mat-cell *matCellDef=\"let row\">\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\">\r\n </mat-checkbox>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n }\r\n </ng-container>\r\n\r\n @for (item of columnOptions(); track item) {\r\n <ng-container matColumnDef={{item.name}}>\r\n <th mat-header-cell *matHeaderCellDef mat-sort-header [disabled]=\"item.titleSortDisable\">{{item.title}}</th>\r\n @if (!item.format) {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n {{element[item.name]}}\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footer) {\r\n <strong>{{ getTotal(item.name) }}</strong>\r\n }\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n } \r\n }\r\n @if (item.format === 'pre-wrap') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" class=\"pre-wrap\" [matTooltip]=\"item.tooltip ?? ''\">\r\n {{element[item.name]}}\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'link') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n <a [href]=\"element[item.name]\" target=\"_blank\">{{element[item.name]}}</a>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'linkIcon') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (element[item.name]) {\r\n <a [href]=\"element[item.name]\" target=\"_blank\">\r\n @if (item.icon) {\r\n <mat-icon [class]=\"item.classList ? item.classList : ''\" >{{item.icon}}</mat-icon>\r\n } \r\n @if (item.symbol) {\r\n <span [class]=\"item.classList ? item.classList : ''\" >{{item.symbol}}</span>\r\n }\r\n </a>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'routerLink') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n <a [routerLink]=\"[element[item.name]]\">{{element[item.name]}}</a>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'routerLinkIcon') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (element[item.name]) {\r\n <a [routerLink]=\"[element[item.name]]\">\r\n @if (item.icon) {\r\n <mat-icon [class]=\"item.classList ? item.classList : ''\" >{{item.icon}}</mat-icon>\r\n } \r\n @if (item.symbol) {\r\n <span [class]=\"item.classList ? item.classList : ''\" >{{item.symbol}}</span>\r\n }\r\n </a>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'checkbox') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n <mat-checkbox [checked]=\"element[item.name] === 1\" [disabled]=\"true\"></mat-checkbox>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'icon') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (item.icon) {\r\n <mat-icon [class]=\"item.classList ? item.classList : ''\" >{{item.icon}}</mat-icon>\r\n } \r\n @if (item.symbol) {\r\n <span [class]=\"item.classList ? item.classList : ''\" >{{item.symbol}}</span>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'icons') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\">\r\n @if (item.icons) {\r\n <mat-icon [class]=\"item.classList ? item.classList[element[item.name]] : ''\" \r\n [matTooltip]=\"item.tooltips ? item.tooltips[element[item.name]] : ''\">{{item.icons[element[item.name]]}}</mat-icon>\r\n } \r\n @if (item.symbols) {\r\n <span [class]=\"item.classList ? item.classList[element[item.name]] : ''\" >{{item.symbols[element[item.name]]}}</span>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'actions') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\">\r\n @if (item.actions) {\r\n <div class=\"actions-container\">\r\n @for (action of item.actions; track action) {\r\n @if (!(action.hideFn ? action.hideFn(element) : action.hide)) {\r\n <button mat-icon-button\r\n (click)=\"action.onClickFn ? action.onClickFn(element) : ''\"\r\n (mousedown)=\"action.onClickMiddleFn ? action.onClickMiddleFn($event, element) : ''\"\r\n [disabled]=\"action.disabledFn ? action.disabledFn(element) : action.disabled\"\r\n [matTooltip]=\"action.tooltip ? action.tooltip : ''\" >\r\n @if (action.icon) {\r\n <mat-icon [class]=\"action.classList ? action.classList : ''\" >{{action.icon}}</mat-icon>\r\n }\r\n @if (action.symbol) {\r\n <span [class]=\"action.classList ? action.classList : ''\" >{{action.symbol}}</span>\r\n }\r\n {{ action.title }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n } \r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'image') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (element[item.name]) {\r\n <img\r\n [src]=\"element[item.name]\"\r\n [alt]=\"item.imageAlt && element[item.imageAlt] ? element[item.imageAlt] : ''\"\r\n [class]=\"item.classList ? item.classList : ''\"\r\n />\r\n } \r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n </ng-container>\r\n }\r\n\r\n <tr class=\"mat-row\" *matNoDataRow>\r\n <td class=\"mat-cell\" colspan=\"9999\">\r\n \u041D\u0435\u0442 \u0434\u0430\u043D\u043D\u044B\u0445 \u0434\u043B\u044F \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\r\n </td>\r\n </tr>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" \r\n (click)=\"onRowClicked(row)\" (dblclick)=\"onRowDblClicked(row)\" \r\n class=\"element-row\" [class.selected-row]=\"selection.isSelected(row)\">\r\n </tr>\r\n @if (footer()) {\r\n <tr mat-footer-row *matFooterRowDef=\"displayedColumns; sticky: true\"></tr>\r\n }\r\n </table>\r\n <div style=\"visibility: hidden; position: fixed\"\r\n [style.left]=\"contextMenuPosition.x\"\r\n [style.top]=\"contextMenuPosition.y\"\r\n [matMenuTriggerFor]=\"contextMenu\" #menuTrigger=\"matMenuTrigger\">\r\n </div>\r\n <mat-menu #contextMenu=\"matMenu\">\r\n <ng-template matMenuContent let-id=\"id\">\r\n @for (menuItem of opt(); track menuItem) {\r\n @if (menuItem.title === '-' && !(menuItem.hideFn ? menuItem.hideFn(itemForMenu) : menuItem.hide)) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (menuItem.title !== '-' && !(menuItem.hideFn ? menuItem.hideFn(itemForMenu) : menuItem.hide)) {\r\n <button mat-menu-item\r\n (click)=\"menuItem.onClickFn ? menuItem.onClickFn(itemForMenu) : ''\"\r\n (mousedown)=\"menuItem.onClickMiddleFn ? menuItem.onClickMiddleFn($event, itemForMenu, menuTrigger) : ''\"\r\n [disabled]=\"menuItem.disabledFn ? menuItem.disabledFn(itemForMenu) : menuItem.disabled\">\r\n @if (menuItem.icon) {\r\n <mat-icon [class]=\"menuItem.classList ? menuItem.classList : ''\">{{menuItem.icon}}</mat-icon>\r\n }\r\n @if (menuItem.symbol) {\r\n <span [class]=\"menuItem.classList ? menuItem.classList : ''\">{{menuItem.symbol}}</span>\r\n }\r\n {{ menuItem.title }}\r\n </button>\r\n }\r\n }\r\n </ng-template>\r\n </mat-menu>\r\n</div>\r\n\r\n\r\n<mat-paginator [length]=\"length()\"\r\n [pageIndex]=\"pageState().pageIndex || defaultPageIndex\"\r\n [pageSizeOptions]=\"[5, 10, 20, 50, 100]\"\r\n [pageSize]=\"pageState().pageSize || defaultPageSize\"\r\n showFirstLastButtons\r\n itemsPerPageLabel=\"\"\r\n></mat-paginator>\r\n</div>\r\n", styles: [".component-container{display:flex;flex-direction:column;height:100%}.table-container{display:flex;flex-direction:column;justify-content:space-between;flex:auto;margin:0 20px;overflow:auto;height:400px}.center{position:absolute;inset:0 0 56px;background:#00000026;z-index:1;display:flex;align-items:center;justify-content:center}.mat-column-select{overflow:initial}tr.mat-footer-row{font-weight:700;height:56px}.mat-table{overflow-x:scroll}.mat-cell,.mat-header-cell{word-wrap:initial;display:table-cell;padding:0 10px;line-break:unset;white-space:nowrap;overflow:hidden;vertical-align:middle}.mat-row,.mat-header-row{display:table-row}tr.element-row:not(.selected-row):hover{background:#f5f5f5}tr.element-row:not(.selected-row):active{background:#efefef}.selected-row{background-color:#eee}.fact-done-row{background-color:#eefdec}a,a:visited,a:hover,a:active{color:inherit}.pre-wrap{white-space:pre-wrap}.actions-container{display:flex;column-gap:5px}\n"], dependencies: [{ kind: "component", type: MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "directive", type: MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "component", type: MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "directive", type: MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: MatNoDataRow, selector: "ng-template[matNoDataRow]" }, { kind: "directive", type: MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "component", type: MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "directive", type: MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "component", type: MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "component", type: MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "directive", type: MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "component", type: MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "ngmodule", type: MatTableModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i1$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }] });
|
|
2238
|
-
}
|
|
2239
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TableComponent, decorators: [{
|
|
2240
|
-
type: Component,
|
|
2241
|
-
args: [{ selector: 'ngx-uik-table', imports: [MatTable, MatSort, MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCheckbox, MatCellDef, MatCell,
|
|
2242
|
-
MatSortHeader, MatIcon, RouterLink, MatNoDataRow, MatHeaderRowDef, MatHeaderRow, MatRowDef, MatRow,
|
|
2243
|
-
MatMenuTrigger, MatMenu, MatMenuContent, MatDivider, MatMenuItem, MatPaginator, MatFooterRowDef, MatFooterRow,
|
|
2244
|
-
MatFooterCellDef, MatFooterCell, MatTableModule, MatTooltipModule, MatIconButton], template: "<div class=\"component-container\">\r\n <div class=\"table-container\">\r\n <table mat-table [dataSource]=\"dataSource\"\r\n matSort\r\n [matSortActive]=\"sortState().sortActive || ''\"\r\n [matSortDirection]=\"sortState().sortDirection\"\r\n matSortDisableClear>\r\n\r\n <!-- \u0412\u044B\u0431\u043E\u0440 \u0441\u0442\u0440\u043E\u043A\u0438 Column -->\r\n <ng-container matColumnDef=\"select\">\r\n <th mat-header-cell *matHeaderCellDef>\r\n @if (allowMultiSelect()) {\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\" [checked]=\"selection.hasValue() && isAllSelected()\"\r\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\">\r\n </mat-checkbox>\r\n }\r\n </th>\r\n <td mat-cell *matCellDef=\"let row\">\r\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\">\r\n </mat-checkbox>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n }\r\n </ng-container>\r\n\r\n @for (item of columnOptions(); track item) {\r\n <ng-container matColumnDef={{item.name}}>\r\n <th mat-header-cell *matHeaderCellDef mat-sort-header [disabled]=\"item.titleSortDisable\">{{item.title}}</th>\r\n @if (!item.format) {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n {{element[item.name]}}\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footer) {\r\n <strong>{{ getTotal(item.name) }}</strong>\r\n }\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n } \r\n }\r\n @if (item.format === 'pre-wrap') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" class=\"pre-wrap\" [matTooltip]=\"item.tooltip ?? ''\">\r\n {{element[item.name]}}\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'link') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n <a [href]=\"element[item.name]\" target=\"_blank\">{{element[item.name]}}</a>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'linkIcon') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (element[item.name]) {\r\n <a [href]=\"element[item.name]\" target=\"_blank\">\r\n @if (item.icon) {\r\n <mat-icon [class]=\"item.classList ? item.classList : ''\" >{{item.icon}}</mat-icon>\r\n } \r\n @if (item.symbol) {\r\n <span [class]=\"item.classList ? item.classList : ''\" >{{item.symbol}}</span>\r\n }\r\n </a>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'routerLink') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n <a [routerLink]=\"[element[item.name]]\">{{element[item.name]}}</a>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'routerLinkIcon') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (element[item.name]) {\r\n <a [routerLink]=\"[element[item.name]]\">\r\n @if (item.icon) {\r\n <mat-icon [class]=\"item.classList ? item.classList : ''\" >{{item.icon}}</mat-icon>\r\n } \r\n @if (item.symbol) {\r\n <span [class]=\"item.classList ? item.classList : ''\" >{{item.symbol}}</span>\r\n }\r\n </a>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'checkbox') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n <mat-checkbox [checked]=\"element[item.name] === 1\" [disabled]=\"true\"></mat-checkbox>\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'icon') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (item.icon) {\r\n <mat-icon [class]=\"item.classList ? item.classList : ''\" >{{item.icon}}</mat-icon>\r\n } \r\n @if (item.symbol) {\r\n <span [class]=\"item.classList ? item.classList : ''\" >{{item.symbol}}</span>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'icons') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\">\r\n @if (item.icons) {\r\n <mat-icon [class]=\"item.classList ? item.classList[element[item.name]] : ''\" \r\n [matTooltip]=\"item.tooltips ? item.tooltips[element[item.name]] : ''\">{{item.icons[element[item.name]]}}</mat-icon>\r\n } \r\n @if (item.symbols) {\r\n <span [class]=\"item.classList ? item.classList[element[item.name]] : ''\" >{{item.symbols[element[item.name]]}}</span>\r\n }\r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'actions') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\">\r\n @if (item.actions) {\r\n <div class=\"actions-container\">\r\n @for (action of item.actions; track action) {\r\n @if (!(action.hideFn ? action.hideFn(element) : action.hide)) {\r\n <button mat-icon-button\r\n (click)=\"action.onClickFn ? action.onClickFn(element) : ''\"\r\n (mousedown)=\"action.onClickMiddleFn ? action.onClickMiddleFn($event, element) : ''\"\r\n [disabled]=\"action.disabledFn ? action.disabledFn(element) : action.disabled\"\r\n [matTooltip]=\"action.tooltip ? action.tooltip : ''\" >\r\n @if (action.icon) {\r\n <mat-icon [class]=\"action.classList ? action.classList : ''\" >{{action.icon}}</mat-icon>\r\n }\r\n @if (action.symbol) {\r\n <span [class]=\"action.classList ? action.classList : ''\" >{{action.symbol}}</span>\r\n }\r\n {{ action.title }}\r\n </button>\r\n }\r\n }\r\n </div>\r\n } \r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n @if (item.format === 'image') {\r\n <td mat-cell *matCellDef=\"let element\" (contextmenu)=\"onContextMenu($event, element)\" [matTooltip]=\"item.tooltip ?? ''\">\r\n @if (element[item.name]) {\r\n <img\r\n [src]=\"element[item.name]\"\r\n [alt]=\"item.imageAlt && element[item.imageAlt] ? element[item.imageAlt] : ''\"\r\n [class]=\"item.classList ? item.classList : ''\"\r\n />\r\n } \r\n </td>\r\n @if (footer()) {\r\n <td mat-footer-cell *matFooterCellDef>\r\n @if (item.footerTitle) {\r\n <strong>{{ item.footerTitle }}</strong>\r\n }\r\n </td>\r\n }\r\n }\r\n </ng-container>\r\n }\r\n\r\n <tr class=\"mat-row\" *matNoDataRow>\r\n <td class=\"mat-cell\" colspan=\"9999\">\r\n \u041D\u0435\u0442 \u0434\u0430\u043D\u043D\u044B\u0445 \u0434\u043B\u044F \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\r\n </td>\r\n </tr>\r\n\r\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\r\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" \r\n (click)=\"onRowClicked(row)\" (dblclick)=\"onRowDblClicked(row)\" \r\n class=\"element-row\" [class.selected-row]=\"selection.isSelected(row)\">\r\n </tr>\r\n @if (footer()) {\r\n <tr mat-footer-row *matFooterRowDef=\"displayedColumns; sticky: true\"></tr>\r\n }\r\n </table>\r\n <div style=\"visibility: hidden; position: fixed\"\r\n [style.left]=\"contextMenuPosition.x\"\r\n [style.top]=\"contextMenuPosition.y\"\r\n [matMenuTriggerFor]=\"contextMenu\" #menuTrigger=\"matMenuTrigger\">\r\n </div>\r\n <mat-menu #contextMenu=\"matMenu\">\r\n <ng-template matMenuContent let-id=\"id\">\r\n @for (menuItem of opt(); track menuItem) {\r\n @if (menuItem.title === '-' && !(menuItem.hideFn ? menuItem.hideFn(itemForMenu) : menuItem.hide)) {\r\n <mat-divider></mat-divider>\r\n }\r\n @if (menuItem.title !== '-' && !(menuItem.hideFn ? menuItem.hideFn(itemForMenu) : menuItem.hide)) {\r\n <button mat-menu-item\r\n (click)=\"menuItem.onClickFn ? menuItem.onClickFn(itemForMenu) : ''\"\r\n (mousedown)=\"menuItem.onClickMiddleFn ? menuItem.onClickMiddleFn($event, itemForMenu, menuTrigger) : ''\"\r\n [disabled]=\"menuItem.disabledFn ? menuItem.disabledFn(itemForMenu) : menuItem.disabled\">\r\n @if (menuItem.icon) {\r\n <mat-icon [class]=\"menuItem.classList ? menuItem.classList : ''\">{{menuItem.icon}}</mat-icon>\r\n }\r\n @if (menuItem.symbol) {\r\n <span [class]=\"menuItem.classList ? menuItem.classList : ''\">{{menuItem.symbol}}</span>\r\n }\r\n {{ menuItem.title }}\r\n </button>\r\n }\r\n }\r\n </ng-template>\r\n </mat-menu>\r\n</div>\r\n\r\n\r\n<mat-paginator [length]=\"length()\"\r\n [pageIndex]=\"pageState().pageIndex || defaultPageIndex\"\r\n [pageSizeOptions]=\"[5, 10, 20, 50, 100]\"\r\n [pageSize]=\"pageState().pageSize || defaultPageSize\"\r\n showFirstLastButtons\r\n itemsPerPageLabel=\"\"\r\n></mat-paginator>\r\n</div>\r\n", styles: [".component-container{display:flex;flex-direction:column;height:100%}.table-container{display:flex;flex-direction:column;justify-content:space-between;flex:auto;margin:0 20px;overflow:auto;height:400px}.center{position:absolute;inset:0 0 56px;background:#00000026;z-index:1;display:flex;align-items:center;justify-content:center}.mat-column-select{overflow:initial}tr.mat-footer-row{font-weight:700;height:56px}.mat-table{overflow-x:scroll}.mat-cell,.mat-header-cell{word-wrap:initial;display:table-cell;padding:0 10px;line-break:unset;white-space:nowrap;overflow:hidden;vertical-align:middle}.mat-row,.mat-header-row{display:table-row}tr.element-row:not(.selected-row):hover{background:#f5f5f5}tr.element-row:not(.selected-row):active{background:#efefef}.selected-row{background-color:#eee}.fact-done-row{background-color:#eefdec}a,a:visited,a:hover,a:active{color:inherit}.pre-wrap{white-space:pre-wrap}.actions-container{display:flex;column-gap:5px}\n"] }]
|
|
2245
|
-
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], columnOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnOptions", required: false }] }], tableState: [{ type: i0.Input, args: [{ isSignal: true, alias: "tableState", required: true }] }], allowMultiSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowMultiSelect", required: false }] }], opt: [{ type: i0.Input, args: [{ isSignal: true, alias: "opt", required: false }] }], rowDblClickedDisable: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowDblClickedDisable", required: false }] }], footer: [{ type: i0.Input, args: [{ isSignal: true, alias: "footer", required: false }] }], pageStateChange: [{ type: i0.Output, args: ["pageStateChange"] }], sortStateChange: [{ type: i0.Output, args: ["sortStateChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], rowDoubleClicked: [{ type: i0.Output, args: ["rowDoubleClicked"] }], sort: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatSort), { isSignal: true }] }], paginator: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatPaginator), { isSignal: true }] }], contextMenu: [{ type: i0.ViewChild, args: [i0.forwardRef(() => MatMenuTrigger), { isSignal: true }] }] } });
|
|
2246
|
-
|
|
2247
|
-
/*
|
|
2248
|
-
* Public API Surface of uikit
|
|
2249
|
-
*/
|
|
2250
|
-
|
|
2251
298
|
/**
|
|
2252
299
|
* Generated bundle index. Do not edit.
|
|
2253
300
|
*/
|
|
2254
301
|
|
|
2255
|
-
export {
|
|
302
|
+
export { API_NAME, AuthEventService, AuthService, BYPASS_AUTH, NotificationService, RoleService, UIKIT_CONFIG, UIKIT_NOTIFICATION_TOKEN, User, UserService };
|
|
2256
303
|
//# sourceMappingURL=kuzntsv-uikit.mjs.map
|