diff --git a/npm/ng-packs/.prettierrc b/npm/ng-packs/.prettierrc new file mode 100644 index 0000000000..4b9a2d97d0 --- /dev/null +++ b/npm/ng-packs/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 120, + "singleQuote": true, + "trailingComma": "all" +} diff --git a/npm/ng-packs/packages/core/src/lib/states/config.state.ts b/npm/ng-packs/packages/core/src/lib/states/config.state.ts index f5bf9ffbe6..758051cce6 100644 --- a/npm/ng-packs/packages/core/src/lib/states/config.state.ts +++ b/npm/ng-packs/packages/core/src/lib/states/config.state.ts @@ -107,6 +107,8 @@ export class ConfigState { } static getCopy(key: string, ...interpolateParams: string[]) { + if (!key) key = ''; + const keys = key.split('::') as string[]; const selector = createSelector( [ConfigState], diff --git a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html index ca93374446..0749ef51ab 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/roles/roles.component.html @@ -58,17 +58,13 @@ - - -
- +
+
- - - + + + + + ; - constructor( - private confirmationService: ConfirmationService, - private modalService: NgbModal, - private fb: FormBuilder, - private store: Store, - ) {} + constructor(private confirmationService: ConfirmationService, private fb: FormBuilder, private store: Store) {} createForm() { this.form = this.fb.group({ @@ -50,7 +46,7 @@ export class RolesComponent { openModal() { this.createForm(); - this.modalService.open(this.modalContent); + this.isModalVisible = true; } onAdd() { @@ -77,7 +73,9 @@ export class RolesComponent { ? new IdentityUpdateRole({ ...this.form.value, id: this.selected.id }) : new IdentityAddRole(this.form.value), ) - .subscribe(() => this.modalService.dismissAll()); + .subscribe(() => { + this.isModalVisible = false; + }); } delete(id: string, name: string) { diff --git a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html index abce666c4d..3801acc6d2 100644 --- a/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html +++ b/npm/ng-packs/packages/identity/src/lib/components/users/users.component.html @@ -77,119 +77,118 @@ - - -
-
- - +
- + diff --git a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts index f82c552b93..7a004003eb 100644 --- a/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts +++ b/npm/ng-packs/packages/permission-management/src/lib/components/permission-management.component.ts @@ -7,11 +7,8 @@ import { Output, Renderer2, SimpleChanges, - TemplateRef, TrackByFunction, - ViewChild, } from '@angular/core'; -import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { Select, Store } from '@ngxs/store'; import { from, Observable } from 'rxjs'; import { map, pluck, take } from 'rxjs/operators'; @@ -35,23 +32,33 @@ export class PermissionManagementComponent implements OnInit, OnChanges { @Input() providerKey: string; + protected _visible; + @Input() - visible: boolean; + get visible(): boolean { + return this._visible; + } + + set visible(value: boolean) { + if (!this.selectedGroup) return; + + this._visible = value; + this.visibleChange.emit(value); + + if (!value) { + this.selectedGroup = null; + } + } @Output() visibleChange = new EventEmitter(); - @ViewChild('modalContent', { static: false }) - modalContent: TemplateRef; - @Select(PermissionManagementState.getPermissionGroups) groups$: Observable; @Select(PermissionManagementState.getEntitiyDisplayName) entityName$: Observable; - modalRef: NgbModalRef; - selectedGroup: PermissionManagement.Group; permissions: PermissionManagement.Permission[] = []; @@ -80,7 +87,7 @@ export class PermissionManagementComponent implements OnInit, OnChanges { ); } - constructor(private modalService: NgbModal, private store: Store, private renderer: Renderer2) {} + constructor(private store: Store, private renderer: Renderer2) {} ngOnInit(): void {} @@ -186,9 +193,11 @@ export class PermissionManagementComponent implements OnInit, OnChanges { permissions: changedPermissions, }), ) - .subscribe(() => this.modalRef.close()); + .subscribe(() => { + this.visible = false; + }); } else { - this.modalRef.close(); + this.visible = false; } } @@ -206,39 +215,22 @@ export class PermissionManagementComponent implements OnInit, OnChanges { this.selectedGroup = permissionRes.groups[0]; this.permissions = getPermissions(permissionRes.groups); - this.modalRef = this.modalService.open(this.modalContent, { size: 'lg' }); - this.visibleChange.emit(true); + this.visible = true; setTimeout(() => { this.setTabCheckboxState(); this.setGrantCheckboxState(); }, 0); - - from(this.modalRef.result) - .pipe(take(1)) - .subscribe( - data => { - this.setVisible(false); - }, - reason => { - this.setVisible(false); - }, - ); }); } - setVisible(value: boolean) { - this.visible = value; - this.visibleChange.emit(value); - } - ngOnChanges({ visible }: SimpleChanges): void { if (!visible) return; if (visible.currentValue) { this.openModal(); - } else if (visible.currentValue === false && this.modalService.hasOpenModals()) { - this.modalRef.close(); + } else if (visible.currentValue === false && this.visible) { + this.visible = false; } } } diff --git a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html index 199c118b19..102b1fd506 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html +++ b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.html @@ -12,7 +12,7 @@ id="create-tenants" class="btn btn-primary" type="button" - (click)="onAdd()" + (click)="onAddTenant()" > {{ 'AbpTenantManagement::NewTenant' | abpLocalization }} @@ -53,14 +53,14 @@ @@ -88,60 +88,62 @@ - - + + +

