Browse Source

fix typescript strict mode errors

pull/15750/head
muhammedaltug 4 years ago
parent
commit
3469485617
  1. 14
      npm/ng-packs/packages/account-core/src/lib/tenant-box.service.ts
  2. 19
      npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts
  3. 4
      npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.ts
  4. 6
      npm/ng-packs/packages/account/src/lib/components/login/login.component.ts
  5. 2
      npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts
  6. 4
      npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings-half-row.component.ts
  7. 6
      npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.ts
  8. 14
      npm/ng-packs/packages/account/src/lib/components/register/register.component.ts
  9. 10
      npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.ts
  10. 10
      npm/ng-packs/packages/components/chart.js/src/chart.component.ts
  11. 2
      npm/ng-packs/packages/components/chart.js/src/widget-utils.ts
  12. 4
      npm/ng-packs/packages/components/page/src/page-part.directive.ts
  13. 2
      npm/ng-packs/packages/components/page/src/page.component.html
  14. 14
      npm/ng-packs/packages/components/page/src/page.component.ts
  15. 2
      npm/ng-packs/packages/core/src/lib/models/session.ts
  16. 2
      npm/ng-packs/packages/core/src/lib/services/session-state.service.ts
  17. 14
      npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts
  18. 92
      npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts
  19. 8
      npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-actions.ts
  20. 4
      npm/ng-packs/packages/identity/src/lib/defaults/default-roles-form-props.ts
  21. 23
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts
  22. 2
      npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts
  23. 38
      npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts
  24. 8
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/abstract-actions/abstract-actions.component.ts
  25. 6
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form-prop.component.ts
  26. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-form/extensible-form.component.ts
  27. 24
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/extensible-table/extensible-table.component.ts
  28. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/grid-actions/grid-actions.component.ts
  29. 20
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.html
  30. 8
      npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.ts
  31. 17
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/actions.ts
  32. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-actions.ts
  33. 10
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/entity-props.ts
  34. 6
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/form-props.ts
  35. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/internal/object-extensions.ts
  36. 9
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/props.ts
  37. 7
      npm/ng-packs/packages/theme-shared/extensions/src/lib/models/toolbar-actions.ts
  38. 2
      npm/ng-packs/packages/theme-shared/extensions/src/lib/pipes/create-injector.pipe.ts
  39. 4
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/actions.util.ts
  40. 4
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/enum.util.ts
  41. 10
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/form-props.util.ts
  42. 20
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/props.util.ts
  43. 44
      npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/state.util.ts

14
npm/ng-packs/packages/account-core/src/lib/tenant-box.service.ts

@ -12,22 +12,22 @@ import { finalize } from 'rxjs/operators';
export class TenantBoxService { export class TenantBoxService {
currentTenant$ = this.sessionState.getTenant$(); currentTenant$ = this.sessionState.getTenant$();
name: string; name?: string;
isModalVisible: boolean; isModalVisible!: boolean;
modalBusy: boolean; modalBusy!: boolean;
constructor( constructor(
private toasterService: ToasterService, private toasterService: ToasterService,
private tenantService: AbpTenantService, private tenantService: AbpTenantService,
private sessionState: SessionStateService, private sessionState: SessionStateService,
private configState: ConfigStateService, private configState: ConfigStateService,
) { } ) {}
onSwitch() { onSwitch() {
const tenant = this.sessionState.getTenant(); const tenant = this.sessionState.getTenant();
this.name = tenant?.name; this.name = tenant?.name || '';
this.isModalVisible = true; this.isModalVisible = true;
} }
@ -53,14 +53,14 @@ export class TenantBoxService {
}); });
} }
private setTenant(tenant: CurrentTenantDto) { private setTenant(tenant: CurrentTenantDto | null) {
this.sessionState.setTenant(tenant); this.sessionState.setTenant(tenant);
this.configState.refreshAppState(); this.configState.refreshAppState();
} }
private showError() { private showError() {
this.toasterService.error('AbpUiMultiTenancy::GivenTenantIsNotAvailable', 'AbpUi::Error', { this.toasterService.error('AbpUiMultiTenancy::GivenTenantIsNotAvailable', 'AbpUi::Error', {
messageLocalizationParams: [this.name], messageLocalizationParams: [this.name || ''],
}); });
} }
} }

19
npm/ng-packs/packages/account/src/lib/components/change-password/change-password.component.ts

