Browse Source

fix: strict mode errors

pull/10581/head
bnymncoskuner 5 years ago
parent
commit
1f69b828ce
  1. 8
      npm/ng-packs/apps/dev-app/tsconfig.json
  2. 10
      npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts
  3. 8
      npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts
  4. 10
      npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts
  5. 2
      npm/ng-packs/packages/core/src/lib/models/common.ts
  6. 4
      npm/ng-packs/packages/core/src/lib/models/replaceable-components.ts
  7. 23
      npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts
  8. 8
      npm/ng-packs/packages/core/src/lib/services/config-state.service.ts
  9. 4
      npm/ng-packs/packages/core/src/lib/services/environment.service.ts
  10. 2
      npm/ng-packs/packages/core/src/lib/services/http-error-reporter.service.ts
  11. 2
      npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts
  12. 10
      npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts
  13. 2
      npm/ng-packs/packages/tenant-management/src/lib/defaults/default-tenants-toolbar-actions.ts
  14. 2
      npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.html
  15. 2
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts
  16. 6
      npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts
  17. 4
      npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.ts
  18. 2
      npm/ng-packs/packages/theme-basic/src/lib/components/validation-error/validation-error.component.ts
  19. 6
      npm/ng-packs/packages/theme-basic/src/lib/services/layout.service.ts
  20. 9
      npm/ng-packs/packages/theme-shared/extensions/src/lib/adapters/date-time.adapter.ts
  21. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/adapters/date.adapter.ts
  22. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/adapters/time.adapter.ts
  23. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/abstract-actions/abstract-actions.component.ts
  24. 6
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/date-time-picker/date-time-picker.component.ts
  25. 18
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts
  26. 6
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts
  27. 6
      npm/ng-packs/packages/theme-shared/extensions/src/lib/directives/prop-data.directive.ts
  28. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/actions.ts
  29. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/props.ts
  30. 4
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/toolbar-actions.ts
  31. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/enum.util.ts
  32. 9
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/state.util.ts
  33. 16
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/typeahead.util.ts
  34. 5
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/validation.util.ts
  35. 3
      npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.ts
  36. 12
      npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts
  37. 4
      npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts
  38. 24
      npm/ng-packs/packages/theme-shared/src/lib/components/http-error-wrapper/http-error-wrapper.component.ts
  39. 2
      npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts
  40. 2
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-ref.service.ts
  41. 4
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html
  42. 38
      npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts
  43. 14
      npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.ts
  44. 2
      npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.html
  45. 4
      npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts
  46. 4
      npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts
  47. 12
      npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts
  48. 2
      npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts
  49. 74
      npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts
  50. 10
      npm/ng-packs/packages/theme-shared/src/lib/handlers/lazy-style.handler.ts
  51. 2
      npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts
  52. 6
      npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts
  53. 4
      npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts
  54. 7
      npm/ng-packs/packages/theme-shared/src/lib/utils/date-parser-formatter.ts
  55. 1
      npm/ng-packs/tsconfig.json

8
npm/ng-packs/apps/dev-app/tsconfig.json

@ -15,14 +15,14 @@
], ],
"compilerOptions": { "compilerOptions": {
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"strict": false, "strict": true,
"noImplicitReturns": false, "noImplicitReturns": false,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true
}, },
"angularCompilerOptions": { "angularCompilerOptions": {
"strictInjectionParameters": true, "strictInjectionParameters": true,
"strictInputAccessModifiers": false, "strictInputAccessModifiers": true,
"strictTemplates": false "strictTemplates": true
} }
} }

10
npm/ng-packs/packages/core/src/lib/directives/autofocus.directive.ts

