Compare commits
No commits in common. "master" and "page-home" have entirely different histories.
|
@ -26,7 +26,7 @@
|
|||
if( !isset($_SESSION['CAS']) || !is_array($_SESSION['CAS']) ) $_SESSION['CAS'] = [];
|
||||
if( !isset($_SESSION['AUTH']) || !is_array($_SESSION['AUTH']) ) $_SESSION['AUTH'] = [];
|
||||
if( !isset($_SESSION['AvailableDepartments']) || !is_array($_SESSION['AvailableDepartments']) ) $_SESSION['AvailableDepartments'] = [];
|
||||
if( !isset($_SESSION['VERSION']) || !is_array($_SESSION['VERSION']) ) $_SESSION['VERSION'] = [];
|
||||
if( !isset($_SESSION['VERSION']) || !is_string($_SESSION['VERSION']) ) $_SESSION['VERSION'] = null;
|
||||
if( !isset($_SESSION['CurrentDepartmentId']) || !is_int($_SESSION['CurrentDepartmentId']) ) $_SESSION['CurrentDepartmentId'] = null;
|
||||
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ class casController{
|
|||
/* (2) Check ticket (validate)
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Build useful variables */
|
||||
$service = ($_SERVER['SERVER_PORT'] == 80) ? 'http' : 'https';
|
||||
$service = ($_SERVER['SERVER_NAME'] == 'ptut.com' ) ? 'http' : 'https';
|
||||
$service .= '://'.$_SERVER['HTTP_HOST'].'/api/v/1.0/cas/'.$popup_mode;
|
||||
$ticket = urlencode($_GET['ticket']);
|
||||
$validate_url = "https://sso.univ-pau.fr/cas/serviceValidate?ticket=$ticket&service=$service";
|
||||
|
@ -146,33 +146,14 @@ class casController{
|
|||
$_SESSION['AvailableDepartments'] = $departments;
|
||||
|
||||
/* (4) Choose first department by default */
|
||||
$_SESSION['CurrentDatabase'] = $departments[0]['dbName'];
|
||||
$_SESSION['CurrentDepartmentId'] = $departments[0]['idDep'];
|
||||
$_SESSION['VERSION'] = [
|
||||
'list' => $departments[0]['versions'],
|
||||
'current' => null
|
||||
];
|
||||
|
||||
/* (5) select version with default = 1 */
|
||||
foreach($_SESSION['VERSION']['list'] as $v){
|
||||
if( $v['default'] == 1 ){
|
||||
$_SESSION['VERSION']['current'] = intval($v['iddatabase']);
|
||||
$_SESSION['CurrentDatabase'] = $v['dbName'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* (6) if no default -> select first */
|
||||
if( !is_int($_SESSION['VERSION']) ){
|
||||
$_SESSION['VERSION']['current'] = intval($_SESSION['VERSION']['list'][0]['iddatabase']);
|
||||
$_SESSION['CurrentDatabase'] = $_SESSION['VERSION']['list'][0]['dbName'];
|
||||
}
|
||||
|
||||
/* (7) Use this department's database */
|
||||
/* (5) Use this department's database */
|
||||
Repo::switchDatabase($_SESSION['CurrentDatabase']);
|
||||
|
||||
|
||||
|
||||
|
||||
/* (4) Fetch @cas_login professor data
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to fetch professor */
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: lucas
|
||||
* Date: 10/05/18
|
||||
* Time: 13:03
|
||||
*/
|
||||
|
||||
namespace api\module\department;
|
||||
|
||||
|
||||
use database\core\Repo;
|
||||
use database\repo\cours;
|
||||
use database\repo\formation;
|
||||
use database\repo\td;
|
||||
use database\repo\tp;
|
||||
use database\repo\ue;
|
||||
use PhpOffice\PhpSpreadsheet\Reader\Xls\Style\Border;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Borders;
|
||||
|
||||
class exportController
|
||||
{
|
||||
|
||||
public function get($args){
|
||||
/** @var ue $ueRepo */
|
||||
$ueRepo = Repo::getRepo("ue");
|
||||
/** @var cours $cmRepo */
|
||||
$cmRepo = Repo::getRepo("cours");
|
||||
/** @var td $tdRepo */
|
||||
$tdRepo = Repo::getRepo("td");
|
||||
/** @var tp $tpRepo */
|
||||
$tpRepo = Repo::getRepo("tp");
|
||||
/** @var formation $formationRepo */
|
||||
$formationRepo = Repo::getRepo("formation");
|
||||
|
||||
$ues = $ueRepo->exportUE();
|
||||
$formations = [];
|
||||
|
||||
//cache formations labels
|
||||
foreach ($formationRepo->get(null) as $form){
|
||||
$formations[$form["idForm"]] = $form["labelForm"];
|
||||
}
|
||||
|
||||
$formatFormations = function(String $formationsId) use ($formations) : String{
|
||||
$returned = "";
|
||||
foreach (json_decode($formationsId,true) as $form){
|
||||
$returned .= $formations[$form]."+";
|
||||
}
|
||||
|
||||
return rtrim($returned,"+");
|
||||
};
|
||||
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$excel = $spreadsheet->getActiveSheet();
|
||||
|
||||
//set up base document
|
||||
$arrayHeaders = ["Code","Intitulé","Statut","V.H.","Cours","NbGr","Enseignant","TD","NbGr","Enseignant","TP","NbGr","Enseignant","Equ. TD","Total"];
|
||||
$excel->setCellValue("B2","CODIFICATION DES UE");
|
||||
$i = 1;
|
||||
foreach ($arrayHeaders as $header){
|
||||
$excel->setCellValueByColumnAndRow($i,4,$header);
|
||||
$i++;
|
||||
}
|
||||
|
||||
$excel->freezePane("O5");
|
||||
|
||||
//set up state variables
|
||||
$currentFormation = null;
|
||||
$currentLine = 5;
|
||||
|
||||
foreach ($ues as $ue){
|
||||
if($currentFormation != $ue["labelFormation"]){
|
||||
$currentFormation = $ue["labelFormation"];
|
||||
$excel->setCellValue("A$currentLine",$ue["labelFormation"]);
|
||||
$excel->getStyle("A$currentLine")->getFont()->setBold(true)->setSize(11);
|
||||
$excel->getStyle("A$currentLine:O$currentLine")->getBorders()->getTop()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_DOUBLE);
|
||||
$currentLine += 2;
|
||||
}
|
||||
|
||||
//get all groups data
|
||||
$cm = $cmRepo->getGroups($ue["code"]);
|
||||
$td = $tdRepo->getGroups($ue["code"]);
|
||||
$tp = $tpRepo->getGroups($ue["code"]);
|
||||
|
||||
//set UE header
|
||||
$nbrGroupeCM = count($cm);
|
||||
$nbrGroupeTD = count($td);
|
||||
$nbrGroupeTP = count($tp);
|
||||
|
||||
$volumeUE = $ue["volumeCours"] + $ue["volumeTD"] + $ue["volumeTP"];
|
||||
$equiTDUE = $nbrGroupeCM*1.5*$ue["volumeCours"] + $nbrGroupeTD*$ue["volumeTD"] + $nbrGroupeTP*$ue["volumeTP"];
|
||||
|
||||
$excel->setCellValue("A$currentLine",$ue["code"]);
|
||||
$excel->setCellValue("B$currentLine",$ue["label"]);
|
||||
$excel->setCellValue("C$currentLine",$ue["required"] == 1? "OBL" : "OPT");
|
||||
$excel->setCellValue("D$currentLine","$volumeUE");
|
||||
$excel->setCellValue("E$currentLine","{$ue["volumeCours"]}");
|
||||
$excel->setCellValue("F$currentLine","$nbrGroupeCM");
|
||||
$excel->setCellValue("H$currentLine","{$ue["volumeTD"]}");
|
||||
$excel->setCellValue("I$currentLine","$nbrGroupeTD");
|
||||
$excel->setCellValue("K$currentLine","{$ue["volumeTP"]}");
|
||||
$excel->setCellValue("L$currentLine","$nbrGroupeTP");
|
||||
$excel->setCellValue("O$currentLine","$equiTDUE");
|
||||
|
||||
$excel->getStyle("A$currentLine:O$currentLine")->getFont()->setBold( true )->setSize(9);
|
||||
$currentLine++;
|
||||
|
||||
$nbrLine = max($nbrGroupeCM,$nbrGroupeTD,$nbrGroupeTP)-1;
|
||||
foreach (range(0,$nbrLine) as $n){
|
||||
$excel->setCellValue("A$currentLine",$ue["code"]);
|
||||
$excel->setCellValue("B$currentLine",$ue["label"]);
|
||||
|
||||
$equiTD = 0;
|
||||
if(isset($cm[$n])){
|
||||
$excel->setCellValue("E$currentLine","{$cm[$n]["volume"]}");
|
||||
$excel->setCellValue("F$currentLine",$formatFormations($cm[$n]["formations"]));
|
||||
$excel->setCellValue("G$currentLine",$cm[$n]["lastName"]." ".$cm[$n]["firstName"]);
|
||||
$equiTD += 1.5*$cm[$n]["volume"];
|
||||
}
|
||||
|
||||
if(isset($td[$n])){
|
||||
$excel->setCellValue("H$currentLine","{$td[$n]["volume"]}");
|
||||
$excel->setCellValue("I$currentLine",$formatFormations($td[$n]["formations"]));
|
||||
$excel->setCellValue("J$currentLine",$td[$n]["lastName"]." ".$td[$n]["firstName"]);
|
||||
$equiTD += $td[$n]["volume"];
|
||||
}
|
||||
|
||||
if(isset($tp[$n])){
|
||||
$excel->setCellValue("K$currentLine","{$tp[$n]["volume"]}");
|
||||
$excel->setCellValue("L$currentLine",$formatFormations($tp[$n]["formations"]));
|
||||
$excel->setCellValue("M$currentLine",$tp[$n]["lastName"]." ".$tp[$n]["firstName"]);
|
||||
$equiTD += $tp[$n]["volume"];
|
||||
}
|
||||
|
||||
$excel->setCellValue("N$currentLine","$equiTD");
|
||||
|
||||
$excel->getStyle("A$currentLine:O$currentLine")->getFont()->setSize(8);
|
||||
|
||||
$currentLine++;
|
||||
}
|
||||
$currentLine++;
|
||||
}
|
||||
|
||||
|
||||
//resize all columns
|
||||
foreach(range('A','O') as $columnID) {
|
||||
$excel->getColumnDimension($columnID)->setAutoSize(true);
|
||||
}
|
||||
|
||||
//set content type headers
|
||||
// header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
|
||||
//reating writer
|
||||
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xls($spreadsheet);
|
||||
|
||||
//as phpSpreadSheet do not support output on the buffer, we have to write in a temp file then read it
|
||||
|
||||
//create temporary file;
|
||||
$file = tmpfile();
|
||||
|
||||
//get URI
|
||||
$metaDatas = stream_get_meta_data($file);
|
||||
$tmpFilename = $metaDatas['uri'];
|
||||
|
||||
//close file pointer
|
||||
fclose($file);
|
||||
|
||||
//write data
|
||||
$writer->save("$tmpFilename");
|
||||
|
||||
//get file content
|
||||
return [
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'Content-Disposition' => 'attachment; filename=archive.xls'
|
||||
],
|
||||
'body' => file_get_contents($tmpFilename)
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: lucas
|
||||
* Date: 07/05/18
|
||||
* Time: 17:59
|
||||
*/
|
||||
|
||||
namespace api\module\department\version;
|
||||
|
||||
|
||||
use database\core\Repo;
|
||||
|
||||
class switchController
|
||||
{
|
||||
|
||||
public function get($args){
|
||||
$version = null;
|
||||
extract($args);
|
||||
|
||||
$versionData = Repo::getRepo("meta")->getVersionById($version);
|
||||
$_SESSION['CurrentDatabase'] = $versionData["dbName"];
|
||||
$_SESSION['VERSION']['current'] = intval( $version );
|
||||
|
||||
return ["success" => true];
|
||||
}
|
||||
|
||||
}
|
|
@ -10,7 +10,6 @@ namespace api\module\department;
|
|||
|
||||
|
||||
use database\core\Repo;
|
||||
use database\repo\meta;
|
||||
use error\core\Error;
|
||||
use error\core\Err;
|
||||
use database\repo\department;
|
||||
|
@ -19,6 +18,95 @@ use Ifsnop\Mysqldump\Mysqldump;
|
|||
class versionController{
|
||||
|
||||
|
||||
/* Attributes
|
||||
---------------------------------------------------------*/
|
||||
private $backup_path;
|
||||
private $origin_dbname;
|
||||
|
||||
|
||||
|
||||
|
||||
/* (1) Initialize object
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
public function __construct(){
|
||||
$this->backup_path = null;
|
||||
$this->origin_dbname = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* (2) Initializes a directory
|
||||
*
|
||||
* @db_name<String> The database name
|
||||
*
|
||||
* @return outName<outType> outDesc
|
||||
*
|
||||
--------------------------------------------------------*/
|
||||
private function initDir(string $db_name){
|
||||
|
||||
/* (1) Manage 'BACKUP' root directory
|
||||
---------------------------------------------------------*/
|
||||
/* (1) If not exists -> try to create it */
|
||||
if( !is_dir(__BACKUP__) )
|
||||
mkdir(__BACKUP__);
|
||||
|
||||
/* (2) Try to override permissions */
|
||||
chmod(__BACKUP__, 0775);
|
||||
|
||||
|
||||
|
||||
/* (2) Manage sub-directory
|
||||
---------------------------------------------------------*/
|
||||
/* (1) If @db_name is 'preview_@database_hash' -> extract @database */
|
||||
if( preg_match('/^preview_(\w+)_[a-f0-9]+$/', $db_name, $m) )
|
||||
$db_name = $m[1];
|
||||
|
||||
/* (2) Store @db_name as origin */
|
||||
$this->origin_dbname = $db_name;
|
||||
|
||||
/* (3) Store backup path */
|
||||
$this->backup_path =__BACKUP__."/$db_name";
|
||||
|
||||
/* (4) If dir. already exists -> do nothing more */
|
||||
if( is_dir($this->backup_path) )
|
||||
return;
|
||||
|
||||
/* (4) Else -> try to create + set permissions */
|
||||
mkdir($this->backup_path);
|
||||
chmod($this->backup_path, 0775);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (3) Scan directory files
|
||||
*
|
||||
* @path<String> Directory path
|
||||
*
|
||||
* @return files<array> Array containing file names
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
private function scandir(string $path) : array {
|
||||
|
||||
/* (1) Return [] if not a directory */
|
||||
if( !is_dir($path) )
|
||||
return [];
|
||||
|
||||
/* (2) Scan the directory */
|
||||
$files = scandir($path);
|
||||
|
||||
/* (3) Remove '.' and '..' (2 first elements) */
|
||||
$files = array_slice($files, 2);
|
||||
|
||||
/* (4) Return file list */
|
||||
return $files;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (4) List available versions for this department
|
||||
*
|
||||
* @return versions<array> Version list
|
||||
|
@ -26,12 +114,17 @@ class versionController{
|
|||
---------------------------------------------------------*/
|
||||
public function get($args){
|
||||
|
||||
//search for the current department in the session and return its versions
|
||||
/** @var meta $depRepo */
|
||||
$depRepo = Repo::getRepo("meta");
|
||||
/* (1) Initialize directory for current database (department) */
|
||||
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||
|
||||
//if no department found, return an empty array
|
||||
return ['versions' => $depRepo->getAllVersions($_SESSION['CurrentDepartmentId']) ];
|
||||
/* (2) Strip extensions */
|
||||
$versions = array_map(
|
||||
function($e){ return pathinfo($e, PATHINFO_FILENAME); },
|
||||
$this->scandir($this->backup_path)
|
||||
);
|
||||
|
||||
/* (3) Return versions */
|
||||
return ['versions' => $versions ];
|
||||
|
||||
}
|
||||
|
||||
|
@ -39,7 +132,7 @@ class versionController{
|
|||
|
||||
/* (5) Remove an existing version for this department
|
||||
*
|
||||
* @version<int> Version name (typically snapshot date)
|
||||
* @version<String> Version name (typically snapshot date)
|
||||
*
|
||||
* @return deleted<bool> Whether the version has been deleted
|
||||
*
|
||||
|
@ -48,35 +141,11 @@ class versionController{
|
|||
$version = null;
|
||||
extract($args);
|
||||
|
||||
/* (1) Try to delete */
|
||||
$deleted = Repo::getRepo("meta")->deleteVersion($version);
|
||||
|
||||
if( !$deleted )
|
||||
return ['error' => new Error(Err::ModuleError)];
|
||||
|
||||
/* (2) Update version list */
|
||||
$_SESSION['VERSION']['list'] = Repo::getRepo("meta")->getAllVersions($_SESSION['CurrentDepartmentId']);
|
||||
|
||||
/* (3) Update current */
|
||||
$_SESSION['VERSION']['current'] = null;
|
||||
|
||||
// select version with default = 1
|
||||
foreach($_SESSION['VERSION']['list'] as $v){
|
||||
if( $v['default'] == 1 ){
|
||||
$_SESSION['VERSION']['current'] = intval($v['iddatabase']);
|
||||
$_SESSION['CurrentDatabase'] = $v['dbName'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if no default -> select first
|
||||
if( !is_int($_SESSION['VERSION']) ){
|
||||
$_SESSION['VERSION']['current'] = intval($_SESSION['VERSION']['list'][0]['iddatabase']);
|
||||
$_SESSION['CurrentDatabase'] = $_SESSION['VERSION']['list'][0]['dbName'];
|
||||
}
|
||||
|
||||
return ['deleted' => true];
|
||||
/* (1) Initialize directory for current database (department) */
|
||||
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||
|
||||
/* (2) Dispatch 'unlink' result */
|
||||
return [ 'deleted' => unlink($this->backup_path."/$version.sql") ];
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,8 +156,10 @@ class versionController{
|
|||
*
|
||||
---------------------------------------------------------*/
|
||||
public function post($args){
|
||||
$label = null;
|
||||
extract($args);
|
||||
|
||||
|
||||
/* (1) Initialize directory for current database (department) */
|
||||
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||
|
||||
/* (2) Try to create the snapshot */
|
||||
try{
|
||||
|
@ -97,33 +168,21 @@ class versionController{
|
|||
$conf = Repo::getDBConfig();
|
||||
|
||||
/* (2.2) Try to dump the database */
|
||||
/** @var Mysqldump*/
|
||||
$dump = new Mysqldump(
|
||||
'mysql:host='.$conf['host'].';dbname='.$_SESSION['CurrentDatabase'],
|
||||
'mysql:host='.$conf['host'].';dbname='.$conf['dbname'],
|
||||
$conf['username'],
|
||||
$conf['password']
|
||||
$conf['password'],
|
||||
[ "compress" => Mysqldump::GZIP ]
|
||||
);
|
||||
|
||||
//create temporary file;
|
||||
$file = tmpfile();
|
||||
//get URI
|
||||
$metaDatas = stream_get_meta_data($file);
|
||||
$tmpFilename = $metaDatas['uri'];
|
||||
//close file pointer
|
||||
fclose($file);
|
||||
//fill the file with sql dump
|
||||
$dump->start($tmpFilename);
|
||||
/* (2.3) Get current date (for naming the version) */
|
||||
$current_date = date('d-m-Y');
|
||||
|
||||
/** @var department $depRepo */
|
||||
$depRepo = Repo::getRepo("department");
|
||||
$dbName = $depRepo->createVersionDatabase($_SESSION['CurrentDepartmentId'],file_get_contents($tmpFilename));
|
||||
|
||||
/** @var meta $metaRep */
|
||||
$metaRep = Repo::getRepo("meta");
|
||||
$versionId = $metaRep->createVersion($label, $dbName,$_SESSION['CurrentDepartmentId'] ,false);
|
||||
/* (2.4) Store the version */
|
||||
$dump->start($this->backup_path."/$current_date.sql");
|
||||
|
||||
/* (2.5) Return status */
|
||||
return ['created_id' => $versionId ];
|
||||
return ['created_id' => $current_date ];
|
||||
|
||||
/* (3) On error -> dispatch error */
|
||||
}catch(\Exception $e){
|
||||
|
@ -135,24 +194,106 @@ class versionController{
|
|||
}
|
||||
|
||||
|
||||
/* (6) Modify a version and use it
|
||||
/* (6) ( Switches to preview || Applies on prod ) for a version
|
||||
*
|
||||
* @apply<int> If 0 -> preview version
|
||||
* If 1 -> apply version into prod database
|
||||
* @version<String> [OPT] Version name to use (if ommited, switch back to prod database)
|
||||
*
|
||||
* @return bool success
|
||||
* @return created_id<String> The created version id (date)
|
||||
*
|
||||
---------------------------------------------------------*/
|
||||
public function put($args){
|
||||
$label = null;
|
||||
$apply = null;
|
||||
$version = null;
|
||||
$default = null;
|
||||
extract($args);
|
||||
|
||||
/** @var meta $metaRepo */
|
||||
$metaRepo = Repo::getRepo("meta");
|
||||
|
||||
/* (1) Initialisation
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Initialize directory for current database (department) */
|
||||
$this->initDir( $_SESSION['CurrentDatabase'] );
|
||||
|
||||
/* (2) Get department repository */
|
||||
/** @var department $dept_repo */
|
||||
$dept_repo = Repo::getRepo('department');
|
||||
|
||||
/* (3) Check whether we have to [apply OR preview] */
|
||||
$apply = ( $apply === '1' );
|
||||
|
||||
|
||||
|
||||
|
||||
/* (2) If back to 'prod' database
|
||||
---------------------------------------------------------*/
|
||||
if( is_null($version) ){
|
||||
|
||||
/* (1) Reset database to 'prod' */
|
||||
$_SESSION['CurrentDatabase'] = $this->origin_dbname;
|
||||
$_SESSION['VERSION'] = null;
|
||||
|
||||
/* (2) Return success */
|
||||
return [ 'updated' => true ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (3) Read the backup version
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Start buffer */
|
||||
ob_start();
|
||||
|
||||
/* (2) Read backup file */
|
||||
readgzfile($this->backup_path."/$version.sql");
|
||||
|
||||
/* (3) Store & Flush buffer into variable */
|
||||
$snapshot = ob_get_clean();
|
||||
|
||||
/* (4) Manage error */
|
||||
if( strlen($snapshot) === 0 )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
|
||||
|
||||
/* (4) APPLY into 'prod' database
|
||||
---------------------------------------------------------*/
|
||||
if( $apply ){
|
||||
|
||||
/* (1) Restore from this version */
|
||||
$restored = $dept_repo->restore($this->origin_dbname, $snapshot);
|
||||
$_SESSION['VERSION'] = null;
|
||||
|
||||
/* (2) Dispatch repo execution status */
|
||||
return [ 'updated' => $restored ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (5) PREVIEW version database
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to get 'preview' database name */
|
||||
$preview_dbname = $dept_repo->previewExists($this->origin_dbname, $version);
|
||||
|
||||
/* (2) If does not exist -> create it */
|
||||
if( is_null($preview_dbname) ){
|
||||
|
||||
/* 1. Try to create preview */
|
||||
$preview_dbname = $dept_repo->createPreview($this->origin_dbname, $version);
|
||||
|
||||
/* 2. Switch to preview */
|
||||
$dept_repo->restore($preview_dbname, $snapshot);
|
||||
|
||||
}
|
||||
|
||||
/* (3) Store 'preview' database in session */
|
||||
$_SESSION['CurrentDatabase'] = $preview_dbname;
|
||||
$_SESSION['VERSION'] = $version;
|
||||
|
||||
|
||||
/* (4) Return status */
|
||||
return [ 'updated' => $metaRepo->updateVersion($version,$label,$default) ];
|
||||
return [ 'updated' => true ];
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -10,10 +10,7 @@ namespace api\module;
|
|||
|
||||
|
||||
use database\core\Repo;
|
||||
use database\repo\database;
|
||||
use database\repo\department;
|
||||
use database\repo\meta;
|
||||
use database\repo\professor;
|
||||
|
||||
class departmentController
|
||||
{
|
||||
|
@ -81,26 +78,8 @@ class departmentController
|
|||
if( $dep['idDep'] == $department){
|
||||
|
||||
$_SESSION['AvailableDepartments'] = $deps;
|
||||
$_SESSION['CurrentDatabase'] = $dep['dbName'];
|
||||
$_SESSION['CurrentDepartmentId'] = $dep['idDep'];
|
||||
$_SESSION['VERSION'] = [
|
||||
'list' => $dep['versions'],
|
||||
'current' => null
|
||||
];
|
||||
|
||||
// select version with default = 1
|
||||
foreach($_SESSION['VERSION']['list'] as $v){
|
||||
if( $v['default'] == 1 ){
|
||||
$_SESSION['VERSION']['current'] = intval($v['iddatabase']);
|
||||
$_SESSION['CurrentDatabase'] = $v['dbName'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if no default -> select first
|
||||
if( !is_int($_SESSION['VERSION']) ){
|
||||
$_SESSION['VERSION']['current'] = intval($_SESSION['VERSION']['list'][0]['iddatabase']);
|
||||
$_SESSION['CurrentDatabase'] = $_SESSION['VERSION']['list'][0]['dbName'];
|
||||
}
|
||||
|
||||
return ['switched' => true];
|
||||
|
||||
|
@ -113,52 +92,4 @@ class departmentController
|
|||
|
||||
}
|
||||
|
||||
|
||||
public function post($args){
|
||||
$name = null;
|
||||
extract($args);
|
||||
|
||||
/** @var meta $metaRepo */
|
||||
$metaRepo = Repo::getRepo("meta");
|
||||
/** @var professor $profRep */
|
||||
$profRep = Repo::getRepo("professor");
|
||||
/** @var database $dbRepo */
|
||||
$dbRepo = Repo::getRepo("database");
|
||||
|
||||
//create the department in the meta database
|
||||
$depId = $metaRepo->createDepartment($name);
|
||||
|
||||
//link the current user to that department
|
||||
$metaRepo->link($_SESSION['CAS']['login'],$depId);
|
||||
|
||||
//create the database and init the structure
|
||||
$dbName = $dbRepo->init($depId);
|
||||
|
||||
//link the new database to the department
|
||||
$metaRepo->createVersion("Version 1",$dbName,$depId,true);
|
||||
|
||||
//get the current user data from current department
|
||||
$user = $profRep->get($_SESSION['CAS']['id'])[0];
|
||||
|
||||
//switch our connexion to that database
|
||||
Repo::switchDatabase($dbName);
|
||||
|
||||
//create the default admin in the new database (categories are common to all department)
|
||||
$profRep->create($user["lastName"],
|
||||
$user["firstName"],
|
||||
$user["Categorie_idCategorie"],
|
||||
$user["hoursToDo"],
|
||||
$user["abreviation"],
|
||||
true,
|
||||
$user["casLogin"]);
|
||||
|
||||
//update user session
|
||||
$departments = $metaRepo->get_prof_departments($user["casLogin"]);
|
||||
$_SESSION['AvailableDepartments'] = $departments;
|
||||
|
||||
//we are good now
|
||||
return [];
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@ use database\core\Repo;
|
|||
class formationController
|
||||
{
|
||||
|
||||
public function get($args){
|
||||
public static function get($args){
|
||||
$form_id = null;
|
||||
extract($args);
|
||||
|
||||
|
@ -24,37 +24,4 @@ class formationController
|
|||
return ['formations' => $repo->get($form_id)];
|
||||
}
|
||||
|
||||
public function post($args){
|
||||
$label = null;
|
||||
$isInternal = null;
|
||||
extract($args);
|
||||
|
||||
/** @var \database\repo\formation $repo */
|
||||
$repo = Repo::getRepo("formation");
|
||||
|
||||
return ['idFormation' => $repo->create($label,$isInternal)];
|
||||
}
|
||||
|
||||
public function put($args){
|
||||
$idFormation = null;
|
||||
$label = null;
|
||||
$isInternal = null;
|
||||
extract($args);
|
||||
|
||||
/** @var \database\repo\formation $repo */
|
||||
$repo = Repo::getRepo("formation");
|
||||
|
||||
return ['success' => $repo->update($idFormation,$label,$isInternal)];
|
||||
}
|
||||
|
||||
public function delete($args){
|
||||
$idFormation = null;
|
||||
extract($args);
|
||||
|
||||
/** @var \database\repo\formation $repo */
|
||||
$repo = Repo::getRepo("formation");
|
||||
|
||||
return ['success' => $repo->delete($idFormation)];
|
||||
}
|
||||
|
||||
}
|
|
@ -22,17 +22,9 @@ class pdfController{
|
|||
* @return download<File> The PDF fiche
|
||||
---------------------------------------------------------*/
|
||||
public static function get($args){
|
||||
|
||||
$prof_id = -1;
|
||||
extract($args);
|
||||
|
||||
if(!$_SESSION["CAS"]["admin"] && $_SESSION["CAS"]["id"] != $prof_id){
|
||||
return [
|
||||
'headers' => ["Content-Type" => "text/html"],
|
||||
'body' => "Unauthorized access"
|
||||
];
|
||||
}
|
||||
|
||||
/* (0) Initialize
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Initialize data structure */
|
||||
|
@ -132,7 +124,7 @@ class pdfController{
|
|||
$fetched = $form_repo->get(null);
|
||||
|
||||
/* (2) Error: no formation found */
|
||||
if( !is_array($fetched) )
|
||||
if( count($fetched) < 1 )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
/* (3) Reference formations by key = idForm */
|
||||
|
@ -285,6 +277,10 @@ class pdfController{
|
|||
Il est à noter qu\'elle contient les données générées au '.$date.'. Elle peut ne plus être à jour.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Si un problème persiste veuillez contacter les responsables à l\'addresse mail suivante <span style="color: red;"><mail_display_error></span>.
|
||||
</p>
|
||||
|
||||
<br><br><br>
|
||||
|
||||
|
||||
|
@ -313,12 +309,12 @@ class pdfController{
|
|||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="ar">Sous service</td>
|
||||
<td class="ar">Heures manquantes</td>
|
||||
<td>'.( $missing_h>0 ? "$svg_warning $missing_h" : $missing_h).' h</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="ar">Sur service</td>
|
||||
<td class="ar">Heures sup.</td>
|
||||
<td>'.$sup_h.' h</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -348,6 +344,10 @@ class pdfController{
|
|||
Il est à noter qu\'elle contient les données générées au '.$date.'. Elle peut ne plus être à jour.
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Si un problème persiste veuillez contacter les responsables à l\'addresse mail suivante <span style="color: red;"><mail_display_error></span>.
|
||||
</p>
|
||||
|
||||
<br><br><br>
|
||||
|
||||
<table>
|
||||
|
|
|
@ -25,31 +25,10 @@ class coursController{
|
|||
$formations = [];
|
||||
extract($args);
|
||||
|
||||
/* Get the repos */
|
||||
/* Get the cours repo */
|
||||
/** @var cours $cours_repo */
|
||||
$cours_repo = Repo::getRepo('cours');
|
||||
/** @var ue $ue_repo */
|
||||
$ue_repo = Repo::getRepo('ue');
|
||||
|
||||
|
||||
/* (1) Fetch default formation from UE
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to fetch the cours' UE */
|
||||
$fetched_ue = $ue_repo->get($code);
|
||||
|
||||
/* (2) Manage error */
|
||||
if( !is_array($fetched_ue) || count($fetched_ue) < 1 )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
$defaultForm = intval($fetched_ue[0]['idForm']);
|
||||
|
||||
/* (3) Add to formation list if got a valid default formation */
|
||||
if( is_int($defaultForm) && $defaultForm >= 0 && !in_array($defaultForm, $formations) )
|
||||
$formations[] = $defaultForm;
|
||||
|
||||
|
||||
/* (2) Create the cours
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to create cours */
|
||||
$created_id = $cours_repo->create($code, $idProf, $volume, $formations);
|
||||
|
||||
|
@ -57,7 +36,7 @@ class coursController{
|
|||
if( is_null($created_id) || !is_int($created_id) )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
return ['created_id' => $created_id, 'formations' => $formations];
|
||||
return ['created_id' => $created_id];
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,31 +25,10 @@ class tdController{
|
|||
$formations = [];
|
||||
extract($args);
|
||||
|
||||
/* Get the repos */
|
||||
/* Get the td repo */
|
||||
/** @var td $td_repo */
|
||||
$td_repo = Repo::getRepo('td');
|
||||
/** @var ue $ue_repo */
|
||||
$ue_repo = Repo::getRepo('ue');
|
||||
|
||||
|
||||
/* (1) Fetch default formation from UE
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to fetch the TD' UE */
|
||||
$fetched_ue = $ue_repo->get($code);
|
||||
|
||||
/* (2) Manage error */
|
||||
if( !is_array($fetched_ue) || count($fetched_ue) < 1 )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
$defaultForm = intval($fetched_ue[0]['idForm']);
|
||||
|
||||
/* (3) Add to formation list if got a valid default formation */
|
||||
if( is_int($defaultForm) && $defaultForm >= 0 && !in_array($defaultForm, $formations) )
|
||||
$formations[] = $defaultForm;
|
||||
|
||||
|
||||
/* (2) Create the TD
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to create td */
|
||||
$created_id = $td_repo->create($code, $idProf, $volume, $formations);
|
||||
|
||||
|
@ -57,7 +36,7 @@ class tdController{
|
|||
if( is_null($created_id) || !is_int($created_id) )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
return ['created_id' => $created_id, 'formations' => $formations];
|
||||
return ['created_id' => $created_id];
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,31 +25,10 @@ class tpController{
|
|||
$formations = [];
|
||||
extract($args);
|
||||
|
||||
/* Get the repos */
|
||||
/* Get the tp repo */
|
||||
/** @var tp $tp_repo */
|
||||
$tp_repo = Repo::getRepo('tp');
|
||||
/** @var ue $ue_repo */
|
||||
$ue_repo = Repo::getRepo('ue');
|
||||
|
||||
|
||||
/* (1) Fetch default formation from UE
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to fetch the TP' UE */
|
||||
$fetched_ue = $ue_repo->get($code);
|
||||
|
||||
/* (2) Manage error */
|
||||
if( !is_array($fetched_ue) || count($fetched_ue) < 1 )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
$defaultForm = intval($fetched_ue[0]['idForm']);
|
||||
|
||||
/* (3) Add to formation list if got a valid default formation */
|
||||
if( is_int($defaultForm) && $defaultForm >= 0 && !in_array($defaultForm, $formations) )
|
||||
$formations[] = $defaultForm;
|
||||
|
||||
|
||||
/* (2) Create the TP
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Try to create tp */
|
||||
$created_id = $tp_repo->create($code, $idProf, $volume, $formations);
|
||||
|
||||
|
@ -57,7 +36,7 @@ class tpController{
|
|||
if( is_null($created_id) || !is_int($created_id) )
|
||||
return ['error' => new Error(Err::RepoError)];
|
||||
|
||||
return ['created_id' => $created_id, 'formations' => $formations];
|
||||
return ['created_id' => $created_id];
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -49,11 +49,7 @@ class PDOWrapper extends \PDO
|
|||
if($this->stacking){
|
||||
return new PDOStatementWrapper($statement, $this);
|
||||
}else{
|
||||
$st = parent::prepare($statement, $options);
|
||||
if($st === false){
|
||||
throw new \PDOException("There is an error in your SQL statement");
|
||||
}
|
||||
return $st;
|
||||
return parent::prepare($statement, $options);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -158,19 +154,23 @@ class PDOWrapper extends \PDO
|
|||
|
||||
//find the given pattern in the request, then call our function and replace the matched string by the return value of our function
|
||||
$finalStatement .= rtrim(preg_replace_callback("/(:[a-z_\-0-9]*)/is",function($matches) use (&$i,&$tempParametes){
|
||||
//get next number
|
||||
$i++;
|
||||
|
||||
//delete the ':' at the beginning of the string
|
||||
$tempKey = ltrim($matches[0],':');
|
||||
|
||||
//copy the parameter with the modified index
|
||||
$tempParametes[":$i"] = $tempParametes[$matches[0]];
|
||||
$tempParametes[$tempKey.$i] = $tempParametes[$tempKey];
|
||||
|
||||
//delete the old index
|
||||
unset($tempParametes[$matches[0]]);
|
||||
unset($tempParametes[$tempKey]);
|
||||
|
||||
//return the modified string for replacement
|
||||
return ":".$i++;
|
||||
return $matches[0].$i;
|
||||
},$statement),';').';';
|
||||
|
||||
$finalExecute += $tempParametes;
|
||||
$finalExecute = array_merge($finalExecute,$tempParametes);
|
||||
}
|
||||
|
||||
//disable stacking
|
||||
|
@ -184,7 +184,6 @@ class PDOWrapper extends \PDO
|
|||
$req = $this->prepare($finalStatement);
|
||||
|
||||
$success = $req->execute($finalExecute);
|
||||
|
||||
//as we execute multiple query that we don't fetch, we have to close the cursor if we want to do other requests later
|
||||
$req->closeCursor();
|
||||
$this->commit();
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
}
|
||||
|
||||
public static function switchDatabase(string $dbName){
|
||||
return static::$driver->pdo()->exec("USE $dbName;SET autocommit=1;");
|
||||
return static::$driver->pdo()->prepare("USE $dbName")->execute();
|
||||
}
|
||||
|
||||
public static function getDBConfig() : array{
|
||||
|
|
|
@ -1,266 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: lucas
|
||||
* Date: 09/05/18
|
||||
* Time: 16:55
|
||||
*/
|
||||
|
||||
namespace database\repo;
|
||||
|
||||
|
||||
use database\core\Repo;
|
||||
use database\core\Repo_i;
|
||||
|
||||
class database extends Repo_i {
|
||||
|
||||
/**
|
||||
* @param int $depId
|
||||
* @return String the name of the department database
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function init(int $depId) : String{
|
||||
|
||||
/** @var department $metaRep */
|
||||
$metaRep = Repo::getRepo("department");
|
||||
|
||||
$SQL = "
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `Categorie`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `Categorie` (
|
||||
`idCategorie` INT(11) NOT NULL,
|
||||
`labelCategorie` VARCHAR(100) NOT NULL,
|
||||
PRIMARY KEY (`idCategorie`))
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `Professeur`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `Professeur` (
|
||||
`idProfesseur` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`casLogin` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`lastName` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`firstName` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`abreviation` VARCHAR(10) NULL DEFAULT NULL COMMENT 'Abreviation used in the excel document',
|
||||
`admin` TINYINT(4) NOT NULL DEFAULT 0,
|
||||
`hoursToDo` INT(11) NOT NULL DEFAULT 0,
|
||||
`Categorie_idCategorie` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`idProfesseur`),
|
||||
INDEX `fk_Professeur_Categorie1_idx` (`Categorie_idCategorie` ASC),
|
||||
CONSTRAINT `fk_Professeur_Categorie1`
|
||||
FOREIGN KEY (`Categorie_idCategorie`)
|
||||
REFERENCES `Categorie` (`idCategorie`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 34
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `Formation`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `Formation` (
|
||||
`idFormation` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`labelFormation` VARCHAR(50) NULL DEFAULT NULL,
|
||||
`isInternal` TINYINT(4) NULL DEFAULT 1,
|
||||
PRIMARY KEY (`idFormation`))
|
||||
ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 20
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `UE`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `UE` (
|
||||
`code` VARCHAR(20) NOT NULL,
|
||||
`label` VARCHAR(100) NOT NULL,
|
||||
`required` TINYINT(4) NOT NULL DEFAULT 1,
|
||||
`volumeCours` FLOAT NOT NULL DEFAULT 0,
|
||||
`volumeTP` FLOAT NOT NULL DEFAULT 0,
|
||||
`volumeTD` FLOAT NOT NULL,
|
||||
`disabled` TINYINT(4) NOT NULL DEFAULT 0,
|
||||
`Formation_idFormation` INT(11) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`code`),
|
||||
INDEX `fk_UE_Formation1_idx` (`Formation_idFormation` ASC),
|
||||
CONSTRAINT `fk_UE_Formation1`
|
||||
FOREIGN KEY (`Formation_idFormation`)
|
||||
REFERENCES `Formation` (`idFormation`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1
|
||||
COMMENT = 'Table contenant le code et le label des UE';
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `Cours`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `Cours` (
|
||||
`idCours` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`UE_code` VARCHAR(20) NOT NULL,
|
||||
`Professeur_idProfesseur` INT(11) NULL DEFAULT NULL,
|
||||
`volume` FLOAT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`idCours`),
|
||||
INDEX `fk_Cours_UE_idx` (`UE_code` ASC),
|
||||
INDEX `fk_Cours_Professeur1_idx` (`Professeur_idProfesseur` ASC),
|
||||
CONSTRAINT `fk_Cours_Professeur1`
|
||||
FOREIGN KEY (`Professeur_idProfesseur`)
|
||||
REFERENCES `Professeur` (`idProfesseur`)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE SET NULL,
|
||||
CONSTRAINT `fk_Cours_UE`
|
||||
FOREIGN KEY (`UE_code`)
|
||||
REFERENCES `UE` (`code`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 88
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `GroupeCours`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `GroupeCours` (
|
||||
`Formation_idFormation` INT(11) NOT NULL,
|
||||
`Cours_idCours` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`Formation_idFormation`, `Cours_idCours`),
|
||||
INDEX `fk_Formation_has_Cours_Cours1_idx` (`Cours_idCours` ASC),
|
||||
INDEX `fk_Formation_has_Cours_Formation1_idx` (`Formation_idFormation` ASC),
|
||||
CONSTRAINT `fk_Formation_has_Cours_Cours1`
|
||||
FOREIGN KEY (`Cours_idCours`)
|
||||
REFERENCES `Cours` (`idCours`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_Formation_has_Cours_Formation1`
|
||||
FOREIGN KEY (`Formation_idFormation`)
|
||||
REFERENCES `Formation` (`idFormation`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `TD`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `TD` (
|
||||
`idTD` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`UE_code` VARCHAR(20) NOT NULL,
|
||||
`Professeur_idProfesseur` INT(11) NULL DEFAULT NULL,
|
||||
`volume` FLOAT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`idTD`),
|
||||
INDEX `fk_TD_UE1_idx` (`UE_code` ASC),
|
||||
INDEX `fk_TD_Professeur1_idx` (`Professeur_idProfesseur` ASC),
|
||||
CONSTRAINT `fk_TD_Professeur1`
|
||||
FOREIGN KEY (`Professeur_idProfesseur`)
|
||||
REFERENCES `Professeur` (`idProfesseur`)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE SET NULL,
|
||||
CONSTRAINT `fk_TD_UE1`
|
||||
FOREIGN KEY (`UE_code`)
|
||||
REFERENCES `UE` (`code`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 107
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `GroupeTD`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `GroupeTD` (
|
||||
`Formation_idFormation` INT(11) NOT NULL,
|
||||
`TD_idTD` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`Formation_idFormation`, `TD_idTD`),
|
||||
INDEX `fk_Formation_has_TD_TD1_idx` (`TD_idTD` ASC),
|
||||
INDEX `fk_Formation_has_TD_Formation1_idx` (`Formation_idFormation` ASC),
|
||||
CONSTRAINT `fk_Formation_has_TD_Formation1`
|
||||
FOREIGN KEY (`Formation_idFormation`)
|
||||
REFERENCES `Formation` (`idFormation`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_Formation_has_TD_TD1`
|
||||
FOREIGN KEY (`TD_idTD`)
|
||||
REFERENCES `TD` (`idTD`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `TP`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `TP` (
|
||||
`idTP` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`UE_code` VARCHAR(20) NOT NULL,
|
||||
`Professeur_idProfesseur` INT(11) NULL DEFAULT NULL,
|
||||
`volume` FLOAT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`idTP`),
|
||||
INDEX `fk_TP_UE1_idx` (`UE_code` ASC),
|
||||
INDEX `fk_TP_Professeur1_idx` (`Professeur_idProfesseur` ASC),
|
||||
CONSTRAINT `fk_TP_Professeur1`
|
||||
FOREIGN KEY (`Professeur_idProfesseur`)
|
||||
REFERENCES `Professeur` (`idProfesseur`)
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE SET NULL,
|
||||
CONSTRAINT `fk_TP_UE1`
|
||||
FOREIGN KEY (`UE_code`)
|
||||
REFERENCES `UE` (`code`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 164
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `GroupeTP`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `GroupeTP` (
|
||||
`Formation_idFormation` INT(11) NOT NULL,
|
||||
`TP_idTP` INT(11) NOT NULL,
|
||||
PRIMARY KEY (`Formation_idFormation`, `TP_idTP`),
|
||||
INDEX `fk_Formation_has_TP_TP1_idx` (`TP_idTP` ASC),
|
||||
INDEX `fk_Formation_has_TP_Formation1_idx` (`Formation_idFormation` ASC),
|
||||
CONSTRAINT `fk_Formation_has_TP_Formation1`
|
||||
FOREIGN KEY (`Formation_idFormation`)
|
||||
REFERENCES `Formation` (`idFormation`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_Formation_has_TP_TP1`
|
||||
FOREIGN KEY (`TP_idTP`)
|
||||
REFERENCES `TP` (`idTP`)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
SET SQL_MODE=@OLD_SQL_MODE;
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
|
||||
LOCK TABLES `Categorie` WRITE;
|
||||
/*!40000 ALTER TABLE `Categorie` DISABLE KEYS */;
|
||||
INSERT INTO `Categorie` VALUES (1,'Professeurs et Maîtres de Conférences'),(2,'ATERs'),(3,'CDDs enseignement'),(4,'Doctorants Vacataires'),(5,'Permanents UPPA'),(6,'Vacataires extérieurs');
|
||||
/*!40000 ALTER TABLE `Categorie` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
";
|
||||
|
||||
return $metaRep->createVersionDatabase($depId,$SQL);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -167,13 +167,36 @@ class department extends Repo_i
|
|||
|
||||
}
|
||||
|
||||
public function createVersionDatabase(String $depId, String $SQL) : String{
|
||||
$dbName = uniqid($depId)."";
|
||||
public function restore(string $dbName, string $SQL) : bool{
|
||||
|
||||
$this->pdo->exec("CREATE DATABASE $dbName; USE $dbName;".$SQL."USE {$_SESSION["CurrentDatabase"]};SET autocommit=1;");
|
||||
$this->pdo->setAttribute(\PDO::ATTR_AUTOCOMMIT,1);
|
||||
//get the list of command to execute
|
||||
$this->pdo->exec("DROP DATABASE $dbName;");
|
||||
$this->pdo->exec("CREATE DATABASE $dbName;");
|
||||
$this->pdo->exec("USE $dbName;");
|
||||
|
||||
return $dbName;
|
||||
return $this->pdo->exec($SQL);
|
||||
}
|
||||
|
||||
private static function generatePreviewDBName(string $bdName, string $backupName) : string{
|
||||
return "preview_{$bdName}_".sha1($bdName.$backupName);
|
||||
}
|
||||
|
||||
public function previewExists(string $dbName, string $backupname) : ?string {
|
||||
$previewDBName = static::generatePreviewDBName($dbName,$backupname);
|
||||
|
||||
$st = $this->pdo->prepare("SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = :dbName");
|
||||
$st->execute(["dbName" => $previewDBName]);
|
||||
|
||||
if($st->fetch() === false) return null;
|
||||
else return $previewDBName;
|
||||
}
|
||||
|
||||
public function createPreview(string $dbName, string $backupname) : string {
|
||||
$previewDBName = static::generatePreviewDBName($dbName,$backupname);
|
||||
|
||||
$this->pdo->exec("CREATE OR REPLACE DATABASE $previewDBName");
|
||||
|
||||
return $previewDBName;
|
||||
}
|
||||
|
||||
}
|
|
@ -42,26 +42,6 @@ class formation extends Repo_i {
|
|||
|
||||
}
|
||||
|
||||
public function update(int $idFormation, ?String $label, ?bool $isInternal) : bool{
|
||||
$req = "";
|
||||
$execute = [];
|
||||
|
||||
if($label != null){
|
||||
$req .= "labelFormation=:label,";
|
||||
$execute["label"] = $label;
|
||||
}
|
||||
if($isInternal != null){
|
||||
$req .= "isInternal=:isInternal,";
|
||||
$execute["isInternal"] = $isInternal?1:0;
|
||||
}
|
||||
$req = rtrim($req,",");
|
||||
$execute["idFormation"] = $idFormation;
|
||||
|
||||
$st = $this->pdo->prepare("UPDATE `Formation` SET $req WHERE idFormation=:idFormation");
|
||||
|
||||
return $st->execute($execute);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (2) Check if a formation exists (by its label)
|
||||
|
|
|
@ -88,7 +88,7 @@ class meta extends Repo_i {
|
|||
public function get_prof_departments(String $casLogin) : array{
|
||||
|
||||
/* (1) Prepare Statement */
|
||||
$st = $this->pdo->prepare("SELECT d2.iddepartement idDep, d2.label labelDep
|
||||
$st = $this->pdo->prepare("SELECT d2.iddepartement idDep, d2.label labelDep, d2.databaseName dbName
|
||||
FROM meta_vhost.casUser
|
||||
JOIN meta_vhost.linkedDep D ON casUser.casLogin = D.casUser_casLogin
|
||||
JOIN meta_vhost.departement d2 ON D.departement_iddepartement = d2.iddepartement
|
||||
|
@ -112,17 +112,7 @@ class meta extends Repo_i {
|
|||
if( $fetched === false )
|
||||
return [];
|
||||
|
||||
/* (7) Add all possible databases to the department */
|
||||
foreach ($fetched as &$dep){
|
||||
$st = $this->pdo->prepare("SELECT *
|
||||
FROM meta_vhost.`databases`
|
||||
WHERE departement_iddepartement = :idDep
|
||||
ORDER BY meta_vhost.`databases`.`default` DESC ");
|
||||
$st->execute(["idDep" => $dep["idDep"]]);
|
||||
$dep["versions"] = $st->fetchAll();
|
||||
}
|
||||
|
||||
/* (8) Return data */
|
||||
/* (7) Return data */
|
||||
return $fetched;
|
||||
|
||||
}
|
||||
|
@ -155,6 +145,15 @@ class meta extends Repo_i {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* (5) Check if a link exists
|
||||
*
|
||||
* @casLogin<String> The professor's cas login
|
||||
|
@ -255,97 +254,4 @@ class meta extends Repo_i {
|
|||
|
||||
}
|
||||
|
||||
public function deleteVersion(int $version) : bool{
|
||||
//get version data
|
||||
$st = $this->pdo->prepare("SELECT * FROM meta_vhost.`databases` WHERE iddatabase = :id");
|
||||
$st->execute(["id" => $version]);
|
||||
|
||||
$versionData = $st->fetch();
|
||||
|
||||
if( !is_array($versionData) || $versionData["default"] == 1){
|
||||
return false;
|
||||
}
|
||||
|
||||
//delete database
|
||||
$versionDatabase = $versionData['dbName'];
|
||||
$this->pdo->exec("DROP DATABASE $versionDatabase;");
|
||||
|
||||
//remove from meta
|
||||
$st = $this->pdo->prepare("DELETE FROM meta_vhost.`databases` WHERE iddatabase = :id");
|
||||
return $st->execute(["id" => $version]);
|
||||
}
|
||||
|
||||
public function createVersion(String $label, String $dbName, int $depId, bool $isDefault = false) : int{
|
||||
|
||||
$st = $this->pdo->prepare("INSERT INTO meta_vhost.`databases`(label, dbName, `default`, departement_iddepartement)
|
||||
VALUE (:label,:dbName,:default,:depId)");
|
||||
$st->execute([
|
||||
"label" => $label,
|
||||
"dbName" => $dbName,
|
||||
"default" => $isDefault? 1 : 0,
|
||||
"depId" => $depId
|
||||
]);
|
||||
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
public function getVersionById(int $id) : array{
|
||||
$st = $this->pdo->prepare("SELECT * FROM meta_vhost.`databases` WHERE iddatabase = :idVersion");
|
||||
$st->execute(["idVersion" => $id]);
|
||||
|
||||
$fetched = $st->fetch();
|
||||
|
||||
return $fetched == false ? [] : $fetched;
|
||||
}
|
||||
|
||||
public function getAllVersions(int $idDep) : array {
|
||||
$st = $this->pdo->prepare("SELECT * FROM meta_vhost.`databases` WHERE departement_iddepartement = :idDep");
|
||||
$st->execute(["idDep" => $idDep]);
|
||||
|
||||
return $st->fetchAll();
|
||||
}
|
||||
|
||||
public function updateVersion(int $version, ?String $label, ?bool $default) : bool{
|
||||
|
||||
//you can't un-default a version, you have to choose another version to be the default one
|
||||
if($default == false){
|
||||
return false;
|
||||
}
|
||||
|
||||
$set = "";
|
||||
$execute = [];
|
||||
|
||||
if($label != null){
|
||||
$set .= "label=:label,";
|
||||
$execute["label"] = $label;
|
||||
}
|
||||
|
||||
if($default != null){
|
||||
$set .= "`default`=:default,";
|
||||
$execute["default"] = $default?1:0;
|
||||
|
||||
//if default = true, set previous default version to non-default
|
||||
if($default == true){
|
||||
|
||||
$req = $this->pdo->prepare("UPDATE meta_vhost.`databases` SET `default`=0 WHERE departement_iddepartement=:idDep");
|
||||
$req->execute(["idDep" => $_SESSION['CurrentDepartmentId']]);
|
||||
}
|
||||
}
|
||||
|
||||
$set = rtrim($set,",");
|
||||
|
||||
$execute["idVersion"] = $version;
|
||||
|
||||
$st = $this->pdo->prepare("UPDATE meta_vhost.`databases` SET $set WHERE iddatabase=:idVersion");
|
||||
|
||||
return $st->execute($execute);
|
||||
}
|
||||
|
||||
public function createDepartment(String $name) : int{
|
||||
$st = $this->pdo->prepare("INSERT INTO meta_vhost.departement(label) VALUE (:label)");
|
||||
|
||||
$st->execute(["label" => $name]);
|
||||
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
}
|
|
@ -321,7 +321,7 @@ class professor extends Repo_i {
|
|||
$parm = is_null($prof_id) ? [] : [':id' => $prof_id];
|
||||
|
||||
/* (2) Prepare Statement */
|
||||
$st = $this->pdo->prepare("SELECT * FROM `Professeur`$cond ORDER BY firstName, lastName ASC");
|
||||
$st = $this->pdo->prepare("SELECT * FROM `Professeur`$cond ORDER BY abreviation ASC");
|
||||
|
||||
/* (3) Bind params and execute statement */
|
||||
if( is_bool($st) ) return [];
|
||||
|
@ -433,8 +433,7 @@ class professor extends Repo_i {
|
|||
AND VHTp.idProf = Prof.idProfesseur
|
||||
AND VHTd.idProf = Prof.idProfesseur
|
||||
GROUP BY
|
||||
Prof.idProfesseur
|
||||
ORDER BY Prof.firstName, Prof.lastName ASC;");
|
||||
Prof.idProfesseur;");
|
||||
|
||||
/* (3) Bind params and execute statement */
|
||||
if( is_bool($st) ) return [];
|
||||
|
|
|
@ -180,8 +180,7 @@ class ue extends Repo_i {
|
|||
$parm = is_null($code) ? [] : [':code' => $code];
|
||||
|
||||
/* (2) Prepare Statement */
|
||||
$st = $this->pdo->prepare("
|
||||
SELECT
|
||||
$st = $this->pdo->prepare("SELECT
|
||||
ue.code,
|
||||
ue.label,
|
||||
ue.disabled,
|
||||
|
@ -191,31 +190,12 @@ class ue extends Repo_i {
|
|||
ue.volumeTP,
|
||||
IFNULL(ue.Formation_idFormation, -1) idForm,
|
||||
fdef.labelFormation labelForm,
|
||||
IFNULL(formlist.formations, '[]') formations,
|
||||
IFNULL(formlist.nbrCours,0) nbrCours,
|
||||
IFNULL(formlist.nbrTD,0) nbrTD,
|
||||
IFNULL(formlist.nbrTP,0) nbrTP,
|
||||
IFNULL(formlist.modCours,0) modCours,
|
||||
IFNULL(formlist.modTD,0) modTD,
|
||||
IFNULL(formlist.modTP,0) modTP,
|
||||
IFNULL(formlist.nbrProfCours,0) nbrProfCours,
|
||||
IFNULL(formlist.nbrProfTD,0) nbrProfTD,
|
||||
IFNULL(formlist.nbrProfTP,0) nbrProfTP
|
||||
IFNULL(formlist.formations, '[]') formations
|
||||
FROM UE ue
|
||||
LEFT JOIN Formation fdef ON ue.Formation_idFormation = fdef.idFormation
|
||||
LEFT JOIN (
|
||||
SELECT ue2.code code, CONCAT('[',GROUP_CONCAT(DISTINCT Formation.idFormation), ']') formations,
|
||||
count(DISTINCT C.idCours) nbrCours, count(DISTINCT T.idTD) nbrTD, count(DISTINCT T2.idTP) nbrTP,
|
||||
MOD(volC.vol,ue2.volumeCours) modCours,
|
||||
MOD(volTD.vol,ue2.volumeTD) modTD,
|
||||
MOD(volTP.vol,ue2.volumeTP) modTP,
|
||||
count(DISTINCT C.Professeur_idProfesseur,C.idCours) nbrProfCours,
|
||||
count(DISTINCT T.Professeur_idProfesseur,T.idTD) nbrProfTD,
|
||||
count(DISTINCT T2.Professeur_idProfesseur,T2.idTP) nbrProfTP
|
||||
SELECT ue2.code code, CONCAT('[',GROUP_CONCAT(DISTINCT Formation.idFormation), ']') formations
|
||||
FROM UE ue2
|
||||
LEFT JOIN (SELECT sum(CO.volume) vol, CO.UE_code FROM Cours CO GROUP BY CO.UE_code) volC ON ue2.code = volC.UE_code
|
||||
LEFT JOIN (SELECT sum(TD2.volume) vol, TD2.UE_code FROM TD TD2 GROUP BY TD2.UE_code) volTD ON ue2.code = volTD.UE_code
|
||||
LEFT JOIN (SELECT sum(TP2.volume) vol, TP2.UE_code FROM TP TP2 GROUP BY TP2.UE_code) volTP ON ue2.code = volTP.UE_code
|
||||
LEFT JOIN Cours C ON ue2.code = C.UE_code
|
||||
LEFT JOIN TD T ON ue2.code = T.UE_code
|
||||
LEFT JOIN TP T2 ON ue2.code = T2.UE_code
|
||||
|
@ -290,13 +270,4 @@ class ue extends Repo_i {
|
|||
return $fetched;
|
||||
|
||||
}
|
||||
|
||||
public function exportUE() : array{
|
||||
$st = $this->pdo->prepare("SELECT * FROM UE
|
||||
LEFT JOIN Formation
|
||||
ON UE.Formation_idFormation = Formation.idFormation
|
||||
ORDER BY Formation_idFormation IS NULL DESC, Formation_idFormation ASC");
|
||||
$st->execute();
|
||||
return $st->fetchAll();
|
||||
}
|
||||
}
|
|
@ -33,43 +33,19 @@
|
|||
|
||||
}
|
||||
|
||||
/* (2) Only teacher */
|
||||
if( !in_array('cas_admin', $_SESSION['AUTH']) ){
|
||||
|
||||
// redirection
|
||||
if( $this->pagename != "fiche" ){
|
||||
header('Location: /fiche/');
|
||||
die();
|
||||
}
|
||||
|
||||
// deconnection
|
||||
if( $this->uri == 'logout' || $this->uri == 'logout/' ){
|
||||
|
||||
\session_destroy();
|
||||
header('Location: /');
|
||||
die();
|
||||
|
||||
}
|
||||
|
||||
// load page
|
||||
include __PUBLIC__."/page/fiche.php";
|
||||
die();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (3) Build page file name */
|
||||
/* (1) Build page file name */
|
||||
$page_fname = __PUBLIC__."/page/".$this->pagename.".php";
|
||||
|
||||
/* (4) If page does not exist -> 404 */
|
||||
/* (2) If page does not exist -> 404 */
|
||||
if( !file_exists($page_fname) )
|
||||
include __PUBLIC__.'/page/404.php';
|
||||
|
||||
/* (5) Set URI arguments */
|
||||
/* (3) Set URI arguments */
|
||||
$_GET['uri'] = explode('/', $this->uri);
|
||||
|
||||
/* (6) Load page */
|
||||
/* (4) Load page */
|
||||
include __PUBLIC__."/page/".$this->pagename.".php";
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
"phpstan/phpstan": "^0.9.2",
|
||||
"ifsnop/mysqldump-php": "2.*",
|
||||
"setasign/fpdf": "1.8.1",
|
||||
"mpdf/mpdf": "^7.0",
|
||||
"php" : ">= 7.1"
|
||||
"mpdf/mpdf": "^7.0"
|
||||
}
|
||||
}
|
||||
|
|
BIN
composer.phar
BIN
composer.phar
Binary file not shown.
|
@ -82,21 +82,13 @@
|
|||
}
|
||||
},
|
||||
|
||||
"POST": {
|
||||
"des": "Create a new Department",
|
||||
"per": [["cas_user"]],
|
||||
"par": {
|
||||
"name": { "des": "Name of the department", "typ": "text"}
|
||||
}
|
||||
},
|
||||
|
||||
"PUT":{
|
||||
"des": "Switch the user on another department database",
|
||||
"per": [["cas_user"]],
|
||||
"par": {
|
||||
"URL0": {"des": "Department id", "typ": "id", "ren": "department" }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"switched": { "des": "Whether the department has been switched", "typ": "bool" }
|
||||
}
|
||||
|
||||
|
@ -117,54 +109,31 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"export":{
|
||||
"GET": {
|
||||
"des": "Export the data of the current department and version to a Excel file",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {},
|
||||
"opt": { "download": true }
|
||||
}
|
||||
},
|
||||
"version":{
|
||||
"switch":{
|
||||
"GET": {
|
||||
"des": "Switch database version for the current session",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"URL0": { "des": "The version id", "typ": "id", "ren": "version" }
|
||||
},
|
||||
"out": {
|
||||
"sucess": { "des": "success of the operation", "typ": "bool" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"GET": {
|
||||
"des": "Get the list of the versions of the department",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {},
|
||||
"out": {
|
||||
"output": {
|
||||
"versions": { "des": "List of available versions", "typ": "array" }
|
||||
}
|
||||
},
|
||||
"POST": {
|
||||
"des": "Create a backup if the name is empty, execute the backup if the name is set",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"label": { "des": "Label of the version", "typ": "text" }
|
||||
},
|
||||
"out": {
|
||||
"par": {},
|
||||
"output": {
|
||||
"created_id": { "des": "The id of the created version", "typ": "varchar(10,10,alphanumeric)" }
|
||||
}
|
||||
},
|
||||
"PUT": {
|
||||
"des": "Update a version and switch to this version",
|
||||
"des": "Switches to a older version or to current state",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"URL0": { "des": "id of the version", "typ": "id", "ren": "version" },
|
||||
"label": { "des": "Label de la version", "typ": "text", "opt": true },
|
||||
"default": { "des": "Whether this version should be used on login", "typ": "bool", "opt": true }
|
||||
"URL0": { "des": "0 to preview, 1 to apply", "typ": "id", "ren": "apply" },
|
||||
"URL1": { "des": "The version name, current state if ommited", "typ": "varchar(10,10,alphanumeric)", "ren": "version", "opt": true }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"updated": { "des": "Whether the version has been switched|applied", "typ": "bool" }
|
||||
}
|
||||
},
|
||||
|
@ -172,9 +141,9 @@
|
|||
"des": "Delete a backup",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"URL0": { "des": "The version id", "typ": "id", "ren": "version" }
|
||||
"URL0": { "des": "The version name", "typ": "varchar(10,10,alphanumeric)", "ren": "version" }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"deleted": { "des": "Whether the version has been deleted", "typ": "bool" }
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +230,7 @@
|
|||
|
||||
"GET": {
|
||||
"des": "Get a professor's fiche",
|
||||
"per": [["cas_admin"], ["cas_user"]],
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"URL0": { "des": "Optional professor UID.", "typ": "id", "ren": "prof_id" }
|
||||
},
|
||||
|
@ -346,9 +315,8 @@
|
|||
"volume": { "des": "Number of hours for Cours", "typ": "id", "opt": true, "def": 0 },
|
||||
"formations": { "des": "List of formations (ids)", "typ": "array<id>", "opt": true, "def": [] }
|
||||
},
|
||||
"out": {
|
||||
"created_id" : { "des": "The id of the created Cours", "typ": "id" },
|
||||
"formations" : { "des": "The ids of the linked formations", "typ": "array<id>" }
|
||||
"output": {
|
||||
"created_id" : { "des": "The id of the created Cours", "typ": "id" }
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -370,7 +338,7 @@
|
|||
"add_form": { "des": "Id of formations to add", "typ": "array<id>", "opt": true, "def": [] },
|
||||
"rem_form": { "des": "Id of formations to remove", "typ": "array<id>", "opt": true, "def": [] }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"updated" : { "des": "Whether it has been updated", "typ": "bool" }
|
||||
}
|
||||
},
|
||||
|
@ -381,7 +349,7 @@
|
|||
"par": {
|
||||
"URL0": { "des": "Id of the Cours", "typ": "id", "ren": "idCours" }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"deleted" : { "des": "Whether it has been deleted", "typ": "bool" }
|
||||
}
|
||||
}
|
||||
|
@ -399,9 +367,8 @@
|
|||
"volume": { "des": "Number of hours for TD", "typ": "id", "opt": true, "def": 0 },
|
||||
"formations": { "des": "List of formations (ids)", "typ": "array<id>", "opt": true, "def": [] }
|
||||
},
|
||||
"out": {
|
||||
"created_id" : { "des": "The id of the created TD", "typ": "id" },
|
||||
"formations" : { "des": "The ids of the linked formations", "typ": "array<id>" }
|
||||
"output": {
|
||||
"created_id" : { "des": "The id of the created TD", "typ": "id" }
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -423,7 +390,7 @@
|
|||
"add_form": { "des": "Id of formations to add", "typ": "array<id>", "opt": true, "def": [] },
|
||||
"rem_form": { "des": "Id of formations to remove", "typ": "array<id>", "opt": true, "def": [] }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"updated" : { "des": "Whether it has been updated", "typ": "bool" }
|
||||
}
|
||||
},
|
||||
|
@ -434,7 +401,7 @@
|
|||
"par": {
|
||||
"URL0": { "des": "Id of the TD", "typ": "id", "ren": "idTD" }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"deleted" : { "des": "Whether it has been deleted", "typ": "bool" }
|
||||
}
|
||||
}
|
||||
|
@ -452,9 +419,8 @@
|
|||
"volume": { "des": "Number of hours for TP", "typ": "id", "opt": true, "def": 0 },
|
||||
"formations": { "des": "List of formations (ids)", "typ": "array<id>", "opt": true, "def": [] }
|
||||
},
|
||||
"out": {
|
||||
"created_id" : { "des": "The id of the created TP", "typ": "id" },
|
||||
"formations" : { "des": "The ids of the linked formations", "typ": "array<id>" }
|
||||
"output": {
|
||||
"created_id" : { "des": "The id of the created TP", "typ": "id" }
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -476,7 +442,7 @@
|
|||
"add_form": { "des": "Id of formations to add", "typ": "array<id>", "opt": true, "def": [] },
|
||||
"rem_form": { "des": "Id of formations to remove", "typ": "array<id>", "opt": true, "def": [] }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"updated" : { "des": "Whether it has been updated", "typ": "bool" }
|
||||
}
|
||||
},
|
||||
|
@ -487,7 +453,7 @@
|
|||
"par": {
|
||||
"URL0": { "des": "Id of the TP", "typ": "id", "ren": "idTP" }
|
||||
},
|
||||
"out": {
|
||||
"output": {
|
||||
"deleted" : { "des": "Whether it has been deleted", "typ": "bool" }
|
||||
}
|
||||
}
|
||||
|
@ -503,33 +469,6 @@
|
|||
"par": {
|
||||
"URL0":{"des" : "Id of the formation", "typ": "id", "ren": "form_id", "opt" : true }
|
||||
}
|
||||
},
|
||||
|
||||
"POST":{
|
||||
"des": "Create a new formation",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"label":{"des" : "name of the formation", "typ": "text" },
|
||||
"isInternal":{"des" : "is this formation internal to the department", "typ": "bool" }
|
||||
}
|
||||
},
|
||||
|
||||
"PUT":{
|
||||
"des": "Update a formation",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"URL0": { "des": "Id of the formation", "typ": "id", "ren": "idFormation" },
|
||||
"label":{"des" : "name of the formation", "typ": "text", "opt":true },
|
||||
"isInternal":{"des" : "is this formation internal to the department", "typ": "bool", "opt":true }
|
||||
}
|
||||
},
|
||||
|
||||
"DELETE":{
|
||||
"des": "Delete a formation",
|
||||
"per": [["cas_admin"]],
|
||||
"par": {
|
||||
"URL0": { "des": "Id of the formation", "typ": "id", "ren": "idFormation" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,7 +37,7 @@
|
|||
"node-sass": "^4.7.2",
|
||||
"sass-loader": "^6.0.6",
|
||||
"vue-loader": "^13.0.5",
|
||||
"vue-template-compiler": "^2.5.16",
|
||||
"vue-template-compiler": "^2.5.9",
|
||||
"webpack": "^3.8.1",
|
||||
"webpack-dev-server": "^2.9.5"
|
||||
}
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="32px"
|
||||
id="Layer_1"
|
||||
style="enable-background:new 0 0 32 32;"
|
||||
version="1.1"
|
||||
viewBox="0 0 32 32"
|
||||
width="32px"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="back.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"><metadata
|
||||
id="metadata9"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs7" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1015"
|
||||
id="namedview5"
|
||||
showgrid="false"
|
||||
inkscape:zoom="7.375"
|
||||
inkscape:cx="16"
|
||||
inkscape:cy="16"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
d="M 12,6 C 11.469,6 11.005141,6.1930781 10.619141,6.5800781 L 2.6621094,14.537109 C 2.3341094,14.865109 2,15.271 2,16 c 0,0.729 0.2794844,1.080266 0.6464844,1.447266 l 7.9726566,7.972656 C 11.005141,25.806922 11.469,26 12,26 c 1.188,0 2,-1.016 2,-2 0,-0.516 -0.186078,-0.986859 -0.580078,-1.380859 L 8.8007812,18 H 28 c 1.104,0 2,-0.896 2,-2 0,-1.104 -0.896,-2 -2,-2 H 8.8007812 L 13.419922,9.3808594 C 13.813922,8.9868594 14,8.516 14,8 14,7.016 13.187,6 12,6 Z"
|
||||
id="fill-edit"
|
||||
inkscape:connector-curvature="0" /></svg>
|
Before Width: | Height: | Size: 2.0 KiB |
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
enable-background="new 0 0 500 500"
|
||||
height="500px"
|
||||
id="Layer_1"
|
||||
version="1.1"
|
||||
viewBox="0 0 500 500"
|
||||
width="500px"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="pin-disabled.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"><metadata
|
||||
id="metadata9"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs7" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1015"
|
||||
id="namedview5"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.6675088"
|
||||
inkscape:cx="186.10652"
|
||||
inkscape:cy="69.51775"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1"
|
||||
inkscape:snap-page="true" /><path
|
||||
style="clip-rule:evenodd;fill:#010101;fill-rule:evenodd"
|
||||
d="M 463.1543 1 L 349.9375 114.2168 L 349.9375 77.375 L 363.56836 77.375 C 376.10336 77.375 386.2832 67.198109 386.2832 54.662109 C 386.2832 42.126109 376.10336 31.949219 363.56836 31.949219 L 136.43164 31.949219 C 123.89564 31.949219 113.71875 42.126109 113.71875 54.662109 C 113.71875 67.199109 123.89564 77.375 136.43164 77.375 L 150.06055 77.375 L 150.06055 232.73828 L 82.828125 300.60742 C 79.465125 303.87442 77.376953 308.50466 77.376953 313.59766 C 77.376953 323.58866 85.459234 331.77148 95.365234 331.77148 L 132.38281 331.77148 L 1 463.1543 L 36.845703 499 L 499 36.845703 L 463.1543 1 z M 213.6582 77.375 C 223.6532 77.375 231.83008 85.552828 231.83008 95.548828 L 231.83008 213.65625 C 231.83008 223.65225 223.6542 231.82812 213.6582 231.82812 C 203.6642 231.82812 195.48633 223.65225 195.48633 213.65625 L 195.48633 95.548828 C 195.48633 85.552828 203.6642 77.375 213.6582 77.375 z M 352.55469 235.29102 L 222.74414 365.10156 L 222.74414 445.33984 C 222.74414 457.87584 232.92103 468.05078 245.45703 468.05078 C 257.99403 468.05078 268.17188 457.87584 268.17188 445.33984 L 268.17188 331.77148 L 404.63281 331.77148 C 414.53181 331.77148 422.62305 323.58866 422.62305 313.59766 C 422.62305 308.60466 420.61847 304.06211 417.35547 300.78711 L 352.55469 235.29102 z "
|
||||
id="fill-edit" /></svg>
|
Before Width: | Height: | Size: 2.8 KiB |
|
@ -32,14 +32,13 @@
|
|||
inkscape:window-height="1015"
|
||||
id="namedview5"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.6675088"
|
||||
inkscape:cx="186.10652"
|
||||
inkscape:cy="69.51775"
|
||||
inkscape:zoom="0.472"
|
||||
inkscape:cx="14.830508"
|
||||
inkscape:cy="250"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1"
|
||||
inkscape:snap-page="true" /><path
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
d="m 150.061,232.739 -67.232,67.868 c -3.363,3.267 -5.453,7.898 -5.453,12.991 0,9.991 8.083,18.173 17.989,18.173 H 222.744 V 445.34 c 0,12.536 10.177,22.711 22.713,22.711 12.537,0 22.715,-10.175 22.715,-22.711 V 331.771 h 136.46 c 9.899,0 17.992,-8.182 17.992,-18.173 0,-4.993 -2.006,-9.536 -5.269,-12.811 L 349.938,232.644 V 77.375 h 13.631 c 12.535,0 22.715,-10.177 22.715,-22.713 0,-12.536 -10.18,-22.713 -22.715,-22.713 H 136.432 c -12.536,0 -22.713,10.177 -22.713,22.713 0,12.537 10.177,22.713 22.713,22.713 h 13.629 V 232.739 Z M 231.83,95.548 v 118.109 c 0,9.996 -8.176,18.172 -18.172,18.172 -9.994,0 -18.171,-8.176 -18.171,-18.172 V 95.548 c 0,-9.996 8.177,-18.173 18.171,-18.173 9.995,0 18.172,8.177 18.172,18.173 z"
|
||||
id="fill-edit"
|
||||
inkscape:connector-curvature="0"
|
||||
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="32"
|
||||
viewBox="0 0 32 32"
|
||||
width="32"
|
||||
version="1.1"
|
||||
id="svg6"
|
||||
sodipodi:docname="switch.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1022"
|
||||
id="namedview8"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:zoom="4.9166667"
|
||||
inkscape:cx="24"
|
||||
inkscape:cy="29.898306"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg6" />
|
||||
<path
|
||||
d="M 23.384615,24.615384 V 18.461538 H 8.615385 v 6.153846 L 0,15.999999 8.615385,7.3846151 v 6.1538459 h 14.76923 V 7.3846151 L 32,15.999999 Z"
|
||||
id="fill-edit"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc"
|
||||
style="stroke-width:1.23076928" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
enable-background="new 0 0 24 24"
|
||||
height="24px"
|
||||
id="Layer_1"
|
||||
version="1.1"
|
||||
viewBox="0 0 24 24"
|
||||
width="24px"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="time.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"><metadata
|
||||
id="metadata13"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs11" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1015"
|
||||
id="namedview9"
|
||||
showgrid="false"
|
||||
inkscape:zoom="9.8333333"
|
||||
inkscape:cx="12"
|
||||
inkscape:cy="12"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="29"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
d="m 12,2.0344069 c -5.5018378,0 -9.9631017,4.4620943 -9.9631017,9.9655931 0,5.503499 4.4612639,9.965593 9.9631017,9.965593 5.502668,0 9.963102,-4.462094 9.963102,-9.965593 0,-5.5034988 -4.460434,-9.9655931 -9.963102,-9.9655931 z m 3.664016,13.8762581 -0.290663,0.290663 c -0.241665,0.241666 -0.649424,0.253292 -0.903547,0.02408 l -3.753707,-3.28449 C 10.460316,12.71254 10.266817,12.244987 10.283427,11.902835 l 0.347965,-5.9245446 c 0.01827,-0.3429825 0.313086,-0.6220191 0.656068,-0.6220191 h 0.40942 c 0.342982,0 0.636967,0.2790366 0.653577,0.6211886 l 0.28485,4.9279861 c 0.01744,0.342982 0.217582,0.830466 0.444299,1.08708 l 2.610985,3.012931 c 0.226718,0.256614 0.215921,0.663542 -0.02657,0.905208 z"
|
||||
id="fill-edit"
|
||||
inkscape:connector-curvature="0"
|
||||
style="clip-rule:evenodd;fill-rule:evenodd;stroke-width:0.83046609" /></svg>
|
Before Width: | Height: | Size: 2.3 KiB |
|
@ -7,29 +7,42 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
|
||||
<title>Espace enseignant</title>
|
||||
<title>Gestion des enseignants</title>
|
||||
|
||||
<!-- Icon -->
|
||||
<link rel='shortcut icon' href='/favicon.ico'>
|
||||
|
||||
<!-- CSS dependencies -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Fira+Sans" rel="stylesheet">
|
||||
<link rel='stylesheet' type='text/css' href='/css/font-loader.css'>
|
||||
<link rel='stylesheet' type='text/css' href='/css/global.css'>
|
||||
<link rel='stylesheet' type='text/css' href='/css/pop-up.css'>
|
||||
<link rel='stylesheet' type='text/css' href='/css/layout.css'>
|
||||
<link rel='stylesheet' type='text/css' href='/css/menu.css'>
|
||||
<link rel='stylesheet' type='text/css' href='/css/header.css'>
|
||||
<link rel='stylesheet' type='text/css' href='/css/container.css'>
|
||||
|
||||
<body>
|
||||
<!-- JS dependencies -->
|
||||
<script type='text/javascript' src='/js/_SERVER.js'></script>
|
||||
|
||||
<div id="WRAPPER" class='login'>
|
||||
</head>
|
||||
<body class='loading'>
|
||||
|
||||
|
||||
<div id='LOGIN_REDIRECT'>
|
||||
<div class='icon'></div>
|
||||
<div class='title'><b>P</b><i>lateforme</i> <b>A</b><i>ssistée de</i> <b>T</b><i>raitement</i> <b>A</b><i>dministratif des</i> <b>T</b><i>aches d'</i><b>E</b><i>nseignement</i></div>
|
||||
<a href="/api/v/1.0/professor/pdf/<?php echo $_SESSION['CAS']["id"]; ?>"><button style='font-weight: normal; margin-bottom: 1em;'>Télécharger ma fiche</button></a>
|
||||
<a href="/fiche/logout"><button style='font-weight: normal'>Me déconnecter</button></a>
|
||||
<div id='main-vue'></div>
|
||||
|
||||
|
||||
|
||||
<!-- POPUP WINDOW -->
|
||||
<div id='POPUP'>
|
||||
<div class='header'></div>
|
||||
<div class='body'></div>
|
||||
<div class='footer'></div>
|
||||
</div>
|
||||
<div id='POPUP-BG'></div>
|
||||
|
||||
|
||||
</div>
|
||||
<!-- Main loop -->
|
||||
<script type='text/javascript' src='/js/bundle@fiche.js' onload="document.body.className=''"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -7,7 +7,7 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
|
||||
<title>Connexion</title>
|
||||
<title>PTUT web title</title>
|
||||
|
||||
<!-- Icon -->
|
||||
<link rel='shortcut icon' href='/favicon.ico'>
|
||||
|
@ -46,5 +46,4 @@
|
|||
<!-- Main loop -->
|
||||
<script type='text/javascript' src='/js/bundle@home.js' onload="document.body.className=''"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -72,6 +72,18 @@ module.exports = [ {
|
|||
module: mod_common,
|
||||
devtool: (process.env.NODE_ENV==='development') ? '#eval-source-map' : false
|
||||
|
||||
}, {
|
||||
|
||||
name: "fiche",
|
||||
entry: './webpack/page/fiche.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, './public_html/js/bundle'),
|
||||
publicPath: '/js/bundle/',
|
||||
filename: 'fiche@0.js'
|
||||
},
|
||||
module: mod_common,
|
||||
devtool: (process.env.NODE_ENV==='development') ? '#eval-source-map' : false
|
||||
|
||||
}, {
|
||||
|
||||
name: "settings",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
|
||||
<div id='CONTAINER' class='list'>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" :viewBox="gstore.viewBox">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<template v-if="gstore.dimensions">
|
||||
<path
|
||||
:d="'m ' + (gstore.dimensions.padding + gstore.dimensions.text.size) + ',' + (gstore.dimensions.padding) + ' ' +
|
||||
|
|
|
@ -33,10 +33,6 @@
|
|||
</h1>
|
||||
|
||||
<div class='table'>
|
||||
<div title='équivalents TD'>
|
||||
<span>0</span>
|
||||
<span>HETD</span>
|
||||
</div>
|
||||
<div>
|
||||
<span><input type='text' placeholder='???' v-model='gstore.create_h'></span>
|
||||
<span>heures à faire</span>
|
||||
|
@ -47,7 +43,6 @@
|
|||
|
||||
<div class='footer'>
|
||||
<button class='valid' @click='gstore.ic_handler()'>Créer l'enseignant</button>
|
||||
<button class='neutral' @click='gstore.ic_reset(); gstore.create_card=false'>Annuler</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -88,24 +83,22 @@
|
|||
|
||||
|
||||
<div class='table'>
|
||||
<div>
|
||||
<!-- if VIEW MODE -->
|
||||
<span v-show='gstore.edit_i!=pi'>{{prof.hoursToDo}}</span>
|
||||
<!-- if EDIT MODE -->
|
||||
<span v-show='gstore.edit_i==pi'><input type='text' placeholder='???' v-model='gstore.edit_h'></span>
|
||||
<!-- endif -->
|
||||
<span>heures à faire</span>
|
||||
</div>
|
||||
<div title='équivalents TD'>
|
||||
<span>{{ prof.equiTD }}</span>
|
||||
<span>HETD</span>
|
||||
</div>
|
||||
<!-- if EDIT MODE -->
|
||||
<div v-show='gstore.edit_i==pi'>
|
||||
<span><input type='text' placeholder='???' v-model='gstore.edit_h'></span>
|
||||
<span>heures à faire</span>
|
||||
</div>
|
||||
<!-- endif -->
|
||||
|
||||
<div title='heures de décalage' v-show='gstore.edit_i!=pi'>
|
||||
<span :data-error='prof.equiTD < prof.hoursToDo?1:0' :data-success='prof.equiTD < prof.hoursToDo?0:1'>{{ Math.floor( (prof.equiTD < prof.hoursToDo ? prof.hoursToDo-prof.equiTD : prof.equiTD-prof.hoursToDo)*100 )/100 }}</span>
|
||||
<span>{{ prof.equiTD < prof.hoursToDo ? 'sous-service' : 'sur-service' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- if VIEW MODE -->
|
||||
<div v-show='gstore.edit_i!=pi' class='sub' title='total des heures prévues'><strong>{{ prof.VHCours + prof.VHTd + prof.VHTp }}</strong> heures présentielles</div>
|
||||
<div v-show='gstore.edit_i!=pi' class='pdfdl' title='Télécharger la fiche' @click='gstore.id_handler(prof.idProfesseur)'>fiche</div>
|
||||
<!-- if EDIT MODE -->
|
||||
<div v-show='gstore.edit_i==pi' :class="gstore.edit_err.length > 0 ? 'sub warning' : 'sub'" :data-valid='gstore.edit_err_valid?1:0'>{{ gstore.edit_err }}</div>
|
||||
|
@ -113,7 +106,7 @@
|
|||
|
||||
<div class='footer'>
|
||||
<!-- if VIEW MODE -->
|
||||
<span v-show='gstore.edit_i!=pi' :class="(prof.VHCours == 0) ? 'course' : 'course active'">{{ prof.VHCours }}h <span>CM</span></span>
|
||||
<span v-show='gstore.edit_i!=pi' :class="(prof.VHCours == 0) ? 'course' : 'course active'">{{ prof.VHCours }}h <span>Cours</span></span>
|
||||
<hr v-show='gstore.edit_i!=pi'>
|
||||
<span v-show='gstore.edit_i!=pi' :class="(prof.VHTd == 0) ? 'td' : 'td active'" >{{ prof.VHTd }}h <span>TD</span></span>
|
||||
<hr v-show='gstore.edit_i!=pi'>
|
||||
|
@ -123,12 +116,6 @@
|
|||
<button v-show='gstore.edit_i==pi' class='grey' @click='gstore.ie_toggle(-1)'>Annuler</button>
|
||||
<!-- endif -->
|
||||
</div>
|
||||
|
||||
|
||||
<div class='info'>
|
||||
<strong>{{ prof.hoursToDo }}h</strong> à faire, <strong>{{ prof.VHCours + prof.VHTd + prof.VHTp }}h</strong> présentielles
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -5,16 +5,13 @@
|
|||
<div class='list container' data-anim-incoming='1' :data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
|
||||
<section class='filter'>
|
||||
<button class='back reflow search' @click='$router.back()'>Retour</button>
|
||||
</section>
|
||||
|
||||
<!-- FILTERS -->
|
||||
<section class='filter'>
|
||||
<div style='flex-basis: 3.2em'></div>
|
||||
<div :data-filter='gstore.order.current===0?1:0' @click='gstore.order_toggle(0)'>enseignant <span class='arrow' :data-way='gstore.order.way'></span></div>
|
||||
<div :data-filter='gstore.order.current===1?1:0' @click='gstore.order_toggle(1)'>volume horaire <span class='arrow' :data-way='gstore.order.way'></span></div>
|
||||
<div :data-filter='gstore.order.current===2?1:0' @click='gstore.order_toggle(2)'>formations <span class='arrow' :data-way='gstore.order.way'></span></div>
|
||||
|
||||
<div>enseignant</div>
|
||||
<div class='null'></div>
|
||||
<div>volume horaire</div>
|
||||
<div>formations</div>
|
||||
|
||||
</section>
|
||||
|
||||
|
@ -32,7 +29,7 @@
|
|||
</select>
|
||||
<select v-model='gstore.ccrea.type' class='min'>
|
||||
<option value='-' disabled>Type</option>
|
||||
<option value='0'>CM</option>
|
||||
<option value='0'>Cours</option>
|
||||
<option value='1'>TD</option>
|
||||
<option value='2'>TP</option>
|
||||
</select>
|
||||
|
@ -48,22 +45,17 @@
|
|||
|
||||
|
||||
<!-- COURS -->
|
||||
<section class='bcours'
|
||||
<section class='cours'
|
||||
v-for='(c,i) in gstore.manage.cours'
|
||||
:data-id='c.idCours'
|
||||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'
|
||||
|
||||
:data-prof='c.idProf'
|
||||
:data-vol='c.volume'
|
||||
:data-form='c.formations.join(`|`)'>
|
||||
:data-id='c.idCours'>
|
||||
|
||||
<div class='icon remove' @click='gstore.rem(0, i)'></div>
|
||||
<select v-model='c.new_prof' @change='gstore.upd_prof(0, i)'>
|
||||
<option value='-1' v-show='c.idProf!=-1'>Aucun enseignant affecté</option>
|
||||
<option v-for='p in gstore.manage.prof' :value='p.idProfesseur' v-show='p.idProfesseur!=c.idProf'>{{ `${p.firstName} ${p.lastName}` }}</option>
|
||||
</select>
|
||||
<div class='cm reflow active'>{{ c.volume }}</div>
|
||||
<div>Cours</div>
|
||||
<div><span class='mono'>{{ c.volume }}</span> heures</div>
|
||||
<div class='taglist'>
|
||||
<div v-for='f in c.formations' data-action>
|
||||
<span class='tag'>{{ gstore.form_by_id(f).labelForm || '???' }}</span>
|
||||
|
@ -86,22 +78,19 @@
|
|||
|
||||
|
||||
<!-- TD -->
|
||||
<section class='btd'
|
||||
<section class='td'
|
||||
v-for='(td,i) in gstore.manage.td'
|
||||
:data-id='td.idTD'
|
||||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'
|
||||
|
||||
:data-prof='td.idProf'
|
||||
:data-vol='td.volume'
|
||||
:data-form='td.formations.join(`|`)'>
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<div class='icon remove' @click='gstore.rem(1, i)'></div>
|
||||
<select v-model='td.new_prof' @change='gstore.upd_prof(1, i)'>
|
||||
<option value='-1' v-show='td.idProf!=-1'>Aucun enseignant affecté</option>
|
||||
<option v-for='p in gstore.manage.prof' :value='p.idProfesseur' v-show='p.idProfesseur!=td.idProf'>{{ `${p.firstName} ${p.lastName}` }}</option>
|
||||
</select>
|
||||
<div class='td reflow active'>{{ td.volume }}</div>
|
||||
<div>TD</div>
|
||||
<div><span class='mono'>{{ td.volume }}</span> heures</div>
|
||||
<div class='taglist'>
|
||||
<div v-for='f in td.formations' data-action>
|
||||
<span class='tag'>{{ gstore.form_by_id(f).labelForm || '???' }}</span>
|
||||
|
@ -124,22 +113,19 @@
|
|||
|
||||
|
||||
<!-- TP -->
|
||||
<section class='btp'
|
||||
<section class='tp'
|
||||
v-for='(tp,i) in gstore.manage.tp'
|
||||
:data-id='tp.idTP'
|
||||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'
|
||||
|
||||
:data-prof='tp.idProf'
|
||||
:data-vol='tp.volume'
|
||||
:data-form='tp.formations.join(`|`)'>
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<div class='icon remove' @click='gstore.rem(2, i)'></div>
|
||||
<select v-model='tp.new_prof' @change='gstore.upd_prof(2, i)'>
|
||||
<option value='-1' v-show='tp.idProf!=-1'>Aucun enseignant affecté</option>
|
||||
<option v-for='p in gstore.manage.prof' :value='p.idProfesseur' v-show='p.idProfesseur!=tp.idProf'>{{ `${p.firstName} ${p.lastName}` }}</option>
|
||||
</select>
|
||||
<div class='tp reflow active'>{{ tp.volume }}</div>
|
||||
<div>TP</div>
|
||||
<div><span class='mono'>{{ tp.volume }}</span> heures</div>
|
||||
<div class='taglist'>
|
||||
<div v-for='f in tp.formations' data-action>
|
||||
<span class='tag'>{{ gstore.form_by_id(f).labelForm || '???' }}</span>
|
||||
|
|
|
@ -2,20 +2,6 @@
|
|||
|
||||
<div id='CONTAINER' class='card'>
|
||||
|
||||
<div class='card filter'>
|
||||
|
||||
<div v-for='(filter_grp, gname) in gstore.filters' :title='gname' data-unblur-filter>
|
||||
|
||||
<div class='fold-toggle' :data-show='gstore.filters[gname][0].visible?1:0' @click='gstore.show_fgroup(gname)' :data-count='gstore.filters[gname][0].active.length' data-unblur-filter>{{ gname }}</div>
|
||||
|
||||
<div class='fold' data-unblur-filter>
|
||||
<span v-for='(data, i) in filter_grp' v-if='i > 0' :class="data.active == true ? 'active' : ''" @click='gstore.toggle_filter(gname, i); gstore.filter_handler(gname);' :title='data.code' data-unblur-filter>{{ data.name }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class='card container' :data-anim-outgoing='gstore.nav_anim.in?1:0'>
|
||||
|
||||
<input data-anim='0' class='card instant-search neutral' type='text' @keyup='gstore.is_handler($event)' placeholder='Recherche instantannée' id='ue_view_instant_search'>
|
||||
|
@ -29,23 +15,11 @@
|
|||
<option v-for='form in gstore.formations' :value='form.idForm'>{{ form.labelForm }}</option>
|
||||
</select>
|
||||
|
||||
<h1 class='pin'>
|
||||
<h1>
|
||||
<input type='text' placeholder='Libellé' v-model='gstore.create_label'>
|
||||
<span data-visible='1'>(<input type='text' placeholder='code' v-model='gstore.create_code'>)</span>
|
||||
</h1>
|
||||
|
||||
<div class='table little'>
|
||||
<div>
|
||||
<span class='notlast active reflow' data-error='0'>0 CM</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class='notlast active reflow' data-error='0'>0 TD</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class='notlast active reflow' data-error='0'>0 TP</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="gstore.create_err.length > 0 ? 'sub warning' : 'sub'" :data-valid='gstore.create_err_valid?1:0'>{{ gstore.create_err }}</div>
|
||||
|
||||
<div class='footer'>
|
||||
|
@ -58,7 +32,6 @@
|
|||
|
||||
<div class='footer'>
|
||||
<button class='valid' @click='gstore.ic_handler()'>Créer l'UE</button>
|
||||
<button class='neutral' @click='gstore.ic_reset(); gstore.create_card=false'>Annuler</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -73,7 +46,6 @@
|
|||
<!-- if VIEW MODE -->
|
||||
<div class='goo-menu' v-show='gstore.edit_i!=pi'>
|
||||
<div class='enabled' :data-enabled='ue.code' :data-active='ue.disabled?0:1' title='UE activée' @click="gstore.ia_handler(pi)"></div>
|
||||
<div class='required' :data-required='ue.code' :data-active='ue.required?1:0' title='UE obligatoire' @click="gstore.io_handler(pi)"></div>
|
||||
<div class='remove' :data-remove='ue.code' title='Supprimer' @click="gstore.ir_handler(ue.code)"></div>
|
||||
<div class='edit' :data-edit='ue.code' title='Modifier' @click="gstore.ie_toggle(pi)"></div>
|
||||
</div>
|
||||
|
@ -89,35 +61,19 @@
|
|||
<!-- endif -->
|
||||
|
||||
<!-- if VIEW MODE -->
|
||||
<h1 v-show='gstore.edit_i!=pi' :class='ue.required?`pin`:`pin disabled`' :title='ue.required?`obligatoire`:`optionnelle`'><span :data-strike='ue.disabled?1:0'>{{ ue.label }}</span><span :data-visible='1'>({{ ue.code }})</span></h1>
|
||||
<h1 v-show='gstore.edit_i!=pi'>{{ ue.label }}<span :data-visible='1'>({{ ue.code }})</span></h1>
|
||||
<!-- if EDIT MODE -->
|
||||
<h1 v-show='gstore.edit_i==pi' :class='ue.required?`pin`:`pin disabled`'>
|
||||
<h1 v-show='gstore.edit_i==pi' :class="ue.required ? 'warning' : ''">
|
||||
<input type='text' placeholder='Libellé' v-model='gstore.edit_label'>
|
||||
<!-- <span :data-visible='1'>({{ ue.code }})</span> -->
|
||||
<span data-visible='1'>(<input type='text' placeholder='code' v-model='gstore.edit_code'>)</span>
|
||||
</h1>
|
||||
<!-- endif -->
|
||||
|
||||
<div class='table little'>
|
||||
<div>
|
||||
<span class='active reflow' :data-error='ue.nbrCours>ue.nbrProfCours || ue.modCours > 0?1:0'>{{ ue.nbrCours }} CM</span>
|
||||
<span v-show='ue.nbrCours>ue.nbrProfCours' class='notlast user-icon reflow nospace' :data-tooltip='`${ue.nbrCours-ue.nbrProfCours} enseignant(s) manquant(s)`'></span>
|
||||
<span v-show='ue.modCours > 0' class='notlast time-icon reflow nospace' :data-tooltip='`${ue.volumeCours-ue.modCours} à ajouter | ${ue.modCours} à enlever`'></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class='active reflow' :data-error='ue.nbrTD>ue.nbrProfTD || ue.modTD > 0?1:0'>{{ ue.nbrTD }} TD</span>
|
||||
<span v-show='ue.nbrTD>ue.nbrProfTD' class='notlast user-icon reflow nospace' :data-tooltip='`${ue.nbrCours-ue.nbrProfCours} enseignant(s) manquant(s)`'></span>
|
||||
<span v-show='ue.modTD > 0' class='notlast time-icon reflow nospace' :data-tooltip='`${ue.volumeTD-ue.modTD} à ajouter | ${ue.modTD} à enlever`'></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class='active reflow' :data-error='ue.nbrTP>ue.nbrProfTP || ue.modTP > 0?1:0'>{{ ue.nbrTP }} TP</span>
|
||||
<span v-show='ue.nbrTP>ue.nbrProfTP' class='notlast user-icon reflow nospace' :data-tooltip='`${ue.nbrCours-ue.nbrProfCours} enseignant(s) manquant(s)`'></span>
|
||||
<span v-show='ue.modTP > 0' class='notlast time-icon reflow nospace' :data-tooltip='`${ue.volumeTP-ue.modTP} à ajouter | ${ue.modTP} à enlever`'></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if VIEW MODE -->
|
||||
<div v-show='gstore.edit_i!=pi' :class="ue.required ? 'sub pin' : 'sub pin neutral'">{{ ue.required ? 'UE obligatoire' : 'UE optionnelle' }}</div>
|
||||
<div v-show='gstore.edit_i!=pi' class='sub'><strong>{{ ue.volumeCours + ue.volumeTD + ue.volumeTP }}h</strong> totales</div>
|
||||
<div v-show='gstore.edit_i!=pi' class='taglist'>
|
||||
<span v-if='ue.formations.length==0' class='tag invalid'>Aucune formation</span>
|
||||
<span v-for='form_id in ue.formations' :class="!!gstore.form_by_id(form_id).isInternal ? 'tag search' : 'tag'">{{ gstore.form_by_id(form_id).labelForm || '???' }}</span>
|
||||
|
@ -127,6 +83,25 @@
|
|||
<div v-show='gstore.edit_i==pi' :class="gstore.edit_err.length > 0 ? 'sub warning' : 'sub'" :data-valid='gstore.edit_err_valid?1:0'>{{ gstore.edit_err }}</div>
|
||||
<!-- endif -->
|
||||
|
||||
<div class='footer'>
|
||||
<!-- if VIEW MODE -->
|
||||
<span v-show='gstore.edit_i!=pi' :class="(ue.volumeCours == 0) ? 'course' : 'course active'">{{ ue.volumeCours }}h <span>Cours</span></span>
|
||||
<hr v-show='gstore.edit_i!=pi'>
|
||||
<span v-show='gstore.edit_i!=pi' :class="(ue.volumeTD == 0) ? 'td' : 'td active'">{{ ue.volumeTD }}h <span>TD</span></span>
|
||||
<hr v-show='gstore.edit_i!=pi'>
|
||||
<span v-show='gstore.edit_i!=pi' :class="(ue.volumeTP == 0) ? 'tp' : 'tp active'">{{ ue.volumeTP }}h <span>TP</span></span>
|
||||
|
||||
<!-- if EDIT MODE -->
|
||||
<span v-show='gstore.edit_i==pi' class='course'><input type='text' placeholder='???' v-model='gstore.edit_vol.c'><span>Cours</span></span>
|
||||
<hr v-show='gstore.edit_i==pi'>
|
||||
<span v-show='gstore.edit_i==pi' class='td'><input type='text' placeholder='???' v-model='gstore.edit_vol.td'><span>TD</span></span>
|
||||
<hr v-show='gstore.edit_i==pi'>
|
||||
<span v-show='gstore.edit_i==pi' class='tp'><input type='text' placeholder='???' v-model='gstore.edit_vol.tp'><span>TP</span></span>
|
||||
|
||||
<!-- endif -->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- if VIEW MODE -->
|
||||
<div class='footer' v-show='gstore.edit_i!=pi'>
|
||||
|
@ -139,13 +114,6 @@
|
|||
</div>
|
||||
<!-- endif -->
|
||||
|
||||
<div class='info'>
|
||||
<strong class='cm reflow'>{{ ue.volumeCours}}</strong> CM
|
||||
<strong class='td reflow'>{{ ue.volumeTD}}</strong> TD
|
||||
<strong class='tp reflow'>{{ ue.volumeTP }}</strong> TP →
|
||||
<strong>{{ ue.volumeCours + ue.volumeTD + ue.volumeTP }}h</strong>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
@ -163,21 +131,6 @@
|
|||
name: 'CONTAINER_VIEW',
|
||||
data(){
|
||||
return { gstore: gstore.get }
|
||||
},
|
||||
beforeMount(){
|
||||
|
||||
// set onblur to hide filter
|
||||
window.onblur.link('ue.filter', (e) => {
|
||||
|
||||
// ignore [data-unblur-filter] elements
|
||||
if( e.target.getAttribute('data-unblur-filter') !== null )
|
||||
return;
|
||||
|
||||
// else: hide
|
||||
gstore.get.show_fgroup(-1);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ gstore.add('URI', document.URL.replace(/^(?:\/\/|[^\/]+)*/, '').split('/').filte
|
|||
gstore.add('is_local', document.URL.replace(/^https?:\/\/([^\/:]+).*$/, '$1') == 'ptut.com');
|
||||
|
||||
/* (4) API instance */
|
||||
window.api = new APIClient(gstore.get.is_local ? 'http://ptut.com:8080/api/v/1.0/' : `${gstore.get.HOST}/api/v/1.0/`);
|
||||
window.api = new APIClient(gstore.get.is_local ? 'http://ptut.com:8080/api/v/1.0/' : 'https://ptut.xdrm.io/api/v/1.0/');
|
||||
|
||||
/* (5) PopUp instance */
|
||||
window.popup = new PopUp();
|
||||
|
@ -49,6 +49,10 @@ gstore.add('menu_item', {
|
|||
label: 'Gestion UE',
|
||||
url: 'ue',
|
||||
icon: 'ue'
|
||||
}, fiche: {
|
||||
label: 'Fiches',
|
||||
url: 'fiche',
|
||||
icon: 'fiche'
|
||||
}, settings: {
|
||||
label: 'Administration',
|
||||
url: 'settings',
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* (1) Load statistics
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Initialize list */
|
||||
gstore.add('stats', null);
|
||||
gstore.add('stats', []);
|
||||
gstore.add('dimensions', null);
|
||||
|
||||
/* (2) Get statistics */
|
||||
|
@ -46,7 +46,7 @@ api.call('GET department/stats', {}, function(rs) {
|
|||
gstore.get.dimensions = {
|
||||
padding: 5,
|
||||
text: {
|
||||
size: maxLabelLength * 8.5,
|
||||
size: maxLabelLength * 9.5,
|
||||
alignH: 5,
|
||||
alignV: 20,
|
||||
},
|
||||
|
@ -71,8 +71,6 @@ api.call('GET department/stats', {}, function(rs) {
|
|||
width: 500,
|
||||
precision: 4
|
||||
};
|
||||
|
||||
gstore.get.viewBox = `0 0 ${gstore.get.dimensions.axis.width + gstore.get.dimensions.text.size + 50} ${gstore.get.dimensions.axis.height + 30}`;
|
||||
});
|
||||
|
||||
gstore.add('colors', ["blue", "yellow", "green", "red", "purple", "lightblue", "lightred", "lightyellow", "lightgreen", "lightpurple"]);
|
|
@ -281,17 +281,7 @@ gstore.add('create_h', '');
|
|||
gstore.add('create_err_valid', false);
|
||||
gstore.add('create_err', '');
|
||||
|
||||
/* (4) Define reset handler */
|
||||
gstore.add('ic_reset', function(){
|
||||
gstore.add('create_cat', '-');
|
||||
gstore.add('create_name', '');
|
||||
gstore.add('create_cas', '');
|
||||
gstore.add('create_h', '');
|
||||
gstore.add('create_err_valid', false);
|
||||
gstore.add('create_err', '');
|
||||
});
|
||||
|
||||
/* (5) Define create handler */
|
||||
/* (4) Define create handler */
|
||||
gstore.add('ic_handler', function(prof_id){
|
||||
|
||||
/* (4.1) Trim text input */
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
/* (1) Load formations
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Define global filter */
|
||||
gstore.add('filters', {
|
||||
formations: [{ visible: false, active: [] }]
|
||||
});
|
||||
|
||||
/* (2) Initialize list */
|
||||
/* (1) Initialize list */
|
||||
gstore.add('formations', []);
|
||||
|
||||
/* (3) Get Formations */
|
||||
/* (2) Get Formations */
|
||||
api.call('GET formation', {}, function(rs){
|
||||
|
||||
// {1} If error -> abort //
|
||||
|
@ -19,17 +14,9 @@ api.call('GET formation', {}, function(rs){
|
|||
for( var i = 0 ; i < rs.formations.length ; i++ )
|
||||
gstore.get.formations.push( rs.formations[i] );
|
||||
|
||||
// {3} Format formation list for filters
|
||||
for( var i = 0 ; i < rs.formations.length ; i++ )
|
||||
gstore.get.filters.formations.push({
|
||||
code: rs.formations[i].idForm,
|
||||
name: rs.formations[i].labelForm,
|
||||
active: false
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/* (4) Get Formation label */
|
||||
/* (3) Get Formation label */
|
||||
gstore.add('form_by_id', function(form_id){
|
||||
|
||||
/* (1) Abort if wrong form_id */
|
||||
|
@ -50,6 +37,7 @@ gstore.add('form_by_id', function(form_id){
|
|||
|
||||
|
||||
|
||||
|
||||
/* (2) Load ues
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Initialize list */
|
||||
|
@ -71,101 +59,10 @@ api.call('GET ue/', { vh: true }, function(rs){
|
|||
|
||||
|
||||
|
||||
/* (3) Define filters' callback
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Define global callback */
|
||||
gstore.add('filter_handler', function(){
|
||||
|
||||
let filter_ids = [];
|
||||
|
||||
// 1. Get each formation ID
|
||||
for( let form of gstore.get.filters.formations ){
|
||||
|
||||
// 1.1. Ignore if 'code' not found
|
||||
if( form.code === null )
|
||||
continue;
|
||||
|
||||
// 1.2. If active -> add to list
|
||||
( form.code != null && form.active ) && filter_ids.push(form.code);
|
||||
|
||||
}
|
||||
|
||||
// 3. For UE element
|
||||
main_loop: for( let ue of gstore.get.ues ){
|
||||
|
||||
// 3.1. Show by default
|
||||
let element = document.querySelector('section[data-id=\''+ue.code+'\']');
|
||||
|
||||
if( !(element instanceof Element) )
|
||||
continue;
|
||||
|
||||
element.remClass('filter-hidden');
|
||||
|
||||
// 3.2. If no filter -> let all visible
|
||||
if( filter_ids.length <= 0 )
|
||||
continue;
|
||||
|
||||
// 3.3. If at least one matching formatiom id -> let visible
|
||||
for( let fid of filter_ids )
|
||||
if( ue.formations.indexOf(fid) > -1 )
|
||||
continue main_loop;
|
||||
|
||||
// XXXXX. If did not match -> hide
|
||||
element.addClass('filter-hidden');
|
||||
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
/* (3) Get Filters
|
||||
---------------------------------------------------------*/
|
||||
/* (2) Define filter group show/hide */
|
||||
gstore.add('show_fgroup', function(gname){
|
||||
|
||||
var opened = gstore.get.filters[gname] != null && gstore.get.filters[gname][0].visible;
|
||||
|
||||
// {1} hide all by default//
|
||||
for( var f in gstore.get.filters )
|
||||
gstore.get.filters[f][0].visible = false;
|
||||
|
||||
// {2} If wrong @gname -> abort //
|
||||
if( gstore.get.filters[gname] == null )
|
||||
return;
|
||||
|
||||
// {3} Show selected filter //
|
||||
gstore.get.filters[gname][0].visible = !opened;
|
||||
|
||||
});
|
||||
|
||||
/* (3) Define filter item toggle */
|
||||
gstore.add('toggle_filter', function(gname, i){
|
||||
|
||||
// {1} If wrong @gname -> abort //
|
||||
if( gstore.get.filters[gname] == null )
|
||||
return;
|
||||
|
||||
// {2} If wrong @i -> abort //
|
||||
if( gstore.get.filters[gname][i] == null )
|
||||
return;
|
||||
|
||||
// {3} Toggle filter activation //
|
||||
gstore.get.filters[gname][i].active = !gstore.get.filters[gname][i].active;
|
||||
|
||||
// {4} Update active table //
|
||||
gstore.get.filters[gname][0].active.splice(0);
|
||||
|
||||
for( var f = 1 ; f < gstore.get.filters[gname].length ; f++ )
|
||||
if( gstore.get.filters[gname][f].active )
|
||||
gstore.get.filters[gname][0].active.push(f);
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* (4) Manage Instant Search (IS)
|
||||
/* (2) Manage Instant Search (IS)
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Define global timeout index */
|
||||
gstore.add('is_to', null);
|
||||
|
@ -179,7 +76,8 @@ gstore.add('is_buf', null);
|
|||
gstore.add('is_handler', function(e){
|
||||
|
||||
/* (1) Remove last timeout */
|
||||
!isNaN(gstore.get.is_to) && clearTimeout(gstore.get.is_to);
|
||||
if( gstore.get.is_to != null )
|
||||
clearTimeout(gstore.get.is_to);
|
||||
|
||||
/* (2) Store value in buffer */
|
||||
gstore.get.is_buf = e.target.value.trim().toLowerCase();
|
||||
|
@ -188,54 +86,26 @@ gstore.add('is_handler', function(e){
|
|||
gstore.get.is_to = setTimeout(function(){
|
||||
|
||||
// 1. Fetch elements
|
||||
let local_ptr = gstore.get.ues;
|
||||
let l = gstore.get.ues.length;
|
||||
let buf = gstore.get.is_buf.replace(/[.?*+^$[\]\\(\){}|-]/g, "\\$&"); // Escape errorful regex characters
|
||||
var local_ptr = gstore.get.ues;
|
||||
var l = gstore.get.ues.length;
|
||||
|
||||
// 2. For each element
|
||||
main_loop: for( let e = 0 ; e < l ; e++ ){
|
||||
for( var e = 0 ; e < l ; e++ ){
|
||||
|
||||
// 2.1. Set visible by default
|
||||
let element = document.querySelector('section[data-id=\''+local_ptr[e].code+'\']');
|
||||
|
||||
if( !(element instanceof Element) )
|
||||
continue;
|
||||
// 2.1. Show by default
|
||||
var element = document.querySelector('section[data-id=\''+local_ptr[e].code+'\']');
|
||||
if( !element ) continue;
|
||||
|
||||
element.remClass('search-hidden');
|
||||
|
||||
// 2.2. Empty text -> let visible
|
||||
if( buf.length == 0 )
|
||||
continue;
|
||||
// 2.2. Extract name components
|
||||
var code = local_ptr[e].code.trim().toLowerCase();
|
||||
var label = local_ptr[e].label.trim().toLowerCase();
|
||||
|
||||
// 2.3. Extract name components
|
||||
let code = local_ptr[e].code.toLowerCase();
|
||||
let label = local_ptr[e].label.toLowerCase();
|
||||
let forms = local_ptr[e].formations;
|
||||
// 2.3. Hide if does not match
|
||||
var match_offset = gstore.get.is_buf.length == 0 || code.search(gstore.get.is_buf) + label.search(gstore.get.is_buf);
|
||||
|
||||
// 2.4-1. Match code -> let visible
|
||||
if( code.search(buf) >= 0 )
|
||||
continue;
|
||||
|
||||
// 2.4-2. Match label -> let visible
|
||||
if( label.search(buf) >= 0 )
|
||||
continue;
|
||||
|
||||
// 2.4-3. Check for each formation
|
||||
for( let f of forms ){
|
||||
|
||||
let fetched_form = gstore.get.form_by_id(f);
|
||||
|
||||
// if formation not found -> ignore
|
||||
if( fetched_form == null )
|
||||
continue;
|
||||
|
||||
// if formation LABEL matches -> let visible
|
||||
if( fetched_form.labelForm.toLowerCase().search(buf) >= 0 )
|
||||
continue main_loop;
|
||||
|
||||
}
|
||||
|
||||
// XXXX. Hide all that did not match
|
||||
if( match_offset <= -2 )
|
||||
element.addClass('search-hidden');
|
||||
|
||||
}
|
||||
|
@ -263,19 +133,7 @@ gstore.add('create_vol', { c: '', td: '', tp: ''});
|
|||
gstore.add('create_err_valid', false);
|
||||
gstore.add('create_err', '');
|
||||
|
||||
/* (4) Define reset handler */
|
||||
gstore.add('ic_reset', function(){
|
||||
gstore.add('create_form', '-');
|
||||
gstore.add('create_label', '');
|
||||
gstore.add('create_code', '');
|
||||
gstore.add('create_vol', { c: '', td: '', tp: ''});
|
||||
|
||||
gstore.add('create_err_valid', false);
|
||||
gstore.add('create_err', '');
|
||||
});
|
||||
|
||||
|
||||
/* (5) Define create handler */
|
||||
/* (4) Define create handler */
|
||||
gstore.add('ic_handler', function(){
|
||||
|
||||
/* (4.1) Trim text input */
|
||||
|
@ -646,9 +504,9 @@ gstore.add('ie_handler', function(ue_i){
|
|||
|
||||
|
||||
|
||||
/* (8) Manage instant toggle
|
||||
/* (8) Manage instant admin
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Define 'disabled' handler */
|
||||
/* (1) Define admin handler */
|
||||
gstore.add('ia_handler', function(ue_i){
|
||||
|
||||
/* (1) Abort if wrong ue_i */
|
||||
|
@ -674,32 +532,6 @@ gstore.add('ia_handler', function(ue_i){
|
|||
|
||||
});
|
||||
|
||||
/* (1) Define 'required' / 'optional handler */
|
||||
gstore.add('io_handler', function(ue_i){
|
||||
|
||||
/* (1) Abort if wrong ue_i */
|
||||
if( ue_i == null || isNaN(ue_i) || gstore.get.ues[ue_i] == null)
|
||||
return;
|
||||
|
||||
/* (2) Toggle current value */
|
||||
var local = gstore.get.ues[ue_i];
|
||||
var is_required = local.required == '1' || local.required === true;
|
||||
var new_state = !is_required;
|
||||
|
||||
/* (3.1) Update in database */
|
||||
api.call('PUT ue/'+local.code, { required: new_state }, function(rs){
|
||||
|
||||
/* (3.1.1) Abort on error */
|
||||
if( rs.error !== 0 || rs.updated !== true )
|
||||
return console.log('Impossible de changer le status \'requis\' / \'optionnel\', erreur '+rs.error);
|
||||
|
||||
/* (3.1.2) Success */
|
||||
gstore.get.ues[ue_i].required = new_state ? 1 : 0;
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* (9) Manage 'manage' sub-page
|
||||
---------------------------------------------------------*/
|
||||
|
@ -1078,66 +910,6 @@ gstore.add('upd_prof', function(type, res_i){
|
|||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
/* (4) Ordering filters */
|
||||
gstore.add('order', {
|
||||
available: ['prof', 'volume', 'forms'],
|
||||
current: 0,
|
||||
way: 1 // 1 ASC, -1 DESC
|
||||
});
|
||||
|
||||
gstore.add('order_toggle', function(ord_i){
|
||||
|
||||
// 1. Check params types
|
||||
if( isNaN(ord_i) || gstore.get.order.available[ord_i] == null )
|
||||
return;
|
||||
|
||||
// 2. If new ordering field -> toggle it
|
||||
if( ord_i !== gstore.get.order.current )
|
||||
gstore.get.order.current = ord_i;
|
||||
|
||||
// 3. If already selected -> toggle way
|
||||
else
|
||||
gstore.get.order.way *= -1;
|
||||
|
||||
// 4. Get all elements to order
|
||||
let els = document.querySelectorAll('section[data-prof][data-vol][data-form]');
|
||||
|
||||
// 5. Ordering by formations
|
||||
if( gstore.get.order.current === 2 ){
|
||||
return els.forEach((el) => {
|
||||
el.style.order = el.getAttribute('data-form').split('|').length * gstore.get.order.way
|
||||
});
|
||||
}
|
||||
|
||||
// 6. Ordering by 'volume'
|
||||
if( gstore.get.order.current === 1 )
|
||||
return els.forEach((el) => {
|
||||
el.style.order = parseInt( el.getAttribute('data-vol') ) * gstore.get.order.way
|
||||
});
|
||||
|
||||
// 7. Ordering by 'prof'
|
||||
els.forEach((el) => {
|
||||
var profId = parseInt( el.getAttribute('data-prof') );
|
||||
|
||||
// outside by default if no prof set
|
||||
el.style.order = - gstore.get.order.way;
|
||||
|
||||
// professors are already sorted
|
||||
for( pi in gstore.get.manage.prof ) {
|
||||
if( gstore.get.manage.prof[pi].idProfesseur == profId ){
|
||||
el.style.order = pi * gstore.get.order.way;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@ -1274,7 +1046,7 @@ gstore.add('ccreate', function(){
|
|||
|
||||
/* (4) Create request */
|
||||
var rq = {
|
||||
code: gstore.get.router.history.current.path.split('/').pop(),
|
||||
code: gstore.get.URI[2],
|
||||
volume: parseInt(vol)
|
||||
};
|
||||
|
||||
|
@ -1310,7 +1082,7 @@ gstore.add('ccreate', function(){
|
|||
newRes[`id${restyp2}`] = rs.created_id;
|
||||
newRes[`idProf`] = prof;
|
||||
newRes[`volume`] = vol;
|
||||
newRes[`formations`] = rs.formations;
|
||||
newRes[`formations`] = [];
|
||||
newRes[`add_form`] = '-';
|
||||
newRes[`new_prof`] = prof;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ window.cas_callback = function(cas_login){
|
|||
// re-activate button
|
||||
gstore.add('popup_opened', false);
|
||||
|
||||
setTimeout(function(){ gstore.get.login_class = 'neutral'; }, 3000);
|
||||
setTimeout(function(){ gstore.get.login_class = 'neutral'; }, 1500);
|
||||
|
||||
/* (4) If error code -> display error */
|
||||
}else if( !isNaN(cas_login) ){
|
||||
|
@ -71,7 +71,7 @@ window.cas_callback = function(cas_login){
|
|||
// re-activate button
|
||||
gstore.add('popup_opened', false);
|
||||
|
||||
setTimeout(function(){ gstore.get.login_class = 'neutral'; }, 3000);
|
||||
setTimeout(function(){ gstore.get.login_class = 'neutral'; }, 1500);
|
||||
|
||||
/* (4) If login -> reload page */
|
||||
}else{
|
||||
|
@ -81,7 +81,7 @@ window.cas_callback = function(cas_login){
|
|||
|
||||
var redirect_url = `/${gstore.get.URI.join('/')}`;
|
||||
|
||||
setTimeout(function(){ document.location = redirect_url; }, 3000);
|
||||
setTimeout(function(){ document.location = redirect_url; }, 1500);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ $rd-form-valid-color: '20d696';
|
|||
$rd-form-neutral-color: 'b8c0c8';
|
||||
$rd-form-search-color: '1d74e5';
|
||||
$rd-form-invalid-color: 'ea4b35';
|
||||
$rd-form-primary-color: '54627c';
|
||||
|
||||
// Menu
|
||||
$menu-bg: #333;
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
|
||||
$btn-size: 1.8em;
|
||||
$btn-space: 0em;
|
||||
$nb-btn: 4;
|
||||
$nb-btn: 3;
|
||||
$nb-spc: $nb-btn - 1;
|
||||
|
||||
$cont-w: $btn-size * $nb-btn + $nb-spc * $btn-space;
|
||||
|
@ -138,14 +138,12 @@
|
|||
& > div.remove[data-remove],
|
||||
& > div.edit[data-edit],
|
||||
& > div.enabled[data-enabled],
|
||||
& > div.required[data-required],
|
||||
& > div.admin[data-admin]{
|
||||
background-color: darken(#fff, 12%);
|
||||
|
||||
/* (2.1.2) displace all but 1st element */
|
||||
&.edit[data-edit]{ left: calc( 100% - #{$btn-size * 2 + $btn-space} ); }
|
||||
&.remove[data-remove]{ left: calc( 100% - #{$btn-size * 3 + $btn-space * 2} ); }
|
||||
&.required[data-required]{ left: calc( 100% - #{$btn-size * 4 + $btn-space * 3} ); }
|
||||
|
||||
}
|
||||
|
||||
|
@ -155,7 +153,6 @@
|
|||
& > div.remove[data-remove],
|
||||
& > div.edit[data-edit],
|
||||
& > div.enabled[data-enabled],
|
||||
& > div.required[data-required],
|
||||
& > div.admin[data-admin]{
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
|
@ -209,16 +206,6 @@
|
|||
&[data-active='1']:hover{ background-image: url('/asset/svg/bell.svg@f4a118'); }
|
||||
}
|
||||
|
||||
/* (2.4) REQUIRED switch */
|
||||
&.required[data-required]{
|
||||
background-image: url('/asset/svg/pin-disabled.svg@aaaaaa');
|
||||
z-index: 104;
|
||||
|
||||
&:hover{ background-image: url('/asset/svg/pin-disabled.svg@555555'); }
|
||||
&[data-active='1']{ background-image: url('/asset/svg/pin.svg@f4bd18'); }
|
||||
&[data-active='1']:hover{ background-image: url('/asset/svg/pin.svg@f4a118'); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -284,8 +271,6 @@
|
|||
color: darken($primary-color, 5%);
|
||||
font-size: 1em;
|
||||
|
||||
margin: .4em 0;
|
||||
|
||||
// flex
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
|
@ -374,16 +359,9 @@
|
|||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
&.little{
|
||||
font-size: .7em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* (6.1) Column */
|
||||
& > div{
|
||||
|
||||
flex: 1;
|
||||
|
||||
display: flex;
|
||||
position: relative;
|
||||
height: 2.3em;
|
||||
|
@ -398,7 +376,7 @@
|
|||
|
||||
// flex properties
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
|
@ -430,7 +408,7 @@
|
|||
}
|
||||
|
||||
/* (6.2) Column Emphasis */
|
||||
& > span:last-child:not(.notlast){
|
||||
& > span:last-child{
|
||||
display: block;
|
||||
position: relative;
|
||||
min-width: 4em;
|
||||
|
@ -603,26 +581,7 @@
|
|||
|
||||
}
|
||||
|
||||
/* (9) Infobar */
|
||||
& > div.info{
|
||||
|
||||
display: block;
|
||||
position: relative;
|
||||
margin-top: 2.1em;
|
||||
margin-left: -2.1em;
|
||||
height: auto;
|
||||
width: calc( 100% + 2*2.1em - 2*1em);
|
||||
|
||||
margin-bottom: -2.1em;
|
||||
padding: .3em 1em;
|
||||
|
||||
border-top: 1px solid #f3f3f3;
|
||||
|
||||
background-color: darken(#fafbfd,1%);
|
||||
|
||||
font-size: .7em;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
/* (1) List element */
|
||||
& > section{
|
||||
|
||||
order: -100000;
|
||||
|
||||
flex: 1 1 90%;
|
||||
|
||||
display: flex;
|
||||
|
@ -45,15 +43,11 @@
|
|||
|
||||
/* (1.1) Element item */
|
||||
& > div:not(.icon),
|
||||
& > select,
|
||||
& > input{
|
||||
flex: 0 1 30%;
|
||||
flex: 1 1 0;
|
||||
|
||||
// fix
|
||||
&.taglist{
|
||||
margin: 0;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
&.taglist{ margin: 0; }
|
||||
}
|
||||
|
||||
/* (1.2) Hover animation */
|
||||
|
@ -66,16 +60,16 @@
|
|||
&.create:hover{ border-left-color: $form-valid-color; }
|
||||
|
||||
&:hover,
|
||||
&.bcours:hover{ border-left-color: $form-search-color; }
|
||||
&.btd:hover{ border-left-color: $form-valid-color; }
|
||||
&.btp:hover{ border-left-color: $form-invalid-color; }
|
||||
&.cours:hover{ border-left-color: $form-search-color; }
|
||||
&.td:hover{ border-left-color: $form-valid-color; }
|
||||
&.tp:hover{ border-left-color: $form-invalid-color; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (1.3) Select elements*/
|
||||
& > select{
|
||||
display: block;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: 1.8em;
|
||||
|
||||
|
@ -99,7 +93,7 @@
|
|||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
// flex: 0 1 15em;
|
||||
flex: 0 1 20em;
|
||||
|
||||
&.min{ flex: 0 1 5em; }
|
||||
|
||||
|
@ -138,15 +132,13 @@
|
|||
background-image: url('/asset/svg/cross.svg@aaaaaa');
|
||||
&:hover{ background-image: url('/asset/svg/cross.svg@#{$rd-form-invalid-color}'); }
|
||||
}
|
||||
|
||||
&.hidden{ background: transparent; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* (2) Filter */
|
||||
& > section.filter{
|
||||
|
||||
// padding-bottom: 0;
|
||||
|
||||
background-color: transparent;
|
||||
|
||||
|
@ -157,37 +149,24 @@
|
|||
font-weight: bold;
|
||||
text-shadow: 1px 1px 2px #fff;
|
||||
|
||||
& > div{
|
||||
|
||||
cursor: default;
|
||||
|
||||
& > span.arrow{
|
||||
& > div:after{
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
position: absolute;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
|
||||
margin-bottom: -.3em;
|
||||
margin-top: -.25em;
|
||||
margin-left: .5em;
|
||||
|
||||
background: url() center center no-repeat;
|
||||
background: url('/asset/svg/down_arrow.svg@aaaaaa') center center no-repeat;
|
||||
background-size: auto 100%;
|
||||
|
||||
cursor: pointer;
|
||||
&[data-filter='up']{ background-image: url('/asset/svg/up_arrow.svg@aaaaaa'); }
|
||||
}
|
||||
|
||||
// selected filter
|
||||
&[data-filter='1']{
|
||||
color: $primary-color;
|
||||
|
||||
& > span.arrow{
|
||||
|
||||
&[data-way='-1']{ background-image: url('/asset/svg/up_arrow.svg@555555'); }
|
||||
&[data-way='1']{ background-image: url('/asset/svg/down_arrow.svg@555555'); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
& > div.null:after{ content: none; }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ $svg-lightpurple: #994499;
|
|||
|
||||
svg {
|
||||
|
||||
width: 100%;
|
||||
height: 30vh;
|
||||
width: 50em;
|
||||
height: 20em;
|
||||
margin: 10px;
|
||||
-webkit-touch-callout: none; /* iOS Safari */
|
||||
-webkit-user-select: none; /* Safari */
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
@import 'global/tag';
|
||||
|
||||
|
||||
.error, [data-error='1']{ font-weight: bold; color: $form-invalid-color; }
|
||||
.success, [data-success='1']{ color: $form-valid-color; }
|
||||
|
||||
|
||||
|
||||
|
@ -57,97 +55,3 @@ a{
|
|||
font-family: 'Mono';
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
|
||||
/* (8) Striked text */
|
||||
[data-strike='1'],
|
||||
.strike{
|
||||
text-decoration: line-through;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
/* (9) Icons (1em wide) */
|
||||
.user-icon, .time-icon{
|
||||
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
||||
background: url('/asset/svg/teacher.svg@#{$rd-form-neutral-color}') center center no-repeat;
|
||||
background-size: contain;
|
||||
|
||||
&.time-icon{
|
||||
background-image: url('/asset/svg/time.svg@#{$rd-form-neutral-color}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* (10) Toggling tooltip on hover */
|
||||
[data-tooltip]{
|
||||
|
||||
position: relative;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&:before{
|
||||
content: attr(data-tooltip);
|
||||
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc( 100% + 1em );
|
||||
left: 50%;
|
||||
|
||||
margin-left: -.1em;
|
||||
|
||||
padding: .4em .6em;
|
||||
|
||||
border-radius: 3px / 3px;
|
||||
|
||||
box-shadow: 0 0 .5em 0 #fff;
|
||||
|
||||
font-size: .7em;
|
||||
color: #ddd;
|
||||
letter-spacing: 0;
|
||||
|
||||
background-color: #444;
|
||||
|
||||
transform: translateX(-50%) translateY(-50%) scale(0);
|
||||
|
||||
transition: transform .1s ease-in-out;
|
||||
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
&:hover:not([data-tooltip='']):before{
|
||||
transform: translateX(-50%) translateY(0) scale(1);
|
||||
}
|
||||
|
||||
|
||||
&:after{
|
||||
content: '';
|
||||
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc( 100% + .6em );
|
||||
left: 50%;
|
||||
width: .4em;
|
||||
height: .4em;
|
||||
|
||||
background-color: #444;
|
||||
|
||||
transform: translateX(-50%) rotate(45deg) scale(0);
|
||||
|
||||
transition: transform .1s ease-in-out;
|
||||
|
||||
z-index: 1000;
|
||||
|
||||
}
|
||||
|
||||
&:hover:not([data-tooltip='']):after{
|
||||
transform: translateX(-50%) rotate(45deg) scale(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -4,13 +4,7 @@
|
|||
|
||||
/* (1) Warning icon */
|
||||
.warning,
|
||||
.user,
|
||||
.time,
|
||||
.pin,
|
||||
.cm,
|
||||
.back,
|
||||
.td,
|
||||
.tp{
|
||||
.pin{
|
||||
|
||||
// add icon before
|
||||
&:before{
|
||||
|
@ -27,30 +21,6 @@
|
|||
background-size: auto 90%;
|
||||
}
|
||||
|
||||
&.nospace:before{
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.reflow{
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
&:before{
|
||||
font-size: 1.2em;
|
||||
background-position: center bottom;
|
||||
background-size: auto 70%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.big{
|
||||
|
||||
&:before{
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// icon color variants
|
||||
&.neutral:before{ background-image: url('/asset/svg/warning.svg@#{$rd-form-neutral-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/warning.svg@#{$rd-form-valid-color}'); }
|
||||
|
@ -70,140 +40,12 @@
|
|||
|
||||
// add icon before
|
||||
&:before{
|
||||
background-image: url('/asset/svg/pin.svg@f4bd18');
|
||||
background-image: url('/asset/svg/pin.svg@#{$rd-form-invalid-color}');
|
||||
}
|
||||
|
||||
// icon color variants
|
||||
&.disabled:before{ background-image: url('/asset/svg/pin-disabled.svg@#{$rd-form-neutral-color}'); }
|
||||
&.neutral:before{ background-image: url('/asset/svg/pin.svg@#{$rd-form-neutral-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/pin.svg@#{$rd-form-valid-color}'); }
|
||||
&.search:before{ background-image: url('/asset/svg/pin.svg@#{$rd-form-search-color}'); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (3) CM */
|
||||
.cm{
|
||||
|
||||
// add icon before
|
||||
&:before{
|
||||
background-image: url('/asset/svg/course.svg@#{$menu-item-inactive}');
|
||||
}
|
||||
|
||||
&.active:before{ background-image: url('/asset/svg/course.svg@5bb8f0'); }
|
||||
|
||||
// icon color variants
|
||||
&.neutral:before{ background-image: url('/asset/svg/course.svg@#{$rd-form-neutral-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/course.svg@#{$rd-form-valid-color}'); }
|
||||
&.search:before{ background-image: url('/asset/svg/course.svg@#{$rd-form-search-color}'); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (4) TD */
|
||||
.td{
|
||||
|
||||
// add icon before
|
||||
&:before{
|
||||
background-image: url('/asset/svg/td.svg@#{$menu-item-inactive}');
|
||||
}
|
||||
|
||||
&.active:before{ background-image: url('/asset/svg/td.svg@20b565'); }
|
||||
|
||||
// icon color variants
|
||||
&.neutral:before{ background-image: url('/asset/svg/td.svg@#{$rd-form-neutral-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/td.svg@#{$rd-form-valid-color}'); }
|
||||
&.search:before{ background-image: url('/asset/svg/td.svg@#{$rd-form-search-color}'); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (5) TP */
|
||||
.tp{
|
||||
|
||||
// add icon before
|
||||
&:before{
|
||||
background-image: url('/asset/svg/tp.svg@#{$menu-item-inactive}');
|
||||
}
|
||||
|
||||
&.active:before{ background-image: url('/asset/svg/tp.svg@e85456'); }
|
||||
|
||||
// icon color variants
|
||||
&.neutral:before{ background-image: url('/asset/svg/tp.svg@#{$rd-form-neutral-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/tp.svg@#{$rd-form-valid-color}'); }
|
||||
&.search:before{ background-image: url('/asset/svg/tp.svg@#{$rd-form-search-color}'); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (6) USER */
|
||||
.user{
|
||||
|
||||
// add icon before
|
||||
&:before{
|
||||
background-image: url('/asset/svg/teacher.svg@#{$menu-item-inactive}');
|
||||
}
|
||||
|
||||
|
||||
// icon color variants
|
||||
&.neutral:before{ background-image: url('/asset/svg/teacher.svg@#{$rd-form-neutral-color}'); }
|
||||
&.invalid:before{ background-image: url('/asset/svg/teacher.svg@#{$rd-form-invalid-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/teacher.svg@#{$rd-form-valid-color}'); }
|
||||
&.search:before{ background-image: url('/asset/svg/teacher.svg@#{$rd-form-search-color}'); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (7) TIME */
|
||||
.time{
|
||||
|
||||
// add icon before
|
||||
&:before{
|
||||
background-image: url('/asset/svg/time.svg@#{$menu-item-inactive}');
|
||||
}
|
||||
|
||||
|
||||
// icon color variants
|
||||
&.neutral:before{ background-image: url('/asset/svg/time.svg@#{$rd-form-neutral-color}'); }
|
||||
&.invalid:before{ background-image: url('/asset/svg/time.svg@#{$rd-form-invalid-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/time.svg@#{$rd-form-valid-color}'); }
|
||||
&.search:before{ background-image: url('/asset/svg/time.svg@#{$rd-form-search-color}'); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* (8) BACK */
|
||||
.back{
|
||||
|
||||
// add icon before
|
||||
&:before{
|
||||
background-image: url('/asset/svg/back.svg@#{$menu-item-inactive}');
|
||||
}
|
||||
|
||||
// icon color variants
|
||||
&.neutral:before{ background-image: url('/asset/svg/back.svg@#{$rd-form-neutral-color}'); }
|
||||
&.invalid:before{ background-image: url('/asset/svg/back.svg@#{$rd-form-invalid-color}'); }
|
||||
&.valid:before{ background-image: url('/asset/svg/back.svg@#{$rd-form-valid-color}'); }
|
||||
&.search:before{ background-image: url('/asset/svg/back.svg@#{$rd-form-search-color}'); }
|
||||
|
||||
// hover
|
||||
&:hover:before{ background-image: url('/asset/svg/back.svg@ffffff'); }
|
||||
|
||||
}
|
|
@ -22,12 +22,11 @@
|
|||
z-index: 150;
|
||||
|
||||
|
||||
/* (1) left-side managers */
|
||||
/* (1) Version management */
|
||||
& > div.departments,
|
||||
& > div.versions,
|
||||
& > div.global-export{
|
||||
& > div.versions{
|
||||
|
||||
/* (1.1) Current status */
|
||||
/* (1.1) Version status */
|
||||
& > div.current{
|
||||
display: block;
|
||||
position: relative;
|
||||
|
@ -35,7 +34,8 @@
|
|||
margin-left: 1em;
|
||||
|
||||
padding: .5em 1em;
|
||||
padding-left: .7em;
|
||||
|
||||
padding-left: 2em;
|
||||
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
|
@ -48,79 +48,26 @@
|
|||
// hover animation
|
||||
&:hover{ box-shadow: 0 2px 2px darken(#fff,10%); }
|
||||
|
||||
// current: EXPORT / CREATE / EDIT / REMOVE icons
|
||||
span.export,
|
||||
span.create,
|
||||
span.edit,
|
||||
span.remove{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: .2em;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
// color state
|
||||
&:before{
|
||||
content: '';
|
||||
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc( 50% - .7em/2 );
|
||||
left: calc( 1em/2 + .7em/2 );
|
||||
width: .7em;
|
||||
height: .7em;
|
||||
|
||||
background: center center no-repeat;
|
||||
background-size: 80% auto;
|
||||
border-radius: 50%;
|
||||
|
||||
&.export{
|
||||
background-image: url('/asset/svg/fiche.svg@b8c0c8');
|
||||
background-size: 100% auto;
|
||||
&:hover{
|
||||
background-image: url('/asset/svg/fiche.svg@#{$rd-form-invalid-color}');
|
||||
}
|
||||
background-color: $form-invalid-color;
|
||||
}
|
||||
|
||||
&.create{
|
||||
background-image: url('/asset/svg/plus.svg@b8c0c8');
|
||||
&:hover{
|
||||
background-image: url('/asset/svg/plus.svg@#{$rd-form-valid-color}');
|
||||
}
|
||||
&[data-id='-1']:before{
|
||||
background-color: $form-valid-color;
|
||||
}
|
||||
|
||||
&.edit{
|
||||
background-image: url('/asset/svg/a.svg@b8c0c8');
|
||||
&:hover{
|
||||
background-image: url('/asset/svg/a.svg@#{$rd-form-search-color}');
|
||||
}
|
||||
}
|
||||
|
||||
&.remove{
|
||||
background-image: url('/asset/svg/cross.svg@b8c0c8');
|
||||
&:hover{
|
||||
background-image: url('/asset/svg/cross.svg@#{$rd-form-invalid-color}');
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child{
|
||||
margin-right: .5em;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover > span.export{
|
||||
background-image: url('/asset/svg/fiche.svg@#{$rd-form-invalid-color}');
|
||||
}
|
||||
overflow: hidden;
|
||||
|
||||
// editable input
|
||||
& > input[type='text']{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 10em;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
|
||||
// background-color: #f00;
|
||||
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -140,8 +87,6 @@
|
|||
border-top: 0;
|
||||
border-radius: 0 0 3px 3px;
|
||||
|
||||
&>:first-child{ border-top: 1px solid #ddd; }
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
// box-shadow: 0 2px 2px #ddd;
|
||||
|
@ -166,29 +111,24 @@
|
|||
// hover animation
|
||||
&:hover{ background-color: darken(#fff, 5%); }
|
||||
|
||||
// switch+create icons
|
||||
// color state
|
||||
&:before{
|
||||
content: '';
|
||||
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: calc( 50% - 1em/2 );
|
||||
left: calc( .5em/2 + 1em/2 );
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
top: calc( 50% - .7em/2 );
|
||||
left: calc( 1em/2 + .7em/2 );
|
||||
width: .7em;
|
||||
height: .7em;
|
||||
|
||||
background: url('/asset/svg/switch.svg@#{$rd-form-primary-color}') center center no-repeat;
|
||||
background-size: auto 80%;
|
||||
}
|
||||
|
||||
// create icon specifications
|
||||
&[data-id='-1']{
|
||||
|
||||
&:before{
|
||||
background-image: url('/asset/svg/plus.svg@#{$rd-form-valid-color}');
|
||||
background-size: auto 60%;
|
||||
border-radius: 50%;
|
||||
|
||||
background-color: $form-invalid-color;
|
||||
}
|
||||
|
||||
&[data-id='-1']:before{
|
||||
background-color: $form-valid-color;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -196,20 +136,16 @@
|
|||
|
||||
}
|
||||
|
||||
/* (2) Department | Version | Export layout */
|
||||
/* (2) Department | Version layout */
|
||||
& > div.departments > div.current{
|
||||
margin-right: 0;
|
||||
padding-left: 1em;
|
||||
border-radius: 3px 0 0 3px;
|
||||
|
||||
&:before{ content: none; }
|
||||
}
|
||||
|
||||
& > div.versions > div.current{
|
||||
margin-left: 0;
|
||||
border-radius: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
& > div.global-export > div.current{
|
||||
margin-left: 0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
border-left: 0;
|
||||
|
|
|
@ -281,13 +281,5 @@ body.body404{
|
|||
|
||||
}
|
||||
|
||||
.downloadButton{
|
||||
text-decoration: none;
|
||||
color: #3f4a5e;
|
||||
box-shadow: 0px 0px 1px 1px #7f8d9b;
|
||||
background: whitesmoke;
|
||||
padding: 10px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,15 +5,9 @@
|
|||
<!-- Department management -->
|
||||
<div class='departments' data-unblur-department>
|
||||
|
||||
<div class='current' data-unblur-department>
|
||||
<span class='create' @click='!department.create?(department.newLabel="")+(department.create=true):d_create()'></span>
|
||||
<span class='remove' @click='d_remove()'></span>
|
||||
<input v-if='department.create' type='text' placeholder='Nouveau nom' v-model='department.newLabel' size=''>
|
||||
<span v-if='!department.create' @click='department.dialog=!department.dialog' data-unblur-department>{{ get_dcurrent().label }}</span>
|
||||
</div>
|
||||
|
||||
<div class='department-dialog' v-show='department.dialog' data-unblur-department>
|
||||
<span v-for='d in department.list' v-show='d.id!=department.current' @click='d_switch(d.id)' data-unblur-department>{{ d.label }}</span>
|
||||
<div class='current' @click='d_dialog=!d_dialog' data-unblur-department>{{ get_dcurrent().label || 'département à jour' }}</div>
|
||||
<div class='department-dialog' v-show='d_dialog' data-unblur-department>
|
||||
<span v-for='d in dpts' v-show='d.id!=dep_id' @click='d_switch(d.id)' data-unblur-department>{{ d.label }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -21,27 +15,14 @@
|
|||
<!-- Version management -->
|
||||
<div class='versions' data-unblur-version>
|
||||
|
||||
<div class='current' :data-id='get_vcurrent().id' data-unblur-version>
|
||||
<span class='remove' @click='v_remove()'></span>
|
||||
<span class='edit' @click='!version.edit?(version.newName="")+(version.edit=true):v_edit()'></span>
|
||||
<input v-if='version.edit' type='text' :placeholder='get_vcurrent().name' v-model='version.newName' size=''>
|
||||
<span v-if='!version.edit' @click='version.dialog=!version.dialog' data-unblur-version>{{ get_vcurrent().name }}</span>
|
||||
</div>
|
||||
|
||||
<div class='version-dialog' v-show='version.dialog' data-unblur-version>
|
||||
<span v-for='v in version.list' @click='v_switch(v.id)' v-show='v.id!=version.current' :data-id='v.id' data-unblur-version> {{ v.name }} </span>
|
||||
<span @click='v_create()' data-unblur-version data-id='-1'>Créer</span>
|
||||
<div class='current' @click='v_dialog=!v_dialog' :data-id='get_vcurrent().id' data-unblur-version>{{ get_vcurrent().date || 'version à jour' }}</div>
|
||||
<div class='version-dialog' v-show='v_dialog' data-unblur-version>
|
||||
<span v-for='v in vers' v-show='v.id!=ver_id' @click='v_switch(v.id)' :data-id='v.id' data-unblur-version>{{ v.date || 'version à jour' }}</span>
|
||||
<span @click='v_create()' data-unblur-version data-id='-1'>Nouvelle version</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Export all -->
|
||||
<div class='global-export'>
|
||||
<div class='current export' @click='global_export()'>
|
||||
<span class='export'></span>
|
||||
exporter
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class='header-title'>{{ gstore.header_title }}</div> -->
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -56,21 +37,17 @@ export default {
|
|||
gstore: gstore.get,
|
||||
is_connected: _SERVER.session.connected,
|
||||
|
||||
department: {
|
||||
dialog: false,
|
||||
current: _SERVER.session.department_id,
|
||||
list: _SERVER.session.departments,
|
||||
create: false,
|
||||
newLabel: ''
|
||||
},
|
||||
d_dialog: false,
|
||||
dep_id: _SERVER.session.department_id,
|
||||
dpts: _SERVER.session.departments,
|
||||
|
||||
version: {
|
||||
dialog: false,
|
||||
current: -1,
|
||||
list: [],
|
||||
edit: false,
|
||||
newName: ''
|
||||
}
|
||||
v_dialog: false,
|
||||
ver_id: -1,
|
||||
vers: [
|
||||
{ id: -1, date: null },
|
||||
{ id: 0, date: '01-02-2017' },
|
||||
{ id: 1, date: '23-03-2017' }
|
||||
]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -79,31 +56,31 @@ export default {
|
|||
---------------------------------------------------------*/
|
||||
get_dcurrent(id){
|
||||
|
||||
// use @current, if invalid argument @id
|
||||
( isNaN(id) ) && ( id = this.department.current );
|
||||
// use @dep_id, if invalid argument @id
|
||||
( isNaN(id) ) && ( id = this.dep_id );
|
||||
|
||||
// search in @list where id is @current
|
||||
for( var d in this.department.list )
|
||||
if( this.department.list[d].id == id )
|
||||
return this.department.list[d];
|
||||
// search in @dpts where id is @dep_id
|
||||
for( var d in this.dpts )
|
||||
if( this.dpts[d].id == id )
|
||||
return this.dpts[d];
|
||||
|
||||
return { id: -2, name: null };
|
||||
return { id: null, label: null };
|
||||
|
||||
},
|
||||
|
||||
/* (2) Get current version data
|
||||
/* (2) Get current versoin data
|
||||
---------------------------------------------------------*/
|
||||
get_vcurrent(id){
|
||||
|
||||
// use @version.current, if invalid argument @id
|
||||
( isNaN(id) ) && ( id = this.version.current );
|
||||
// use @dep_id, if invalid argument @id
|
||||
( isNaN(id) ) && ( id = this.ver_id );
|
||||
|
||||
// search in @ist where id is @id
|
||||
for( var v in this.version.list )
|
||||
if( this.version.list[v].id == id )
|
||||
return this.version.list[v];
|
||||
// search in @vers where id is @ver_id
|
||||
for( var v in this.vers )
|
||||
if( this.vers[v].id == id )
|
||||
return this.vers[v];
|
||||
|
||||
return { id: -2, name: '-' };
|
||||
return { date: null };
|
||||
|
||||
},
|
||||
|
||||
|
@ -112,11 +89,11 @@ export default {
|
|||
d_switch(id){
|
||||
|
||||
// 1. De-activate dialogs
|
||||
this.department.dialog = false;
|
||||
this.version.dialog = false;
|
||||
this.d_dialog = false;
|
||||
this.v_dialog = false;
|
||||
|
||||
// 2. Do nothing if no change
|
||||
if( this.department.current == id )
|
||||
if( this.dep_id == id )
|
||||
return;
|
||||
|
||||
// 3. Ask for department change
|
||||
|
@ -127,7 +104,7 @@ export default {
|
|||
return;
|
||||
|
||||
// 2. Update GUI
|
||||
this.department.current = id;
|
||||
this.dep_id = id;
|
||||
|
||||
// 3. Reload page if needed
|
||||
setTimeout(() => { document.location = ''; }, 200);
|
||||
|
@ -141,22 +118,28 @@ export default {
|
|||
v_switch(id){
|
||||
|
||||
// 1. De-activate dialogs
|
||||
this.department.dialog = false;
|
||||
this.version.dialog = false;
|
||||
this.d_dialog = false;
|
||||
this.v_dialog = false;
|
||||
|
||||
// 2. Do nothing if no change
|
||||
if( this.version.current == id )
|
||||
if( this.ver_id == id )
|
||||
return;
|
||||
|
||||
// 3. Ask for department change
|
||||
api.call(`GET department/version/switch/${id}`, {}, function(rs){
|
||||
// 3. Get version date
|
||||
var verdate = this.get_vcurrent(id).date;
|
||||
|
||||
// 4. If null date -> go to current version
|
||||
( verdate === null ) && ( verdate = '' );
|
||||
|
||||
// 5. Ask for department change
|
||||
api.call(`PUT department/version/0/${verdate}`, {}, function(rs){
|
||||
|
||||
// 1. error -> do nothing
|
||||
if( rs.error !== 0 )
|
||||
if( rs.error !== 0 || rs.updated !== true )
|
||||
return;
|
||||
|
||||
// 2. Update GUI
|
||||
this.version.current = id;
|
||||
this.ver_id = id;
|
||||
|
||||
// 3. Reload page if needed
|
||||
setTimeout(() => { document.location = ''; }, 200);
|
||||
|
@ -165,67 +148,13 @@ export default {
|
|||
|
||||
},
|
||||
|
||||
/* (5) Create a new empty department
|
||||
---------------------------------------------------------*/
|
||||
d_create(){
|
||||
|
||||
// 1. De-activate dialogs
|
||||
this.department.dialog = false;
|
||||
this.version.dialog = false;
|
||||
|
||||
// get current department
|
||||
var cur = this.get_dcurrent();
|
||||
if( cur.id < 0 || this.department.newLabel.length < 1 ){
|
||||
this.department.create = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var newlabel = this.department.newLabel;
|
||||
|
||||
// 2. Popup confirm
|
||||
(new Promise( (resolve, reject) => {
|
||||
|
||||
popup.ask({
|
||||
title: 'Confirmation de création de département',
|
||||
content: `Le nouveau département <b>${newlabel}</b> va être créé; il ne contiendra aucune donnée, il permet de gérer plusieurs départements ne partageant pas les mêmes UEs, enseignants, formations, etc<br><br>Voulez-vous créer un nouveau département vide ?`,
|
||||
action: 'Créer',
|
||||
type: 'valid'
|
||||
}, (popup_rs) => { popup_rs && resolve() });
|
||||
|
||||
// 3. On popup confirm
|
||||
})).then( () => {
|
||||
|
||||
// Call API to create a new department
|
||||
api.call(`POST department/`, {name:newlabel}, function(rs){
|
||||
|
||||
// 1. error -> popup
|
||||
if( rs.error !== 0 || !rs.hasOwnProperty('created_id') ){
|
||||
|
||||
return popup.ask({
|
||||
title: 'Erreur ('+rs.error+')',
|
||||
content: 'La création de département a échoué.',
|
||||
action: 'OK',
|
||||
type: 'neutral'
|
||||
}, () => {});
|
||||
|
||||
}
|
||||
|
||||
// 3. Update GUI
|
||||
this.department.list.push( { id: parseInt(rs.created_id), name: newlabel } );
|
||||
|
||||
}.bind(this));
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/* (5) Create a new version from now
|
||||
---------------------------------------------------------*/
|
||||
v_create(){
|
||||
|
||||
// 1. De-activate dialogs
|
||||
this.department.dialog = false;
|
||||
this.version.dialog = false;
|
||||
this.d_dialog = false;
|
||||
this.v_dialog = false;
|
||||
|
||||
// 2. Popup confirm
|
||||
(new Promise( (resolve, reject) => {
|
||||
|
@ -240,224 +169,34 @@ export default {
|
|||
// 3. On popup confirm
|
||||
})).then( () => {
|
||||
|
||||
let newVersionName = `${this.get_vcurrent().name}*`;
|
||||
// Call API to create a new version
|
||||
api.call(`POST department/version/`, {label:newVersionName}, function(rs){
|
||||
api.call(`POST department/version/`, {}, function(rs){
|
||||
|
||||
// 1. error -> popup
|
||||
if( rs.error !== 0 || !rs.hasOwnProperty('created_id') ){
|
||||
|
||||
return popup.ask({
|
||||
title: 'Erreur ('+rs.error+')',
|
||||
content: 'La création de version à échoué.',
|
||||
title: 'Error ('+err_code+')',
|
||||
content: 'La création de sauvegarde à échoué.',
|
||||
action: 'OK',
|
||||
type: 'neutral'
|
||||
}, () => {});
|
||||
|
||||
}
|
||||
|
||||
// 2. Get last version id
|
||||
var last_id = this.vers[ this.vers.length-1 ].id;
|
||||
|
||||
// 3. Update GUI
|
||||
this.version.list.push( { id: parseInt(rs.created_id), name: newVersionName } );
|
||||
this.vers.push( { id: last_id+1, date: rs.created_id } );
|
||||
|
||||
}.bind(this));
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/* (6) Rename a version
|
||||
---------------------------------------------------------*/
|
||||
v_edit(){
|
||||
|
||||
// get current version
|
||||
var cur = this.get_vcurrent();
|
||||
if( cur.id < 0 || this.version.newName.length < 1 ){
|
||||
this.version.edit = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var newname = this.version.newName;
|
||||
|
||||
// 2. Popup confirm
|
||||
(new Promise( (resolve, reject) => {
|
||||
|
||||
popup.ask({
|
||||
title: 'Confirmation de modification de version',
|
||||
content: `La version <b>${cur.name}</b> va être renommée en <b>${newname}</b><br><br>Voulez-vous valider cette modification ?`,
|
||||
action: 'Valider',
|
||||
type: 'search'
|
||||
}, (popup_rs) => { popup_rs && resolve() });
|
||||
|
||||
// 3. On popup confirm
|
||||
})).then( () => {
|
||||
|
||||
// Call API to create a new version
|
||||
api.call(`PUT department/version/${cur.id}`, {label:newname}, function(rs){
|
||||
|
||||
// 1. error -> popup
|
||||
if( rs.error !== 0 || !rs.hasOwnProperty('updated') ){
|
||||
|
||||
return popup.ask({
|
||||
title: 'Erreur ('+rs.error+')',
|
||||
content: 'La modification a échoué.',
|
||||
action: 'OK',
|
||||
type: 'neutral'
|
||||
}, () => {});
|
||||
|
||||
}
|
||||
|
||||
// 3. Update GUI
|
||||
cur.name = newname;
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}).finally( () => {
|
||||
this.version.edit = false;
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
/* (7) Remove a department
|
||||
---------------------------------------------------------*/
|
||||
d_remove(){
|
||||
|
||||
// get current department
|
||||
var cur = this.get_dcurrent();
|
||||
if( cur.id < 0 )
|
||||
return;
|
||||
|
||||
// if last department -> forbid
|
||||
if( this.department.list.length < 2 ){
|
||||
return popup.ask({
|
||||
title: 'Dernier départment',
|
||||
content: `Le département <b>${cur.label}</b> ne peut être supprimé car il est le dernier disponible`,
|
||||
action: 'OK',
|
||||
type: 'invalid'
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Popup confirm
|
||||
(new Promise( (resolve, reject) => {
|
||||
|
||||
popup.ask({
|
||||
title: 'Confirmation de suppression',
|
||||
content: `Le département <b>${cur.label}</b> va être supprimé. Toutes les données seront perdues de manière définitive</b><br><br>Voulez-vous supprimer ce département ?`,
|
||||
action: 'Supprimer',
|
||||
type: 'invalid'
|
||||
}, (popup_rs) => { popup_rs && resolve() });
|
||||
|
||||
// 3. On popup confirm
|
||||
})).then( () => {
|
||||
|
||||
// Call API to delete the current department
|
||||
api.call(`DELETE department/${cur.id}`, {}, function(rs){
|
||||
|
||||
// 1. error -> popup
|
||||
if( rs.error !== 0 || !rs.hasOwnProperty('deleted') ){
|
||||
|
||||
return popup.ask({
|
||||
title: 'Erreur ('+rs.error+')',
|
||||
content: 'La suppression a échoué.',
|
||||
action: 'OK',
|
||||
type: 'neutral'
|
||||
}, () => {});
|
||||
|
||||
}
|
||||
|
||||
// 3. Reload page
|
||||
document.location = '';
|
||||
|
||||
}.bind(this));
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/* (7) Remove a version
|
||||
---------------------------------------------------------*/
|
||||
v_remove(){
|
||||
|
||||
// get current version
|
||||
var cur = this.get_vcurrent();
|
||||
if( cur.id < 0 )
|
||||
return;
|
||||
|
||||
// if last version -> forbid
|
||||
if( this.version.list.length < 2 ){
|
||||
return popup.ask({
|
||||
title: 'Dernière version',
|
||||
content: `La version <b>${cur.name}</b> ne peut être supprimée car il ne reste aucune autre version pour ce département`,
|
||||
action: 'OK',
|
||||
type: 'invalid'
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Popup confirm
|
||||
(new Promise( (resolve, reject) => {
|
||||
|
||||
popup.ask({
|
||||
title: 'Confirmation de suppression',
|
||||
content: `La version <b>${cur.name}</b> va être supprimée. Toutes les données seront perdues de manière définitive</b><br><br>Voulez-vous supprimer cette version ?`,
|
||||
action: 'Supprimer',
|
||||
type: 'invalid'
|
||||
}, (popup_rs) => { popup_rs && resolve() });
|
||||
|
||||
// 3. On popup confirm
|
||||
})).then( () => {
|
||||
|
||||
// Call API to create a new version
|
||||
api.call(`DELETE department/version/${cur.id}`, {}, function(rs){
|
||||
|
||||
// 1. error -> popup
|
||||
if( rs.error !== 0 || !rs.hasOwnProperty('deleted') ){
|
||||
|
||||
return popup.ask({
|
||||
title: 'Erreur ('+rs.error+')',
|
||||
content: 'La suppression a échoué.',
|
||||
action: 'OK',
|
||||
type: 'neutral'
|
||||
}, () => {});
|
||||
|
||||
}
|
||||
|
||||
// 3. Reload page
|
||||
document.location = '';
|
||||
|
||||
}.bind(this));
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
|
||||
/* (x) Exports all data about this department's version
|
||||
---------------------------------------------------------*/
|
||||
global_export(){
|
||||
|
||||
api.call(`GET department/export`, {}, function(rs){
|
||||
|
||||
// 1. error -> popup
|
||||
if( rs.error !== 0 || !rs.hasOwnProperty('link') ){
|
||||
|
||||
return popup.ask({
|
||||
title: 'Erreur ('+rs.error+')',
|
||||
content: 'L\'export a échoué.',
|
||||
action: 'OK',
|
||||
type: 'neutral'
|
||||
}, () => {});
|
||||
|
||||
}
|
||||
|
||||
// 2. Launch download
|
||||
document.location = rs.link;
|
||||
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
beforeMount(){
|
||||
|
||||
/* (1) Try to fetch versions from API */
|
||||
|
@ -468,22 +207,21 @@ export default {
|
|||
return;
|
||||
|
||||
// 2. Init version list
|
||||
this.version.list = [];
|
||||
this.vers = [ { id: -1, date: null } ];
|
||||
var idv = 0;
|
||||
|
||||
// 3. Store versions
|
||||
for( var ver of rs.versions ){
|
||||
|
||||
// if current version -> set @version.current
|
||||
if( _SERVER.session.version.current === ver.iddatabase )
|
||||
this.version.current = ver.iddatabase
|
||||
// if current version -> set @ver_id
|
||||
if( _SERVER.session.version === ver )
|
||||
this.ver_id = idv
|
||||
|
||||
// add version to list
|
||||
this.version.list.push( { id: ver.iddatabase, name: ver.label, new_name: ver.label } );
|
||||
this.vers.push( { id: idv++, date: ver } );
|
||||
|
||||
}
|
||||
|
||||
this.version
|
||||
|
||||
}.bind(this) );
|
||||
|
||||
|
||||
|
@ -493,11 +231,11 @@ export default {
|
|||
|
||||
// only hide not [data-unblur-department] elements
|
||||
if( e.target.getAttribute('data-unblur-department') === null )
|
||||
this.department.dialog = false;
|
||||
this.d_dialog = false;
|
||||
|
||||
// only hide not [data-unblur-version] elements
|
||||
if( e.target.getAttribute('data-unblur-version') === null )
|
||||
this.version.dialog = false;
|
||||
this.v_dialog = false;
|
||||
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue