This commit is contained in:
Adina Țeudan 2021-10-05 22:22:15 +03:00
parent 5b6f35cbc1
commit 4becbfa80c
8 changed files with 93 additions and 56 deletions

View File

@ -1,9 +1,15 @@
{ {
"extends": ["../../.eslintrc.json"], "extends": [
"ignorePatterns": ["!**/*"], "../../.eslintrc.json"
],
"ignorePatterns": [
"!**/*"
],
"overrides": [ "overrides": [
{ {
"files": ["*.ts"], "files": [
"*.ts"
],
"extends": [ "extends": [
"plugin:@nrwl/nx/angular", "plugin:@nrwl/nx/angular",
"plugin:@angular-eslint/template/process-inline-templates", "plugin:@angular-eslint/template/process-inline-templates",
@ -14,7 +20,9 @@
"plugin:@angular-eslint/recommended--extra" "plugin:@angular-eslint/recommended--extra"
], ],
"parserOptions": { "parserOptions": {
"project": ["libs/common-ui/tsconfig.*?.json"] "project": [
"libs/common-ui/tsconfig.*?.json"
]
}, },
"rules": { "rules": {
"@angular-eslint/directive-selector": [ "@angular-eslint/directive-selector": [
@ -47,20 +55,33 @@
"error", "error",
{ {
"selector": "memberLike", "selector": "memberLike",
"modifiers": ["private"], "modifiers": [
"format": ["camelCase"], "private"
],
"format": [
"camelCase"
],
"leadingUnderscore": "require" "leadingUnderscore": "require"
}, },
{ {
"selector": "memberLike", "selector": "memberLike",
"modifiers": ["protected"], "modifiers": [
"format": ["camelCase"], "protected"
],
"format": [
"camelCase"
],
"leadingUnderscore": "require" "leadingUnderscore": "require"
}, },
{ {
"selector": "memberLike", "selector": "memberLike",
"modifiers": ["private"], "modifiers": [
"format": ["UPPER_CASE", "camelCase"], "private"
],
"format": [
"UPPER_CASE",
"camelCase"
],
"leadingUnderscore": "require" "leadingUnderscore": "require"
} }
], ],
@ -68,14 +89,27 @@
"no-underscore-dangle": "off", "no-underscore-dangle": "off",
"no-param-reassign": "error", "no-param-reassign": "error",
"consistent-return": "off", "consistent-return": "off",
"class-methods-use-this": "off" "class-methods-use-this": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/restrict-template-expressions": "off"
}, },
"plugins": ["@angular-eslint/eslint-plugin", "@typescript-eslint"] "plugins": [
"@angular-eslint/eslint-plugin",
"@typescript-eslint"
]
}, },
{ {
"files": ["*.html"], "files": [
"extends": ["plugin:@nrwl/nx/angular-template", "plugin:@angular-eslint/template/recommended"], "*.html"
"plugins": ["prettier"], ],
"extends": [
"plugin:@nrwl/nx/angular-template",
"plugin:@angular-eslint/template/recommended"
],
"plugins": [
"prettier"
],
"rules": {} "rules": {}
} }
] ]

View File

@ -26,8 +26,8 @@ function backoffOnServerError(maxRetries = 3): MonoTypeOperatorFunction<HttpEven
console.error(`Retrying in ${seconds} seconds...`); console.error(`Retrying in ${seconds} seconds...`);
return timer(seconds * 1000); return timer(seconds * 1000);
} }
}) }),
) ),
); );
} }
@ -35,7 +35,7 @@ function backoffOnServerError(maxRetries = 3): MonoTypeOperatorFunction<HttpEven
export class ServerErrorInterceptor implements HttpInterceptor { export class ServerErrorInterceptor implements HttpInterceptor {
constructor( constructor(
private readonly _errorService: ErrorService, private readonly _errorService: ErrorService,
@Optional() @Inject(MAX_RETRIES_ON_SERVER_ERROR) private readonly _maxRetries: number @Optional() @Inject(MAX_RETRIES_ON_SERVER_ERROR) private readonly _maxRetries: number,
) {} ) {}
intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
@ -46,7 +46,7 @@ export class ServerErrorInterceptor implements HttpInterceptor {
} }
return throwError(error); return throwError(error);
}), }),
backoffOnServerError(this._maxRetries || 3) backoffOnServerError(this._maxRetries || 3),
); );
} }
} }

View File