@ -5,8 +5,16 @@ import { AfterViewInit, Directive, ElementRef, Input } from '@angular/core';
selector: '[autofocus]', selector: '[autofocus]',
}) })
export class AutofocusDirective implements AfterViewInit { export class AutofocusDirective implements AfterViewInit {
private _delay = 0;
@Input('autofocus') @Input('autofocus')
delay = 0; set delay(val: number | undefined) {
this._delay = val ?? 0;
}
get delay() {
return this._delay;
}
constructor(private elRef: ElementRef) {} constructor(private elRef: ElementRef) {}

8
npm/ng-packs/packages/core/src/lib/directives/permission.directive.ts

@ -1,12 +1,10 @@
import { import {
ChangeDetectorRef, ChangeDetectorRef,
Directive, Directive,
ElementRef,
Input, Input,
OnChanges, OnChanges,
OnDestroy, OnDestroy,
Optional, Optional,
Renderer2,
TemplateRef, TemplateRef,
ViewContainerRef, ViewContainerRef,
} from '@angular/core'; } from '@angular/core';
@ -18,13 +16,11 @@ import { PermissionService } from '../services/permission.service';
selector: '[abpPermission]', selector: '[abpPermission]',
}) })
export class PermissionDirective implements OnDestroy, OnChanges { export class PermissionDirective implements OnDestroy, OnChanges {
@Input('abpPermission') condition: string; @Input('abpPermission') condition!: string;
subscription: Subscription; subscription!: Subscription;
constructor( constructor(
private elRef: ElementRef<HTMLElement>,
private renderer: Renderer2,
@Optional() private templateRef: TemplateRef<any>, @Optional() private templateRef: TemplateRef<any>,
private vcRef: ViewContainerRef, private vcRef: ViewContainerRef,
private permissionService: PermissionService, private permissionService: PermissionService,

10
npm/ng-packs/packages/core/src/lib/directives/replaceable-template.directive.ts

@ -24,7 +24,7 @@ import { SubscriptionService } from '../services/subscription.service';
}) })
export class ReplaceableTemplateDirective implements OnInit, OnChanges { export class ReplaceableTemplateDirective implements OnInit, OnChanges {
@Input('abpReplaceableTemplate') @Input('abpReplaceableTemplate')
data: ReplaceableComponents.ReplaceableTemplateDirectiveInput<any, any>; data!: ReplaceableComponents.ReplaceableTemplateDirectiveInput<any, any>;
providedData = { providedData = {
inputs: {}, inputs: {},
@ -33,7 +33,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
context = {} as any; context = {} as any;
externalComponent: Type<any>; externalComponent!: Type<any>;
defaultComponentRef: any; defaultComponentRef: any;
@ -50,7 +50,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
private subscription: SubscriptionService, private subscription: SubscriptionService,
) { ) {
this.context = { this.context = {
initTemplate: ref => { initTemplate: (ref: any) => {
this.resetDefaultComponent(); this.resetDefaultComponent();
this.defaultComponentRef = ref; this.defaultComponentRef = ref;
this.setDefaultComponentInputs(); this.setDefaultComponentInputs();
@ -121,7 +121,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
if (Object.prototype.hasOwnProperty.call(this.data.outputs, key)) { if (Object.prototype.hasOwnProperty.call(this.data.outputs, key)) {
if (!this.defaultComponentSubscriptions[key]) { if (!this.defaultComponentSubscriptions[key]) {
this.defaultComponentSubscriptions[key] = this.defaultComponentRef[key].subscribe( this.defaultComponentSubscriptions[key] = this.defaultComponentRef[key].subscribe(
value => { (value: any) => {
this.data.outputs[key](value); this.data.outputs[key](value);
}, },
); );
@ -144,7 +144,7 @@ export class ReplaceableTemplateDirective implements OnInit, OnChanges {
configurable: true, configurable: true,
get: () => this.data.inputs[key].value, get: () => this.data.inputs[key].value,
...(this.data.inputs[key].twoWay && { ...(this.data.inputs[key].twoWay && {
set: newValue => { set: (newValue: any) => {
this.data.inputs[key].value = newValue; this.data.inputs[key].value = newValue;
this.data.outputs[`${key}Change`](newValue); this.data.outputs[`${key}Change`](newValue);
}, },

2
npm/ng-packs/packages/core/src/lib/models/common.ts

@ -52,7 +52,7 @@ export namespace ABP {
} }
export interface Route extends Nav { export interface Route extends Nav {
path: string; path?: string;
layout?: eLayoutType; layout?: eLayoutType;
iconClass?: string; iconClass?: string;
} }

4
npm/ng-packs/packages/core/src/lib/models/replaceable-components.ts

@ -16,8 +16,8 @@ export namespace ReplaceableComponents {
I, I,
O extends { [K in keyof O]: EventEmitter<any> | Subject<any> }, O extends { [K in keyof O]: EventEmitter<any> | Subject<any> },
> { > {
inputs: { -readonly [K in keyof I]: { value: I[K]; twoWay?: boolean } }; inputs?: { -readonly [K in keyof I]: { value: I[K]; twoWay?: boolean } };
outputs: { -readonly [K in keyof O]: (value: ABP.ExtractFromOutput<O[K]>) => void }; outputs?: { -readonly [K in keyof O]: (value: ABP.ExtractFromOutput<O[K]>) => void };
componentKey: string; componentKey: string;
} }

23
npm/ng-packs/packages/core/src/lib/pipes/localization.pipe.ts

@ -9,13 +9,20 @@ import { LocalizationService } from '../services/localization.service';
export class LocalizationPipe implements PipeTransform { export class LocalizationPipe implements PipeTransform {
constructor(private localization: LocalizationService) {} constructor(private localization: LocalizationService) {}
transform(value: string | LocalizationWithDefault = '', ...interpolateParams: string[]): string { transform(
return this.localization.instant( value: string | LocalizationWithDefault = '',
value, ...interpolateParams: (string | string[] | undefined)[]
...interpolateParams.reduce( ): string {
(acc, val) => (Array.isArray(val) ? [...acc, ...val] : [...acc, val]), const params =
[], interpolateParams.reduce((acc, val) => {
), if (!acc) {
); return val;
}
if (!val) {
return acc;
}
return Array.isArray(val) ? [...acc, ...val] : [...acc, val];
}, []) || [];
return this.localization.instant(value, ...params);
} }
} }

8
npm/ng-packs/packages/core/src/lib/services/config-state.service.ts

@ -48,14 +48,14 @@ export class ConfigStateService {
return this.store.state; return this.store.state;
} }
getDeep$(keys: string[] | string) { getDeep$(keys: string[] | string): Observable<any> {
keys = splitKeys(keys); keys = splitKeys(keys);
return this.store return this.store
.sliceState(state => state) .sliceState(state => state)
.pipe( .pipe(
map(state => { map(state => {
return (keys as string[]).reduce((acc, val) => { return (keys as string[]).reduce((acc: any, val) => {
if (acc) { if (acc) {
return acc[val]; return acc[val];
} }
@ -66,10 +66,10 @@ export class ConfigStateService {
); );
} }
getDeep(keys: string[] | string) { getDeep(keys: string[] | string): any {
keys = splitKeys(keys); keys = splitKeys(keys);
return (keys as string[]).reduce((acc, val) => { return (keys as string[]).reduce((acc: any, val) => {
if (acc) { if (acc) {
return acc[val]; return acc[val];
} }

4
npm/ng-packs/packages/core/src/lib/services/environment.service.ts

@ -23,11 +23,11 @@ export class EnvironmentService {
return this.store.state; return this.store.state;
} }
getApiUrl(key?: string) { getApiUrl(key: string) {
return mapToApiUrl(key)(this.store.state.apis); return mapToApiUrl(key)(this.store.state.apis);
} }
getApiUrl$(key?: string) { getApiUrl$(key: string) {
return this.store.sliceState(state => state.apis).pipe(map(mapToApiUrl(key))); return this.store.sliceState(state => state.apis).pipe(map(mapToApiUrl(key)));
} }

2
npm/ng-packs/packages/core/src/lib/services/http-error-reporter.service.ts

@ -4,7 +4,7 @@ import { BehaviorSubject, Subject } from 'rxjs';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class HttpErrorReporterService { export class HttpErrorReporterService {
private _reporter$ = new Subject(); private _reporter$ = new Subject<HttpErrorResponse>();
private _errors$ = new BehaviorSubject<HttpErrorResponse[]>([]); private _errors$ = new BehaviorSubject<HttpErrorResponse[]>([]);
get reporter$() { get reporter$() {

2
npm/ng-packs/packages/core/src/lib/services/lazy-load.service.ts

@ -8,7 +8,7 @@ import { ResourceWaitService } from './resource-wait.service';
providedIn: 'root', providedIn: 'root',
}) })
export class LazyLoadService { export class LazyLoadService {
readonly loaded = new Map<string, HTMLScriptElement | HTMLLinkElement>(); readonly loaded = new Map<string, HTMLScriptElement | HTMLLinkElement | null>();
constructor(private resourceWaitService: ResourceWaitService) {} constructor(private resourceWaitService: ResourceWaitService) {}

10
npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts

@ -26,18 +26,16 @@ import { eTenantManagementComponents } from '../../enums/components';
export class TenantsComponent implements OnInit { export class TenantsComponent implements OnInit {
data: PagedResultDto<TenantDto> = { items: [], totalCount: 0 }; data: PagedResultDto<TenantDto> = { items: [], totalCount: 0 };
selected: TenantDto; selected!: TenantDto;
tenantForm: FormGroup; tenantForm!: FormGroup;
isModalVisible: boolean; isModalVisible!: boolean;
visibleFeatures = false; visibleFeatures = false;
providerKey: string; providerKey: string;
_useSharedDatabase: boolean;
modalBusy = false; modalBusy = false;
featureManagementKey = eFeatureManagementComponents.FeatureManagement; featureManagementKey = eFeatureManagementComponents.FeatureManagement;
@ -142,7 +140,7 @@ export class TenantsComponent implements OnInit {
}, 0); }, 0);
} }
sort(data) { sort(data: any) {
const { prop, dir } = data.sorts[0]; const { prop, dir } = data.sorts[0];
this.list.sortKey = prop; this.list.sortKey = prop;
this.list.sortOrder = dir; this.list.sortOrder = dir;

2
npm/ng-packs/packages/tenant-management/src/lib/defaults/default-tenants-toolbar-actions.ts

@ -7,7 +7,7 @@ export const DEFAULT_TENANTS_TOOLBAR_ACTIONS = ToolbarAction.createMany<TenantDt
text: 'AbpTenantManagement::ManageHostFeatures', text: 'AbpTenantManagement::ManageHostFeatures',
action: data => { action: data => {
const component = data.getInjected(TenantsComponent); const component = data.getInjected(TenantsComponent);
component.openFeaturesModal(null); component.openFeaturesModal('');
}, },
permission: 'FeatureManagement.ManageHostFeatures', permission: 'FeatureManagement.ManageHostFeatures',
icon: 'fa fa-cog', icon: 'fa fa-cog',

2
npm/ng-packs/packages/theme-basic/src/lib/components/account-layout/tenant-box/tenant-box.component.html

@ -1,4 +1,4 @@
<ng-container *ngIf="(service.currentTenant$ | async) || {} as currentTenant"> <ng-container *ngIf="(service.currentTenant$ | async) || { name: '' } as currentTenant">
<div class="card shadow-sm rounded mb-3"> <div class="card shadow-sm rounded mb-3">
<div class="card-body px-5"> <div class="card-body px-5">
<div class="row"> <div class="row">

2
npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/current-user.component.ts

@ -21,7 +21,7 @@ export class CurrentUserComponent {
} }
constructor( constructor(
@Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile, @Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile: () => void,
private authService: AuthService, private authService: AuthService,
private configState: ConfigStateService, private configState: ConfigStateService,
private sessionState: SessionStateService, private sessionState: SessionStateService,

6
npm/ng-packs/packages/theme-basic/src/lib/components/nav-items/languages.component.ts

@ -7,7 +7,7 @@ import { map } from 'rxjs/operators';
selector: 'abp-languages', selector: 'abp-languages',
template: ` template: `
<div <div
*ngIf="(dropdownLanguages$ | async)?.length > 0" *ngIf="(dropdownLanguages$ | async).length > 0"
class="dropdown" class="dropdown"
ngbDropdown ngbDropdown
#languageDropdown="ngbDropdown" #languageDropdown="ngbDropdown"
@ -34,7 +34,7 @@ import { map } from 'rxjs/operators';
*ngFor="let lang of dropdownLanguages$ | async" *ngFor="let lang of dropdownLanguages$ | async"
href="javascript:void(0)" href="javascript:void(0)"
class="dropdown-item" class="dropdown-item"
(click)="onChangeLang(lang.cultureName)" (click)="onChangeLang(lang.cultureName || '')"
>{{ lang?.displayName }}</a >{{ lang?.displayName }}</a
> >
</div> </div>
@ -52,7 +52,7 @@ export class LanguagesComponent {
return this.languages$.pipe( return this.languages$.pipe(
map( map(
languages => languages =>
languages?.find(lang => lang.cultureName === this.selectedLangCulture).displayName || '', languages?.find(lang => lang.cultureName === this.selectedLangCulture)?.displayName || '',
), ),
); );
} }

4
npm/ng-packs/packages/theme-basic/src/lib/components/routes/routes.component.ts

@ -14,9 +14,9 @@ import {
templateUrl: 'routes.component.html', templateUrl: 'routes.component.html',
}) })
export class RoutesComponent { export class RoutesComponent {
@Input() smallScreen: boolean; @Input() smallScreen?: boolean;
@ViewChildren('childrenContainer') childrenContainers: QueryList<ElementRef<HTMLDivElement>>; @ViewChildren('childrenContainer') childrenContainers!: QueryList<ElementRef<HTMLDivElement>>;
trackByFn: TrackByFunction<TreeNode<ABP.Route>> = (_, item) => item.name; trackByFn: TrackByFunction<TreeNode<ABP.Route>> = (_, item) => item.name;

2
npm/ng-packs/packages/theme-basic/src/lib/components/validation-error/validation-error.component.ts

@ -12,7 +12,7 @@ import { Validation, ValidationErrorComponent as ErrorComponent } from '@ngx-val
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
}) })
export class ValidationErrorComponent extends ErrorComponent { export class ValidationErrorComponent extends ErrorComponent {
get abpErrors(): Validation.Error[] & { interpoliteParams?: string[] } { get abpErrors(): (Validation.Error & { interpoliteParams?: string[] })[] {
if (!this.errors || !this.errors.length) return []; if (!this.errors || !this.errors.length) return [];
return this.errors.map(error => { return this.errors.map(error => {

6
npm/ng-packs/packages/theme-basic/src/lib/services/layout.service.ts

@ -1,14 +1,14 @@
import { ChangeDetectorRef, Injectable } from '@angular/core';
import { eThemeBasicComponents } from '../enums';
import { SubscriptionService } from '@abp/ng.core'; import { SubscriptionService } from '@abp/ng.core';
import { ChangeDetectorRef, Injectable } from '@angular/core';
import { fromEvent } from 'rxjs'; import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators'; import { debounceTime } from 'rxjs/operators';
import { eThemeBasicComponents } from '../enums';
@Injectable() @Injectable()
export class LayoutService { export class LayoutService {
isCollapsed = true; isCollapsed = true;
smallScreen: boolean; // do not set true or false smallScreen!: boolean; // do not set true or false
logoComponentKey = eThemeBasicComponents.Logo; logoComponentKey = eThemeBasicComponents.Logo;

9
npm/ng-packs/packages/theme-shared/extensions/src/lib/adapters/date-time.adapter.ts

@ -3,7 +3,7 @@ import { NgbDateStruct, NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap';
@Injectable() @Injectable()
export class DateTimeAdapter { export class DateTimeAdapter {
value: NgbDateTimeStruct; value!: NgbDateTimeStruct;
fromModel(value: string | Date): NgbDateTimeStruct | null { fromModel(value: string | Date): NgbDateTimeStruct | null {
if (!value) return null; if (!value) return null;
@ -27,15 +27,16 @@ export class DateTimeAdapter {
toModel(value: NgbDateTimeStruct | null): string { toModel(value: NgbDateTimeStruct | null): string {
if (!value) return ''; if (!value) return '';
const now = new Date(); //const now = new Date();
value = { value = {
year: now.getUTCFullYear(), // TODO
/* year: now.getUTCFullYear(),
month: now.getMonth() + 1, month: now.getMonth() + 1,
day: now.getDate(), day: now.getDate(),
hour: 0, hour: 0,
minute: 0, minute: 0,
second: 0, second: 0, */
...this.value, ...this.value,
...value, ...value,
}; };

2
npm/ng-packs/packages/theme-shared/extensions/src/lib/adapters/date.adapter.ts

@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
import { NgbDateAdapter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'; import { NgbDateAdapter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap';
@Injectable() @Injectable()
export class DateAdapter extends NgbDateAdapter<string> { export class DateAdapter extends NgbDateAdapter<string | Date> {
fromModel(value: string | Date): NgbDateStruct | null { fromModel(value: string | Date): NgbDateStruct | null {
if (!value) return null; if (!value) return null;

2
npm/ng-packs/packages/theme-shared/extensions/src/lib/adapters/time.adapter.ts

@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
import { NgbTimeAdapter, NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap'; import { NgbTimeAdapter, NgbTimeStruct } from '@ng-bootstrap/ng-bootstrap';
@Injectable() @Injectable()
export class TimeAdapter extends NgbTimeAdapter<string> { export class TimeAdapter extends NgbTimeAdapter<string | Date> {
fromModel(value: string | Date): NgbTimeStruct | null { fromModel(value: string | Date): NgbTimeStruct | null {
if (!value) return null; if (!value) return null;

2
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/abstract-actions/abstract-actions.component.ts

@ -13,7 +13,7 @@ export abstract class AbstractActionsComponent<L extends ActionList<any>> extend
readonly getInjected: InferredData<L>['getInjected']; readonly getInjected: InferredData<L>['getInjected'];
@Input() readonly record: InferredData<L>['record']; @Input() readonly record!: InferredData<L>['record'];
constructor(injector: Injector) { constructor(injector: Injector) {
super(); super();

6
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/date-time-picker/date-time-picker.component.ts

@ -58,11 +58,11 @@ import { selfFactory } from '../../utils/factory.util';
], ],
}) })
export class DateTimePickerComponent { export class DateTimePickerComponent {
@Input() prop: FormProp; @Input() prop!: FormProp;
@Input() meridian = false; @Input() meridian = false;
@ViewChild(NgbInputDatepicker) date: NgbInputDatepicker; @ViewChild(NgbInputDatepicker) date!: NgbInputDatepicker;
@ViewChild(NgbTimepicker) time: NgbTimepicker; @ViewChild(NgbTimepicker) time!: NgbTimepicker;
constructor(public readonly cdRef: ChangeDetectorRef) {} constructor(public readonly cdRef: ChangeDetectorRef) {}

18
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts

@ -46,13 +46,13 @@ import { addTypeaheadTextSuffix } from '../../utils/typeahead.util';
], ],
}) })
export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit { export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
@Input() data: PropData; @Input() data!: PropData;
@Input() prop: FormProp; @Input() prop!: FormProp;
@Input() first: boolean; @Input() first?: boolean;
@ViewChild('field') private fieldRef: ElementRef<HTMLElement>; @ViewChild('field') private fieldRef!: ElementRef<HTMLElement>;
asterisk = ''; asterisk = '';
@ -60,9 +60,9 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
validators: ValidatorFn[] = []; validators: ValidatorFn[] = [];
readonly: boolean; readonly!: boolean;
disabled: boolean; disabled!: boolean;
private readonly form: FormGroup; private readonly form: FormGroup;
@ -72,9 +72,9 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
this.typeaheadModel = selectedOption || { key: null, value: null }; this.typeaheadModel = selectedOption || { key: null, value: null };
const { key, value } = this.typeaheadModel; const { key, value } = this.typeaheadModel;
const [keyControl, valueControl] = this.getTypeaheadControls(); const [keyControl, valueControl] = this.getTypeaheadControls();
if (valueControl.value && !value) valueControl.markAsDirty(); if (valueControl?.value && !value) valueControl.markAsDirty();
keyControl.setValue(key); keyControl?.setValue(key);
valueControl.setValue(value); valueControl?.setValue(value);
} }
search = (text$: Observable<string>) => search = (text$: Observable<string>) =>

6
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts

@ -33,7 +33,7 @@ import { ExtensibleFormPropComponent } from './extensible-form-prop.component';
}) })
export class ExtensibleFormComponent<R = any> { export class ExtensibleFormComponent<R = any> {
@ViewChildren(ExtensibleFormPropComponent) @ViewChildren(ExtensibleFormPropComponent)
formProps: QueryList<ExtensibleFormPropComponent>; formProps!: QueryList<ExtensibleFormPropComponent>;
@Input() @Input()
set selectedRecord(record: R) { set selectedRecord(record: R) {
@ -43,8 +43,8 @@ export class ExtensibleFormComponent<R = any> {
} }
extraPropertiesKey = EXTRA_PROPERTIES_KEY; extraPropertiesKey = EXTRA_PROPERTIES_KEY;
propList: FormPropList<R>; propList!: FormPropList<R>;
record: R; record!: R;
get form(): FormGroup { get form(): FormGroup {
return (this.container ? this.container.control : { controls: {} }) as FormGroup; return (this.container ? this.container.control : { controls: {} }) as FormGroup;

6
npm/ng-packs/packages/theme-shared/extensions/src/lib/directives/prop-data.directive.ts

@ -18,11 +18,11 @@ export class PropDataDirective<L extends PropList<any>>
extends PropData<InferredData<L>> extends PropData<InferredData<L>>
implements OnChanges, OnDestroy implements OnChanges, OnDestroy
{ {
@Input('abpPropDataFromList') readonly propList: L; @Input('abpPropDataFromList') readonly propList?: L;
@Input('abpPropDataWithRecord') readonly record: InferredData<L>['record']; @Input('abpPropDataWithRecord') readonly record!: InferredData<L>['record'];
@Input('abpPropDataAtIndex') readonly index: number; @Input('abpPropDataAtIndex') readonly index?: number;
readonly getInjected: InferredData<L>['getInjected']; readonly getInjected: InferredData<L>['getInjected'];

2
npm/ng-packs/packages/theme-shared/extensions/src/lib/models/actions.ts

@ -32,7 +32,7 @@ export abstract class Action<R = any> {
) {} ) {}
} }
export type ActionCallback<T, R = any> = (data?: Omit<ActionData<T>, 'data'>) => R; export type ActionCallback<T, R = any> = (data: Omit<ActionData<T>, 'data'>) => R;
export type ActionPredicate<T> = (data?: Omit<ActionData<T>, 'data'>) => boolean; export type ActionPredicate<T> = (data?: Omit<ActionData<T>, 'data'>) => boolean;
export abstract class ActionsFactory<C extends Actions<any>> { export abstract class ActionsFactory<C extends Actions<any>> {

2
npm/ng-packs/packages/theme-shared/extensions/src/lib/models/props.ts

@ -38,7 +38,7 @@ export abstract class Prop<R = any> {
} }
} }
export type PropCallback<T, R = any> = (data?: Omit<PropData<T>, 'data'>, auxData?: any) => R; export type PropCallback<T, R = any> = (data: Omit<PropData<T>, 'data'>, auxData?: any) => R;
export type PropPredicate<T> = (data?: Omit<PropData<T>, 'data'>, auxData?: any) => boolean; export type PropPredicate<T> = (data?: Omit<PropData<T>, 'data'>, auxData?: any) => boolean;
export abstract class PropsFactory<C extends Props<any>> { export abstract class PropsFactory<C extends Props<any>> {

4
npm/ng-packs/packages/theme-shared/extensions/src/lib/models/toolbar-actions.ts

@ -27,7 +27,7 @@ export class ToolbarAction<R = any> extends Action<R> {
readonly icon: string; readonly icon: string;
constructor(options: ToolbarActionOptions<R>) { constructor(options: ToolbarActionOptions<R>) {
super(options.permission, options.visible, options.action); super(options.permission || '', options.visible, options.action);
this.text = options.text; this.text = options.text;
this.icon = options.icon || ''; this.icon = options.icon || '';
} }
@ -45,7 +45,7 @@ export class ToolbarComponent<R = any> extends Action<R> {
readonly component: Type<any>; readonly component: Type<any>;
constructor(options: ToolbarComponentOptions<R>) { constructor(options: ToolbarComponentOptions<R>) {
super(options.permission, options.visible, options.action); super(options.permission || '', options.visible, options.action);
this.component = options.component; this.component = options.component;
} }

2
npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/enum.util.ts

@ -68,6 +68,6 @@ function createEnumLocalizer(
); );
} }
function getShortEnumType(enumType: string): string { function getShortEnumType(enumType: string) {
return enumType.split('.').pop(); return enumType.split('.').pop();
} }

9
npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/state.util.ts

@ -74,7 +74,7 @@ export function mapEntitiesToContributors<T = any>(
resource: string, resource: string,
) { ) {
return pipe( return pipe(
switchMap(entities => switchMap((entities: any) =>
zip(selectLocalization(configState), selectEnums(configState)).pipe( zip(selectLocalization(configState), selectEnums(configState)).pipe(
map(([localization, enums]) => { map(([localization, enums]) => {
const generateDisplayName = createDisplayNameLocalizationPipeKeyGenerator(localization); const generateDisplayName = createDisplayNameLocalizationPipeKeyGenerator(localization);
@ -166,8 +166,9 @@ function createPropertiesToContributorsMapper<T = any>(
if (isOnCreateForm || isOnEditForm) { if (isOnCreateForm || isOnEditForm) {
const defaultValue = property.defaultValue; const defaultValue = property.defaultValue;
const validators = () => getValidatorsFromProperty(property); const validators = () => getValidatorsFromProperty(property);
let options: PropCallback<any, Observable<ABP.Option<any>[]>>; let options: PropCallback<any, Observable<ABP.Option<any>[]>> | undefined;
if (type === ePropType.Enum) options = createEnumOptions(propName, enums[property.type]); if (type === ePropType.Enum)
options = createEnumOptions(propName, enums[property.type || '']);
else if (type === ePropType.Typeahead) options = createTypeaheadOptions(lookup); else if (type === ePropType.Typeahead) options = createTypeaheadOptions(lookup);
const formProp = new FormProp({ const formProp = new FormProp({
@ -192,7 +193,7 @@ function createPropertiesToContributorsMapper<T = any>(
} }
function getTypeFromProperty(property: ObjectExtensions.ExtensionPropertyDto): ePropType { function getTypeFromProperty(property: ObjectExtensions.ExtensionPropertyDto): ePropType {
return property.typeSimple.replace(/\?$/, '') as string as ePropType; return property?.typeSimple?.replace(/\?$/, '') as string as ePropType;
} }
function isUndefined(obj: any): obj is undefined { function isUndefined(obj: any): obj is undefined {

16
npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/typeahead.util.ts

@ -12,25 +12,25 @@ export function createTypeaheadOptions(
lookup: ExtensionPropertyUiLookupDto, lookup: ExtensionPropertyUiLookupDto,
): PropCallback<any, Observable<ABP.Option<any>[]>> { ): PropCallback<any, Observable<ABP.Option<any>[]>> {
return (data, searchText) => return (data, searchText) =>
searchText searchText && data
? data ? data
.getInjected(RestService) .getInjected(RestService)
.request( .request(
{ {
method: 'GET', method: 'GET',
url: lookup.url, url: lookup.url || '',
params: { params: {
[lookup.filterParamName]: searchText, [lookup.filterParamName || '']: searchText,
}, },
}, },
{ apiName: 'Default' }, { apiName: 'Default' },
) )
.pipe( .pipe(
map(response => { map((response: any) => {
const list = response[lookup.resultListPropertyName]; const list = response[lookup.resultListPropertyName || ''];
const mapToOption = (item: any) => ({ const mapToOption = (item: any) => ({
key: item[lookup.displayPropertyName], key: item[lookup.displayPropertyName || ''],
value: item[lookup.valuePropertyName], value: item[lookup.valuePropertyName || ''],
}); });
return list.map(mapToOption); return list.map(mapToOption);
}), }),
@ -51,7 +51,7 @@ export function createTypeaheadDisplayNameGenerator(
properties: ObjectExtensions.EntityExtensionProperties, properties: ObjectExtensions.EntityExtensionProperties,
): ObjectExtensions.DisplayNameGeneratorFn { ): ObjectExtensions.DisplayNameGeneratorFn {
return (displayName, fallback) => { return (displayName, fallback) => {
const name = removeTypeaheadTextSuffix(fallback.name); const name = removeTypeaheadTextSuffix(fallback.name || '');
return displayNameGeneratorFn(displayName || properties[name].displayName, { return displayNameGeneratorFn(displayName || properties[name].displayName, {
name, name,
resource: fallback.resource, resource: fallback.resource,

5
npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/validation.util.ts

@ -8,8 +8,9 @@ export function getValidatorsFromProperty(
const validators: ValidatorFn[] = []; const validators: ValidatorFn[] = [];
property.attributes.forEach(attr => { property.attributes.forEach(attr => {
if (attr.typeSimple in AbpValidators) if (attr.typeSimple && attr.typeSimple in AbpValidators) {
validators.push(AbpValidators[attr.typeSimple](attr.config)); validators.push((AbpValidators as any)[attr.typeSimple](attr.config));
}
}); });
return validators; return validators;

3
npm/ng-packs/packages/theme-shared/src/lib/components/breadcrumb-items/breadcrumb-items.component.ts

@ -1,3 +1,4 @@
import { ABP } from '@abp/ng.core';
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
@Component({ @Component({
@ -5,5 +6,5 @@ import { Component, Input } from '@angular/core';
templateUrl: './breadcrumb-items.component.html', templateUrl: './breadcrumb-items.component.html',
}) })
export class BreadcrumbItemsComponent { export class BreadcrumbItemsComponent {
@Input() items = []; @Input() items: Partial<ABP.Route>[] = [];
} }

12
npm/ng-packs/packages/theme-shared/src/lib/components/button/button.component.ts

@ -39,16 +39,16 @@ export class ButtonComponent implements OnInit {
buttonType = 'button'; buttonType = 'button';
@Input() @Input()
iconClass: string; iconClass?: string;
@Input() @Input()
loading = false; loading = false;
@Input() @Input()
disabled = false; disabled: boolean | undefined = false;
@Input() @Input()
attributes: ABP.Dictionary<string>; attributes?: ABP.Dictionary<string>;
@Output() readonly click = new EventEmitter<MouseEvent>(); @Output() readonly click = new EventEmitter<MouseEvent>();
@ -63,7 +63,7 @@ export class ButtonComponent implements OnInit {
@Output() readonly abpBlur = new EventEmitter<FocusEvent>(); @Output() readonly abpBlur = new EventEmitter<FocusEvent>();
@ViewChild('button', { static: true }) @ViewChild('button', { static: true })
buttonRef: ElementRef<HTMLButtonElement>; buttonRef!: ElementRef<HTMLButtonElement>;
get icon(): string { get icon(): string {
return `${this.loading ? 'fa fa-spinner fa-spin' : this.iconClass || 'd-none'}`; return `${this.loading ? 'fa fa-spinner fa-spin' : this.iconClass || 'd-none'}`;
@ -74,7 +74,9 @@ export class ButtonComponent implements OnInit {
ngOnInit() { ngOnInit() {
if (this.attributes) { if (this.attributes) {
Object.keys(this.attributes).forEach(key => { Object.keys(this.attributes).forEach(key => {
this.renderer.setAttribute(this.buttonRef.nativeElement, key, this.attributes[key]); if (this.attributes?.[key]) {
this.renderer.setAttribute(this.buttonRef.nativeElement, key, this.attributes[key]);
}
}); });
} }
} }

4
npm/ng-packs/packages/theme-shared/src/lib/components/confirmation/confirmation.component.ts

@ -12,9 +12,9 @@ export class ConfirmationComponent {
reject = Confirmation.Status.reject; reject = Confirmation.Status.reject;
dismiss = Confirmation.Status.dismiss; dismiss = Confirmation.Status.dismiss;
confirmation$: ReplaySubject<Confirmation.DialogData>; confirmation$!: ReplaySubject<Confirmation.DialogData>;
clear: (status: Confirmation.Status) => void; clear!: (status: Confirmation.Status) => void;
close(status: Confirmation.Status) { close(status: Confirmation.Status) {
this.clear(status); this.clear(status);

24
npm/ng-packs/packages/theme-shared/src/lib/components/http-error-wrapper/http-error-wrapper.component.ts

@ -22,11 +22,11 @@ import { debounceTime, filter } from 'rxjs/operators';
providers: [SubscriptionService], providers: [SubscriptionService],
}) })
export class HttpErrorWrapperComponent implements AfterViewInit, OnDestroy, OnInit { export class HttpErrorWrapperComponent implements AfterViewInit, OnDestroy, OnInit {
appRef: ApplicationRef; appRef!: ApplicationRef;
cfRes: ComponentFactoryResolver; cfRes!: ComponentFactoryResolver;
injector: Injector; injector!: Injector;
status = 0; status = 0;
@ -34,18 +34,18 @@ export class HttpErrorWrapperComponent implements AfterViewInit, OnDestroy, OnIn
details: LocalizationParam = 'Sorry, an error has occured.'; details: LocalizationParam = 'Sorry, an error has occured.';
customComponent: Type<any> = null; customComponent: Type<any> | undefined = undefined;
destroy$: Subject<void>; destroy$!: Subject<void>;
hideCloseIcon = false; hideCloseIcon = false;
backgroundColor: string; backgroundColor!: string;
isHomeShow = true; isHomeShow = true;
@ViewChild('container', { static: false }) @ViewChild('container', { static: false })
containerRef: ElementRef<HTMLDivElement>; containerRef?: ElementRef<HTMLDivElement>;
get statusText(): string { get statusText(): string {
return this.status ? `[${this.status}]` : ''; return this.status ? `[${this.status}]` : '';
@ -66,13 +66,15 @@ export class HttpErrorWrapperComponent implements AfterViewInit, OnDestroy, OnIn
customComponentRef.instance.errorStatus = this.status; customComponentRef.instance.errorStatus = this.status;
customComponentRef.instance.destroy$ = this.destroy$; customComponentRef.instance.destroy$ = this.destroy$;
this.appRef.attachView(customComponentRef.hostView); this.appRef.attachView(customComponentRef.hostView);
this.containerRef.nativeElement.appendChild( if (this.containerRef) {
(customComponentRef.hostView as EmbeddedViewRef<any>).rootNodes[0], this.containerRef.nativeElement.appendChild(
); (customComponentRef.hostView as EmbeddedViewRef<any>).rootNodes[0],
);
}
customComponentRef.changeDetectorRef.detectChanges(); customComponentRef.changeDetectorRef.detectChanges();
} }
const keyup$ = fromEvent(document, 'keyup').pipe( const keyup$ = fromEvent<KeyboardEvent>(document, 'keyup').pipe(
debounceTime(150), debounceTime(150),
filter((key: KeyboardEvent) => key && key.key === 'Escape'), filter((key: KeyboardEvent) => key && key.key === 'Escape'),
); );

2
npm/ng-packs/packages/theme-shared/src/lib/components/loader-bar/loader-bar.component.ts

@ -22,7 +22,7 @@ import { combineLatest, Subscription, timer } from 'rxjs';
providers: [SubscriptionService], providers: [SubscriptionService],
}) })
export class LoaderBarComponent implements OnDestroy, OnInit { export class LoaderBarComponent implements OnDestroy, OnInit {
protected _isLoading: boolean; protected _isLoading!: boolean;
@Input() @Input()
set isLoading(value: boolean) { set isLoading(value: boolean) {

2
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal-ref.service.ts

@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
export type ModalDismissMode = 'hard' | 'soft'; export type ModalDismissMode = 'hard' | 'soft';
export interface DismissableModal { export interface DismissableModal {
dismiss(mode: ModalDismissMode); dismiss(mode: ModalDismissMode): void;
} }
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })

4
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.html

@ -1,7 +1,7 @@
<ng-content></ng-content> <ng-content></ng-content>
<ng-template #modalContent let-modal> <ng-template #modalContent let-modal>
<div id="abp-modal-header" class="modal-header"> <div *ngIf="abpHeader" id="abp-modal-header" class="modal-header">
<ng-container *ngTemplateOutlet="abpHeader"></ng-container> <ng-container *ngTemplateOutlet="abpHeader"></ng-container>
​ ​
<button <button
@ -14,7 +14,7 @@
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<div id="abp-modal-body" class="modal-body"> <div *ngIf="abpBody" id="abp-modal-body" class="modal-body">
<ng-container *ngTemplateOutlet="abpBody"></ng-container> <ng-container *ngTemplateOutlet="abpBody"></ng-container>
</div> </div>
<div *ngIf="abpFooter" id="abp-modal-footer" class="modal-footer"> <div *ngIf="abpFooter" id="abp-modal-footer" class="modal-footer">

38
npm/ng-packs/packages/theme-shared/src/lib/components/modal/modal.component.ts

@ -55,16 +55,16 @@ export class ModalComponent implements OnInit, OnDestroy, DismissableModal {
@Input() suppressUnsavedChangesWarning = this.suppressUnsavedChangesWarningToken; @Input() suppressUnsavedChangesWarning = this.suppressUnsavedChangesWarningToken;
@ViewChild('modalContent') modalContent: TemplateRef<any>; @ViewChild('modalContent') modalContent?: TemplateRef<any>;
@ContentChild('abpHeader', { static: false }) abpHeader: TemplateRef<any>; @ContentChild('abpHeader', { static: false }) abpHeader?: TemplateRef<any>;
@ContentChild('abpBody', { static: false }) abpBody: TemplateRef<any>; @ContentChild('abpBody', { static: false }) abpBody?: TemplateRef<any>;
@ContentChild('abpFooter', { static: false }) abpFooter: TemplateRef<any>; @ContentChild('abpFooter', { static: false }) abpFooter?: TemplateRef<any>;
@ContentChild(ButtonComponent, { static: false, read: ButtonComponent }) @ContentChild(ButtonComponent, { static: false, read: ButtonComponent })
abpSubmit: ButtonComponent; abpSubmit?: ButtonComponent;
@Output() readonly visibleChange = new EventEmitter<boolean>(); @Output() readonly visibleChange = new EventEmitter<boolean>();
@ -78,7 +78,7 @@ export class ModalComponent implements OnInit, OnDestroy, DismissableModal {
_busy = false; _busy = false;
modalRef: NgbModalRef; modalRef!: NgbModalRef;
isConfirmationOpen = false; isConfirmationOpen = false;
@ -93,7 +93,7 @@ export class ModalComponent implements OnInit, OnDestroy, DismissableModal {
} }
get isFormDirty(): boolean { get isFormDirty(): boolean {
return Boolean(this.modalWindowRef.querySelector('.ng-dirty')); return Boolean(this.modalWindowRef?.querySelector('.ng-dirty'));
} }
constructor( constructor(
@ -191,22 +191,22 @@ export class ModalComponent implements OnInit, OnDestroy, DismissableModal {
} }
listen() { listen() {
fromEvent(this.modalWindowRef, 'keyup') if (this.modalWindowRef) {
.pipe( fromEvent<KeyboardEvent>(this.modalWindowRef, 'keyup')
takeUntil(this.destroy$), .pipe(
debounceTime(150), takeUntil(this.destroy$),
filter((key: KeyboardEvent) => key && key.key === 'Escape'), debounceTime(150),
) filter((key: KeyboardEvent) => key && key.key === 'Escape'),
.subscribe(() => this.close()); )
.subscribe(() => this.close());
}
fromEvent(window, 'beforeunload') fromEvent(window, 'beforeunload')
.pipe(takeUntil(this.destroy$)) .pipe(takeUntil(this.destroy$))
.subscribe(event => { .subscribe(event => {
event.preventDefault(); // TODO: check this
if (this.isFormDirty && !this.suppressUnsavedChangesWarning) { if (!this.isFormDirty || this.suppressUnsavedChangesWarning) {
event.returnValue = true; event.preventDefault();
} else {
delete event.returnValue;
} }
}); });

14
npm/ng-packs/packages/theme-shared/src/lib/components/toast-container/toast-container.component.ts

@ -10,14 +10,14 @@ import { Toaster } from '../../models/toaster';
animations: [toastInOut], animations: [toastInOut],
}) })
export class ToastContainerComponent implements OnInit { export class ToastContainerComponent implements OnInit {
toasts$: ReplaySubject<Toaster.Toast[]>; toasts$!: ReplaySubject<Toaster.Toast[]>;
remove: (toastId: number) => void; remove!: (toastId: number) => void;
toasts = [] as Toaster.Toast[]; toasts = [] as Toaster.Toast[];
@Input() @Input()
top: string; top?: string;
@Input() @Input()
right = '30px'; right = '30px';
@ -26,10 +26,10 @@ export class ToastContainerComponent implements OnInit {
bottom = '30px'; bottom = '30px';
@Input() @Input()
left: string; left?: string;
@Input() @Input()
toastKey: string; toastKey?: string;
ngOnInit() { ngOnInit() {
this.toasts$.subscribe(toasts => { this.toasts$.subscribe(toasts => {
@ -41,8 +41,8 @@ export class ToastContainerComponent implements OnInit {
}); });
} }
trackByFunc(index, toast) { trackByFunc(index: number, toast: Toaster.Toast) {
if (!toast) return null; if (!toast) return null;
return toast.options.id; return toast.options?.id;
} }
} }

2
npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.html

@ -3,7 +3,7 @@
<i class="fa icon" [ngClass]="iconClass"></i> <i class="fa icon" [ngClass]="iconClass"></i>
</div> </div>
<div class="abp-toast-content"> <div class="abp-toast-content">
<button class="abp-toast-close-button" (click)="close()" *ngIf="toast.options.closable"> <button class="abp-toast-close-button" (click)="close()" *ngIf="toast.options?.closable">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
</button> </button>
<div class="abp-toast-title"> <div class="abp-toast-title">

4
npm/ng-packs/packages/theme-shared/src/lib/components/toast/toast.component.ts

@ -7,7 +7,7 @@ import { Toaster } from '../../models/toaster';
}) })
export class ToastComponent implements OnInit { export class ToastComponent implements OnInit {
@Input() @Input()
toast: Toaster.Toast; toast!: Toaster.Toast;
@Output() remove = new EventEmitter<number>(); @Output() remove = new EventEmitter<number>();
@ -42,7 +42,7 @@ export class ToastComponent implements OnInit {
} }
close() { close() {
this.remove.emit(this.toast.options.id); this.remove.emit(this.toast.options?.id);
} }
tap() { tap() {

4
npm/ng-packs/packages/theme-shared/src/lib/directives/ellipsis.directive.ts

@ -13,11 +13,11 @@ import {
}) })
export class EllipsisDirective implements AfterViewInit { export class EllipsisDirective implements AfterViewInit {
@Input('abpEllipsis') @Input('abpEllipsis')
width: string; width?: string;
@HostBinding('title') @HostBinding('title')
@Input() @Input()
title: string; title?: string;
@Input('abpEllipsisEnabled') @Input('abpEllipsisEnabled')
enabled = true; enabled = true;

12
npm/ng-packs/packages/theme-shared/src/lib/directives/loading.directive.ts

@ -18,7 +18,7 @@ import { LoadingComponent } from '../components/loading/loading.component';
@Directive({ selector: '[abpLoading]' }) @Directive({ selector: '[abpLoading]' })
export class LoadingDirective implements OnInit, OnDestroy { export class LoadingDirective implements OnInit, OnDestroy {
private _loading: boolean; private _loading!: boolean;
@HostBinding('style.position') @HostBinding('style.position')
position = 'relative'; position = 'relative';
@ -53,7 +53,7 @@ export class LoadingDirective implements OnInit, OnDestroy {
if (newValue && !this.rootNode) { if (newValue && !this.rootNode) {
this.rootNode = (this.componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0]; this.rootNode = (this.componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0];
this.targetElement.appendChild(this.rootNode); this.targetElement?.appendChild(this.rootNode as HTMLDivElement);
} else if (this.rootNode) { } else if (this.rootNode) {
this.renderer.removeChild(this.rootNode.parentElement, this.rootNode); this.renderer.removeChild(this.rootNode.parentElement, this.rootNode);
this.rootNode = null; this.rootNode = null;
@ -66,14 +66,14 @@ export class LoadingDirective implements OnInit, OnDestroy {
} }
@Input('abpLoadingTargetElement') @Input('abpLoadingTargetElement')
targetElement: HTMLElement; targetElement: HTMLElement | undefined;
@Input('abpLoadingDelay') @Input('abpLoadingDelay')
delay = 0; delay = 0;
componentRef: ComponentRef<LoadingComponent>; componentRef!: ComponentRef<LoadingComponent>;
rootNode: HTMLDivElement; rootNode: HTMLDivElement | null = null;
timerSubscription: Subscription; timerSubscription: Subscription | null = null;
constructor( constructor(
private elRef: ElementRef<HTMLElement>, private elRef: ElementRef<HTMLElement>,

2
npm/ng-packs/packages/theme-shared/src/lib/directives/ngx-datatable-list.directive.ts

@ -27,7 +27,7 @@ export class NgxDatatableListDirective implements OnChanges, OnDestroy, OnInit {
private subscription = new Subscription(); private subscription = new Subscription();
private querySubscription = new Subscription(); private querySubscription = new Subscription();
@Input() list: ListService; @Input() list!: ListService;
constructor( constructor(
private table: DatatableComponent, private table: DatatableComponent,

74
npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts

@ -71,7 +71,7 @@ export const DEFAULT_ERROR_LOCALIZATIONS = {
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ErrorHandler { export class ErrorHandler {
componentRef: ComponentRef<HttpErrorWrapperComponent>; componentRef: ComponentRef<HttpErrorWrapperComponent> | null = null;
protected httpErrorHandler = this.injector.get(HTTP_ERROR_HANDLER, (_, err: HttpErrorResponse) => protected httpErrorHandler = this.injector.get(HTTP_ERROR_HANDLER, (_, err: HttpErrorResponse) =>
throwError(err), throwError(err),
@ -109,7 +109,7 @@ export class ErrorHandler {
.getEvents(ResolveEnd) .getEvents(ResolveEnd)
.pipe(filter(() => !!this.componentRef)) .pipe(filter(() => !!this.componentRef))
.subscribe(() => { .subscribe(() => {
this.componentRef.destroy(); this.componentRef?.destroy();
this.componentRef = null; this.componentRef = null;
}); });
} }
@ -120,7 +120,7 @@ export class ErrorHandler {
.subscribe(); .subscribe();
} }
private executeErrorHandler = error => { private executeErrorHandler = (error: any) => {
const returnValue = this.httpErrorHandler(this.injector, error); const returnValue = this.httpErrorHandler(this.injector, error);
return (returnValue instanceof Observable ? returnValue : of(null)).pipe( return (returnValue instanceof Observable ? returnValue : of(null)).pipe(
@ -138,7 +138,7 @@ export class ErrorHandler {
}; };
if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) { if (err instanceof HttpErrorResponse && err.headers.get('_AbpErrorFormat')) {
const confirmation$ = this.showError(null, null, body); const confirmation$ = this.showErrorWithRequestBody(body);
if (err.status === 401) { if (err.status === 401) {
confirmation$.subscribe(() => { confirmation$.subscribe(() => {
@ -249,29 +249,34 @@ export class ErrorHandler {
}); });
} }
protected showError( protected showErrorWithRequestBody(body: any) {
message?: LocalizationParam, let message: LocalizationParam;
title?: LocalizationParam, let title: LocalizationParam;
body?: any,
): Observable<Confirmation.Status> { if (body.details) {
if (body) { message = body.details;
if (body.details) { title = body.message;
message = body.details; } else if (body.message) {
title = body.message; title = {
} else if (body.message) { key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title,
title = { defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title,
key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, };
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, message = body.message;
}; } else {
message = body.message; message = body.message || {
} else { key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title,
message = body.message || { defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title,
key: DEFAULT_ERROR_LOCALIZATIONS.defaultError.title, };
defaultValue: DEFAULT_ERROR_MESSAGES.defaultError.title, title = '';
};
}
} }
return this.showError(message, title);
}
protected showError(
message: LocalizationParam,
title: LocalizationParam,
): Observable<Confirmation.Status> {
return this.confirmationService.error(message, title, { return this.confirmationService.error(message, title, {
hideCancelBtn: true, hideCancelBtn: true,
yesText: 'AbpAccount::Close', yesText: 'AbpAccount::Close',
@ -293,18 +298,18 @@ export class ErrorHandler {
for (const key in instance) { for (const key in instance) {
/* istanbul ignore else */ /* istanbul ignore else */
if (Object.prototype.hasOwnProperty.call(this.componentRef.instance, key)) { if (Object.prototype.hasOwnProperty.call(this.componentRef.instance, key)) {
this.componentRef.instance[key] = instance[key]; (this.componentRef.instance as any)[key] = (instance as any)[key];
} }
} }
this.componentRef.instance.hideCloseIcon = this.httpErrorConfig.errorScreen.hideCloseIcon; this.componentRef.instance.hideCloseIcon = !!this.httpErrorConfig.errorScreen?.hideCloseIcon;
const appRef = this.injector.get(ApplicationRef); const appRef = this.injector.get(ApplicationRef);
if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) { if (this.canCreateCustomError(instance.status as ErrorScreenErrorCodes)) {
this.componentRef.instance.cfRes = this.cfRes; this.componentRef.instance.cfRes = this.cfRes;
this.componentRef.instance.appRef = appRef; this.componentRef.instance.appRef = appRef;
this.componentRef.instance.injector = this.injector; this.componentRef.instance.injector = this.injector;
this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen.component; this.componentRef.instance.customComponent = this.httpErrorConfig.errorScreen?.component;
} }
appRef.attachView(this.componentRef.hostView); appRef.attachView(this.componentRef.hostView);
@ -313,27 +318,32 @@ export class ErrorHandler {
const destroy$ = new Subject<void>(); const destroy$ = new Subject<void>();
this.componentRef.instance.destroy$ = destroy$; this.componentRef.instance.destroy$ = destroy$;
destroy$.subscribe(() => { destroy$.subscribe(() => {
this.componentRef.destroy(); this.componentRef?.destroy();
this.componentRef = null; this.componentRef = null;
}); });
} }
canCreateCustomError(status: ErrorScreenErrorCodes): boolean { canCreateCustomError(status: ErrorScreenErrorCodes): boolean {
return ( return !!(
this.httpErrorConfig?.errorScreen?.component && this.httpErrorConfig?.errorScreen?.component &&
this.httpErrorConfig?.errorScreen?.forWhichErrors?.indexOf(status) > -1 this.httpErrorConfig?.errorScreen?.forWhichErrors &&
this.httpErrorConfig?.errorScreen?.forWhichErrors.indexOf(status) > -1
); );
} }
protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => { protected filterRestErrors = ({ status }: HttpErrorResponse): boolean => {
if (typeof status !== 'number') return false; if (typeof status !== 'number') return false;
return this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0; return (
!!this.httpErrorConfig.skipHandledErrorCodes &&
this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === status) < 0
);
}; };
protected filterRouteErrors = (navigationError: NavigationError): boolean => { protected filterRouteErrors = (navigationError: NavigationError): boolean => {
return ( return (
navigationError.error?.message?.indexOf('Cannot match') > -1 && navigationError.error?.message?.indexOf('Cannot match') > -1 &&
!!this.httpErrorConfig.skipHandledErrorCodes &&
this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === 404) < 0 this.httpErrorConfig.skipHandledErrorCodes.findIndex(code => code === 404) < 0
); );
}; };

10
npm/ng-packs/packages/theme-shared/src/lib/handlers/lazy-style.handler.ts

@ -5,7 +5,7 @@ import {
LocalizationService, LocalizationService,
} from '@abp/ng.core'; } from '@abp/ng.core';
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { map, startWith } from 'rxjs/operators'; import { startWith } from 'rxjs/operators';
import { BOOTSTRAP } from '../constants/styles'; import { BOOTSTRAP } from '../constants/styles';
import { LocaleDirection } from '../models/common'; import { LocaleDirection } from '../models/common';
import { LAZY_STYLES } from '../tokens/lazy-styles.token'; import { LAZY_STYLES } from '../tokens/lazy-styles.token';
@ -14,8 +14,8 @@ import { LAZY_STYLES } from '../tokens/lazy-styles.token';
providedIn: 'root', providedIn: 'root',
}) })
export class LazyStyleHandler { export class LazyStyleHandler {
private lazyLoad: LazyLoadService; private lazyLoad!: LazyLoadService;
private styles: string[]; private styles!: string[];
private _dir: LocaleDirection = 'ltr'; private _dir: LocaleDirection = 'ltr';
readonly loaded = new Map<string, HTMLLinkElement>(); readonly loaded = new Map<string, HTMLLinkElement>();
@ -38,7 +38,7 @@ export class LazyStyleHandler {
this.listenToLanguageChanges(injector); this.listenToLanguageChanges(injector);
} }
private getHrefFromLink(link: HTMLLinkElement | null): string { private getHrefFromLink(link: HTMLLinkElement | null | undefined): string {
if (!link) return ''; if (!link) return '';
const a = document.createElement('a'); const a = document.createElement('a');
@ -107,5 +107,5 @@ export function initLazyStyleHandler(injector: Injector) {
interface LoadedStyle { interface LoadedStyle {
href: string; href: string;
link: HTMLLinkElement; link: HTMLLinkElement | null;
} }

2
npm/ng-packs/packages/theme-shared/src/lib/models/nav-item.ts

@ -1,7 +1,7 @@
import { Type } from '@angular/core'; import { Type } from '@angular/core';
export class NavItem { export class NavItem {
id: string | number; id?: string | number;
component?: Type<any>; component?: Type<any>;
html?: string; html?: string;
action?: () => void; action?: () => void;

6
npm/ng-packs/packages/theme-shared/src/lib/services/confirmation.service.ts

@ -7,10 +7,10 @@ import { Confirmation } from '../models/confirmation';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ConfirmationService { export class ConfirmationService {
status$: Subject<Confirmation.Status>; status$!: Subject<Confirmation.Status>;
confirmation$ = new ReplaySubject<Confirmation.DialogData>(1); confirmation$ = new ReplaySubject<Confirmation.DialogData>(1);
private containerComponentRef: ComponentRef<ConfirmationComponent>; private containerComponentRef!: ComponentRef<ConfirmationComponent>;
clear = (status: Confirmation.Status = Confirmation.Status.dismiss) => { clear = (status: Confirmation.Status = Confirmation.Status.dismiss) => {
this.confirmation$.next(); this.confirmation$.next();
@ -87,7 +87,7 @@ export class ConfirmationService {
} }
private listenToEscape() { private listenToEscape() {
fromEvent(document, 'keyup') fromEvent<KeyboardEvent>(document, 'keyup')
.pipe( .pipe(
takeUntil(this.status$), takeUntil(this.status$),
debounceTime(150), debounceTime(150),

4
npm/ng-packs/packages/theme-shared/src/lib/services/toaster.service.ts

@ -19,7 +19,7 @@ export class ToasterService implements ToasterContract {
private toasts = [] as Toaster.Toast[]; private toasts = [] as Toaster.Toast[];
private containerComponentRef: ComponentRef<ToastContainerComponent>; private containerComponentRef!: ComponentRef<ToastContainerComponent>;
constructor(private contentProjectionService: ContentProjectionService) {} constructor(private contentProjectionService: ContentProjectionService) {}
@ -100,7 +100,7 @@ export class ToasterService implements ToasterContract {
show( show(
message: LocalizationParam, message: LocalizationParam,
title: LocalizationParam = null, title: LocalizationParam | undefined = undefined,
severity: Toaster.Severity = 'neutral', severity: Toaster.Severity = 'neutral',
options = {} as Partial<Toaster.ToastOptions>, options = {} as Partial<Toaster.ToastOptions>,
): Toaster.ToasterId { ): Toaster.ToasterId {

7
npm/ng-packs/packages/theme-shared/src/lib/utils/date-parser-formatter.ts

@ -17,13 +17,14 @@ export class DateParserFormatter extends NgbDateParserFormatter {
super(); super();
} }
parse(value: string): NgbDateStruct { parse(value: string): NgbDateStruct | null {
if (value) { if (value) {
const dateParts = value.trim().split('-'); const dateParts = value.trim().split('-');
// TODO: CHANGED
if (dateParts.length === 1 && isNumber(dateParts[0])) { if (dateParts.length === 1 && isNumber(dateParts[0])) {
return { year: toInteger(dateParts[0]), month: null, day: null }; return { year: toInteger(dateParts[0]), month: -1, day: -1 };
} else if (dateParts.length === 2 && isNumber(dateParts[0]) && isNumber(dateParts[1])) { } else if (dateParts.length === 2 && isNumber(dateParts[0]) && isNumber(dateParts[1])) {
return { year: toInteger(dateParts[0]), month: toInteger(dateParts[1]), day: null }; return { year: toInteger(dateParts[0]), month: toInteger(dateParts[1]), day: -1 };
} else if ( } else if (
dateParts.length === 3 && dateParts.length === 3 &&
isNumber(dateParts[0]) && isNumber(dateParts[0]) &&

1
npm/ng-packs/tsconfig.json

@ -1,6 +1,7 @@
{ {
"compileOnSave": false, "compileOnSave": false,
"compilerOptions": { "compilerOptions": {
"strict": true,
"sourceMap": true, "sourceMap": true,
"declaration": false, "declaration": false,
"moduleResolution": "node", "moduleResolution": "node",

Loading…
Cancel
Save