{{ selectedModalContent.title | abpLocalization }}

+
-
- + + + - -
-
+ + + + + - -
-
- - + +
+
+
+ + +
-
+ - -
-
-
- -
+ - + Manage Features diff --git a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts index 443ab95187..a18667570c 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts +++ b/npm/ng-packs/packages/tenant-management/src/lib/components/tenants/tenants.component.ts @@ -2,7 +2,6 @@ import { ABP } from '@abp/ng.core'; import { ConfirmationService, Toaster } from '@abp/ng.theme.shared'; import { Component, TemplateRef, ViewChild } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { Select, Store } from '@ngxs/store'; import { Observable } from 'rxjs'; import { pluck, switchMap, take } from 'rxjs/operators'; @@ -15,6 +14,12 @@ import { import { TenantManagementService } from '../../services/tenant-management.service'; import { TenantManagementState } from '../../states/tenant-management.state'; +type SelectedModalContent = { + type: string; + title: string; + template: TemplateRef; +}; + @Component({ selector: 'abp-tenants', templateUrl: './tenants.component.html', @@ -31,46 +36,36 @@ export class TenantsComponent { defaultConnectionString: string; - useSharedDatabase: boolean; + isModalVisible: boolean; + + selectedModalContent = {} as SelectedModalContent; - selectedModalContent: { - title: string; - template: TemplateRef; - onSave: () => void; - }; + _useSharedDatabase: boolean; - get showInput(): boolean { - return !this.defaultConnectionStringForm.get('useSharedDatabase').value; + get useSharedDatabase(): boolean { + return this.defaultConnectionStringForm.get('useSharedDatabase').value; } get connectionString(): string { return this.defaultConnectionStringForm.get('defaultConnectionString').value; } - @ViewChild('modalWrapper', { static: false }) - modalWrapper: TemplateRef; - - @ViewChild('mTemplateConnStr', { static: false }) - mTemplateConnStr: TemplateRef; + @ViewChild('tenantModalTemplate', { static: false }) + tenantModalTemplate: TemplateRef; - @ViewChild('mTemplateFeatures', { static: false }) - mTemplateFeatures: TemplateRef; + @ViewChild('connectionStringModalTemplate', { static: false }) + connectionStringModalTemplate: TemplateRef; - @ViewChild('mTemplateTenant', { static: false }) - mTemplateTenant: TemplateRef; + @ViewChild('featuresModalTemplate', { static: false }) + featuresModalTemplate: TemplateRef; constructor( private confirmationService: ConfirmationService, private tenantService: TenantManagementService, - private modalService: NgbModal, private fb: FormBuilder, private store: Store, ) {} - openModal() { - this.modalService.open(this.modalWrapper); - } - private createTenantForm() { this.tenantForm = this.fb.group({ name: [this.selected.name || '', [Validators.required, Validators.maxLength(256)]], @@ -79,17 +74,22 @@ export class TenantsComponent { private createDefaultConnectionStringForm() { this.defaultConnectionStringForm = this.fb.group({ - useSharedDatabase: this.useSharedDatabase, + useSharedDatabase: this._useSharedDatabase, defaultConnectionString: this.defaultConnectionString || '', }); } - onEditConnStr(id: string) { + openModal(title: string, template: TemplateRef, type: string) { this.selectedModalContent = { - title: this.selected && this.selected.id ? 'AbpTenantManagement::Edit' : 'AbpTenantManagement::NewTenant', - template: this.mTemplateConnStr, - onSave: () => this.saveConnStr, + title, + template, + type, }; + + this.isModalVisible = true; + } + + onEditConnectionString(id: string) { this.store .dispatch(new TenantManagementGetById(id)) .pipe( @@ -100,56 +100,59 @@ export class TenantsComponent { }), ) .subscribe(fetchedConnectionString => { - this.useSharedDatabase = fetchedConnectionString ? false : true; + this._useSharedDatabase = fetchedConnectionString ? false : true; this.defaultConnectionString = fetchedConnectionString ? fetchedConnectionString : ''; this.createDefaultConnectionStringForm(); - this.openModal(); + this.openModal('AbpTenantManagement::ConnectionStrings', this.connectionStringModalTemplate, 'saveConnStr'); }); } - saveConnStr() { - this.tenantService - .updateDefaultConnectionString({ id: this.selected.id, defaultConnectionString: this.connectionString }) - .pipe(take(1)) - .subscribe(() => this.modalService.dismissAll()); - } - onManageFeatures(id: string) { - this.selectedModalContent = { - title: this.selected && this.selected.id ? 'AbpTenantManagement::Edit' : 'AbpTenantManagement::NewTenant', - template: this.mTemplateFeatures, - onSave: () => {}, - }; - this.openModal(); + this.openModal('AbpTenantManagement::Features', this.featuresModalTemplate, 'saveFeatures'); } - onAdd() { + onAddTenant() { this.selected = {} as ABP.BasicItem; this.createTenantForm(); - this.openModal(); - this.selectedModalContent = { - title: 'AbpTenantManagement::NewTenant', - template: this.mTemplateTenant, - onSave: () => this.saveTenant, - }; + this.openModal('AbpTenantManagement::NewTenant', this.tenantModalTemplate, 'saveTenant'); } - onEdit(id: string) { + onEditTenant(id: string) { this.store .dispatch(new TenantManagementGetById(id)) .pipe(pluck('TenantManagementState', 'selectedItem')) .subscribe(selected => { this.selected = selected; - this.selectedModalContent = { - title: 'AbpTenantManagement::Edit', - template: this.mTemplateTenant, - onSave: () => this.saveTenant, - }; this.createTenantForm(); - this.openModal(); + this.openModal('AbpTenantManagement::Edit', this.tenantModalTemplate, 'saveTenant'); }); } + save() { + const { type } = this.selectedModalContent; + if (!type) return; + if (type === 'saveTenant') this.saveTenant(); + else if (type === 'saveConnStr') this.saveConnectionString(); + } + + saveConnectionString() { + if (this.useSharedDatabase) { + this.tenantService + .deleteDefaultConnectionString(this.selected.id) + .pipe(take(1)) + .subscribe(() => { + this.isModalVisible = false; + }); + } else { + this.tenantService + .updateDefaultConnectionString({ id: this.selected.id, defaultConnectionString: this.connectionString }) + .pipe(take(1)) + .subscribe(() => { + this.isModalVisible = false; + }); + } + } + saveTenant() { if (!this.tenantForm.valid) return; @@ -159,7 +162,9 @@ export class TenantsComponent { ? new TenantManagementUpdate({ ...this.tenantForm.value, id: this.selected.id }) : new TenantManagementAdd(this.tenantForm.value), ) - .subscribe(() => this.modalService.dismissAll()); + .subscribe(() => { + this.isModalVisible = false; + }); } delete(id: string, name: string) { diff --git a/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts b/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts index e01b635135..bacfa52fe2 100644 --- a/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts +++ b/npm/ng-packs/packages/tenant-management/src/lib/services/tenant-management.service.ts @@ -80,4 +80,14 @@ export class TenantManagementService { }; return this.rest.request(request); } + + deleteDefaultConnectionString(id: string): Observable { + const url = `/api/multi-tenancy/tenant/${id}/defaultConnectionString`; + + const request: Rest.Request = { + method: 'DELETE', + url, + }; + return this.rest.request(request); + } } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.html index ba138e281b..76b83162b5 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.html @@ -1,12 +1,9 @@ - - -
- -
- - - - + + + + + + + diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.ts b/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.ts index 8c127dae18..db819492e3 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.ts +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/change-password/change-password.component.ts @@ -11,11 +11,8 @@ import { ViewChild, } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { NgbActiveModal, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { comparePasswords, validatePassword } from '@ngx-validate/core'; import { Store } from '@ngxs/store'; -import { from } from 'rxjs'; -import { take } from 'rxjs/operators'; const { minLength, required } = Validators; @@ -24,8 +21,17 @@ const { minLength, required } = Validators; templateUrl: './change-password.component.html', }) export class ChangePasswordComponent implements OnInit, OnChanges { + protected _visible; + @Input() - visible: boolean; + get visible(): boolean { + return this._visible; + } + + set visible(value: boolean) { + this._visible = value; + this.visibleChange.emit(value); + } @Output() visibleChange = new EventEmitter(); @@ -35,9 +41,7 @@ export class ChangePasswordComponent implements OnInit, OnChanges { form: FormGroup; - modalRef: NgbModalRef; - - constructor(private fb: FormBuilder, private modalService: NgbModal, private store: Store) {} + constructor(private fb: FormBuilder, private store: Store) {} ngOnInit(): void { this.form = this.fb.group( @@ -62,28 +66,13 @@ export class ChangePasswordComponent implements OnInit, OnChanges { newPassword: this.form.get('newPassword').value, }), ) - .subscribe(() => this.modalRef.close()); + .subscribe(() => { + this.visible = false; + }); } openModal() { - this.modalRef = this.modalService.open(this.modalContent); - this.visibleChange.emit(true); - - from(this.modalRef.result) - .pipe(take(1)) - .subscribe( - data => { - this.setVisible(false); - }, - reason => { - this.setVisible(false); - }, - ); - } - - setVisible(value: boolean) { - this.visible = value; - this.visibleChange.emit(value); + this.visible = true; } ngOnChanges({ visible }: SimpleChanges): void { @@ -91,8 +80,8 @@ export class ChangePasswordComponent implements OnInit, OnChanges { if (visible.currentValue) { this.openModal(); - } else if (visible.currentValue === false && this.modalService.hasOpenModals()) { - this.modalRef.close(); + } else if (visible.currentValue === false && this.visible) { + this.visible = false; } } } diff --git a/npm/ng-packs/packages/theme-basic/src/lib/components/layout-application/layout-application.component.html b/npm/ng-packs/packages/theme-basic/src/lib/components/layout-application/layout-application.component.html index 7016872e7c..6fc2ffe62c 100644 --- a/npm/ng-packs/packages/theme-basic/src/lib/components/layout-application/layout-application.component.html +++ b/npm/ng-packs/packages/theme-basic/src/lib/components/layout-application/layout-application.component.html @@ -9,14 +9,20 @@ -