User & Role Override
This commit is contained in:
parent
e65b1f5870
commit
ec91f9ee4f
@ -20,7 +20,7 @@
|
|||||||
"@abp/ng.setting-management": "~9.0.2",
|
"@abp/ng.setting-management": "~9.0.2",
|
||||||
"@abp/ng.tenant-management": "~9.0.2",
|
"@abp/ng.tenant-management": "~9.0.2",
|
||||||
"@abp/ng.theme.lepton-x": "~4.0.3",
|
"@abp/ng.theme.lepton-x": "~4.0.3",
|
||||||
"@abp/ng.theme.shared": "~9.0.2",
|
"@abp/ng.theme.shared": "^9.0.4",
|
||||||
"@angular/animations": "~18.1.0",
|
"@angular/animations": "~18.1.0",
|
||||||
"@angular/common": "~18.1.0",
|
"@angular/common": "~18.1.0",
|
||||||
"@angular/compiler": "~18.1.0",
|
"@angular/compiler": "~18.1.0",
|
||||||
@ -30,6 +30,7 @@
|
|||||||
"@angular/platform-browser": "~18.1.0",
|
"@angular/platform-browser": "~18.1.0",
|
||||||
"@angular/platform-browser-dynamic": "~18.1.0",
|
"@angular/platform-browser-dynamic": "~18.1.0",
|
||||||
"@angular/router": "~18.1.0",
|
"@angular/router": "~18.1.0",
|
||||||
|
"@swimlane/ngx-datatable": "^20.1.0",
|
||||||
"bootstrap-icons": "~1.8.0",
|
"bootstrap-icons": "~1.8.0",
|
||||||
"primeflex": "^3.3.1",
|
"primeflex": "^3.3.1",
|
||||||
"primeicons": "^6.0.1",
|
"primeicons": "^6.0.1",
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { CustomUsersComponent } from './modules/custom-identity/custom-users/custom-users.component';
|
||||||
|
import { CustomRolesComponent } from './modules/custom-identity/custom-roles/custom-roles.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
@ -11,10 +13,12 @@ const routes: Routes = [
|
|||||||
path: 'account',
|
path: 'account',
|
||||||
loadChildren: () => import('@abp/ng.account').then(m => m.AccountModule.forLazy()),
|
loadChildren: () => import('@abp/ng.account').then(m => m.AccountModule.forLazy()),
|
||||||
},
|
},
|
||||||
{
|
{ path: 'identity/users', component: CustomUsersComponent },
|
||||||
path: 'identity',
|
{ path: 'identity/roles', component: CustomRolesComponent },
|
||||||
loadChildren: () => import('@abp/ng.identity').then(m => m.IdentityModule.forLazy()),
|
// {
|
||||||
},
|
// path: 'identity',
|
||||||
|
// loadChildren: () => import('@abp/ng.identity').then(m => m.IdentityModule.forLazy()),
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
path: 'tenant-management',
|
path: 'tenant-management',
|
||||||
loadChildren: () =>
|
loadChildren: () =>
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { IdentityModule } from '@abp/ng.identity';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { CustomRolesComponent } from './custom-roles/custom-roles.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [],
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
IdentityModule,
|
||||||
|
TableModule,
|
||||||
|
ButtonModule,
|
||||||
|
CustomRolesComponent
|
||||||
|
],
|
||||||
|
exports:[
|
||||||
|
CustomRolesComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class CustomIdentityModule { }
|
@ -0,0 +1,78 @@
|
|||||||
|
<abp-page [title]="'AbpIdentity::Roles' | abpLocalization" [toolbar]="data.items">
|
||||||
|
<div id="identity-roles-wrapper" class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<!-- <abp-extensible-table
|
||||||
|
[data]="data.items"
|
||||||
|
[recordsTotal]="data.totalCount"
|
||||||
|
[list]="list"
|
||||||
|
></abp-extensible-table> -->
|
||||||
|
<div class="flex justify-content-between align-items-center mb-3">
|
||||||
|
<button pButton icon="pi pi-plus" label="Add Roles" class="p-button-success" (click)="add()"></button>
|
||||||
|
</div>
|
||||||
|
<p-table [value]="data.items" [paginator]="true" [rows]="5" responsiveLayout="scroll">
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<tr>
|
||||||
|
<th pSortableColumn="name">name <p-sortIcon field="name"></p-sortIcon></th>
|
||||||
|
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="body" let-role>
|
||||||
|
<tr>
|
||||||
|
<td>{{ role.name }}</td>
|
||||||
|
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<button pButton icon="pi pi-pencil" class="p-button-text p-button-primary" (click)="edit(role.id)"></button>
|
||||||
|
<button pButton icon="pi pi-trash" class="p-button-text p-button-danger" (click)="delete(role.id,role.name)"></button>
|
||||||
|
<button pButton icon="pi pi-external-link" class="p-button-text p-button-success" (click)="openPermissionsModal(role.name)"></button>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<abp-modal [(visible)]="isModalVisible" [busy]="modalBusy">
|
||||||
|
<ng-template #abpHeader>
|
||||||
|
<h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewRole') | abpLocalization }}</h3>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #abpBody>
|
||||||
|
<form [formGroup]="form" (ngSubmit)="save()" validateOnSubmit>
|
||||||
|
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
|
||||||
|
</form>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #abpFooter>
|
||||||
|
<button type="button" class="btn btn-outline-primary" abpClose>
|
||||||
|
{{ 'AbpIdentity::Cancel' | abpLocalization }}
|
||||||
|
</button>
|
||||||
|
<abp-button iconClass="fa fa-check" [disabled]="form?.invalid" (click)="save()">{{
|
||||||
|
'AbpIdentity::Save' | abpLocalization
|
||||||
|
}}</abp-button>
|
||||||
|
</ng-template>
|
||||||
|
</abp-modal>
|
||||||
|
|
||||||
|
<abp-permission-management
|
||||||
|
#abpPermissionManagement="abpPermissionManagement"
|
||||||
|
*abpReplaceableTemplate="
|
||||||
|
{
|
||||||
|
inputs: {
|
||||||
|
providerName: { value: 'R' },
|
||||||
|
providerKey: { value: providerKey },
|
||||||
|
visible: { value: visiblePermissions, twoWay: true },
|
||||||
|
hideBadges: { value: true }
|
||||||
|
},
|
||||||
|
outputs: { visibleChange: onVisiblePermissionChange },
|
||||||
|
componentKey: permissionManagementKey
|
||||||
|
};
|
||||||
|
let init = initTemplate
|
||||||
|
"
|
||||||
|
(abpInit)="init(abpPermissionManagement)"
|
||||||
|
>
|
||||||
|
</abp-permission-management>
|
||||||
|
</abp-page>
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CustomRolesComponent } from './custom-roles.component';
|
||||||
|
|
||||||
|
describe('CustomRolesComponent', () => {
|
||||||
|
let component: CustomRolesComponent;
|
||||||
|
let fixture: ComponentFixture<CustomRolesComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [CustomRolesComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(CustomRolesComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,162 @@
|
|||||||
|
import {
|
||||||
|
ExtensibleModule,
|
||||||
|
EXTENSIONS_IDENTIFIER,
|
||||||
|
FormPropData,
|
||||||
|
generateFormFromProps,
|
||||||
|
} from '@abp/ng.components/extensible';
|
||||||
|
import { PageModule } from '@abp/ng.components/page';
|
||||||
|
import {
|
||||||
|
CoreModule,
|
||||||
|
ListResultDto,
|
||||||
|
ListService,
|
||||||
|
LocalizationModule,
|
||||||
|
PagedAndSortedResultRequestDto,
|
||||||
|
PagedResultDto,
|
||||||
|
} from '@abp/ng.core';
|
||||||
|
import { IdentityRoleDto, IdentityRoleService } from '@abp/ng.identity/proxy';
|
||||||
|
import {
|
||||||
|
ThemeSharedModule,
|
||||||
|
ConfirmationService,
|
||||||
|
ToasterService,
|
||||||
|
Confirmation,
|
||||||
|
} from '@abp/ng.theme.shared';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, inject, Injector, OnInit } from '@angular/core';
|
||||||
|
import { FormsModule, UntypedFormGroup } from '@angular/forms';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
import { finalize } from 'rxjs';
|
||||||
|
import { ePermissionManagementComponents } from '@abp/ng.permission-management';
|
||||||
|
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
|
||||||
|
import { eIdentityComponents } from '@abp/ng.identity';
|
||||||
|
import { PermissionManagementModule } from '@abp/ng.permission-management';
|
||||||
|
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-custom-roles',
|
||||||
|
standalone: true,
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
TableModule,
|
||||||
|
ButtonModule,
|
||||||
|
PageModule,
|
||||||
|
LocalizationModule,
|
||||||
|
ThemeSharedModule,
|
||||||
|
NgxDatatableModule,
|
||||||
|
ExtensibleModule,
|
||||||
|
PermissionManagementModule,
|
||||||
|
CoreModule,
|
||||||
|
NgbNavModule
|
||||||
|
],
|
||||||
|
templateUrl: './custom-roles.component.html',
|
||||||
|
providers: [
|
||||||
|
ListService,
|
||||||
|
{
|
||||||
|
provide: EXTENSIONS_IDENTIFIER,
|
||||||
|
useValue: eIdentityComponents.Roles,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
styleUrl: './custom-roles.component.scss',
|
||||||
|
})
|
||||||
|
export class CustomRolesComponent implements OnInit {
|
||||||
|
protected readonly list = inject(ListService<PagedAndSortedResultRequestDto>);
|
||||||
|
protected readonly confirmationService = inject(ConfirmationService);
|
||||||
|
protected readonly toasterService = inject(ToasterService);
|
||||||
|
private readonly injector = inject(Injector);
|
||||||
|
protected readonly service = inject(IdentityRoleService);
|
||||||
|
|
||||||
|
data: PagedResultDto<IdentityRoleDto> = { items: [], totalCount: 0 };
|
||||||
|
|
||||||
|
form!: UntypedFormGroup;
|
||||||
|
|
||||||
|
selected?: IdentityRoleDto;
|
||||||
|
|
||||||
|
isModalVisible!: boolean;
|
||||||
|
|
||||||
|
visiblePermissions = false;
|
||||||
|
|
||||||
|
providerKey?: string;
|
||||||
|
|
||||||
|
modalBusy = false;
|
||||||
|
|
||||||
|
permissionManagementKey = ePermissionManagementComponents.PermissionManagement;
|
||||||
|
|
||||||
|
onVisiblePermissionChange = (event: boolean) => {
|
||||||
|
this.visiblePermissions = event;
|
||||||
|
};
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.hookToQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm() {
|
||||||
|
const data = new FormPropData(this.injector, this.selected);
|
||||||
|
this.form = generateFormFromProps(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
openModal() {
|
||||||
|
this.buildForm();
|
||||||
|
this.isModalVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
add() {
|
||||||
|
this.selected = {} as IdentityRoleDto;
|
||||||
|
this.openModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
edit(id: string) {
|
||||||
|
debugger
|
||||||
|
this.service.get(id).subscribe(res => {
|
||||||
|
this.selected = res;
|
||||||
|
this.openModal();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
if (!this.form.valid) return;
|
||||||
|
this.modalBusy = true;
|
||||||
|
|
||||||
|
const { id } = this.selected || {};
|
||||||
|
(id
|
||||||
|
? this.service.update(id, { ...this.selected, ...this.form.value })
|
||||||
|
: this.service.create(this.form.value)
|
||||||
|
)
|
||||||
|
.pipe(finalize(() => (this.modalBusy = false)))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.isModalVisible = false;
|
||||||
|
this.toasterService.success('AbpUi::SavedSuccessfully');
|
||||||
|
this.list.get();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(id: string, name: string) {
|
||||||
|
this.confirmationService
|
||||||
|
.warn('AbpIdentity::RoleDeletionConfirmationMessage', 'AbpIdentity::AreYouSure', {
|
||||||
|
messageLocalizationParams: [name],
|
||||||
|
})
|
||||||
|
.subscribe((status: Confirmation.Status) => {
|
||||||
|
if (status === Confirmation.Status.confirm) {
|
||||||
|
this.toasterService.success('AbpUi::DeletedSuccessfully');
|
||||||
|
this.service.delete(id).subscribe(() => this.list.get());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private hookToQuery() {
|
||||||
|
this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => (this.data = res));
|
||||||
|
}
|
||||||
|
|
||||||
|
openPermissionsModal(providerKey: string) {
|
||||||
|
this.providerKey = providerKey;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.visiblePermissions = true;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort(data: any) {
|
||||||
|
const { prop, dir } = data.sorts[0];
|
||||||
|
this.list.sortKey = prop;
|
||||||
|
this.list.sortOrder = dir;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
<!-- <div>
|
||||||
|
<h3>Total Users: {{ data.totalCount }}</h3>
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let user of data.items">
|
||||||
|
<strong>{{ user.userName }}</strong> ({{ user.email }})
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<abp-page [title]="'AbpIdentity::Users' | abpLocalization" [toolbar]="data.items">
|
||||||
|
<div id="identity-roles-wrapper" class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="data-tables-table-filter" class="data-tables-filter mb-3">
|
||||||
|
<div class="flex justify-content-between align-items-center mb-3">
|
||||||
|
<button pButton icon="pi pi-plus" label="Add User" class="p-button-success" (click)="add()"></button>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
class="form-control"
|
||||||
|
[placeholder]="'AbpUi::PagerSearch' | abpLocalization"
|
||||||
|
[(ngModel)]="list.filter"
|
||||||
|
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<abp-extensible-table
|
||||||
|
|
||||||
|
[data]="data.items"
|
||||||
|
[recordsTotal]="data.totalCount"
|
||||||
|
[list]="list"
|
||||||
|
|
||||||
|
></abp-extensible-table> -->
|
||||||
|
<p-table [value]="data.items" [paginator]="true" [rows]="5" responsiveLayout="scroll">
|
||||||
|
<ng-template pTemplate="header">
|
||||||
|
<tr>
|
||||||
|
<th pSortableColumn="userName">Username <p-sortIcon field="userName"></p-sortIcon></th>
|
||||||
|
<th pSortableColumn="name">First Name <p-sortIcon field="name"></p-sortIcon></th>
|
||||||
|
<th pSortableColumn="surname">Last Name <p-sortIcon field="surname"></p-sortIcon></th>
|
||||||
|
<th pSortableColumn="email">Email <p-sortIcon field="email"></p-sortIcon></th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template pTemplate="body" let-user>
|
||||||
|
<tr>
|
||||||
|
<td>{{ user.userName }}</td>
|
||||||
|
<td>{{ user.name }}</td>
|
||||||
|
<td>{{ user.surname }}</td>
|
||||||
|
<td>{{ user.email }}</td>
|
||||||
|
<td>
|
||||||
|
<p-tag [value]="user.isActive ? 'Active' : 'Inactive'" [severity]="user.isActive ? 'success' : 'danger'"></p-tag>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button pButton icon="pi pi-pencil" class="p-button-text p-button-primary" (click)="edit(user.id)"></button>
|
||||||
|
<button pButton icon="pi pi-trash" class="p-button-text p-button-danger" (click)="delete(user.id,user.userName)"></button>
|
||||||
|
<button pButton icon="pi pi-external-link" class="p-button-text p-button-success" (click)="openPermissionsModal(user.name,user.name)"></button>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</ng-template>
|
||||||
|
</p-table>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<abp-modal [(visible)]="isModalVisible" [busy]="modalBusy">
|
||||||
|
<ng-template #abpHeader>
|
||||||
|
<h3>{{ (selected?.id ? 'AbpIdentity::Edit' : 'AbpIdentity::NewUser') | abpLocalization }}</h3>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #abpBody>
|
||||||
|
@if (form) {
|
||||||
|
<form [formGroup]="form" (ngSubmit)="save()">
|
||||||
|
<ul ngbNav #nav="ngbNav" class="nav-tabs">
|
||||||
|
<li ngbNavItem>
|
||||||
|
<a ngbNavLink>{{ 'AbpIdentity::UserInformations' | abpLocalization }}</a>
|
||||||
|
<ng-template ngbNavContent>
|
||||||
|
<abp-extensible-form [selectedRecord]="selected"></abp-extensible-form>
|
||||||
|
</ng-template>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li ngbNavItem>
|
||||||
|
<a ngbNavLink>{{ 'AbpIdentity::Roles' | abpLocalization }}</a>
|
||||||
|
<ng-template ngbNavContent>
|
||||||
|
@for (roleGroup of roleGroups; track $index; let i = $index) {
|
||||||
|
<div class="form-check mb-2">
|
||||||
|
<abp-checkbox
|
||||||
|
*abpReplaceableTemplate="{
|
||||||
|
inputs: {
|
||||||
|
checkboxId: 'roles-' + i,
|
||||||
|
label: roles[i].name,
|
||||||
|
formControl: roleGroup.controls[roles[i].name]
|
||||||
|
},
|
||||||
|
componentKey: inputKey
|
||||||
|
}"
|
||||||
|
[checkboxId]="'roles-' + i"
|
||||||
|
[formControl]="roleGroup.controls[roles[i].name]"
|
||||||
|
[label]="roles[i].name"
|
||||||
|
>
|
||||||
|
</abp-checkbox>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</ng-template>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="mt-2 fade-in-top" [ngbNavOutlet]="nav"></div>
|
||||||
|
</form>
|
||||||
|
} @else {
|
||||||
|
<div class="text-center"><i class="fa fa-pulse fa-spinner" aria-hidden="true"></i></div>
|
||||||
|
}
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #abpFooter>
|
||||||
|
<button type="button" class="btn btn-outline-primary" abpClose>
|
||||||
|
{{ 'AbpIdentity::Cancel' | abpLocalization }}
|
||||||
|
</button>
|
||||||
|
<abp-button iconClass="fa fa-check" [disabled]="form?.invalid" (click)="save()">{{
|
||||||
|
'AbpIdentity::Save' | abpLocalization
|
||||||
|
}}</abp-button>
|
||||||
|
</ng-template>
|
||||||
|
</abp-modal>
|
||||||
|
|
||||||
|
<abp-permission-management
|
||||||
|
#abpPermissionManagement="abpPermissionManagement"
|
||||||
|
*abpReplaceableTemplate="
|
||||||
|
{
|
||||||
|
inputs: {
|
||||||
|
providerName: { value: 'U' },
|
||||||
|
providerKey: { value: providerKey },
|
||||||
|
visible: { value: visiblePermissions, twoWay: true }
|
||||||
|
},
|
||||||
|
outputs: { visibleChange: onVisiblePermissionChange },
|
||||||
|
componentKey: permissionManagementKey
|
||||||
|
};
|
||||||
|
let init = initTemplate
|
||||||
|
"
|
||||||
|
[entityDisplayName]="entityDisplayName"
|
||||||
|
(abpInit)="init(abpPermissionManagement)"
|
||||||
|
>
|
||||||
|
</abp-permission-management>
|
||||||
|
</abp-page>
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CustomUsersComponent } from './custom-users.component';
|
||||||
|
|
||||||
|
describe('CustomUsersComponent', () => {
|
||||||
|
let component: CustomUsersComponent;
|
||||||
|
let fixture: ComponentFixture<CustomUsersComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [CustomUsersComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(CustomUsersComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,211 @@
|
|||||||
|
import { FormPropData,EXTENSIONS_IDENTIFIER ,generateFormFromProps, ExtensibleModule} from '@abp/ng.components/extensible';
|
||||||
|
import { PageModule } from '@abp/ng.components/page';
|
||||||
|
import { CoreModule, ListResultDto, ListService, LocalizationModule, PagedResultDto } from '@abp/ng.core';
|
||||||
|
import { eIdentityComponents } from '@abp/ng.identity';
|
||||||
|
import { GetIdentityUsersInput, IdentityRoleDto, IdentityUserDto, IdentityUserService } from '@abp/ng.identity/proxy';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, inject, Injector, OnInit, TemplateRef, TrackByFunction, ViewChild } from '@angular/core';
|
||||||
|
import { AbstractControl, FormsModule, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||||
|
import { ButtonModule } from 'primeng/button';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
import { Confirmation, eFormComponets, ThemeSharedModule,ToasterService ,ConfirmationService} from '@abp/ng.theme.shared';
|
||||||
|
import { finalize, switchMap, tap } from 'rxjs';
|
||||||
|
import { ePermissionManagementComponents, PermissionManagementModule } from '@abp/ng.permission-management';
|
||||||
|
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
|
||||||
|
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { PaginatorModule } from 'primeng/paginator';
|
||||||
|
import { TagModule } from 'primeng/tag'; // For active/inactive status
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-custom-users',
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule,FormsModule,TableModule,ButtonModule,PageModule,LocalizationModule,ThemeSharedModule,NgxDatatableModule,ExtensibleModule,
|
||||||
|
PermissionManagementModule,
|
||||||
|
CoreModule,
|
||||||
|
NgbNavModule,
|
||||||
|
PaginatorModule,TagModule
|
||||||
|
],
|
||||||
|
templateUrl: './custom-users.component.html',
|
||||||
|
providers: [
|
||||||
|
ListService,
|
||||||
|
{
|
||||||
|
provide: EXTENSIONS_IDENTIFIER,
|
||||||
|
useValue: eIdentityComponents.Users,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
styleUrl: './custom-users.component.scss'
|
||||||
|
})
|
||||||
|
export class CustomUsersComponent implements OnInit{
|
||||||
|
protected readonly list = inject(ListService<GetIdentityUsersInput>);
|
||||||
|
protected readonly confirmationService = inject(ConfirmationService);
|
||||||
|
protected readonly service = inject(IdentityUserService);
|
||||||
|
protected readonly toasterService = inject(ToasterService);
|
||||||
|
private readonly fb = inject(UntypedFormBuilder);
|
||||||
|
private readonly injector = inject(Injector);
|
||||||
|
|
||||||
|
data: PagedResultDto<IdentityUserDto> = { items: [], totalCount: 0 };
|
||||||
|
|
||||||
|
@ViewChild('modalContent', { static: false })
|
||||||
|
modalContent!: TemplateRef<any>;
|
||||||
|
|
||||||
|
form!: UntypedFormGroup;
|
||||||
|
|
||||||
|
selected?: IdentityUserDto;
|
||||||
|
|
||||||
|
selectedUserRoles?: IdentityRoleDto[];
|
||||||
|
|
||||||
|
roles?: IdentityRoleDto[];
|
||||||
|
|
||||||
|
visiblePermissions = false;
|
||||||
|
|
||||||
|
providerKey?: string;
|
||||||
|
|
||||||
|
isModalVisible?: boolean;
|
||||||
|
|
||||||
|
modalBusy = false;
|
||||||
|
|
||||||
|
permissionManagementKey = ePermissionManagementComponents.PermissionManagement;
|
||||||
|
|
||||||
|
entityDisplayName: string;
|
||||||
|
|
||||||
|
inputKey = eFormComponets.FormCheckboxComponent;
|
||||||
|
|
||||||
|
trackByFn: TrackByFunction<AbstractControl> = (index, item) => Object.keys(item)[0] || index;
|
||||||
|
|
||||||
|
onVisiblePermissionChange = (event: boolean) => {
|
||||||
|
this.visiblePermissions = event;
|
||||||
|
};
|
||||||
|
|
||||||
|
get roleGroups(): UntypedFormGroup[] {
|
||||||
|
return ((this.form.get('roleNames') as UntypedFormArray)?.controls as UntypedFormGroup[]) || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.hookToQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm() {
|
||||||
|
debugger
|
||||||
|
const data = new FormPropData(this.injector, this.selected);
|
||||||
|
this.form = generateFormFromProps(data);
|
||||||
|
|
||||||
|
this.service.getAssignableRoles().subscribe(({ items }) => {
|
||||||
|
this.roles = items;
|
||||||
|
if (this.roles) {
|
||||||
|
this.form.addControl(
|
||||||
|
'roleNames',
|
||||||
|
this.fb.array(
|
||||||
|
this.roles.map(role =>
|
||||||
|
this.fb.group({
|
||||||
|
[role.name as string]: [
|
||||||
|
this.selected?.id
|
||||||
|
? !!this.selectedUserRoles?.find(userRole => userRole.id === role.id)
|
||||||
|
: role.isDefault,
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openModal() {
|
||||||
|
this.buildForm();
|
||||||
|
this.isModalVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
add() {
|
||||||
|
debugger
|
||||||
|
this.selected = {} as IdentityUserDto;
|
||||||
|
this.selectedUserRoles = [] as IdentityRoleDto[];
|
||||||
|
this.openModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
edit(id: string) {
|
||||||
|
debugger
|
||||||
|
this.service
|
||||||
|
.get(id)
|
||||||
|
.pipe(
|
||||||
|
tap(user => (this.selected = user)),
|
||||||
|
switchMap(() => this.service.getRoles(id)),
|
||||||
|
)
|
||||||
|
.subscribe(userRole => {
|
||||||
|
debugger
|
||||||
|
|
||||||
|
this.selectedUserRoles = userRole.items || [];
|
||||||
|
this.openModal();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
if (!this.form.valid || this.modalBusy) return;
|
||||||
|
this.modalBusy = true;
|
||||||
|
|
||||||
|
const { roleNames = [] } = this.form.value;
|
||||||
|
const mappedRoleNames =
|
||||||
|
roleNames
|
||||||
|
.filter((role: { [key: string]: any }) => !!role[Object.keys(role)[0]])
|
||||||
|
.map((role: { [key: string]: any }) => Object.keys(role)[0]) || [];
|
||||||
|
|
||||||
|
const { id } = this.selected || {};
|
||||||
|
|
||||||
|
(id
|
||||||
|
? this.service.update(id, {
|
||||||
|
...this.selected,
|
||||||
|
...this.form.value,
|
||||||
|
roleNames: mappedRoleNames,
|
||||||
|
})
|
||||||
|
: this.service.create({ ...this.form.value, roleNames: mappedRoleNames })
|
||||||
|
)
|
||||||
|
.pipe(finalize(() => (this.modalBusy = false)))
|
||||||
|
.subscribe(() => {
|
||||||
|
this.isModalVisible = false;
|
||||||
|
this.toasterService.success('AbpUi::SavedSuccessfully');
|
||||||
|
this.list.get();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(id: string, userName: string) {
|
||||||
|
this.confirmationService
|
||||||
|
.warn('AbpIdentity::UserDeletionConfirmationMessage', 'AbpIdentity::AreYouSure', {
|
||||||
|
messageLocalizationParams: [userName],
|
||||||
|
})
|
||||||
|
.subscribe((status: Confirmation.Status) => {
|
||||||
|
if (status === Confirmation.Status.confirm) {
|
||||||
|
this.service.delete(id).subscribe(() => {
|
||||||
|
this.toasterService.success('AbpUi::DeletedSuccessfully');
|
||||||
|
this.list.get();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sort(data: any) {
|
||||||
|
const { prop, dir } = data.sorts[0];
|
||||||
|
this.list.sortKey = prop;
|
||||||
|
this.list.sortOrder = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private hookToQuery() {
|
||||||
|
// this.list.hookToQuery(query => this.service.getList(query)).subscribe(res => (this.data = res));
|
||||||
|
// }
|
||||||
|
private hookToQuery() {
|
||||||
|
this.list.hookToQuery(query => {
|
||||||
|
console.log('Query:', query); // Log the query
|
||||||
|
return this.service.getList(query);
|
||||||
|
}).subscribe(res => {
|
||||||
|
debugger
|
||||||
|
this.data = res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openPermissionsModal(providerKey: string, entityDisplayName?: string) {
|
||||||
|
debugger
|
||||||
|
this.providerKey = providerKey;
|
||||||
|
this.entityDisplayName = entityDisplayName;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.visiblePermissions = true;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ export const APP_ROUTE_PROVIDER = [
|
|||||||
|
|
||||||
function configureRoutes(routesService: RoutesService) {
|
function configureRoutes(routesService: RoutesService) {
|
||||||
return () => {
|
return () => {
|
||||||
|
|
||||||
routesService.add([
|
routesService.add([
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
@ -15,6 +16,7 @@ function configureRoutes(routesService: RoutesService) {
|
|||||||
order: 1,
|
order: 1,
|
||||||
layout: eLayoutType.application,
|
layout: eLayoutType.application,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: '/appointment',
|
path: '/appointment',
|
||||||
name: 'Appointments',
|
name: 'Appointments',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user