diff --git a/apps/maarch_entreprise/Views/users-administration.component.html b/apps/maarch_entreprise/Views/users-administration.component.html new file mode 100644 index 0000000000000000000000000000000000000000..45d699f86d751f0bd9e37079b8d41e8e1a0aa28f --- /dev/null +++ b/apps/maarch_entreprise/Views/users-administration.component.html @@ -0,0 +1,40 @@ +<div id="resultInfo" class="fade" style="display:none;"> + {{resultInfo}} +</div> +<div *ngIf="loading"> + <i class="fa fa-spinner fa-spin fa-5x" style="margin-left: 50%;margin-top: 16%;font-size: 8em"></i> +</div> +<div *ngIf="!loading" class="container-fluid"> + <h1 style="margin-top: 0"><i class="fa fa-cogs fa-2x"></i> Administration des utilisateurs : {{users.length}} utilisateurs</h1> + <div class="col-md-12" style="margin-top: 1%"> + <table id="usersTable" class="display" style="width: 100%" cellspacing="0" border="0"> + <thead> + <tr> + <th style="width:15%;" valign="bottom" align="left"><span>Identifiant</span></th> + <th style="width:20%;" valign="bottom" align="left"><span>Nom</span></th> + <th style="width:20%;" valign="bottom" align="left"><span>Prénom</span></th> + <th style="width:5%;" valign="bottom" align="left"><span>Statut</span></th> + <th style="width:20%;" valign="bottom" align="left"><span>Courriel</span></th> + <th style="width:20%;"><span> </span></th> + </tr> + </thead> + <tbody> + <tr *ngFor="let user of users"> + <td>{{user.user_id}}</td> + <td>{{user.lastname}}</td> + <td>{{user.firstname}}</td> + <td>{{user.status}}</td> + <td>{{user.mail}}</td> + <td> + <a><i routerLink="/administration" style="cursor:pointer" class="fa fa-edit fa-2x"></i></a> + <a *ngIf="user.enabled == 'Y'"><i class="fa fa-pause fa-2x"></i></a> + <a *ngIf="user.enabled == 'N'"><i class="fa fa-check fa-2x"></i></a> + <a><i style="cursor:pointer;color: #D9534F" class="fa fa-trash fa-2x"></i></a> + </td> + </tr> + </tbody> + </table> + <i routerLink="/administration" class="fa fa-plus-square fa-3x" style="cursor:pointer; position: absolute; right: 25px; color : #337AB7" title="Nouveau paramètre"></i> + </div> +</div> + diff --git a/apps/maarch_entreprise/css/styles.css b/apps/maarch_entreprise/css/styles.css index 722b23094fa02ba3791e6cfce1ef45f5bb797412..696c78ca7ec477e101c4f13ea014ab7cbf71e483 100644 --- a/apps/maarch_entreprise/css/styles.css +++ b/apps/maarch_entreprise/css/styles.css @@ -3595,3 +3595,19 @@ a.actionList { input.button { width:auto; } + +table.dataTable thead .sorting { + background-image: url("../../node_modules/datatables/media/images/sort_both.png")!important; +} +table.dataTable thead .sorting_asc { + background-image: url("../../node_modules/datatables/media/images/sort_asc.png")!important; +} +table.dataTable thead .sorting_desc { + background-image: url("../../node_modules/datatables/media/images/sort_desc.png")!important; +} +table.dataTable thead .sorting_asc_disabled { + background-image: url("../../node_modules/datatables/media/images/sort_asc_disabled.png")!important; +} +table.dataTable thead .sorting_desc_disabled { + background-image: url("../../node_modules/datatables/media/images/sort_desc_disabled.png")!important; +} diff --git a/apps/maarch_entreprise/js/angular/app/app.module.js b/apps/maarch_entreprise/js/angular/app/app.module.js index 0b3af7ff026eeea13635fcb7d84e528eaff2363f..30fcc12d3f2d4077910f4a98576144f01887ab7b 100644 --- a/apps/maarch_entreprise/js/angular/app/app.module.js +++ b/apps/maarch_entreprise/js/angular/app/app.module.js @@ -13,6 +13,7 @@ var http_1 = require("@angular/http"); var forms_1 = require("@angular/forms"); var app_component_1 = require("./app.component"); var administration_component_1 = require("./administration.component"); +var users_administration_component_1 = require("./users-administration.component"); var profile_component_1 = require("./profile.component"); var signature_book_component_1 = require("./signature-book.component"); var AppModule = (function () { @@ -27,13 +28,14 @@ AppModule = __decorate([ forms_1.FormsModule, router_1.RouterModule.forRoot([ { path: 'administration', component: administration_component_1.AdministrationComponent }, + { path: 'administration/users', component: users_administration_component_1.UsersAdministrationComponent }, { path: 'profile', component: profile_component_1.ProfileComponent }, { path: ':basketId/signatureBook/:resId', component: signature_book_component_1.SignatureBookComponent }, { path: '**', redirectTo: '', pathMatch: 'full' }, ], { useHash: true }), http_1.HttpModule ], - declarations: [app_component_1.AppComponent, administration_component_1.AdministrationComponent, profile_component_1.ProfileComponent, signature_book_component_1.SignatureBookComponent, signature_book_component_1.SafeUrlPipe], + declarations: [app_component_1.AppComponent, administration_component_1.AdministrationComponent, users_administration_component_1.UsersAdministrationComponent, profile_component_1.ProfileComponent, signature_book_component_1.SignatureBookComponent, signature_book_component_1.SafeUrlPipe], bootstrap: [app_component_1.AppComponent] }) ], AppModule); diff --git a/apps/maarch_entreprise/js/angular/app/app.module.ts b/apps/maarch_entreprise/js/angular/app/app.module.ts index 87ee084d8e90c6d4906372bd377bd8c3b743f949..c07bfc4428850f724fc6544715746632974e010e 100644 --- a/apps/maarch_entreprise/js/angular/app/app.module.ts +++ b/apps/maarch_entreprise/js/angular/app/app.module.ts @@ -6,6 +6,7 @@ import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { AdministrationComponent } from './administration.component'; +import { UsersAdministrationComponent } from './users-administration.component'; import { ProfileComponent } from './profile.component'; import { SignatureBookComponent, SafeUrlPipe } from './signature-book.component'; @@ -15,13 +16,14 @@ import { SignatureBookComponent, SafeUrlPipe } from './signature-book.component FormsModule, RouterModule.forRoot([ { path: 'administration', component: AdministrationComponent }, + { path: 'administration/users', component: UsersAdministrationComponent }, { path: 'profile', component: ProfileComponent }, { path: ':basketId/signatureBook/:resId', component: SignatureBookComponent }, { path: '**', redirectTo: '', pathMatch: 'full' }, ], { useHash: true }), HttpModule ], - declarations: [ AppComponent, AdministrationComponent, ProfileComponent, SignatureBookComponent, SafeUrlPipe ], + declarations: [ AppComponent, AdministrationComponent, UsersAdministrationComponent, ProfileComponent, SignatureBookComponent, SafeUrlPipe ], bootstrap: [ AppComponent] }) export class AppModule { } diff --git a/apps/maarch_entreprise/js/angular/app/users-administration.component.js b/apps/maarch_entreprise/js/angular/app/users-administration.component.js new file mode 100644 index 0000000000000000000000000000000000000000..29b5f554d817366bae39737df6de1ecd93251c47 --- /dev/null +++ b/apps/maarch_entreprise/js/angular/app/users-administration.component.js @@ -0,0 +1,51 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +var core_1 = require("@angular/core"); +var http_1 = require("@angular/http"); +require("rxjs/add/operator/map"); +var UsersAdministrationComponent = (function () { + function UsersAdministrationComponent(http) { + this.http = http; + this.users = []; + this.resultInfo = ""; + this.loading = false; + } + UsersAdministrationComponent.prototype.updateBreadcrumb = function (applicationName) { + if ($j('#ariane')[0]) { + $j('#ariane')[0].innerHTML = "<a href='index.php?reinit=true'>" + applicationName + "</a> > <a onclick='location.hash = \"/administration\"' style='cursor: pointer'>Administration</a> > Utilisateurs"; + } + }; + UsersAdministrationComponent.prototype.ngOnInit = function () { + var _this = this; + this.updateBreadcrumb(angularGlobals.applicationName); + this.coreUrl = angularGlobals.coreUrl; + this.loading = true; + this.http.get(this.coreUrl + 'rest/administration/users') + .map(function (res) { return res.json(); }) + .subscribe(function (data) { + _this.users = data; + setTimeout(function () { + $j('#usersTable').DataTable({}); + }, 0); + _this.loading = false; + }); + }; + return UsersAdministrationComponent; +}()); +UsersAdministrationComponent = __decorate([ + core_1.Component({ + templateUrl: angularGlobals["users-administrationView"], + styleUrls: ['../../node_modules/bootstrap/dist/css/bootstrap.min.css'] + }), + __metadata("design:paramtypes", [http_1.Http]) +], UsersAdministrationComponent); +exports.UsersAdministrationComponent = UsersAdministrationComponent; diff --git a/apps/maarch_entreprise/js/angular/app/users-administration.component.ts b/apps/maarch_entreprise/js/angular/app/users-administration.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..c10277e1591db751f107b1e66b92c9b860b4ecb6 --- /dev/null +++ b/apps/maarch_entreprise/js/angular/app/users-administration.component.ts @@ -0,0 +1,66 @@ +import { Component, OnInit } from '@angular/core'; +import { Http } from '@angular/http'; +import 'rxjs/add/operator/map'; + +declare function $j(selector: any) : any; + +declare var angularGlobals : any; + + +@Component({ + templateUrl : angularGlobals["users-administrationView"], + styleUrls : ['../../node_modules/bootstrap/dist/css/bootstrap.min.css'] +}) +export class UsersAdministrationComponent implements OnInit { + + coreUrl : string; + + users : any[] = []; + + resultInfo : string = ""; + loading : boolean = false; + + + constructor(public http: Http) { + } + + updateBreadcrumb(applicationName: string) { + if ($j('#ariane')[0]) { + $j('#ariane')[0].innerHTML = "<a href='index.php?reinit=true'>" + applicationName + "</a> > <a onclick='location.hash = \"/administration\"' style='cursor: pointer'>Administration</a> > Utilisateurs"; + } + } + + ngOnInit(): void { + this.updateBreadcrumb(angularGlobals.applicationName); + this.coreUrl = angularGlobals.coreUrl; + + this.loading = true; + + this.http.get(this.coreUrl + 'rest/administration/users') + .map(res => res.json()) + .subscribe((data) => { + this.users = data; + + setTimeout(() => { + $j('#usersTable').DataTable({ + //"language": { + // "lengthMenu": tempLang.display + " _MENU_ " + tempLang.recordsPerPage, + // "zeroRecords": tempLang.noRecords, + // "info": tempLang.page + " _PAGE_ "+ tempLang.outOf +" _PAGES_", + // "infoEmpty": tempLang.noRecords + " " + tempLang.available, + // "infoFiltered": "(" + tempLang.filteredFrom + " _MAX_ " + tempLang.records + ")", + // "search" : tempLang.search, + // "paginate" : { + // "first" : tempLang.first, + // "last" : tempLang.last, + // "next" : tempLang.next, + // "previous" : tempLang.previous + // } + //} + }); + }, 0); + + this.loading = false; + }); + } +} diff --git a/apps/maarch_entreprise/js/functions.js b/apps/maarch_entreprise/js/functions.js index 19aa617261a5f00e341e2005beabceb3f0fbbb09..94fee8f434b6bfda0c9a564fafc34e3cff981d17 100755 --- a/apps/maarch_entreprise/js/functions.js +++ b/apps/maarch_entreprise/js/functions.js @@ -7,6 +7,7 @@ var angularGlobals = {}; function triggerAngular(prodmode, locationToGo) { var views = [ 'administration', + 'users-administration', 'profile', 'signature-book' ]; diff --git a/apps/maarch_entreprise/merged_css.php b/apps/maarch_entreprise/merged_css.php index 248f04dc38a4f248da5da069e8caeef8d5afe992..6ed5da7adb58218adb297fae2711705e89d4fde2 100644 --- a/apps/maarch_entreprise/merged_css.php +++ b/apps/maarch_entreprise/merged_css.php @@ -50,6 +50,7 @@ readfile('apps/maarch_entreprise/css/administration.component.css'); //Dependencies readfile('node_modules/tooltipster/dist/css/tooltipster.bundle.min.css'); +readfile('node_modules/datatables/media/css/jquery.dataTables.min.css'); readfile('node_modules/jquery-typeahead/dist/jquery.typeahead.min.css'); readfile('node_modules/photoswipe/dist/photoswipe.css'); readfile('node_modules/photoswipe/dist/default-skin/default-skin.css'); diff --git a/apps/maarch_entreprise/merged_jsAbstract.php b/apps/maarch_entreprise/merged_jsAbstract.php index ab10f3a944993567e6054f790a2f71f3115ced0e..e4e4ca050f806fb2f2ae42c2982b4936fac635f6 100644 --- a/apps/maarch_entreprise/merged_jsAbstract.php +++ b/apps/maarch_entreprise/merged_jsAbstract.php @@ -59,6 +59,7 @@ class MergedJsAbstract { readfile('node_modules/bootstrap/dist/js/bootstrap.min.js'); readfile('node_modules/chart.js/Chart.min.js'); readfile('node_modules/tinymce/tinymce.min.js'); + readfile('node_modules/datatables/media/js/jquery.dataTables.min.js'); readfile('node_modules/jquery.nicescroll/jquery.nicescroll.min.js'); readfile('node_modules/jquery-typeahead/dist/jquery.typeahead.min.js'); readfile('node_modules/tooltipster/dist/js/tooltipster.bundle.min.js'); diff --git a/core/Controllers/UserController.php b/core/Controllers/UserController.php index 08b933c67422170dffd43a2c0922094f2ea9dc2e..fdb08b6996eda0e1d2a5bc3a05033b3fd8549c13 100644 --- a/core/Controllers/UserController.php +++ b/core/Controllers/UserController.php @@ -17,6 +17,7 @@ namespace Core\Controllers; use Baskets\Models\BasketsModel; use Core\Models\LangModel; +use Entities\Models\EntitiesModel; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Respect\Validation\Validator; @@ -321,7 +322,11 @@ class UserController public function getUsersForAutocompletion(RequestInterface $request, ResponseInterface $response) { - $users = UserModel::get(); + $users = UserModel::get([ + 'select' => ['user_id', 'firstname', 'lastname'], + 'where' => ['enabled = ?', 'user_id != ?'], + 'data' => ['Y', 'superadmin'] + ]); $formattedUsers = []; foreach ($users as $value) { @@ -331,6 +336,26 @@ class UserController return $response->withJson($formattedUsers); } + public function getUsersForAdministration(RequestInterface $request, ResponseInterface $response) + { + + if ($_SESSION['user']['UserId'] == 'superadmin') { + $users = UserModel::get([ + 'select' => ['user_id', 'firstname', 'lastname', 'status', 'enabled', 'mail'], + 'where' => ['user_id != ?'], + 'data' => ['superadmin'] + ]); + } else { + $entities = EntitiesModel::getAllEntitiesByUserId(['userId' => $_SESSION['user']['UserId']]); + $users = UserModel::getByEntities([ + 'select' => ['users.user_id', 'firstname', 'lastname', 'status', 'enabled', 'mail'], + 'entities' => $entities + ]); + } + + return $response->withJson($users); + } + private function checkNeededParameters($aArgs = []) { foreach ($aArgs['needed'] as $value) { diff --git a/core/Models/UserModelAbstract.php b/core/Models/UserModelAbstract.php index 115ed0c6207bd527d1f604853c1421f08f38cd3e..ef1a9fa0dd838adb16c04df0afe18cbd80c0a988 100644 --- a/core/Models/UserModelAbstract.php +++ b/core/Models/UserModelAbstract.php @@ -19,13 +19,16 @@ require_once 'apps/maarch_entreprise/services/Table.php'; class UserModelAbstract extends \Apps_Table_Service { - public static function get() + public static function get(array $aArgs = []) { + static::checkRequired($aArgs, ['where', 'data']); + static::checkArray($aArgs, ['where', 'data']); + $aUsers = static::select([ - 'select' => ['firstname', 'lastname', 'user_id'], + 'select' => empty($aArgs['select']) ? ['*'] : $aArgs['select'], 'table' => ['users'], - 'where' => ['enabled = ?'], - 'data' => ['Y'], + 'where' => $aArgs['where'], + 'data' => $aArgs['data'] ]); return $aUsers; @@ -40,12 +43,27 @@ class UserModelAbstract extends \Apps_Table_Service 'select' => empty($aArgs['select']) ? ['*'] : $aArgs['select'], 'table' => ['users'], 'where' => ['user_id = ?'], - 'data' => [$aArgs['userId']], + 'data' => [$aArgs['userId']] ]); return $aUser[0]; } + public static function getByEntities(array $aArgs = []) + { + static::checkRequired($aArgs, ['entities']); + static::checkArray($aArgs, ['entities']); + + $aUsers = static::select([ + 'select' => empty($aArgs['select']) ? ['*'] : $aArgs['select'], + 'table' => ['users, users_entities'], + 'where' => ['users.user_id = users_entities.user_id', 'users_entities.entity_id in (?)'], + 'data' => $aArgs['entities'] + ]); + + return $aUsers; + } + public static function getByEmail(array $aArgs = []) { static::checkRequired($aArgs, ['mail']); @@ -56,7 +74,7 @@ class UserModelAbstract extends \Apps_Table_Service 'table' => ['users'], 'where' => ['mail = ? and status = ?'], 'data' => [$aArgs['mail'], 'OK'], - 'limit' => 1, + 'limit' => 1 ]); return $aUser; diff --git a/modules/entities/Models/EntitiesModelAbstract.php b/modules/entities/Models/EntitiesModelAbstract.php index 1050ceda06216c37ca7c808dc1aa73458695d22d..85400af011d6afb2886c8699f30ed7255cccee34 100644 --- a/modules/entities/Models/EntitiesModelAbstract.php +++ b/modules/entities/Models/EntitiesModelAbstract.php @@ -15,6 +15,8 @@ namespace Entities\Models; +use Core\Models\UserModel; + require_once 'apps/maarch_entreprise/services/Table.php'; class EntitiesModelAbstract extends \Apps_Table_Service @@ -51,4 +53,39 @@ class EntitiesModelAbstract extends \Apps_Table_Service return $aReturn; } + + private static function getEntityChilds(array $aArgs = []) + { + static::checkRequired($aArgs, ['entityId']); + static::checkString($aArgs, ['entityId']); + + $aReturn = static::select([ + 'select' => ['entity_id'], + 'table' => ['entities'], + 'where' => ['parent_entity_id = ?'], + 'data' => [$aArgs['entityId']] + ]); + + $entities = [$aArgs['entityId']]; + foreach ($aReturn as $value) { + $entities = array_merge($entities, static::getEntityChilds(['entityId' => $value['entity_id']])); + } + + return $entities; + } + + public static function getAllEntitiesByUserId(array $aArgs = []) + { + static::checkRequired($aArgs, ['userId']); + static::checkString($aArgs, ['userId']); + + $aReturn = UserModel::getEntitiesById(['userId' => $aArgs['userId']]); + + $entities = []; + foreach ($aReturn as $value) { + $entities = array_merge($entities, static::getEntityChilds(['entityId' => $value['entity_id']])); + } + + return array_unique($entities); + } } diff --git a/package.json b/package.json index b52bcbbe7b0191901eeb899016f67d5b58796448..1e3668addab09d3ec20644f25411502f633969a5 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "bootstrap": "^3.3.7", "chart.js": "1.1.1", "core-js": "^2.4.1", + "datatables": "^1.10.13", "jquery": "^3.2.1", "jquery-typeahead": "^2.8.0", "jquery.nicescroll": "^3.6.8", diff --git a/rest/index.php b/rest/index.php index 9d353ca86b22c13c0953fb50a3932eaa1784ff7c..109a90df33ddbf1effdff78bf17ce60240c162a7 100644 --- a/rest/index.php +++ b/rest/index.php @@ -101,6 +101,7 @@ $app->post('/initialize', \Core\Controllers\CoreController::class . ':initialize //Administration $app->get('/administration', \Core\Controllers\CoreController::class . ':getAdministration'); +$app->get('/administration/users', \Core\Controllers\UserController::class . ':getUsersForAdministration'); //status $app->get('/status', \Core\Controllers\StatusController::class . ':getList');