feature/30-group-authentication #9

Merged
william merged 6 commits from feature/30-group-authentication into develop 2022-08-03 08:07:11 -04:00
18 changed files with 174 additions and 80 deletions
Showing only changes of commit 63e70cd109 - Show all commits

View File

@ -38,6 +38,9 @@ const routes: Routes = [{
}, {
path: 'group',
loadChildren: () => import('./modules/groups/group.module').then(m => m.GroupModule)
}, {
path: 'group-token',
loadChildren: () => import('./modules/groupTokens/group-tokens.module').then(m => m.GroupTokensModule)
}, {
path: 'config',
loadChildren: () => import('./modules/configuration/config.module').then(m => m.ConfigModule),

View File

@ -3,19 +3,14 @@ import {NgModule} from '@angular/core'
import {AccountsRoutingModule} from './accounts-routing.module'
import {SharedModule} from '../shared/shared.module'
import {Login, Logout} from './accounts'
import {CreInputsModule} from '../shared/components/inputs/inputs.module'
import {CreButtonsModule} from '../shared/components/buttons/buttons.module'
import {GroupTokenAdd} from "./group-tokens";
import {CreInputsModule} from "../shared/components/inputs/inputs.module";
import {CreButtonsModule} from "../shared/components/buttons/buttons.module";
@NgModule({
declarations: [
Login,
Logout,
GroupTokenAdd
],
exports: [
GroupTokenAdd
Logout
],
imports: [
SharedModule,

View File

@ -1,8 +0,0 @@
<cre-prompt-dialog
title="Définir le groupe par défaut de cet ordinateur">
<cre-dialog-body>
<div>
<cre-input [control]="controls.name" label="Name" icon="form-textbox"></cre-input>
</div>
</cre-dialog-body>
</cre-prompt-dialog>

View File

@ -1,18 +0,0 @@
import {Component, ViewChild} from "@angular/core";
import {CrePromptDialog} from "../shared/components/dialogs/dialogs";
import {Group} from "../shared/model/account.model";
import {FormControl, Validators} from "@angular/forms";
@Component({
selector: 'cre-group-token-add',
templateUrl: 'group-token-add.html'
})
export class GroupTokenAdd {
@ViewChild(CrePromptDialog) dialog: CrePromptDialog
controls = {name: new FormControl(null, Validators.required)}
show(group: Group) {
this.dialog.show()
}
}

View File

@ -20,7 +20,7 @@ export class GroupTokenService {
return this.api.get<GroupToken | null>('/account/group/token/current')
}
save(name: string): Observable<GroupToken> {
return this.api.post<GroupToken>('/account/group/token')
save(name: string, groupId: number): Observable<GroupToken> {
return this.api.post<GroupToken>('/account/group/token', {name, groupId})
}
}

View File

@ -0,0 +1,10 @@
<cre-prompt-dialog
title="Définir le groupe par défaut de cet ordinateur"
[continueButtonDisabled]="!form.valid"
(continue)="submit()">
<cre-dialog-body>
<form [formGroup]="form" class="w-100">
<cre-input [control]="controls.name" label="Name" icon="form-textbox"></cre-input>
</form>
</cre-dialog-body>
</cre-prompt-dialog>

View File

@ -0,0 +1,18 @@
import {RouterModule, Routes} from "@angular/router";
import {GroupTokenList} from "./group-tokens";
import {NgModule} from "@angular/core";
const routes: Routes = [{
path: 'list',
component: GroupTokenList
}, {
path: '',
redirectTo: 'list'
}]
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class GroupTokensRoutingModule {
}

View File

@ -0,0 +1,24 @@
import {NgModule} from '@angular/core'
import {SharedModule} from '../shared/shared.module'
import {CreInputsModule} from '../shared/components/inputs/inputs.module'
import {CreButtonsModule} from '../shared/components/buttons/buttons.module'
import {GroupTokenAdd, GroupTokenList} from "../groupTokens/group-tokens";
@NgModule({
declarations: [
GroupTokenAdd,
GroupTokenList
],
exports: [
GroupTokenAdd
],
imports: [
SharedModule,
CreInputsModule,
CreButtonsModule
]
})
export class GroupTokensModule {
}

View File

@ -0,0 +1,69 @@
import {Component, EventEmitter, Output, ViewChild} from "@angular/core";
import {CrePromptDialog} from "../shared/components/dialogs/dialogs";
import {Group, GroupToken} from "../shared/model/account.model";
import {FormControl, FormGroup, Validators} from "@angular/forms";
import {GroupTokenService} from "../accounts/services/group-token.service";
import {SubscribingComponent} from "../shared/components/subscribing.component";
import {ErrorService} from "../shared/service/error.service";
import {ActivatedRoute, Router} from "@angular/router";
@Component({
selector: 'cre-group-token-list',
templateUrl: 'list.html'
})
export class GroupTokenList extends SubscribingComponent {
tokens$ = this.groupTokenService.all
columns = ['id', 'name', 'groupName', 'deleteButton']
constructor(
private groupTokenService: GroupTokenService,
errorService: ErrorService,
router: Router,
activatedRoute: ActivatedRoute
) {
super(errorService, activatedRoute, router)
}
}
@Component({
selector: 'cre-group-token-add',
templateUrl: 'add.html'
})
export class GroupTokenAdd extends SubscribingComponent {
@ViewChild(CrePromptDialog) dialog: CrePromptDialog
@Output() defaultGroupUpdate = new EventEmitter<GroupToken>()
controls = {name: new FormControl(null, Validators.required)}
form = new FormGroup(this.controls)
private group: Group | null
constructor(
private groupTokenService: GroupTokenService,
errorService: ErrorService,
router: Router,
activatedRoute: ActivatedRoute
) {
super(errorService, activatedRoute, router)
}
show(group: Group) {
this.group = group
this.dialog.show()
}
submit() {
if (!this.group) {
console.error("Group token group id was not defined")
return
}
const name = this.controls.name.value
this.subscribe(
this.groupTokenService.save(name, this.group.id),
groupToken => this.defaultGroupUpdate.emit(groupToken.group)
)
}
}

View File

@ -0,0 +1 @@
<div>A list</div>

View File

@ -9,17 +9,19 @@ import {AccountsModule} from "../accounts/accounts.module";
import {CreActionBarModule} from "../shared/components/action-bar/action-bar.module";
import {CreButtonsModule} from "../shared/components/buttons/buttons.module";
import {CreTablesModule} from "../shared/components/tables/tables.module";
import {GroupTokensModule} from "../groupTokens/group-tokens.module";
@NgModule({
declarations: [ListComponent, AddComponent, EditComponent],
imports: [
GroupRoutingModule,
SharedModule,
AccountsModule,
CreActionBarModule,
CreButtonsModule,
CreTablesModule
]
imports: [
GroupRoutingModule,
SharedModule,
AccountsModule,
CreActionBarModule,
CreButtonsModule,
CreTablesModule,
GroupTokensModule
]
})
export class GroupModule { }

View File

@ -20,10 +20,17 @@
<td mat-cell *matCellDef="let group">{{group.permissions.length}}</td>
</ng-container>
<ng-container matColumnDef="currentDefaultGroup">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let group">
<ng-container *ngIf="isCurrentGroup(group)">Groupe par défaut</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="setAsDefaultButton">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell [class.disabled]="!hasAdminPermission" *matCellDef="let group; let i = index">
<cre-accent-button [creInteractiveCell]="i" (click)="setDefaultGroup(group)" >
<cre-accent-button [creInteractiveCell]="i" (click)="setDefaultGroup(group)">
Définir par défaut
</cre-accent-button>
</td>
@ -39,4 +46,4 @@
</ng-container>
</cre-table>
<cre-group-token-add></cre-group-token-add>
<cre-group-token-add (defaultGroupUpdate)="currentGroupToken = $event"></cre-group-token-add>

View File

@ -1,6 +1,6 @@
import {Component, ViewChild} from '@angular/core'
import {GroupService} from '../../services/group.service'
import {Group, Permission} from '../../../shared/model/account.model'
import {Group, GroupToken, Permission} from '../../../shared/model/account.model'
import {AccountService} from '../../../accounts/services/account.service'
import {ErrorHandlingComponent} from '../../../shared/components/subscribing.component'
import {ActivatedRoute, Router} from '@angular/router'
@ -8,7 +8,7 @@ import {ErrorHandler, ErrorService} from '../../../shared/service/error.service'
import {AlertService} from '../../../shared/service/alert.service'
import {AppState} from '../../../shared/app-state'
import {GroupTokenService} from "../../../accounts/services/group-token.service";
import {GroupTokenAdd} from "../../../accounts/group-tokens";
import {GroupTokenAdd} from "../../../groupTokens/group-tokens";
@Component({
selector: 'cre-groups',
@ -17,28 +17,18 @@ import {GroupTokenAdd} from "../../../accounts/group-tokens";
})
export class ListComponent extends ErrorHandlingComponent {
groups$ = this.groupService.all
defaultGroup: Group = null
// columns = [
// {def: 'name', title: 'Nom', valueFn: g => g.name},
// {def: 'permissionCount', title: 'Nombre de permissions', valueFn: g => g.permissions.length}
// ]
// buttons = [{
// text: 'Définir par défaut',
// clickFn: group => this.setDefaultGroup(group),
// disabledFn: group => this.isDefaultGroup(group)
// }, {
// text: 'Modifier',
// linkFn: group => `/admin/group/edit/${group.id}`,
// permission: Permission.EDIT_USERS
// }]
groupsEmpty = false
currentGroupToken: GroupToken | null
columns = ['name', 'permissionCount', 'setAsDefaultButton', 'editButton']
noDefaultGroupColumns = ['name', 'permissionCount', 'setAsDefaultButton', 'editButton']
defaultGroupColumns = ['name', 'permissionCount', 'currentDefaultGroup', 'editButton']
errorHandlers: ErrorHandler[] = [{
filter: error => error.type === 'nodefaultgroup',
consumer: () => this.alertService.pushWarning('Aucun groupe par défaut n\'a été défini sur cet ordinateur')
}, {
filter: error => error.type === 'exists-grouptoken-name',
messageProducer: error => `Un ordinateur avec le nom '${error.name}' existe déjà`
}]
@ViewChild(GroupTokenAdd) groupTokenDialog: GroupTokenAdd
@ -58,14 +48,9 @@ export class ListComponent extends ErrorHandlingComponent {
}
ngOnInit(): void {
// this.subscribe(
// this.groupService.defaultGroup,
// group => this.defaultGroup = group,
// true
// )
this.subscribe(
this.groupTokenService.current,
token => console.info(token)
token => this.currentGroupToken = token
)
}
@ -73,8 +58,12 @@ export class ListComponent extends ErrorHandlingComponent {
this.groupTokenDialog.show(group)
}
isDefaultGroup(group: Group): boolean {
return this.defaultGroup && this.defaultGroup.id == group.id
isCurrentGroup(group: Group): boolean {
return this.currentGroupToken && this.currentGroupToken.group.id == group.id
}
get columns(): string[] {
return this.currentGroupToken ? this.defaultGroupColumns : this.noDefaultGroupColumns
}
get hasEditPermission(): boolean {

View File

@ -58,6 +58,7 @@ abstract class CreDialog<D = CreDialogData> {
})
export class CrePromptDialog extends CreDialog<CrePromptDialogData> {
@Input() title: string
@Input() continueButtonDisabled = false
protected get data(): CrePromptDialogData {
return {

View File

@ -5,6 +5,6 @@
</div>
<div mat-dialog-actions>
<cre-primary-button (click)="onCancel()">Annuler</cre-primary-button>
<cre-accent-button (click)="onContinue()">Continuer</cre-accent-button>
<cre-accent-button [disabled]="continueButtonDisabled" (click)="onContinue()">Continuer</cre-accent-button>
</div>
</ng-template>

View File

@ -32,7 +32,7 @@ export interface GroupToken {
id: string,
name: string,
enabled: boolean,
groupId: Group
group: Group
}
export enum Permission {

View File

@ -13,28 +13,28 @@ export class UserService {
}
get all(): Observable<AccountModel[]> {
return this.api.get<AccountModel[]>('/user')
return this.api.get<AccountModel[]>('/account/user')
}
getById(id: number): Observable<AccountModel> {
return this.api.get<AccountModel>(`/user/${id}`)
return this.api.get<AccountModel>(`/account/user/${id}`)
}
save(id: number, firstName: string, lastName: string, password: string, group: number, permissions: Permission[]): Observable<AccountModel> {
const user = {id, firstName, lastName, password, groupId: group >= 0 ? group : null, permissions}
return this.api.post<AccountModel>('/user', user)
return this.api.post<AccountModel>('/account/user', user)
}
update(id: number, firstName: string, lastName: string, group: number, permissions: Permission[]): Observable<void> {
const user = {id, firstName, lastName, groupId: group >= 0 ? group : null, permissions}
return this.api.put<void>('/user', user)
return this.api.put<void>('/account/user', user)
}
updatePassword(id: number, password: string): Observable<void> {
return this.api.put<void>(`/user/${id}/password`, password, true, {contentType: 'text/plain'})
return this.api.put<void>(`/account/user/${id}/password`, password, true, {contentType: 'text/plain'})
}
delete(id: number): Observable<void> {
return this.api.delete<void>(`/user/${id}`)
return this.api.delete<void>(`/account/user/${id}`)
}
}

View File

@ -12,6 +12,7 @@ export class AdministrationComponent extends SubMenuComponent {
links: NavLink[] = [
{route: '/admin/user', title: 'Utilisateurs', permission: Permission.VIEW_USERS},
{route: '/admin/group', title: 'Groupes', permission: Permission.VIEW_USERS},
{route: '/admin/group-token', title: 'Ordinateurs', permission: Permission.ADMIN},
{route: '/admin/config', title: 'Configuration', permission: Permission.ADMIN}
]
}