From 9c010ab29646bcf9140032464aa54e582e2f2e71 Mon Sep 17 00:00:00 2001 From: Damien <damien.burel@maarch.org> Date: Tue, 26 Jun 2018 12:33:13 +0200 Subject: [PATCH] FEAT #7990 Display baskets in group administration --- .../Views/group-administration.component.html | 119 ++++++++++-------- .../group-administration.component.ts | 39 +++--- .../js/angular/lang/lang-en.ts | 1 + .../js/angular/lang/lang-fr.ts | 1 + .../models/GroupBasketModelAbstract.php | 24 +++- src/app/group/controllers/GroupController.php | 11 +- test/GroupControllerTest.php | 12 ++ test/ResControllerTest.php | 3 +- 8 files changed, 139 insertions(+), 71 deletions(-) diff --git a/apps/maarch_entreprise/Views/group-administration.component.html b/apps/maarch_entreprise/Views/group-administration.component.html index a8db256420f..62846508f41 100644 --- a/apps/maarch_entreprise/Views/group-administration.component.html +++ b/apps/maarch_entreprise/Views/group-administration.component.html @@ -91,56 +91,77 @@ </mat-tab-group> </mat-tab> <mat-tab label="{{lang.relatedUsers}}" *ngIf="!creationMode"> - <div class="row" style="margin:0px;"> - <div class="col-md-12" *ngIf="group.canAdminUsers" style="padding:5px;"> - <mat-form-field> - <span matPrefix><mat-icon class="fa fa-user-plus" color="primary"></mat-icon> </span> - <input class="autocompleteSearch" #autocompleteFilter placeholder="{{lang.linkUser}}" type="text" matInput [matAutocomplete]="auto" - [formControl]="userCtrl"> - <mat-autocomplete #auto="matAutocomplete"> - <mat-option *ngFor="let user of filteredUsers | async" [value]="user.idToDisplay" (click)="linkUser(user)"> - <p mat-line style="margin:0;"> - <span class="col-xm-1" style="padding-right:5px;"> - <mat-icon color="primary" [class]="user.type == 'entity' ? 'fa fa-sitemap fa-2x' : 'fa fa-user fa-2x'" style="margin-right:0px;"></mat-icon> - </span> - <span class="col-xm-11"> - {{ user.idToDisplay }} - <small>{{ user.otherInfo }}</small> - </span> - </p> - </mat-option> - </mat-autocomplete> - </mat-form-field> - <hr/> - </div> - <div class="col-md-6 col-xs-6"> - <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> - </mat-form-field> - </div> - <div class="col-md-6 col-xs-6"> - <mat-paginator #paginator [length]="100" [pageSize]="10"> - </mat-paginator> - </div> + <div class="row" style="margin:0px;"> + <div class="col-md-12" *ngIf="group.canAdminUsers" style="padding:5px;"> + <mat-form-field> + <span matPrefix><mat-icon class="fa fa-user-plus" color="primary"></mat-icon> </span> + <input class="autocompleteSearch" #autocompleteFilter placeholder="{{lang.linkUser}}" type="text" matInput [matAutocomplete]="auto" + [formControl]="userCtrl"> + <mat-autocomplete #auto="matAutocomplete"> + <mat-option *ngFor="let user of filteredUsers | async" [value]="user.idToDisplay" (click)="linkUser(user)"> + <p mat-line style="margin:0;"> + <span class="col-xm-1" style="padding-right:5px;"> + <mat-icon color="primary" [class]="user.type == 'entity' ? 'fa fa-sitemap fa-2x' : 'fa fa-user fa-2x'" style="margin-right:0px;"></mat-icon> + </span> + <span class="col-xm-11"> + {{ user.idToDisplay }} + <small>{{ user.otherInfo }}</small> + </span> + </p> + </mat-option> + </mat-autocomplete> + </mat-form-field> + <hr/> + </div> + <div class="col-md-6 col-xs-6"> + <mat-form-field> + <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + </mat-form-field> + </div> + <div class="col-md-6 col-xs-6"> + <mat-paginator #paginator [length]="100" [pageSize]="10"> + </mat-paginator> </div> - <mat-table #table [dataSource]="dataSource" matSort matSortActive="lastname" matSortDirection="asc"> - <ng-container matColumnDef="user_id"> - <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.id}}</mat-header-cell> - <mat-cell *matCellDef="let element"> {{element.user_id}} </mat-cell> - </ng-container> - <ng-container matColumnDef="firstname"> - <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.firstname}}</mat-header-cell> - <mat-cell *matCellDef="let element"> {{element.firstname}} </mat-cell> - </ng-container> - <ng-container matColumnDef="lastname"> - <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.lastname}}</mat-header-cell> - <mat-cell *matCellDef="let element"> {{element.lastname}} </mat-cell> - </ng-container> - <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/users/{{row.id}}" matTooltip="{{lang.view}}" - style="cursor:pointer;"></mat-row> - </mat-table> - </mat-tab> + </div> + <mat-table #table [dataSource]="usersDataSource" matSort matSortActive="lastname" matSortDirection="asc"> + <ng-container matColumnDef="firstname"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.firstname}}</mat-header-cell> + <mat-cell *matCellDef="let element"> {{element.firstname}} </mat-cell> + </ng-container> + <ng-container matColumnDef="lastname"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.lastname}}</mat-header-cell> + <mat-cell *matCellDef="let element"> {{element.lastname}} </mat-cell> + </ng-container> + <mat-header-row *matHeaderRowDef="usersDisplayedColumns"></mat-header-row> + <mat-row *matRowDef="let row; columns: usersDisplayedColumns;" routerLink="/administration/users/{{row.id}}" matTooltip="{{lang.view}}" + style="cursor:pointer;"></mat-row> + </mat-table> + </mat-tab> + <mat-tab label="{{lang.relatedBaskets}}" *ngIf="!creationMode"> + <div class="row" style="margin:0px;"> + <div class="col-md-6 col-xs-6"> + <mat-form-field> + <input matInput (keyup)="applyBasketsFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + </mat-form-field> + </div> + <div class="col-md-6 col-xs-6"> + <mat-paginator #paginatorBaskets [length]="100" [pageSize]="10"> + </mat-paginator> + </div> + </div> + <mat-table #table [dataSource]="basketsDataSource" matSort matSortActive="basket_name" matSortDirection="asc"> + <ng-container matColumnDef="basket_name"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.label}}</mat-header-cell> + <mat-cell *matCellDef="let element"> {{element.basket_name}} </mat-cell> + </ng-container> + <ng-container matColumnDef="basket_desc"> + <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.description}}</mat-header-cell> + <mat-cell *matCellDef="let element"> {{element.basket_desc}} </mat-cell> + </ng-container> + <mat-header-row *matHeaderRowDef="basketsDisplayedColumns"></mat-header-row> + <mat-row *matRowDef="let row; columns: basketsDisplayedColumns;" routerLink="/administration/baskets/{{row.basket_id}}" matTooltip="{{lang.view}}" style="cursor:pointer;"></mat-row> + </mat-table> + </mat-tab> </mat-tab-group> </mat-card> </mat-sidenav-content> diff --git a/apps/maarch_entreprise/js/angular/app/administration/group-administration.component.ts b/apps/maarch_entreprise/js/angular/app/administration/group-administration.component.ts index 686644a14c1..98329eaca6d 100644 --- a/apps/maarch_entreprise/js/angular/app/administration/group-administration.component.ts +++ b/apps/maarch_entreprise/js/angular/app/administration/group-administration.component.ts @@ -30,16 +30,25 @@ export class GroupAdministrationComponent extends AutoCompletePlugin implements }; creationMode : boolean; - displayedColumns = ['firstname', 'lastname']; - dataSource : any; + usersDisplayedColumns = ['firstname', 'lastname']; + basketsDisplayedColumns = ['basket_name', 'basket_desc']; + usersDataSource : any; + basketsDataSource : any; + @ViewChild('paginatorBaskets') paginatorBaskets: MatPaginator; @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; + applyFilter(filterValue: string) { filterValue = filterValue.trim(); filterValue = filterValue.toLowerCase(); - this.dataSource.filter = filterValue; + this.usersDataSource.filter = filterValue; + } + applyBasketsFilter(filterValue: string) { + filterValue = filterValue.trim(); + filterValue = filterValue.toLowerCase(); + this.basketsDataSource.filter = filterValue; } constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher,public http: HttpClient, private route: ActivatedRoute, private router: Router, private notify: NotificationService) { @@ -69,9 +78,12 @@ export class GroupAdministrationComponent extends AutoCompletePlugin implements this.group = data['group']; this.loading = false; setTimeout(() => { - this.dataSource = new MatTableDataSource(this.group.users); - this.dataSource.paginator = this.paginator; - this.dataSource.sort = this.sort; + this.usersDataSource = new MatTableDataSource(this.group.users); + this.usersDataSource.paginator = this.paginator; + this.usersDataSource.sort = this.sort; + this.basketsDataSource = new MatTableDataSource(this.group.baskets); + this.basketsDataSource.paginator = this.paginatorBaskets; + this.basketsDataSource.sort = this.sort; }, 0); }, () => { @@ -98,7 +110,6 @@ export class GroupAdministrationComponent extends AutoCompletePlugin implements this.notify.error(err.error.errors); }); } - } updateService(service: any) { @@ -115,22 +126,22 @@ export class GroupAdministrationComponent extends AutoCompletePlugin implements this.userCtrl.setValue(''); $j('.autocompleteSearch').blur(); var groupReq = { - "groupId": this.group.group_id, - "role": this.group.role + "groupId" : this.group.group_id, + "role" : this.group.role }; this.http.post(this.coreUrl + "rest/users/" + newUser.id + "/groups", groupReq) - .subscribe((data: any) => { + .subscribe(() => { var displayName = newUser.idToDisplay.split(" "); var user = { id : newUser.id, user_id : newUser.otherInfo, firstname : displayName[0], lastname : displayName[1] - } + }; this.group.users.push(user); - this.dataSource = new MatTableDataSource(this.group.users); - this.dataSource.paginator = this.paginator; - this.dataSource.sort = this.sort; + this.usersDataSource = new MatTableDataSource(this.group.users); + this.usersDataSource.paginator = this.paginator; + this.usersDataSource.sort = this.sort; this.notify.success(this.lang.userAdded); }, (err) => { this.notify.error(err.error.errors); diff --git a/apps/maarch_entreprise/js/angular/lang/lang-en.ts b/apps/maarch_entreprise/js/angular/lang/lang-en.ts index 7e244ae2e40..eee9d2b0ea1 100755 --- a/apps/maarch_entreprise/js/angular/lang/lang-en.ts +++ b/apps/maarch_entreprise/js/angular/lang/lang-en.ts @@ -319,6 +319,7 @@ export const LANG_EN = { "redirects" : "Redirections", "reinitPassword" : "Reset password", "relatedUsers" : "Related users", + "relatedBaskets" : "Related basket(s)", "removeUserRedirect" : "Remove user (diffusion list + diffusion model entity)", "renewPsw" : "Enter the password again", "reports" : "Reports", diff --git a/apps/maarch_entreprise/js/angular/lang/lang-fr.ts b/apps/maarch_entreprise/js/angular/lang/lang-fr.ts index d4e99e41137..de4abfa135d 100755 --- a/apps/maarch_entreprise/js/angular/lang/lang-fr.ts +++ b/apps/maarch_entreprise/js/angular/lang/lang-fr.ts @@ -401,6 +401,7 @@ export const LANG_FR = { "redirectWhenAbscence" : "Rediriger la bannette à une personne", "reinitPassword" : "Réinitialiser le mot de passe", "relatedUsers" : "Utilisateur(s) associé(s)", + "relatedBaskets" : "Bannette(s) associée(s)", "removeUserRedirect" : "Supprimer la personne (liste de diffusion + modèle de l'entité)", "renewPsw" : "Retaper le mot de passe", "reports" : "Statistiques", diff --git a/src/app/basket/models/GroupBasketModelAbstract.php b/src/app/basket/models/GroupBasketModelAbstract.php index 4d5e2e0e0a8..75e62fd0be3 100644 --- a/src/app/basket/models/GroupBasketModelAbstract.php +++ b/src/app/basket/models/GroupBasketModelAbstract.php @@ -23,13 +23,15 @@ abstract class GroupBasketModelAbstract public static function get(array $aArgs) { ValidatorModel::arrayType($aArgs, ['select', 'where', 'data', 'orderBy']); + ValidatorModel::intType($aArgs, ['limit']); $aGroupsBaskets = DatabaseModel::select([ 'select' => empty($aArgs['select']) ? ['*'] : $aArgs['select'], 'table' => ['groupbasket'], - 'where' => $aArgs['where'], - 'data' => $aArgs['data'], - 'order_by' => $aArgs['orderBy'] + 'where' => empty($aArgs['where']) ? [] : $aArgs['where'], + 'data' => empty($aArgs['data']) ? [] : $aArgs['data'], + 'order_by' => empty($aArgs['orderBy']) ? [] : $aArgs['orderBy'], + 'limit' => empty($aArgs['limit']) ? 0 : $aArgs['limit'] ]); return $aGroupsBaskets; @@ -91,4 +93,20 @@ abstract class GroupBasketModelAbstract return true; } + + public static function getBasketsByGroupId(array $aArgs) + { + ValidatorModel::notEmpty($aArgs, ['groupId']); + ValidatorModel::stringType($aArgs, ['groupId']); + ValidatorModel::arrayType($aArgs, ['select']); + + $aGroupsBaskets = DatabaseModel::select([ + 'select' => empty($aArgs['select']) ? ['*'] : $aArgs['select'], + 'table' => ['groupbasket, baskets'], + 'where' => ['groupbasket.group_id = ?', 'groupbasket.basket_id = baskets.basket_id'], + 'data' => [$aArgs['groupId']] + ]); + + return $aGroupsBaskets; + } } diff --git a/src/app/group/controllers/GroupController.php b/src/app/group/controllers/GroupController.php index 7ff0cb92480..a4699f7add7 100644 --- a/src/app/group/controllers/GroupController.php +++ b/src/app/group/controllers/GroupController.php @@ -2,6 +2,7 @@ namespace Group\controllers; +use Basket\models\GroupBasketModel; use Group\models\ServiceModel; use Group\models\GroupModel; use Respect\Validation\Validator; @@ -134,10 +135,12 @@ class GroupController return $response->withStatus(400)->withJson(['errors' => 'Group not found']); } - $group['users'] = GroupModel::getUsersByGroupId(['groupId' => $group['group_id'], 'select' => ['users.id', 'users.user_id', 'users.firstname', 'users.lastname']]); - $group['security'] = GroupModel::getSecurityByGroupId(['groupId' => $group['group_id']]); - $group['services'] = GroupModel::getAllServicesByGroupId(['groupId' => $group['group_id']]); - $group['canAdminUsers'] = ServiceModel::hasService(['id' => 'admin_users', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin']); + $group['security'] = GroupModel::getSecurityByGroupId(['groupId' => $group['group_id']]); + $group['services'] = GroupModel::getAllServicesByGroupId(['groupId' => $group['group_id']]); + $group['users'] = GroupModel::getUsersByGroupId(['groupId' => $group['group_id'], 'select' => ['users.id', 'users.user_id', 'users.firstname', 'users.lastname']]); + $group['baskets'] = GroupBasketModel::getBasketsByGroupId(['select' => ['baskets.basket_id', 'baskets.basket_name', 'baskets.basket_desc'], 'groupId' => $group['group_id']]); + $group['canAdminUsers'] = ServiceModel::hasService(['id' => 'admin_users', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin']); + $group['canAdminBaskets'] = ServiceModel::hasService(['id' => 'admin_baskets', 'userId' => $GLOBALS['userId'], 'location' => 'basket', 'type' => 'admin']); return $response->withJson(['group' => $group]); } diff --git a/test/GroupControllerTest.php b/test/GroupControllerTest.php index fc323c47a34..a80eb0f910e 100644 --- a/test/GroupControllerTest.php +++ b/test/GroupControllerTest.php @@ -51,6 +51,12 @@ class GroupControllerTest extends TestCase $this->assertSame('Y', $responseBody->group->enabled); $this->assertSame('1=2', $responseBody->group->security->where_clause); $this->assertSame('commentateur du dimanche', $responseBody->group->security->maarch_comment); + $this->assertInternalType('array', $responseBody->group->users); + $this->assertInternalType('array', $responseBody->group->baskets); + $this->assertEmpty($responseBody->group->users); + $this->assertEmpty($responseBody->group->baskets); + $this->assertSame(true, $responseBody->group->canAdminUsers); + $this->assertSame(true, $responseBody->group->canAdminBaskets); } public function testUpdate() @@ -86,6 +92,12 @@ class GroupControllerTest extends TestCase $this->assertSame('Y', $responseBody->group->enabled); $this->assertSame('1=3', $responseBody->group->security->where_clause); $this->assertSame('commentateur du dimanche #2', $responseBody->group->security->maarch_comment); + $this->assertInternalType('array', $responseBody->group->users); + $this->assertInternalType('array', $responseBody->group->baskets); + $this->assertEmpty($responseBody->group->users); + $this->assertEmpty($responseBody->group->baskets); + $this->assertSame(true, $responseBody->group->canAdminUsers); + $this->assertSame(true, $responseBody->group->canAdminBaskets); } public function testDelete() diff --git a/test/ResControllerTest.php b/test/ResControllerTest.php index b8482059e27..22043b79c95 100644 --- a/test/ResControllerTest.php +++ b/test/ResControllerTest.php @@ -369,6 +369,7 @@ class ResControllerTest extends TestCase // READ $res = \Resource\models\ResModel::getById(['resId' => self::$id]); - $this->assertSame(null, $res); + $this->assertInternalType('array', $res); + $this->assertEmpty($res); } } -- GitLab