@ -1,7 +1,12 @@
import { ProfileService } from '@abp/ng.account.core/proxy'; import { ProfileService } from '@abp/ng.account.core/proxy';
import { getPasswordValidators, ToasterService } from '@abp/ng.theme.shared'; import { getPasswordValidators, ToasterService } from '@abp/ng.theme.shared';
import { Component, Injector, OnInit } from '@angular/core'; import { Component, Injector, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import {
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
Validators,
} from '@angular/forms';
import { comparePasswords, Validation } from '@ngx-validate/core'; import { comparePasswords, Validation } from '@ngx-validate/core';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import { Account } from '../../models/account'; import { Account } from '../../models/account';
@ -19,14 +24,14 @@ const PASSWORD_FIELDS = ['newPassword', 'repeatNewPassword'];
export class ChangePasswordComponent export class ChangePasswordComponent
implements OnInit, Account.ChangePasswordComponentInputs, Account.ChangePasswordComponentOutputs implements OnInit, Account.ChangePasswordComponentInputs, Account.ChangePasswordComponentOutputs
{ {
form: UntypedFormGroup; form!: UntypedFormGroup;
inProgress: boolean; inProgress?: boolean;
hideCurrentPassword: boolean; hideCurrentPassword?: boolean;
mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => { mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => {
if (PASSWORD_FIELDS.indexOf(String(control.name)) < 0) return errors; if (PASSWORD_FIELDS.indexOf(String(control?.name)) < 0) return errors;
return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch')); return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch'));
}; };
@ -73,8 +78,8 @@ export class ChangePasswordComponent
this.inProgress = true; this.inProgress = true;
this.profileService this.profileService
.changePassword({ .changePassword({
...(!this.hideCurrentPassword && { currentPassword: this.form.get('password').value }), ...(!this.hideCurrentPassword && { currentPassword: this.form.get('password')?.value }),
newPassword: this.form.get('newPassword').value, newPassword: this.form.get('newPassword')?.value,
}) })
.pipe(finalize(() => (this.inProgress = false))) .pipe(finalize(() => (this.inProgress = false)))
.subscribe({ .subscribe({

4
npm/ng-packs/packages/account/src/lib/components/forgot-password/forgot-password.component.ts

@ -10,7 +10,7 @@ import { finalize } from 'rxjs/operators';
export class ForgotPasswordComponent { export class ForgotPasswordComponent {
form: UntypedFormGroup; form: UntypedFormGroup;
inProgress: boolean; inProgress?: boolean;
isEmailSent = false; isEmailSent = false;
@ -27,7 +27,7 @@ export class ForgotPasswordComponent {
this.accountService this.accountService
.sendPasswordResetCode({ .sendPasswordResetCode({
email: this.form.get('email').value, email: this.form.get('email')?.value,
appName: 'Angular', appName: 'Angular',
}) })
.pipe(finalize(() => (this.inProgress = false))) .pipe(finalize(() => (this.inProgress = false)))

6
npm/ng-packs/packages/account/src/lib/components/login/login.component.ts

@ -14,9 +14,9 @@ const { maxLength, required } = Validators;
templateUrl: './login.component.html', templateUrl: './login.component.html',
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
form: UntypedFormGroup; form!: UntypedFormGroup;
inProgress: boolean; inProgress?: boolean;
isSelfRegistrationEnabled = true; isSelfRegistrationEnabled = true;
@ -67,7 +67,7 @@ export class LoginComponent implements OnInit {
err.error?.error_description || err.error?.error_description ||
err.error?.error.message || err.error?.error.message ||
'AbpAccount::DefaultErrorMessage', 'AbpAccount::DefaultErrorMessage',
null, '',
{ life: 7000 }, { life: 7000 },
); );
return throwError(err); return throwError(err);

2
npm/ng-packs/packages/account/src/lib/components/manage-profile/manage-profile.component.ts

@ -26,7 +26,7 @@ export class ManageProfileComponent implements OnInit {
profile$ = this.manageProfileState.getProfile$(); profile$ = this.manageProfileState.getProfile$();
hideChangePasswordTab: boolean; hideChangePasswordTab?: boolean;
constructor( constructor(
protected profileService: ProfileService, protected profileService: ProfileService,

4
npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings-half-row.component.ts

@ -27,11 +27,11 @@ export class PersonalSettingsHalfRowComponent {
public displayName: string; public displayName: string;
public name: string; public name: string;
public id: string; public id: string;
public formGroup: UntypedFormGroup; public formGroup!: UntypedFormGroup;
constructor(@Inject(EXTENSIONS_FORM_PROP) private propData: FormProp) { constructor(@Inject(EXTENSIONS_FORM_PROP) private propData: FormProp) {
this.displayName = propData.displayName; this.displayName = propData.displayName;
this.name = propData.name; this.name = propData.name;
this.id = propData.id; this.id = propData.id || '';
} }
} }

6
npm/ng-packs/packages/account/src/lib/components/personal-settings/personal-settings.component.ts

@ -31,11 +31,11 @@ export class PersonalSettingsComponent
Account.PersonalSettingsComponentInputs, Account.PersonalSettingsComponentInputs,
Account.PersonalSettingsComponentOutputs Account.PersonalSettingsComponentOutputs
{ {
selected: ProfileDto; selected?: ProfileDto;
form: UntypedFormGroup; form!: UntypedFormGroup;
inProgress: boolean; inProgress?: boolean;
constructor( constructor(
private fb: UntypedFormBuilder, private fb: UntypedFormBuilder,

14
npm/ng-packs/packages/account/src/lib/components/register/register.component.ts

@ -15,9 +15,9 @@ const { maxLength, required, email } = Validators;
templateUrl: './register.component.html', templateUrl: './register.component.html',
}) })
export class RegisterComponent implements OnInit { export class RegisterComponent implements OnInit {
form: UntypedFormGroup; form!: UntypedFormGroup;
inProgress: boolean; inProgress?: boolean;
isSelfRegistrationEnabled = true; isSelfRegistrationEnabled = true;
@ -48,7 +48,7 @@ export class RegisterComponent implements OnInit {
key: 'AbpAccount::SelfRegistrationDisabledMessage', key: 'AbpAccount::SelfRegistrationDisabledMessage',
defaultValue: 'Self registration is disabled.', defaultValue: 'Self registration is disabled.',
}, },
null, '',
{ life: 10000 }, { life: 10000 },
); );
return; return;
@ -69,9 +69,9 @@ export class RegisterComponent implements OnInit {
this.inProgress = true; this.inProgress = true;
const newUser = { const newUser = {
userName: this.form.get('username').value, userName: this.form.get('username')?.value,
password: this.form.get('password').value, password: this.form.get('password')?.value,
emailAddress: this.form.get('email').value, emailAddress: this.form.get('email')?.value,
appName: 'Angular', appName: 'Angular',
} as RegisterDto; } as RegisterDto;
@ -90,7 +90,7 @@ export class RegisterComponent implements OnInit {
err.error?.error_description || err.error?.error_description ||
err.error?.error.message || err.error?.error.message ||
'AbpAccount::DefaultErrorMessage', 'AbpAccount::DefaultErrorMessage',
null, '',
{ life: 7000 }, { life: 7000 },
); );

10
npm/ng-packs/packages/account/src/lib/components/reset-password/reset-password.component.ts

@ -13,14 +13,14 @@ const PASSWORD_FIELDS = ['password', 'confirmPassword'];
templateUrl: './reset-password.component.html', templateUrl: './reset-password.component.html',
}) })
export class ResetPasswordComponent implements OnInit { export class ResetPasswordComponent implements OnInit {
form: UntypedFormGroup; form!: UntypedFormGroup;
inProgress = false; inProgress = false;
isPasswordReset = false; isPasswordReset = false;
mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => { mapErrorsFn: Validation.MapErrorsFn = (errors, groupErrors, control) => {
if (PASSWORD_FIELDS.indexOf(String(control.name)) < 0) return errors; if (PASSWORD_FIELDS.indexOf(String(control?.name)) < 0) return errors;
return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch')); return errors.concat(groupErrors.filter(({ key }) => key === 'passwordMismatch'));
}; };
@ -58,9 +58,9 @@ export class ResetPasswordComponent implements OnInit {
this.accountService this.accountService
.resetPassword({ .resetPassword({
userId: this.form.get('userId').value, userId: this.form.get('userId')?.value,
resetToken: this.form.get('resetToken').value, resetToken: this.form.get('resetToken')?.value,
password: this.form.get('password').value, password: this.form.get('password')?.value,
}) })
.pipe(finalize(() => (this.inProgress = false))) .pipe(finalize(() => (this.inProgress = false)))
.subscribe(() => { .subscribe(() => {

10
npm/ng-packs/packages/components/chart.js/src/chart.component.ts

@ -35,7 +35,7 @@ let Chart: any;
exportAs: 'abpChart', exportAs: 'abpChart',
}) })
export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges { export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Input() type: string; @Input() type!: string;
@Input() data: any = {}; @Input() data: any = {};
@ -43,9 +43,9 @@ export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Input() plugins: any[] = []; @Input() plugins: any[] = [];
@Input() width: string; @Input() width?: string;
@Input() height: string; @Input() height?: string;
@Input() responsive = true; @Input() responsive = true;
@ -53,7 +53,7 @@ export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Output() initialized = new EventEmitter<boolean>(); @Output() initialized = new EventEmitter<boolean>();
@ViewChild('canvas') canvas: ElementRef<HTMLCanvasElement>; @ViewChild('canvas') canvas!: ElementRef<HTMLCanvasElement>;
chart: any; chart: any;
@ -67,7 +67,7 @@ export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges {
}); });
} }
onCanvasClick(event) { onCanvasClick(event: MouseEvent) {
if (this.chart) { if (this.chart) {
const element = this.chart.getElementsAtEventForMode( const element = this.chart.getElementsAtEventForMode(
event, event,

2
npm/ng-packs/packages/components/chart.js/src/widget-utils.ts

@ -1,4 +1,4 @@
export function getRandomBackgroundColor(count) { export function getRandomBackgroundColor(count: number) {
const colors = []; const colors = [];
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {

4
npm/ng-packs/packages/components/page/src/page-part.directive.ts

@ -27,8 +27,8 @@ export const PAGE_RENDER_STRATEGY = new InjectionToken<PageRenderStrategy>('PAGE
@Directive({ selector: '[abpPagePart]' }) @Directive({ selector: '[abpPagePart]' })
export class PagePartDirective implements OnInit, OnDestroy, OnChanges { export class PagePartDirective implements OnInit, OnDestroy, OnChanges {
hasRendered = false; hasRendered = false;
type: string; type!: string;
subscription: Subscription; subscription!: Subscription;
@Input('abpPagePartContext') context: any; @Input('abpPagePartContext') context: any;
@Input() set abpPagePart(type: string) { @Input() set abpPagePart(type: string) {

2
npm/ng-packs/packages/components/page/src/page.component.html

@ -25,7 +25,7 @@
</ng-template> </ng-template>
<ng-template #defaultBreadcrumbTemplate> <ng-template #defaultBreadcrumbTemplate>
<ng-container *ngIf="breadcrumbVisible"> <ng-container *ngIf="breadcrumb">
<div class="col-lg-auto ps-lg-0" *abpPagePart="pageParts.breadcrumb"> <div class="col-lg-auto ps-lg-0" *abpPagePart="pageParts.breadcrumb">
<abp-breadcrumb></abp-breadcrumb> <abp-breadcrumb></abp-breadcrumb>
</div> </div>

14
npm/ng-packs/packages/components/page/src/page.component.ts

@ -12,11 +12,11 @@ import {
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
}) })
export class PageComponent { export class PageComponent {
@Input() title: string; @Input() title?: string;
toolbarVisible = false; toolbarVisible = false;
_toolbarData: any; _toolbarData: any;
@Input('toolbar') set toolbarData(val: any) { @Input() set toolbar(val: any) {
this._toolbarData = val; this._toolbarData = val;
this.toolbarVisible = true; this.toolbarVisible = true;
} }
@ -25,7 +25,7 @@ export class PageComponent {
return this._toolbarData; return this._toolbarData;
} }
@Input('breadcrumb') breadcrumbVisible = true; @Input() breadcrumb = true;
pageParts = { pageParts = {
title: PageParts.title, title: PageParts.title,
@ -33,16 +33,16 @@ export class PageComponent {
toolbar: PageParts.toolbar, toolbar: PageParts.toolbar,
}; };
@ContentChild(PageTitleContainerComponent) customTitle: PageTitleContainerComponent; @ContentChild(PageTitleContainerComponent) customTitle?: PageTitleContainerComponent;
@ContentChild(PageBreadcrumbContainerComponent) @ContentChild(PageBreadcrumbContainerComponent)
customBreadcrumb: PageBreadcrumbContainerComponent; customBreadcrumb?: PageBreadcrumbContainerComponent;
@ContentChild(PageToolbarContainerComponent) customToolbar: PageToolbarContainerComponent; @ContentChild(PageToolbarContainerComponent) customToolbar?: PageToolbarContainerComponent;
get shouldRenderRow() { get shouldRenderRow() {
return !!( return !!(
this.title || this.title ||
this.toolbarVisible || this.toolbarVisible ||
this.breadcrumbVisible || this.breadcrumb ||
this.customTitle || this.customTitle ||
this.customBreadcrumb || this.customBreadcrumb ||
this.customToolbar this.customToolbar

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

@ -3,6 +3,6 @@ import { CurrentTenantDto } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenan
export namespace Session { export namespace Session {
export interface State { export interface State {
language: string; language: string;
tenant: CurrentTenantDto; tenant: CurrentTenantDto | null;
} }
} }

2
npm/ng-packs/packages/core/src/lib/services/session-state.service.ts

@ -73,7 +73,7 @@ export class SessionStateService {
return this.store.sliceState(state => state.tenant); return this.store.sliceState(state => state.tenant);
} }
setTenant(tenant: CurrentTenantDto) { setTenant(tenant: CurrentTenantDto | null) {
if (compare(tenant, this.store.state.tenant)) return; if (compare(tenant, this.store.state.tenant)) return;
this.store.set({ ...this.store.state, tenant }); this.store.set({ ...this.store.state, tenant });

14
npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.ts

@ -26,21 +26,21 @@ import { eIdentityComponents } from '../../enums/components';
export class RolesComponent implements OnInit { export class RolesComponent implements OnInit {
data: PagedResultDto<IdentityRoleDto> = { items: [], totalCount: 0 }; data: PagedResultDto<IdentityRoleDto> = { items: [], totalCount: 0 };
form: UntypedFormGroup; form!: UntypedFormGroup;
selected: IdentityRoleDto; selected?: IdentityRoleDto;
isModalVisible: boolean; isModalVisible!: boolean;
visiblePermissions = false; visiblePermissions = false;
providerKey: string; providerKey?: string;
modalBusy = false; modalBusy = false;
permissionManagementKey = ePermissionManagementComponents.PermissionManagement; permissionManagementKey = ePermissionManagementComponents.PermissionManagement;
onVisiblePermissionChange = event => { onVisiblePermissionChange = (event: boolean) => {
this.visiblePermissions = event; this.visiblePermissions = event;
}; };
@ -82,7 +82,7 @@ export class RolesComponent implements OnInit {
if (!this.form.valid) return; if (!this.form.valid) return;
this.modalBusy = true; this.modalBusy = true;
const { id } = this.selected; const { id } = this.selected || {};
(id (id
? this.service.update(id, { ...this.selected, ...this.form.value }) ? this.service.update(id, { ...this.selected, ...this.form.value })
: this.service.create(this.form.value) : this.service.create(this.form.value)
@ -118,7 +118,7 @@ export class RolesComponent 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;

92
npm/ng-packs/packages/identity/src/lib/components/users/users.component.ts

@ -1,28 +1,12 @@
import { ListService, PagedResultDto } from '@abp/ng.core'; import { ListService, PagedResultDto } from "@abp/ng.core";
import { import { GetIdentityUsersInput, IdentityRoleDto, IdentityUserDto, IdentityUserService } from "@abp/ng.identity/proxy";
GetIdentityUsersInput, import { ePermissionManagementComponents } from "@abp/ng.permission-management";
IdentityRoleDto, import { Confirmation, ConfirmationService, ToasterService } from "@abp/ng.theme.shared";
IdentityUserDto, import { EXTENSIONS_IDENTIFIER, FormPropData, generateFormFromProps } from "@abp/ng.theme.shared/extensions";
IdentityUserService, import { Component, Injector, OnInit, TemplateRef, TrackByFunction, ViewChild } from "@angular/core";
} from '@abp/ng.identity/proxy'; import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from "@angular/forms";
import { ePermissionManagementComponents } from '@abp/ng.permission-management'; import { finalize, switchMap, tap } from "rxjs/operators";
import {Confirmation, ConfirmationService, ToasterService} from '@abp/ng.theme.shared'; import { eIdentityComponents } from "../../enums/components";
import {
EXTENSIONS_IDENTIFIER,
FormPropData,
generateFormFromProps,
} from '@abp/ng.theme.shared/extensions';
import {
Component,
Injector,
OnInit,
TemplateRef,
TrackByFunction,
ViewChild,
} from '@angular/core';
import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { finalize, switchMap, tap } from 'rxjs/operators';
import { eIdentityComponents } from '../../enums/components';
@Component({ @Component({
selector: 'abp-users', selector: 'abp-users',
@ -39,31 +23,31 @@ export class UsersComponent implements OnInit {
data: PagedResultDto<IdentityUserDto> = { items: [], totalCount: 0 }; data: PagedResultDto<IdentityUserDto> = { items: [], totalCount: 0 };
@ViewChild('modalContent', { static: false }) @ViewChild('modalContent', { static: false })
modalContent: TemplateRef<any>; modalContent!: TemplateRef<any>;
form: UntypedFormGroup; form!: UntypedFormGroup;
selected: IdentityUserDto; selected?: IdentityUserDto;
selectedUserRoles: IdentityRoleDto[]; selectedUserRoles?: IdentityRoleDto[];
roles: IdentityRoleDto[]; roles?: IdentityRoleDto[];
visiblePermissions = false; visiblePermissions = false;
providerKey: string; providerKey?: string;
isModalVisible: boolean; isModalVisible?: boolean;
modalBusy = false; modalBusy = false;
permissionManagementKey = ePermissionManagementComponents.PermissionManagement; permissionManagementKey = ePermissionManagementComponents.PermissionManagement;
entityDisplayName: string; entityDisplayName?: string;
trackByFn: TrackByFunction<AbstractControl> = (index, item) => Object.keys(item)[0] || index; trackByFn: TrackByFunction<AbstractControl> = (index, item) => Object.keys(item)[0] || index;
onVisiblePermissionChange = event => { onVisiblePermissionChange = (event: boolean) => {
this.visiblePermissions = event; this.visiblePermissions = event;
}; };
@ -90,20 +74,22 @@ export class UsersComponent implements OnInit {
this.service.getAssignableRoles().subscribe(({ items }) => { this.service.getAssignableRoles().subscribe(({ items }) => {
this.roles = items; this.roles = items;
this.form.addControl( if (this.roles) {
'roleNames', this.form.addControl(
this.fb.array( 'roleNames',
this.roles.map(role => this.fb.array(
this.fb.group({ this.roles.map(role =>
[role.name]: [ this.fb.group({
this.selected.id [role.name as string]: [
? !!this.selectedUserRoles?.find(userRole => userRole.id === role.id) this.selected?.id
: role.isDefault, ? !!this.selectedUserRoles?.find(userRole => userRole.id === role.id)
], : role.isDefault,
}), ],
}),
),
), ),
), );
); }
}); });
} }
@ -137,10 +123,11 @@ export class UsersComponent implements OnInit {
const { roleNames = [] } = this.form.value; const { roleNames = [] } = this.form.value;
const mappedRoleNames = const mappedRoleNames =
roleNames.filter(role => !!role[Object.keys(role)[0]]).map(role => Object.keys(role)[0]) || roleNames
[]; .filter((role: { [key: string]: any }) => !!role[Object.keys(role)[0]])
.map((role: { [key: string]: any }) => Object.keys(role)[0]) || [];
const { id } = this.selected; const { id } = this.selected || {};
(id (id
? this.service.update(id, { ? this.service.update(id, {
@ -166,12 +153,13 @@ export class UsersComponent implements OnInit {
if (status === Confirmation.Status.confirm) { if (status === Confirmation.Status.confirm) {
this.service.delete(id).subscribe(() => { this.service.delete(id).subscribe(() => {
this.toasterService.success('AbpUi::SuccessfullyDeleted'); this.toasterService.success('AbpUi::SuccessfullyDeleted');
this.list.get()}); this.list.get();
});
} }
}); });
} }
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;

8
npm/ng-packs/packages/identity/src/lib/defaults/default-roles-entity-actions.ts

@ -7,7 +7,7 @@ export const DEFAULT_ROLES_ENTITY_ACTIONS = EntityAction.createMany<IdentityRole
text: 'AbpIdentity::Edit', text: 'AbpIdentity::Edit',
action: data => { action: data => {
const component = data.getInjected(RolesComponent); const component = data.getInjected(RolesComponent);
component.edit(data.record.id); component.edit(data.record.id || '');
}, },
permission: 'AbpIdentity.Roles.Update', permission: 'AbpIdentity.Roles.Update',
}, },
@ -15,7 +15,7 @@ export const DEFAULT_ROLES_ENTITY_ACTIONS = EntityAction.createMany<IdentityRole
text: 'AbpIdentity::Permissions', text: 'AbpIdentity::Permissions',
action: data => { action: data => {
const component = data.getInjected(RolesComponent); const component = data.getInjected(RolesComponent);
component.openPermissionsModal(data.record.name); component.openPermissionsModal(data.record.name || '');
}, },
permission: 'AbpIdentity.Roles.ManagePermissions', permission: 'AbpIdentity.Roles.ManagePermissions',
}, },
@ -23,9 +23,9 @@ export const DEFAULT_ROLES_ENTITY_ACTIONS = EntityAction.createMany<IdentityRole
text: 'AbpIdentity::Delete', text: 'AbpIdentity::Delete',
action: data => { action: data => {
const component = data.getInjected(RolesComponent); const component = data.getInjected(RolesComponent);
component.delete(data.record.id, data.record.name); component.delete(data.record.id || '', data.record.name || '');
}, },
permission: 'AbpIdentity.Roles.Delete', permission: 'AbpIdentity.Roles.Delete',
visible: data => !data.record.isStatic, visible: data => !data?.record.isStatic,
}, },
]); ]);

4
npm/ng-packs/packages/identity/src/lib/defaults/default-roles-form-props.ts

@ -1,5 +1,5 @@
import { IdentityRoleDto } from '@abp/ng.identity/proxy'; import { IdentityRoleDto } from '@abp/ng.identity/proxy';
import { ePropType, FormProp, PropData } from '@abp/ng.theme.shared/extensions'; import { ePropType, FormProp, PropData, PropPredicate } from "@abp/ng.theme.shared/extensions";
import { Validators } from '@angular/forms'; import { Validators } from '@angular/forms';
export const DEFAULT_ROLES_CREATE_FORM_PROPS = FormProp.createMany<IdentityRoleDto>([ export const DEFAULT_ROLES_CREATE_FORM_PROPS = FormProp.createMany<IdentityRoleDto>([
@ -8,7 +8,7 @@ export const DEFAULT_ROLES_CREATE_FORM_PROPS = FormProp.createMany<IdentityRoleD
name: 'name', name: 'name',
displayName: 'AbpIdentity::RoleName', displayName: 'AbpIdentity::RoleName',
id: 'role-name', id: 'role-name',
disabled: (data: PropData<IdentityRoleDto>) => data.record && data.record.isStatic, disabled: ((data: PropData<IdentityRoleDto>) => data.record && data.record.isStatic) as PropPredicate<IdentityRoleDto>,
validators: () => [Validators.required], validators: () => [Validators.required],
}, },
{ {

23
npm/ng-packs/packages/identity/src/lib/defaults/default-users-entity-actions.ts

@ -1,14 +1,14 @@
import {IdentityUserDto} from '@abp/ng.identity/proxy'; import { IdentityUserDto } from '@abp/ng.identity/proxy';
import { EntityAction } from '@abp/ng.theme.shared/extensions'; import { EntityAction } from '@abp/ng.theme.shared/extensions';
import { UsersComponent } from '../components/users/users.component'; import { UsersComponent } from '../components/users/users.component';
import {ConfigStateService, CurrentUserDto} from "@abp/ng.core"; import { ConfigStateService, CurrentUserDto } from '@abp/ng.core';
export const DEFAULT_USERS_ENTITY_ACTIONS = EntityAction.createMany<IdentityUserDto>([ export const DEFAULT_USERS_ENTITY_ACTIONS = EntityAction.createMany<IdentityUserDto>([
{ {
text: 'AbpIdentity::Edit', text: 'AbpIdentity::Edit',
action: data => { action: data => {
const component = data.getInjected(UsersComponent); const component = data.getInjected(UsersComponent);
component.edit(data.record.id); component.edit(data.record.id || '');
}, },
permission: 'AbpIdentity.Users.Update', permission: 'AbpIdentity.Users.Update',
}, },
@ -16,20 +16,21 @@ export const DEFAULT_USERS_ENTITY_ACTIONS = EntityAction.createMany<IdentityUser
text: 'AbpIdentity::Permissions', text: 'AbpIdentity::Permissions',
action: data => { action: data => {
const component = data.getInjected(UsersComponent); const component = data.getInjected(UsersComponent);
component.openPermissionsModal(data.record.id, data.record.userName); component.openPermissionsModal(data.record.id || '', data.record.userName);
}, },
permission: 'AbpIdentity.Users.ManagePermissions', permission: 'AbpIdentity.Users.ManagePermissions',
}, { },
{
text: 'AbpIdentity::Delete', text: 'AbpIdentity::Delete',
action: data => { action: data => {
const component = data.getInjected(UsersComponent); const component = data.getInjected(UsersComponent);
component.delete(data.record.id, data.record.name || data.record.userName); component.delete(data.record.id || '', data.record.name || data.record.userName || '');
}, },
visible: data => { visible: data => {
const userName = data.record.userName; const userName = data?.record.userName;
const configStateService = data.getInjected(ConfigStateService) const configStateService = data?.getInjected(ConfigStateService);
const currentUser = configStateService.getOne("currentUser") as CurrentUserDto; const currentUser = configStateService?.getOne('currentUser') as CurrentUserDto;
return userName !== currentUser.userName; return userName !== currentUser.userName;
}, },
permission: 'AbpIdentity.Users.Delete', permission: 'AbpIdentity.Users.Delete',
}, },

2
npm/ng-packs/packages/identity/src/lib/defaults/default-users-form-props.ts

@ -67,7 +67,7 @@ export const DEFAULT_USERS_EDIT_FORM_PROPS = DEFAULT_USERS_CREATE_FORM_PROPS.map
if (prop.name === 'password') { if (prop.name === 'password') {
return { return {
...prop, ...prop,
validators: data => [...getPasswordValidators({ get: data.getInjected })], validators: (data: any) => [...getPasswordValidators({ get: data.getInjected })],
}; };
} }
return prop; return prop;

38
npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts

@ -49,10 +49,10 @@ export class PermissionManagementComponent
PermissionManagement.PermissionManagementComponentOutputs PermissionManagement.PermissionManagementComponentOutputs
{ {
@Input() @Input()
readonly providerName: string; readonly providerName!: string;
@Input() @Input()
readonly providerKey: string; readonly providerKey!: string;
@Input() @Input()
readonly hideBadges = false; readonly hideBadges = false;
@ -90,13 +90,13 @@ export class PermissionManagementComponent
@Output() readonly visibleChange = new EventEmitter<boolean>(); @Output() readonly visibleChange = new EventEmitter<boolean>();
@ViewChildren('selectAllInThisTabsRef') @ViewChildren('selectAllInThisTabsRef')
selectAllInThisTabsRef: QueryList<ElementRef<HTMLInputElement>>; selectAllInThisTabsRef!: QueryList<ElementRef<HTMLInputElement>>;
@ViewChildren('selectAllInAllTabsRef') @ViewChildren('selectAllInAllTabsRef')
selectAllInAllTabsRef: QueryList<ElementRef<HTMLInputElement>>; selectAllInAllTabsRef!: QueryList<ElementRef<HTMLInputElement>>;
data: GetPermissionListResultDto = { groups: [], entityDisplayName: null }; data: GetPermissionListResultDto = { groups: [], entityDisplayName: '' };
selectedGroup: PermissionGroupDto; selectedGroup?: PermissionGroupDto | null;
permissions: PermissionWithGroupName[] = []; permissions: PermissionWithGroupName[] = [];
@ -119,16 +119,16 @@ export class PermissionManagementComponent
(document.body.dir as LocaleDirection) === 'rtl' ? 'right' : 'left' (document.body.dir as LocaleDirection) === 'rtl' ? 'right' : 'left'
}.px`; }.px`;
const permissions = this.data.groups.find( const permissions =
group => group.name === this.selectedGroup.name, (this.data.groups.find(group => group.name === this.selectedGroup?.name) || {}).permissions ||
).permissions; [];
return permissions.map( return permissions.map(
permission => permission =>
({ ({
...permission, ...permission,
style: { [margin]: findMargin(permissions, permission) }, style: { [margin]: findMargin(permissions, permission) },
isGranted: this.permissions.find(per => per.name === permission.name).isGranted, isGranted: (this.permissions.find(per => per.name === permission.name) || {}).isGranted,
} as unknown as PermissionWithStyle), } as unknown as PermissionWithStyle),
); );
} }
@ -158,7 +158,7 @@ export class PermissionManagementComponent
return false; return false;
} }
onClickCheckbox(clickedPermission: PermissionGrantInfoDto, value) { onClickCheckbox(clickedPermission: PermissionGrantInfoDto) {
if ( if (
clickedPermission.isGranted && clickedPermission.isGranted &&
this.isGrantedByOtherProviderName(clickedPermission.grantedProviders) this.isGrantedByOtherProviderName(clickedPermission.grantedProviders)
@ -257,7 +257,7 @@ export class PermissionManagementComponent
const changedPermissions: UpdatePermissionDto[] = this.permissions const changedPermissions: UpdatePermissionDto[] = this.permissions
.filter(per => .filter(per =>
unchangedPermissions.find(unchanged => unchanged.name === per.name).isGranted === (unchangedPermissions.find(unchanged => unchanged.name === per.name) || {}).isGranted ===
per.isGranted per.isGranted
? false ? false
: true, : true,
@ -305,7 +305,7 @@ export class PermissionManagementComponent
initModal() { initModal() {
// TODO: Refactor // TODO: Refactor
setTimeout(() => { setTimeout(() => {
this.setDisabled(this.selectedGroup.permissions); this.setDisabled(this.selectedGroup?.permissions || []);
this.setTabCheckboxState(); this.setTabCheckboxState();
this.setGrantCheckboxState(); this.setGrantCheckboxState();
}); });
@ -329,7 +329,10 @@ export class PermissionManagementComponent
} }
} }
function findMargin(permissions: PermissionGrantInfoDto[], permission: PermissionGrantInfoDto) { function findMargin(
permissions: PermissionGrantInfoDto[],
permission: PermissionGrantInfoDto,
): number {
const parentPermission = permissions.find(per => per.name === permission.parentName); const parentPermission = permissions.find(per => per.name === permission.parentName);
if (parentPermission && parentPermission.parentName) { if (parentPermission && parentPermission.parentName) {
@ -342,7 +345,10 @@ function findMargin(permissions: PermissionGrantInfoDto[], permission: Permissio
function getPermissions(groups: PermissionGroupDto[]): PermissionWithGroupName[] { function getPermissions(groups: PermissionGroupDto[]): PermissionWithGroupName[] {
return groups.reduce( return groups.reduce(
(acc, val) => [...acc, ...val.permissions.map(p => ({ ...p, groupName: val.name }))], (acc, val) => [
[], ...acc,
...val.permissions.map<PermissionWithGroupName>(p => ({ ...p, groupName: val.name || '' })),
],
[] as PermissionWithGroupName[],
); );
} }

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

@ -1,5 +1,5 @@
import { Directive, Injector, Input } from '@angular/core'; import { Directive, Injector, Input } from '@angular/core';
import { ActionData, ActionList } from '../../models/actions'; import { ActionData, ActionList, InferredAction } from '../../models/actions';
import { ExtensionsService } from '../../services/extensions.service'; import { ExtensionsService } from '../../services/extensions.service';
import { EXTENSIONS_ACTION_TYPE, EXTENSIONS_IDENTIFIER } from '../../tokens/extensions.token'; import { EXTENSIONS_ACTION_TYPE, EXTENSIONS_IDENTIFIER } from '../../tokens/extensions.token';
import { InferredData, InferredRecord } from '../../models/toolbar-actions'; import { InferredData, InferredRecord } from '../../models/toolbar-actions';
@ -7,9 +7,9 @@ import { InferredData, InferredRecord } from '../../models/toolbar-actions';
// Fix for https://github.com/angular/angular/issues/23904 // Fix for https://github.com/angular/angular/issues/23904
// @dynamic // @dynamic
@Directive() @Directive()
export abstract class AbstractActionsComponent<L extends ActionList<any>> extends ActionData< export abstract class AbstractActionsComponent<
InferredRecord<L> L extends ActionList<any, InferredAction<L>>,
> { > extends ActionData<InferredRecord<L>> {
readonly actionList: L; readonly actionList: L;
readonly getInjected: InferredData<L>['getInjected']; readonly getInjected: InferredData<L>['getInjected'];

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

@ -57,7 +57,7 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
@ViewChild('field') private fieldRef!: ElementRef<HTMLElement>; @ViewChild('field') private fieldRef!: ElementRef<HTMLElement>;
public injectorForCustomComponent: Injector; public injectorForCustomComponent?: Injector;
asterisk = ''; asterisk = '';
@ -95,7 +95,7 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
? text$.pipe( ? text$.pipe(
debounceTime(300), debounceTime(300),
distinctUntilChanged(), distinctUntilChanged(),
switchMap(text => this.prop.options(this.data, text)), switchMap(text => this.prop?.options?.(this.data, text) || of([])),
) )
: of([]); : of([]);
@ -109,7 +109,7 @@ export class ExtensibleFormPropComponent implements OnChanges, AfterViewInit {
get isInvalid() { get isInvalid() {
const control = this.form.get(this.prop.name); const control = this.form.get(this.prop.name);
return control.touched && control.invalid; return control?.touched && control.invalid;
} }
constructor( constructor(

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

@ -44,7 +44,7 @@ export class ExtensibleFormComponent<R = any> {
} }
extraPropertiesKey = EXTRA_PROPERTIES_KEY; extraPropertiesKey = EXTRA_PROPERTIES_KEY;
groupedPropList: GroupedFormPropList; groupedPropList!: GroupedFormPropList;
record!: R; record!: R;
createGroupedList(propList: FormPropList<R>) { createGroupedList(propList: FormPropList<R>) {

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

@ -48,7 +48,7 @@ const DEFAULT_ACTIONS_COLUMN_WIDTH = 150;
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class ExtensibleTableComponent<R = any> implements OnChanges { export class ExtensibleTableComponent<R = any> implements OnChanges {
protected _actionsText: string; protected _actionsText!: string;
@Input() @Input()
set actionsText(value: string) { set actionsText(value: string) {
this._actionsText = value; this._actionsText = value;
@ -57,13 +57,13 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
return this._actionsText ?? (this.actionList.length > 1 ? 'AbpUi::Actions' : ''); return this._actionsText ?? (this.actionList.length > 1 ? 'AbpUi::Actions' : '');
} }
@Input() data: R[]; @Input() data!: R[];
@Input() list: ListService; @Input() list!: ListService;
@Input() recordsTotal: number; @Input() recordsTotal!: number;
@Input() set actionsColumnWidth(width: number) { @Input() set actionsColumnWidth(width: number) {
this.setColumnWidths(width ? Number(width) : undefined); this.setColumnWidths(width ? Number(width) : undefined);
} }
@Input() actionsTemplate: TemplateRef<any>; @Input() actionsTemplate?: TemplateRef<any>;
@Output() tableActivate = new EventEmitter(); @Output() tableActivate = new EventEmitter();
@ -73,7 +73,7 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
entityPropTypeClasses: EntityPropTypeClass; entityPropTypeClasses: EntityPropTypeClass;
readonly columnWidths: number[]; readonly columnWidths!: number[];
readonly propList: EntityPropList<R>; readonly propList: EntityPropList<R>;
@ -102,7 +102,7 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
this.setColumnWidths(DEFAULT_ACTIONS_COLUMN_WIDTH); this.setColumnWidths(DEFAULT_ACTIONS_COLUMN_WIDTH);
} }
private setColumnWidths(actionsColumn: number) { private setColumnWidths(actionsColumn: number | undefined) {
const widths = [actionsColumn]; const widths = [actionsColumn];
this.propList.forEach(({ value: prop }) => { this.propList.forEach(({ value: prop }) => {
widths.push(prop.columnWidth); widths.push(prop.columnWidth);
@ -110,8 +110,8 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
(this.columnWidths as any) = widths; (this.columnWidths as any) = widths;
} }
private getDate(value: Date, format: string) { private getDate(value: Date | undefined, format: string | undefined) {
return value ? formatDate(value, format, this.locale) : ''; return value && format ? formatDate(value, format, this.locale) : '';
} }
private getIcon(value: boolean) { private getIcon(value: boolean) {
@ -122,7 +122,7 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
private getEnum(rowValue: any, list: Array<ABP.Option<any>>) { private getEnum(rowValue: any, list: Array<ABP.Option<any>>) {
if (!list) return rowValue; if (!list) return rowValue;
const { key } = list.find(({ value }) => value === rowValue); const { key } = list.find(({ value }) => value === rowValue) || {};
return key; return key;
} }
@ -139,7 +139,7 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
case ePropType.DateTime: case ePropType.DateTime:
return this.getDate(value, getShortDateShortTimeFormat(this.config)); return this.getDate(value, getShortDateShortTimeFormat(this.config));
case ePropType.Enum: case ePropType.Enum:
return this.getEnum(value, prop.enumList); return this.getEnum(value, prop.enumList || []);
default: default:
return value; return value;
// More types can be handled in the future // More types can be handled in the future
@ -151,7 +151,7 @@ export class ExtensibleTableComponent<R = any> implements OnChanges {
ngOnChanges({ data }: SimpleChanges) { ngOnChanges({ data }: SimpleChanges) {
if (!data?.currentValue) return; if (!data?.currentValue) return;
this.data = data.currentValue.map((record, index) => { this.data = data.currentValue.map((record: any, index: number) => {
this.propList.forEach(prop => { this.propList.forEach(prop => {
const propData = { getInjected: this.getInjected, record, index } as any; const propData = { getInjected: this.getInjected, record, index } as any;
const value = this.getContent(prop.value, propData); const value = this.getContent(prop.value, propData);

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

@ -24,7 +24,7 @@ import { AbstractActionsComponent } from '../abstract-actions/abstract-actions.c
export class GridActionsComponent<R = any> extends AbstractActionsComponent<EntityActionList<R>> { export class GridActionsComponent<R = any> extends AbstractActionsComponent<EntityActionList<R>> {
@Input() icon = 'fa fa-cog'; @Input() icon = 'fa fa-cog';
@Input() readonly index: number; @Input() readonly index?: number;
@Input() text = ''; @Input() text = '';

20
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.html

@ -13,15 +13,17 @@
</ng-container> </ng-container>
<ng-template #button> <ng-template #button>
<button <ng-container *ngIf="asToolbarAction(action).value as toolbarAction">
(click)="action.action(data)" <button
type="button" (click)="action.action(data)"
[ngClass]="action.btnClass ? action.btnClass : defaultBtnClass" type="button"
class="d-inline-flex align-items-center gap-1" [ngClass]="toolbarAction.btnClass ? toolbarAction.btnClass : defaultBtnClass"
> class="d-inline-flex align-items-center gap-1"
<i [ngClass]="action.icon" [class.me-1]="action.icon"></i> >
{{ action.text | abpLocalization }} <i [ngClass]="toolbarAction.icon" [class.me-1]="toolbarAction.icon"></i>
</button> {{ toolbarAction.text | abpLocalization }}
</button>
</ng-container>
</ng-template> </ng-template>
</ng-container> </ng-container>
</ng-container> </ng-container>

8
npm/ng-packs/packages/theme-shared/extensions/src/lib/components/page-toolbar/page-toolbar.component.ts

@ -1,6 +1,8 @@
import { ChangeDetectionStrategy, Component, Injector, TrackByFunction } from '@angular/core'; import { ChangeDetectionStrategy, Component, Injector, TrackByFunction } from '@angular/core';
import { import {
HasCreateInjectorPipe, HasCreateInjectorPipe,
ToolbarAction,
ToolbarActionDefault,
ToolbarActionList, ToolbarActionList,
ToolbarComponent, ToolbarComponent,
} from '../../models/toolbar-actions'; } from '../../models/toolbar-actions';
@ -32,4 +34,10 @@ export class PageToolbarComponent<R = any>
constructor(public readonly injector: Injector) { constructor(public readonly injector: Injector) {
super(injector); super(injector);
} }
asToolbarAction(value: ToolbarActionDefault): { value: ToolbarAction } {
return {
value: value as ToolbarAction,
};
}
} }

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

@ -1,5 +1,5 @@
import { LinkedList } from '@abp/utils'; import { LinkedList } from '@abp/utils';
import { InjectFlags, InjectionToken, Type } from '@angular/core'; import { InjectFlags, InjectionToken, InjectOptions, Type } from '@angular/core';
import { O } from 'ts-toolbelt'; import { O } from 'ts-toolbelt';
export abstract class ActionList<R = any, A = Action<R>> extends LinkedList<A> {} export abstract class ActionList<R = any, A = Action<R>> extends LinkedList<A> {}
@ -8,7 +8,7 @@ export abstract class ActionData<R = any> {
abstract getInjected: <T>( abstract getInjected: <T>(
token: Type<T> | InjectionToken<T>, token: Type<T> | InjectionToken<T>,
notFoundValue?: T, notFoundValue?: T,
flags?: InjectFlags, flags?: InjectOptions | InjectFlags,
) => T; ) => T;
index?: number; index?: number;
abstract record: R; abstract record: R;
@ -27,8 +27,8 @@ export type ReadonlyActionData<R = any> = O.Readonly<Omit<ActionData<R>, 'data'>
export abstract class Action<R = any> { export abstract class Action<R = any> {
constructor( constructor(
public readonly permission: string, public readonly permission: string,
public readonly visible: ActionPredicate<R> = _ => true, public readonly visible: ActionPredicate<R> = () => true,
public readonly action: ActionCallback<R> = _ => {}, public readonly action: ActionCallback<R> = () => {},
) {} ) {}
} }
@ -46,7 +46,7 @@ export abstract class ActionsFactory<C extends Actions<any>> {
} }
} }
export abstract class Actions<L extends ActionList> { export abstract class Actions<L extends ActionList<any, InferredAction<L>>> {
protected abstract _ctor: Type<L>; protected abstract _ctor: Type<L>;
get actions(): L { get actions(): L {
@ -68,11 +68,14 @@ export abstract class Actions<L extends ActionList> {
} }
} }
export type ActionContributorCallbacks<L extends ActionList<any>> = Record< export type ActionContributorCallbacks<L extends ActionList<any, InferredAction<L>>> = Record<
string, string,
ActionContributorCallback<L>[] ActionContributorCallback<L>[]
>; >;
export type ActionContributorCallback<L extends ActionList<any>> = (actionList: L) => any; export type ActionContributorCallback<L extends ActionList<any, InferredAction<L>>> = (
actionList: L,
) => any;
type InferredActionList<C> = C extends Actions<infer L> ? L : never; type InferredActionList<C> = C extends Actions<infer L> ? L : never;
export type InferredAction<T> = T extends ActionList<any, infer U> ? U : T;

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

@ -24,7 +24,7 @@ export class EntityAction<R = any> extends Action<R> {
readonly icon: string; readonly icon: string;
constructor(options: EntityActionOptions<R>) { constructor(options: EntityActionOptions<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 || '';
} }

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

@ -27,9 +27,9 @@ export class EntityProp<R = any> extends Prop<R> {
readonly columnWidth: number | undefined; readonly columnWidth: number | undefined;
readonly sortable: boolean; readonly sortable: boolean;
readonly valueResolver: PropCallback<R, Observable<any>>; readonly valueResolver: PropCallback<R, Observable<any>>;
readonly action: ActionCallback<R>; readonly action?: ActionCallback<R>;
readonly component: Type<any>; readonly component?: Type<any>;
readonly enumList: Array<ABP.Option<any>>; readonly enumList?: Array<ABP.Option<any>>;
constructor(options: EntityPropOptions<R>) { constructor(options: EntityPropOptions<R>) {
super( super(
@ -44,7 +44,8 @@ export class EntityProp<R = any> extends Prop<R> {
this.columnWidth = options.columnWidth; this.columnWidth = options.columnWidth;
this.sortable = options.sortable || false; this.sortable = options.sortable || false;
this.valueResolver = this.valueResolver =
options.valueResolver || (data => of(escapeHtmlChars(data.record[this.name]))); options.valueResolver ||
(data => of(escapeHtmlChars((data.record as PropDataObject)[this.name])));
if (options.action) { if (options.action) {
this.action = options.action; this.action = options.action;
} }
@ -82,3 +83,4 @@ export type EntityPropOptions<R = any> = O.Optional<
export type EntityPropDefaults<R = any> = Record<string, EntityProp<R>[]>; export type EntityPropDefaults<R = any> = Record<string, EntityProp<R>[]>;
export type EntityPropContributorCallback<R = any> = PropContributorCallback<EntityPropList<R>>; export type EntityPropContributorCallback<R = any> = PropContributorCallback<EntityPropList<R>>;
export type EntityPropContributorCallbacks<R = any> = PropContributorCallbacks<EntityPropList<R>>; export type EntityPropContributorCallbacks<R = any> = PropContributorCallbacks<EntityPropList<R>>;
type PropDataObject = { [key: string]: any };

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

@ -18,7 +18,7 @@ import {
export class FormPropList<R = any> extends PropList<R, FormProp<R>> {} export class FormPropList<R = any> extends PropList<R, FormProp<R>> {}
export class FormProps<R = any> extends Props<PropList<R, FormProp<R>> { export class FormProps<R = any> extends Props<PropList<R, FormProp<R>>> {
protected _ctor: Type<FormPropList<R>> = FormPropList; protected _ctor: Type<FormPropList<R>> = FormPropList;
} }
@ -46,7 +46,7 @@ export class GroupedFormPropList<R = any> {
} }
export interface GroupedFormPropItem { export interface GroupedFormPropItem {
group: FormPropGroup; group?: FormPropGroup;
formPropList: FormPropList; formPropList: FormPropList;
} }
@ -94,7 +94,7 @@ export class FormProp<R = any> extends Prop<R> {
this.options = options.options; this.options = options.options;
this.id = options.id || options.name; this.id = options.id || options.name;
const defaultValue = options.defaultValue; const defaultValue = options.defaultValue;
this.defaultValue = isFalsyValue(defaultValue) ? defaultValue as number : defaultValue || ''; this.defaultValue = isFalsyValue(defaultValue) ? (defaultValue as number) : defaultValue || '';
this.displayTextResolver = options.displayTextResolver; this.displayTextResolver = options.displayTextResolver;
} }

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

@ -6,7 +6,7 @@ import { PropContributorCallbacks } from '../props';
export type DisplayNameGeneratorFn = ( export type DisplayNameGeneratorFn = (
displayName: LocalizableStringDto, displayName: LocalizableStringDto,
fallback: LocalizableStringDto, fallback: LocalizableStringDto,
) => string; ) => string | undefined;
export type EntityExtensions = Record<string, EntityExtensionDto>; export type EntityExtensions = Record<string, EntityExtensionDto>;

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

@ -56,7 +56,7 @@ export abstract class PropsFactory<C extends Props<any>> {
} }
} }
export abstract class Props<L extends PropList> { export abstract class Props<L extends PropList<any, InferredProp<L>>> {
protected abstract _ctor: Type<L>; protected abstract _ctor: Type<L>;
get props(): L { get props(): L {
@ -78,11 +78,14 @@ export abstract class Props<L extends PropList> {
} }
} }
export type PropContributorCallbacks<L extends PropList<any>> = Record< export type PropContributorCallbacks<L extends PropList<any, InferredProp<L>>> = Record<
string, string,
PropContributorCallback<L>[] PropContributorCallback<L>[]
>; >;
export type PropContributorCallback<L extends PropList<any>> = (propList: L) => any; export type PropContributorCallback<L extends PropList<any, InferredProp<L>>> = (
propList: L,
) => any;
type InferredPropList<C> = C extends Props<infer L> ? L : never; type InferredPropList<C> = C extends Props<infer L> ? L : never;
export type InferredProp<T> = T extends PropList<any, infer U> ? U : T;

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

@ -11,10 +11,7 @@ import {
ReadonlyActionData, ReadonlyActionData,
} from './actions'; } from './actions';
export class ToolbarActionList<R = any> extends ActionList< export class ToolbarActionList<R = any> extends ActionList<R, ToolbarActionDefault<R>> {}
R,
ToolbarAction<R> | ToolbarComponent<R>
> {}
export class ToolbarActions<R = any> extends Actions<ToolbarActionList<R>> { export class ToolbarActions<R = any> extends Actions<ToolbarActionList<R>> {
protected _ctor: Type<ToolbarActionList<R>> = ToolbarActionList; protected _ctor: Type<ToolbarActionList<R>> = ToolbarActionList;
@ -84,7 +81,7 @@ export type ToolbarActionContributorCallbacks<R = any> = ActionContributorCallba
ToolbarActionList<R> ToolbarActionList<R>
>; >;
export type InferredData<L> = ActionData<InferredRecord<L>>; export type InferredData<L> = ActionData<InferredRecord<L>>;
export type InferredRecord<L> = L extends ActionList<infer R> ? R : never; export type InferredRecord<L> = L extends ActionList<infer R> ? R : any;
export interface HasCreateInjectorPipe<R> { export interface HasCreateInjectorPipe<R> {
getData: () => ReadonlyActionData<R>; getData: () => ReadonlyActionData<R>;

2
npm/ng-packs/packages/theme-shared/extensions/src/lib/pipes/create-injector.pipe.ts

@ -25,7 +25,7 @@ export class CreateInjectorPipe<R> implements PipeTransform {
options?: InjectOptions | InjectFlags, options?: InjectOptions | InjectFlags,
) => { ) => {
const componentData = context.getData(); const componentData = context.getData();
const componentDataCallback = data => { const componentDataCallback = (data: any) => {
data = data ?? context.getData(); data = data ?? context.getData();
return action.action(data); return action.action(data);
}; };

4
npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/actions.util.ts

@ -1,4 +1,4 @@
import { ActionContributorCallback, ActionList, ActionsFactory } from '../models/actions'; import { ActionContributorCallback, ActionList, ActionsFactory, InferredAction } from "../models/actions";
import { import {
EntityActionContributorCallbacks, EntityActionContributorCallbacks,
EntityActionDefaults, EntityActionDefaults,
@ -20,7 +20,7 @@ export function mergeWithDefaultActions<F extends ActionsFactory<any>>(
Object.keys(defaultActions).forEach((name: string) => { Object.keys(defaultActions).forEach((name: string) => {
const actions: InferredActions<F> = extension.get(name); const actions: InferredActions<F> = extension.get(name);
actions.clearContributors(); actions.clearContributors();
actions.addContributor((actionList: ActionList) => actions.addContributor((actionList: ActionList<any, InferredAction<any>>) =>
actionList.addManyTail(defaultActions[name]), actionList.addManyTail(defaultActions[name]),
); );
contributors.forEach(contributor => contributors.forEach(contributor =>

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

@ -1,11 +1,11 @@
import { ABP, LocalizationService } from '@abp/ng.core'; import { ABP, ExtensionEnumFieldDto, LocalizationService } from '@abp/ng.core';
import { merge, Observable, of } from 'rxjs'; import { merge, Observable, of } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { EXTRA_PROPERTIES_KEY } from '../constants/extra-properties'; import { EXTRA_PROPERTIES_KEY } from '../constants/extra-properties';
import { ObjectExtensions } from '../models/object-extensions'; import { ObjectExtensions } from '../models/object-extensions';
import { PropCallback } from '../models/props'; import { PropCallback } from '../models/props';
export function createEnum(members: ObjectExtensions.ExtensionEnumFieldDto[]) { export function createEnum(members: ExtensionEnumFieldDto[]) {
const enumObject: any = {}; const enumObject: any = {};
members.forEach(({ name = '', value }) => { members.forEach(({ name = '', value }) => {

10
npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/form-props.util.ts

@ -4,20 +4,20 @@ import { DateAdapter } from '../adapters/date.adapter';
import { TimeAdapter } from '../adapters/time.adapter'; import { TimeAdapter } from '../adapters/time.adapter';
import { EXTRA_PROPERTIES_KEY } from '../constants/extra-properties'; import { EXTRA_PROPERTIES_KEY } from '../constants/extra-properties';
import { ePropType } from '../enums/props.enum'; import { ePropType } from '../enums/props.enum';
import { FormPropList } from '../models/form-props'; import { FormProp, FormPropList } from "../models/form-props";
import { PropData } from '../models/props'; import { InferredProp, PropData } from "../models/props";
import { ExtensionsService } from '../services/extensions.service'; import { ExtensionsService } from '../services/extensions.service';
import { EXTENSIONS_IDENTIFIER } from '../tokens/extensions.token'; import { EXTENSIONS_IDENTIFIER } from '../tokens/extensions.token';
export function generateFormFromProps<R extends any>(data: PropData<R>) { export function generateFormFromProps<R = any>(data: PropData<R>) {
const extensions = data.getInjected(ExtensionsService); const extensions = data.getInjected(ExtensionsService<R>);
const identifier = data.getInjected(EXTENSIONS_IDENTIFIER); const identifier = data.getInjected(EXTENSIONS_IDENTIFIER);
const form = new UntypedFormGroup({}); const form = new UntypedFormGroup({});
const extraForm = new UntypedFormGroup({}); const extraForm = new UntypedFormGroup({});
form.addControl(EXTRA_PROPERTIES_KEY, extraForm); form.addControl(EXTRA_PROPERTIES_KEY, extraForm);
const record = data.record || {}; const record = data.record || {} as {[key:string]: any};
const type = JSON.stringify(record) === '{}' ? 'create' : 'edit'; const type = JSON.stringify(record) === '{}' ? 'create' : 'edit';
const props: FormPropList<R> = extensions[`${type}FormProps`].get(identifier).props; const props: FormPropList<R> = extensions[`${type}FormProps`].get(identifier).props;
const extraProperties = record[EXTRA_PROPERTIES_KEY] || {}; const extraProperties = record[EXTRA_PROPERTIES_KEY] || {};

20
npm/ng-packs/packages/theme-shared/extensions/src/lib/utils/props.util.ts

@ -1,4 +1,4 @@
import { of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { EXTRA_PROPERTIES_KEY } from '../constants/extra-properties'; import { EXTRA_PROPERTIES_KEY } from '../constants/extra-properties';
import { import {
EntityPropContributorCallbacks, EntityPropContributorCallbacks,
@ -15,10 +15,18 @@ import {
EditFormPropsFactory, EditFormPropsFactory,
FormProps, FormProps,
} from '../models/form-props'; } from '../models/form-props';
import { PropContributorCallback, PropData, PropList, PropsFactory } from '../models/props'; import {
InferredProp,
PropCallback,
PropContributorCallback,
PropList,
PropsFactory,
} from '../models/props';
export function createExtraPropertyValueResolver<T>(name: string) { export function createExtraPropertyValueResolver<T>(
return (data?: PropData<T>) => of(data.record[EXTRA_PROPERTIES_KEY][name]); name: string,
): PropCallback<T, Observable<any>> {
return (data?) => of((data.record as { [key: string]: any })[EXTRA_PROPERTIES_KEY][name]);
} }
export function mergeWithDefaultProps<F extends PropsFactory<any>>( export function mergeWithDefaultProps<F extends PropsFactory<any>>(
@ -29,7 +37,9 @@ export function mergeWithDefaultProps<F extends PropsFactory<any>>(
Object.keys(defaultProps).forEach((name: string) => { Object.keys(defaultProps).forEach((name: string) => {
const props: InferredProps<F> = extension.get(name); const props: InferredProps<F> = extension.get(name);
props.clearContributors(); props.clearContributors();
props.addContributor((propList: PropList) => propList.addManyTail(defaultProps[name])); props.addContributor((propList: PropList<any, InferredProp<any>>) =>
propList.addManyTail(defaultProps[name]),
);
contributors.forEach(contributor => contributors.forEach(contributor =>
(contributor[name] || []).forEach((callback: PropContributorCallback<any>) => (contributor[name] || []).forEach((callback: PropContributorCallback<any>) =>
props.addContributor(callback), props.addContributor(callback),

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

@ -2,29 +2,29 @@ import {
ABP, ABP,
ApplicationLocalizationConfigurationDto, ApplicationLocalizationConfigurationDto,
ConfigStateService, ConfigStateService,
ExtensionEnumDto,
ExtensionPropertyUiLookupDto, ExtensionPropertyUiLookupDto,
} from '@abp/ng.core'; ObjectExtensionsDto
import { Observable, pipe, zip } from 'rxjs'; } from "@abp/ng.core";
import { filter, map, switchMap, take } from 'rxjs/operators'; import { Observable, pipe, zip } from "rxjs";
import { ePropType } from '../enums/props.enum'; import { filter, map, switchMap, take } from "rxjs/operators";
import { EntityProp, EntityPropList } from '../models/entity-props'; import { ePropType } from "../enums/props.enum";
import { FormProp, FormPropList } from '../models/form-props'; import { EntityProp, EntityPropList } from "../models/entity-props";
import { ObjectExtensions } from '../models/object-extensions'; import { FormProp, FormPropList } from "../models/form-props";
import { PropCallback } from '../models/props'; import { ObjectExtensions } from "../models/object-extensions";
import { createEnum, createEnumOptions, createEnumValueResolver } from './enum.util'; import { PropCallback } from "../models/props";
import { createDisplayNameLocalizationPipeKeyGenerator } from './localization.util'; import { createEnum, createEnumOptions, createEnumValueResolver } from "./enum.util";
import { createExtraPropertyValueResolver } from './props.util'; import { createDisplayNameLocalizationPipeKeyGenerator } from "./localization.util";
import { createExtraPropertyValueResolver } from "./props.util";
import { import {
createTypeaheadDisplayNameGenerator, createTypeaheadDisplayNameGenerator,
createTypeaheadOptions, createTypeaheadOptions,
getTypeaheadType, getTypeaheadType,
hasTypeaheadTextSuffix, hasTypeaheadTextSuffix
} from './typeahead.util'; } from "./typeahead.util";
import { getValidatorsFromProperty } from './validation.util'; import { getValidatorsFromProperty } from "./validation.util";
function selectObjectExtensions( function selectObjectExtensions(configState: ConfigStateService): Observable<ObjectExtensionsDto> {
configState: ConfigStateService,
): Observable<ObjectExtensions.ObjectExtensionsDto> {
return configState.getOne$('objectExtensions'); return configState.getOne$('objectExtensions');
} }
@ -36,9 +36,9 @@ function selectLocalization(
function selectEnums( function selectEnums(
configState: ConfigStateService, configState: ConfigStateService,
): Observable<Record<string, ObjectExtensions.ExtensionEnumDto>> { ): Observable<Record<string, ExtensionEnumDto>> {
return selectObjectExtensions(configState).pipe( return selectObjectExtensions(configState).pipe(
map((extensions: ObjectExtensions.ObjectExtensionsDto) => map((extensions: ObjectExtensionsDto) =>
Object.keys(extensions.enums).reduce((acc, key) => { Object.keys(extensions.enums).reduce((acc, key) => {
const { fields, localizationResource } = extensions.enums[key]; const { fields, localizationResource } = extensions.enums[key];
acc[key] = { acc[key] = {
@ -63,7 +63,7 @@ export function getObjectExtensionEntitiesFromStore(
return (extensions.modules[moduleKey] || ({} as ObjectExtensions.ModuleExtensionDto)) return (extensions.modules[moduleKey] || ({} as ObjectExtensions.ModuleExtensionDto))
.entities; .entities;
}), }),
map(entities => (isUndefined(entities) ? {} : entities)), map(entities => (isUndefined(entities) ? ({} as any) : entities)),
filter<ObjectExtensions.EntityExtensions>(Boolean), filter<ObjectExtensions.EntityExtensions>(Boolean),
take(1), take(1),
); );
@ -141,8 +141,8 @@ function createPropertiesToContributorsMapper<T = any>(
if (property.ui.onTable.isVisible) { if (property.ui.onTable.isVisible) {
const sortable = Boolean(property.ui.onTable.isSortable); const sortable = Boolean(property.ui.onTable.isSortable);
const columnWidth = type === ePropType.Boolean ? 150 : 250; const columnWidth = type === ePropType.Boolean ? 150 : 250;
const valueResolver = const valueResolver: PropCallback<T, Observable<any>> =
type === ePropType.Enum type === ePropType.Enum && property.type
? createEnumValueResolver(property.type, enums[property.type], propName) ? createEnumValueResolver(property.type, enums[property.type], propName)
: createExtraPropertyValueResolver<T>(propName); : createExtraPropertyValueResolver<T>(propName);

Loading…
Cancel
Save