RED-3804: Entity permissions initial

This commit is contained in:
Adina Țeudan 2022-04-05 17:48:19 +03:00
parent 69351a3a3e
commit e64c8c29a0
13 changed files with 169 additions and 0 deletions

View File

@ -125,6 +125,9 @@ const components = [AppComponent, AuthErrorComponent, NotificationsComponent, Sp
PDF: {
enabled: false,
},
STATS: {
enabled: false,
},
},
} as ILoggerConfig,
},

View File

@ -0,0 +1,15 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate } from '@angular/router';
import { firstValueFrom } from 'rxjs';
import { EntityPermissionsService } from '../services/entity-services/entity-permissions.service';
@Injectable({ providedIn: 'root' })
export class PermissionsGuard implements CanActivate {
constructor(private readonly _entityPermissionsService: EntityPermissionsService) {}
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
const targetObject = route.data.permissionsObject;
await firstValueFrom(this._entityPermissionsService.loadPermissionsMappingFor(targetObject));
return true;
}
}

View File

@ -24,6 +24,8 @@ import { DossierStatesListingScreenComponent } from './screens/dossier-states-li
import { DossiersGuard } from '@guards/dossiers.guard';
import { ACTIVE_DOSSIERS_SERVICE } from '../../tokens';
import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-screen.component';
import { TargetObjects } from '@red/domain';
import { PermissionsGuard } from '../../guards/permissions-guard';
const routes: Routes = [
{ path: '', redirectTo: 'dossier-templates', pathMatch: 'full' },
@ -159,6 +161,16 @@ const routes: Routes = [
requiredRoles: ['RED_USER_ADMIN'],
},
},
{
path: 'dossier-permissions',
component: BaseAdminScreenComponent,
canActivate: [CompositeRouteGuard],
data: {
routeGuards: [AuthGuard, RedRoleGuard, PermissionsGuard],
permissionsObject: TargetObjects.Dossier,
},
loadChildren: () => import('./screens/permissions/permissions.module').then(m => m.PermissionsModule),
},
{
path: 'license-info',
component: LicenseInformationScreenComponent,

View File

@ -44,6 +44,7 @@ export class AdminSideNavComponent implements OnInit {
},
{ screen: 'audit', label: _('admin-side-nav.audit'), hideIf: !this.currentUser.isAdmin },
{ screen: 'users', label: _('admin-side-nav.user-management'), hideIf: !this.currentUser.isUserAdmin },
{ screen: 'dossier-permissions', label: _('dossier-permissions'), hideIf: !this.currentUser.isAdmin },
{
screen: 'general-config',
label: _('admin-side-nav.configurations'),

View File

@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import { TableColumnConfig } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { EntityPermissionsService } from '@services/entity-services/entity-permissions.service';
import { TargetObjects } from '@red/domain';
@Injectable()
export class ConfigService {
constructor(private readonly _entityPermissionsService: EntityPermissionsService) {}
get tableConfig(): TableColumnConfig<unknown>[] {
const columns = this._entityPermissionsService.getPermissionsMapping(TargetObjects.Dossier)[0].mappedPermissions.map(c => ({
label: c.name,
notTranslatable: true,
}));
return [
{
label: _('dossier-overview.table-col-names.name'),
width: '3fr',
},
...columns,
];
}
}

View File

@ -0,0 +1,17 @@
<iqser-table [itemSize]="80" [tableColumnConfigs]="tableColumnConfigs"></iqser-table>
<ng-template #tableItemTemplate let-entity="entity">
<div>
<div class="center cell">
<!-- <mat-slide-toggle-->
<!-- (toggleChange)="toggleActive(user)"-->
<!-- [checked]="user.isActive"-->
<!-- [disabled]="!canDeactivate(user)"-->
<!-- color="primary"-->
<!-- ></mat-slide-toggle>-->
<mat-slide-toggle [checked]="true" color="primary"></mat-slide-toggle>
</div>
<div class="small-label cell">abc</div>
</div>
</ng-template>

View File

@ -0,0 +1,4 @@
:host {
flex-grow: 1;
overflow: hidden;
}

View File

@ -0,0 +1,25 @@
import { ChangeDetectionStrategy, Component, forwardRef, Injector } from '@angular/core';
import { DefaultListingServices, ListingComponent, TableColumnConfig } from '@iqser/common-ui';
import { User } from '@red/domain';
import { ConfigService } from '../config.service';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { EntityPermissionsService } from '@services/entity-services/entity-permissions.service';
@Component({
templateUrl: './permissions-screen.component.html',
styleUrls: ['./permissions-screen.component.scss'],
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => PermissionsScreenComponent) }],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PermissionsScreenComponent extends ListingComponent<User> {
readonly tableColumnConfigs: TableColumnConfig<User>[] = this._configService.tableConfig;
readonly tableHeaderLabel = _('dossier-permissions.table-header.title');
constructor(
protected readonly _injector: Injector,
private readonly _configService: ConfigService,
private readonly _entityPermissionsService: EntityPermissionsService,
) {
super(_injector);
}
}

View File

@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { SharedModule } from '@shared/shared.module';
import { PermissionsScreenComponent } from './permissions-screen/permissions-screen.component';
import { ConfigService } from './config.service';
import { CommonUiModule } from '@iqser/common-ui';
const routes = [{ path: '', component: PermissionsScreenComponent }];
@NgModule({
declarations: [PermissionsScreenComponent],
imports: [RouterModule.forChild(routes), CommonModule, SharedModule, CommonUiModule],
providers: [ConfigService],
})
export class PermissionsModule {}

View File

@ -0,0 +1,33 @@
import { Injectable, Injector } from '@angular/core';
import { GenericService } from '@iqser/common-ui';
import { IPermissionsMapping, TargetObject } from '@red/domain';
import { BehaviorSubject, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class EntityPermissionsService extends GenericService<IPermissionsMapping> {
readonly #permissionsMapping$ = new BehaviorSubject<Partial<Record<TargetObject, IPermissionsMapping[]>>>({});
constructor(protected readonly _injector: Injector) {
super(_injector, 'permissions');
}
getPermissionsMapping(targetObject: TargetObject): IPermissionsMapping[] {
return this.#permissionsMapping$.value[targetObject];
}
loadPermissionsMappingFor(targetObject: TargetObject, params = ''): Observable<IPermissionsMapping[]> {
return this._http.get<IPermissionsMapping[]>(`/${this._defaultModelPath}/${targetObject}${params}`).pipe(
tap(mapping => {
this.#permissionsMapping$.next({ ...this.#permissionsMapping$.value, [targetObject]: mapping });
}),
);
}
//
// getTargetObjects(): Observable<string[]> {
// return this._http.get<string[]>(`/${this._defaultModelPath}/target-object`);
// }
}

View File

@ -23,3 +23,4 @@ export * from './lib/dossier-stats';
export * from './lib/dossier-state';
export * from './lib/trash';
export * from './lib/text-highlight';
export * from './lib/permissions';

View File

@ -0,0 +1 @@
export * from './permissions';

View File

@ -0,0 +1,16 @@
export const TargetObjects = {
Dossier: 'Dossier',
} as const;
export type TargetObject = keyof typeof TargetObjects;
export interface IPermission {
mask: number;
name: string;
sort: number;
}
export interface IPermissionsMapping {
mappedPermissions: IPermission[];
targetPermission: IPermission;
}