@ -1,8 +1,8 @@
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
import { INestedFilter } from "./models/nested-filter.model"; import { INestedFilter } from './models/nested-filter.model';
import { IFilterGroup } from "./models/filter-group.model"; import { IFilterGroup } from './models/filter-group.model';
import { IFilter } from "./models/filter.model"; import { IFilter } from './models/filter.model';
import { NestedFilter } from "./models/nested-filter"; import { NestedFilter } from './models/nested-filter';
function copySettings(oldFilters: INestedFilter[], newFilters: INestedFilter[]) { function copySettings(oldFilters: INestedFilter[], newFilters: INestedFilter[]) {
if (!oldFilters || !newFilters) { if (!oldFilters || !newFilters) {
@ -50,7 +50,7 @@ export function checkFilter(
validate?: (...args: unknown[]) => boolean, validate?: (...args: unknown[]) => boolean,
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
validateArgs: any = [], validateArgs: any = [],
matchAll = false matchAll = false,
): boolean { ): boolean {
const hasChecked = filters.find(f => f.checked); const hasChecked = filters.find(f => f.checked);
@ -72,8 +72,8 @@ export function checkFilter(
return filterMatched; return filterMatched;
} }
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const keyChecker = (key: string) => (entity: Record<string, string>, filter: INestedFilter) =>
export const keyChecker = (key: string) => (entity: Record<string, string>, filter: INestedFilter) => entity[key] === filter.id; entity[key] === filter.id;
export function getFilteredEntities<T>(entities: T[], filters: IFilterGroup[]): T[] { export function getFilteredEntities<T>(entities: T[], filters: IFilterGroup[]): T[] {
const filteredEntities: T[] = []; const filteredEntities: T[] = [];

View File

@ -39,7 +39,10 @@ export class EntitiesService<E extends IListable, I = E> extends GenericService<
private _displayed: E[] = []; private _displayed: E[] = [];
private readonly _selected$ = new BehaviorSubject<(string | number)[]>([]); private readonly _selected$ = new BehaviorSubject<(string | number)[]>([]);
constructor(protected readonly _injector: Injector, @Optional() @Inject(ENTITY_PATH) protected readonly _defaultModelPath = '') { constructor(
protected readonly _injector: Injector,
@Optional() @Inject(ENTITY_PATH) protected readonly _defaultModelPath = '',
) {
super(_injector, _defaultModelPath); super(_injector, _defaultModelPath);
this.all$ = this._all$.asObservable(); this.all$ = this._all$.asObservable();
this.allLength$ = this._all$.pipe(getLength); this.allLength$ = this._all$.pipe(getLength);
@ -75,35 +78,35 @@ export class EntitiesService<E extends IListable, I = E> extends GenericService<
map(entities => this._searchService.searchIn(entities)), map(entities => this._searchService.searchIn(entities)),
tap(displayed => { tap(displayed => {
this._displayed = displayed; this._displayed = displayed;
}) }),
); );
} }
private get _areAllSelected$(): Observable<boolean> { private get _areAllSelected$(): Observable<boolean> {
return combineLatest([this.displayedLength$, this.selectedLength$]).pipe( return combineLatest([this.displayedLength$, this.selectedLength$]).pipe(
map(([displayedLength, selectedLength]) => !!displayedLength && displayedLength === selectedLength), map(([displayedLength, selectedLength]) => !!displayedLength && displayedLength === selectedLength),
distinctUntilChanged() distinctUntilChanged(),
); );
} }
private get _areSomeSelected$(): Observable<boolean> { private get _areSomeSelected$(): Observable<boolean> {
return this.selectedLength$.pipe( return this.selectedLength$.pipe(
map(length => !!length), map(length => !!length),
distinctUntilChanged() distinctUntilChanged(),
); );
} }
private get _notAllSelected$(): Observable<boolean> { private get _notAllSelected$(): Observable<boolean> {
return combineLatest([this.areAllSelected$, this.areSomeSelected$]).pipe( return combineLatest([this.areAllSelected$, this.areSomeSelected$]).pipe(
map(([allAreSelected, someAreSelected]) => !allAreSelected && someAreSelected), map(([allAreSelected, someAreSelected]) => !allAreSelected && someAreSelected),
distinctUntilChanged() distinctUntilChanged(),
); );
} }
private get _noData$(): Observable<boolean> { private get _noData$(): Observable<boolean> {
return this.allLength$.pipe( return this.allLength$.pipe(
map(length => length === 0), map(length => length === 0),
distinctUntilChanged() distinctUntilChanged(),
); );
} }

View File

@ -7,7 +7,7 @@ export type TitleColor = 'default' | 'primary';
export enum TitleColors { export enum TitleColors {
DEFAULT = 'default', DEFAULT = 'default',
PRIMARY = 'primary' PRIMARY = 'primary',
} }
export class ConfirmationDialogInput { export class ConfirmationDialogInput {
@ -37,7 +37,7 @@ export class ConfirmationDialogInput {
@Component({ @Component({
templateUrl: './confirmation-dialog.component.html', templateUrl: './confirmation-dialog.component.html',
styleUrls: ['./confirmation-dialog.component.scss'], styleUrls: ['./confirmation-dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class ConfirmationDialogComponent { export class ConfirmationDialogComponent {
config: ConfirmationDialogInput; config: ConfirmationDialogInput;
@ -47,11 +47,11 @@ export class ConfirmationDialogComponent {
constructor( constructor(
private readonly _dialogRef: MatDialogRef<ConfirmationDialogComponent>, private readonly _dialogRef: MatDialogRef<ConfirmationDialogComponent>,
private readonly _translateService: TranslateService, private readonly _translateService: TranslateService,
@Inject(MAT_DIALOG_DATA) private readonly _confirmationDialogInput: ConfirmationDialogInput @Inject(MAT_DIALOG_DATA) private readonly _confirmationDialogInput: ConfirmationDialogInput,
) { ) {
this.config = _confirmationDialogInput ?? new ConfirmationDialogInput(); this.config = _confirmationDialogInput ?? new ConfirmationDialogInput();
this.translate(this.config); this.translate(this.config);
this.inputLabel = `${this._translateService.instant('confirmation-dialog.input-label') as string} '${ this.inputLabel = `${this._translateService.instant('confirmation-dialog.input-label')} '${
this.config.confirmationText || '' this.config.confirmationText || ''
}'`; }'`;
} }
@ -86,14 +86,14 @@ export class ConfirmationDialogComponent {
'details', 'details',
'confirmationText', 'confirmationText',
'alternativeConfirmationText', 'alternativeConfirmationText',
'denyText' 'denyText',
]; ];
translateKeys translateKeys
.filter(key => !!obj[key]) .filter(key => !!obj[key])
.forEach(key => { .forEach(key => {
Object.assign(obj, { Object.assign(obj, {
[key]: this._translateService.instant(obj[key] as string, this.config.translateParams) as string [key]: this._translateService.instant(obj[key] as string, this.config.translateParams) as string,
}); });
}); });
} }

View File

@ -3,7 +3,7 @@ import { TranslateService } from '@ngx-translate/core';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root',
}) })
export class ErrorMessageService { export class ErrorMessageService {
constructor(private readonly _translateService: TranslateService) {} constructor(private readonly _translateService: TranslateService) {}
@ -13,8 +13,6 @@ export class ErrorMessageService {
} }
private _parseErrorResponse(err: HttpErrorResponse): string { private _parseErrorResponse(err: HttpErrorResponse): string {
// eslint-disable-next-line max-len
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/restrict-template-expressions
return err?.error?.message?.includes('message') ? ` ${err.error.message.match('"message":"(.*?)\\"')[1]}` : ''; return err?.error?.message?.includes('message') ? ` ${err.error.message.match('"message":"(.*?)\\"')[1]}` : '';
} }
} }

View File

@ -24,12 +24,16 @@ export abstract class GenericService<Entity> {
getAll<R = Entity>(modelPath = this._defaultModelPath): Observable<R[]> { getAll<R = Entity>(modelPath = this._defaultModelPath): Observable<R[]> {
return this._http.get<R[]>(`/${encodeURI(modelPath)}`, { return this._http.get<R[]>(`/${encodeURI(modelPath)}`, {
headers: HeadersConfiguration.getHeaders({ contentType: false }), headers: HeadersConfiguration.getHeaders({ contentType: false }),
observe: 'body' observe: 'body',
}); });
} }
@Validate() @Validate()
delete(@RequiredParam() body: unknown, modelPath = this._defaultModelPath, queryParams?: List<QueryParam>): Observable<unknown> { delete(
@RequiredParam() body: unknown,
modelPath = this._defaultModelPath,
queryParams?: List<QueryParam>,
): Observable<unknown> {
let path = `/${encodeURI(modelPath)}`; let path = `/${encodeURI(modelPath)}`;
if (typeof body === 'string') { if (typeof body === 'string') {
@ -40,7 +44,7 @@ export abstract class GenericService<Entity> {
body: body, body: body,
params: this._queryParams(queryParams), params: this._queryParams(queryParams),
headers: HeadersConfiguration.getHeaders({ contentType: false }), headers: HeadersConfiguration.getHeaders({ contentType: false }),
observe: 'body' observe: 'body',
}); });
} }
@ -48,12 +52,12 @@ export abstract class GenericService<Entity> {
protected _post<R = Entity>( protected _post<R = Entity>(
@RequiredParam() body: unknown, @RequiredParam() body: unknown,
modelPath = this._defaultModelPath, modelPath = this._defaultModelPath,
queryParams?: List<QueryParam> queryParams?: List<QueryParam>,
): Observable<R> { ): Observable<R> {
return this._http.post<R>(`/${encodeURI(modelPath)}`, body, { return this._http.post<R>(`/${encodeURI(modelPath)}`, body, {
params: this._queryParams(queryParams), params: this._queryParams(queryParams),
headers: HeadersConfiguration.getHeaders(), headers: HeadersConfiguration.getHeaders(),
observe: 'body' observe: 'body',
}); });
} }
@ -61,12 +65,12 @@ export abstract class GenericService<Entity> {
protected _put<R = Entity>( protected _put<R = Entity>(
@RequiredParam() body: unknown, @RequiredParam() body: unknown,
modelPath = this._defaultModelPath, modelPath = this._defaultModelPath,
queryParams?: List<QueryParam> queryParams?: List<QueryParam>,
): Observable<R> { ): Observable<R> {
return this._http.put<R>(`/${encodeURI(modelPath)}`, body, { return this._http.put<R>(`/${encodeURI(modelPath)}`, body, {
params: this._queryParams(queryParams), params: this._queryParams(queryParams),
headers: HeadersConfiguration.getHeaders(), headers: HeadersConfiguration.getHeaders(),
observe: 'body' observe: 'body',
}); });
} }
@ -74,14 +78,14 @@ export abstract class GenericService<Entity> {
protected _getOne<R = Entity>( protected _getOne<R = Entity>(
@RequiredParam() path: List, @RequiredParam() path: List,
modelPath = this._defaultModelPath, modelPath = this._defaultModelPath,
queryParams?: List<QueryParam> queryParams?: List<QueryParam>,
): Observable<R> { ): Observable<R> {
const entityPath = path.map(item => encodeURIComponent(item)).join('/'); const entityPath = path.map(item => encodeURIComponent(item)).join('/');
return this._http.get<R>(`/${encodeURI(modelPath)}/${entityPath}`, { return this._http.get<R>(`/${encodeURI(modelPath)}/${entityPath}`, {
headers: HeadersConfiguration.getHeaders({ contentType: false }), headers: HeadersConfiguration.getHeaders({ contentType: false }),
params: this._queryParams(queryParams), params: this._queryParams(queryParams),
observe: 'body' observe: 'body',
}); });
} }

View File

@ -39,15 +39,13 @@ export class CustomRouteReuseStrategy implements RouteReuseStrategy {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const element: any = handle; const element: any = handle;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (element?.componentRef?.instance?.ngOnDetach) { if (element?.componentRef?.instance?.ngOnDetach) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
this._onDetach(element.componentRef?.instance); this._onDetach(element.componentRef?.instance);
} }
this._storedRoutes[this._getKey(route)] = { this._storedRoutes[this._getKey(route)] = {
handle: element as DetachedRouteHandle, handle: element as DetachedRouteHandle,
previousRoute: route previousRoute: route,
}; };
} }
@ -60,9 +58,7 @@ export class CustomRouteReuseStrategy implements RouteReuseStrategy {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const element: any = this._storedRoutes[key]?.handle; const element: any = this._storedRoutes[key]?.handle;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (element?.componentRef?.instance?.ngOnAttach) { if (element?.componentRef?.instance?.ngOnAttach) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
this._onAttach(element.componentRef?.instance, this._storedRoutes[key].previousRoute); this._onAttach(element.componentRef?.instance, this._storedRoutes[key].previousRoute);
} }
@ -75,7 +71,9 @@ export class CustomRouteReuseStrategy implements RouteReuseStrategy {
private _getKey(route: ActivatedRouteSnapshot): string { private _getKey(route: ActivatedRouteSnapshot): string {
return route.pathFromRoot return route.pathFromRoot
.map((el: ActivatedRouteSnapshot) => (el.routeConfig ? (el.routeConfig.path as string) + JSON.stringify(el.params) : '')) .map((el: ActivatedRouteSnapshot) =>
el.routeConfig ? el.routeConfig.path + JSON.stringify(el.params) : '',
)
.filter(str => str.length > 0) .filter(str => str.length > 0)
.join(''); .join('');
} }