From b73f71c6522a83413f15d62b01207541713afd37 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Sat, 11 Nov 2017 18:46:43 +0100 Subject: [PATCH] Svg generation + historyDefault/get_timeline + repo history/getByIdMachine + container.scss to generate machine timeline --- build/api/module/historyDefault.php | 49 +++++++ build/database/repo/history.php | 50 +++++-- build/generic/view/history/details/main.php | 132 ++++++++++++++++++- build/generic/view/history/details/main.twig | 4 +- config/modules.json | 11 ++ config/repositories.json | 1 + public_html/css/container.scss | 40 ++++++ public_html/css/min/container.css | 51 +++++++ public_html/src/static/timeline/lock.svg | 51 +++++++ public_html/src/static/timeline/signal.svg | 60 +++++++++ public_html/src/static/timeline/start.svg | 48 +++++++ public_html/src/static/timeline/stop.svg | 49 +++++++ public_html/src/static/timeline/unlock.svg | 70 ++++++++++ public_html/src/static/timeline/unsignal.svg | 70 ++++++++++ 14 files changed, 671 insertions(+), 15 deletions(-) create mode 100644 public_html/src/static/timeline/lock.svg create mode 100644 public_html/src/static/timeline/signal.svg create mode 100644 public_html/src/static/timeline/start.svg create mode 100644 public_html/src/static/timeline/stop.svg create mode 100644 public_html/src/static/timeline/unlock.svg create mode 100644 public_html/src/static/timeline/unsignal.svg diff --git a/build/api/module/historyDefault.php b/build/api/module/historyDefault.php index 0e84167..50797d1 100755 --- a/build/api/module/historyDefault.php +++ b/build/api/module/historyDefault.php @@ -150,6 +150,55 @@ ]; } + + + + /* (x) Return the machine history for an history entry + * + * @id_entry UID of the history entry + * + * @return timeline Machine timeline data + * + ---------------------------------------------------------*/ + + public function get_timeline($params){ + extract($params); + + /* (1) Get history entry data + ---------------------------------------------------------*/ + /* (1) Request */ + $entry = new Repo('history/getById', [$id_entry]); + + /* (2) Get response */ + $entry = $entry->answer(); + + /* (3) Manage error */ + if( !is_array($entry) ) + return ['error' => new Error(Err::RepoError)]; + + + /* (2) Get history for machine + ---------------------------------------------------------*/ + /* (1) Request */ + $timeline = new Repo('history/getByIdMachine', [ + $_SESSION['WAREHOUSE']['id'], + $entry['id_machine'] + ]); + + /* (2) Get response */ + $timeline = $timeline->answer(); + + /* (3) Manage error */ + if( $timeline === false ) + return ['error' => new Error(Err::RepoError)]; + + + /* (3) Return data + ---------------------------------------------------------*/ + return [ 'timeline' => $timeline ]; + + } + } diff --git a/build/database/repo/history.php b/build/database/repo/history.php index 5af5024..8bf3fb1 100755 --- a/build/database/repo/history.php +++ b/build/database/repo/history.php @@ -88,15 +88,37 @@ * FALSE si aucun résultat * */ - public static function getByIdMachine($id_machine){ + public static function getByIdMachine($id_warehouse, $id_machine){ + /* [1] On rédige/execute la requête =========================================================*/ - $machine = Table::get('history') - ->whereIdMachine($id_machine) - ->orderby('timestamp', Rows::ORDER_DESC) - ->select('*'); + $users = Table::get('user') + ->whereIdWarehouse($id_warehouse) + ->select('id_user') + ->select('username', null, null, 'user_name') + ->select('firstname', null, null, 'user_firstname') + ->select('lastname', null, null, 'user_lastname'); - return $machine->fetch(); + $machines = Table::get('machine') + ->whereIdWarehouse($id_warehouse) + ->whereId($id_machine) + ->select('id_machine') + ->select('name', null, null, 'machine_name'); + + $actions = Table::get('action') + ->select('id_action') + ->select('name', null, null, 'action_name'); + + + $history = Table::get('history') + ->join('id_user', $users) + ->join('id_machine', $machines) + ->join('id_action', $actions) + ->select('id_history') + ->select('timestamp') + ->orderby('timestamp', Rows::ORDER_DESC); + + return $history->fetch(); } @@ -134,21 +156,23 @@ /* RETOURNE UNE ENTREE SPECIFIQUE * - * @id_history UID de l'entree + * @id_entry UID de l'entrée historique * * @return entry Données de l'entree - * FALSE si aucun résultat + * FALSE si erreur | aucun résultat * */ - public static function getById($id_history){ + public static function getById($id_entry){ /* [1] On rédige/execute la requête =========================================================*/ - $user = Table::get('user') - ->whereId($id_history) + $entry = Table::get('history') + ->whereId($id_entry) ->orderby('timestamp', Rows::ORDER_DESC) - ->select('*'); + ->select('*') + ->unique(); + + return $entry->fetch(); - return $user->fetch(); } diff --git a/build/generic/view/history/details/main.php b/build/generic/view/history/details/main.php index 9c7912f..d4b2b03 100644 --- a/build/generic/view/history/details/main.php +++ b/build/generic/view/history/details/main.php @@ -10,11 +10,141 @@ class main extends i_view{ public $id_history; + private $timeline = []; - + /* (1) Constructor + * + * @id_history UID of the history entry + * + ---------------------------------------------------------*/ public function __construct($id_history){ + /* (1) Set attributes + ---------------------------------------------------------*/ $this->id_history = $id_history; + + /* (2) Get machine timeline + ---------------------------------------------------------*/ + /* (1) Request */ + $mac_req = new Request('historyDefault/get_timeline', [ 'id_entry' => $this->id_history ]); + + /* (2) Get response */ + $mac_res = $mac_req->dispatch(); + + /* (3) On success, store timeline data */ + if( $mac_res->error->get() == Err::Success ) + $this->timeline = $mac_res->get('timeline'); + + } + + + + /* (2) Format timeline data to svg render + * + * @timeline Timeline data + * + * @return svg SVG raw render + * + ---------------------------------------------------------*/ + public function svg(){ + + /* (1) Initialize variables + ---------------------------------------------------------*/ + /* (1) Set date() timezone */ + date_default_timezone_set('Europe/Paris'); + + /* (2) Init. result raw svg */ + $RAW = ''; + + /* (3) Set global range */ + $c = 0; + $cl = count($this->timeline); + + /* (4) Create ranges of size 15 */ + $r_size = 10; + $rl = round( $cl / $r_size ); + $y_range_diff = 100; + $total_height = $y_range_diff*$rl; + + + /* (1) Svg tag */ + $RAW .= ""; + + /* (2) Start CIRCLE */ + $RAW .= ""; + $RAW .= ""; + + + for( $r = 0 ; $r < $rl ; $r++ ){ + + $y = $y_range_diff*$r + 50; + + /* (2) Build barebone + ---------------------------------------------------------*/ + /* (1) Timeline LINE */ + $RAW .= ""; + + + /* (3) Build each action + ---------------------------------------------------------*/ + for( $c = 0 ; $c < $r_size ; $c++ ){ + + // exit if no more entry + if( !isset($this->timeline[$r*$r_size+$c]) ) + break; + + $entry = $this->timeline[$r*$r_size+$c]; + + $action_class = strtolower($entry['action_name']); + $icon_uri = '/src/static/timeline/'.$action_class.'@'.$this->get_action_color($action_class).'.svg'; + $x_offset = 100 + $c*800/$r_size; + $x_img_offset = $x_offset - 5.5; + + // circle + $RAW .= ""; + $RAW .= ""; + + // inside icon + $y_decal = $y - 5.5; + $RAW .= ""; + + } + + // exit if no more entry + if( !isset($this->timeline[$r*$r_size]) ) + break; + + } + + + /* (4) Stop CIRCLE */ + $x_offset = 100 + $c*800/$r_size; + $RAW .= ""; + $RAW .= ""; + + /* (5) Close SVG tag */ + $RAW .= ""; + + + return $RAW; + } + + + + private function get_action_color($action_name){ + + return 'ffffff'; + + switch($action_name){ + case 'start': return '2cde8b'; break; + case 'stop': return '3a3a3a'; break; + case 'lock': return 'e04343'; break; + case 'unlock': return 'af1c1c'; break; + case 'signal': return '3258d8'; break; + case 'unsignal': return '2041ab'; break; + } + + return '000000'; } } \ No newline at end of file diff --git a/build/generic/view/history/details/main.twig b/build/generic/view/history/details/main.twig index cfa9de2..9a99c0c 100644 --- a/build/generic/view/history/details/main.twig +++ b/build/generic/view/history/details/main.twig @@ -1 +1,3 @@ -In development.. This feature will soon be available. \ No newline at end of file + + +{{ core.svg() | raw }} \ No newline at end of file diff --git a/config/modules.json b/config/modules.json index d57ffff..ef7873a 100755 --- a/config/modules.json +++ b/config/modules.json @@ -605,6 +605,17 @@ "options": { "download": true }, "parameters": {}, "output": {} + }, + + "get_timeline": { + "description": "Retourne la timeline d'une machine pour associée à une entrée historique.", + "permissions": [["admin"]], + "parameters": { + "id_entry": { "description": "UID de l'entrée historique", "type": "id" } + }, + "output": { + "timeline": { "description": "Données de la timeline.", "type": "array" } + } } }, diff --git a/config/repositories.json b/config/repositories.json index 3b66f9d..6a23ee4 100755 --- a/config/repositories.json +++ b/config/repositories.json @@ -18,6 +18,7 @@ "search", "getAll", + "getById", "getByIdUser", "getByIdMachine", "getByIdAction" diff --git a/public_html/css/container.scss b/public_html/css/container.scss index a81a148..8ecf77c 100755 --- a/public_html/css/container.scss +++ b/public_html/css/container.scss @@ -534,3 +534,43 @@ article.check-table{ } } + + + + +/* [4] Timeline SVG +=========================================================*/ +/* (1) svg circles -> set right transform-origin */ +svg > circle[class^=svg_]{ + + -webkit-transform-origin: 50% 50% 0; + transform-origin: 50% 50% 0; + + transition: transform .2s ease-in-out; + +} + +/* (2) Middle circles -> scale+ on hover */ +svg > circle[class^=svg_]:not(.op_svg):hover{ + -webkit-transform: scale(1.2); + transform: scale(1.2); +} + +/* (3) Avoid icons inside middle circles to block :hover */ +svg > circle[class^=svg_]:not(.op_svg) + image{ + -webkit-pionter-events: none; + pointer-events: none; +} + +/* (4) Make around circles a bit transparent */ +svg > circle.op_svg{ + opacity: .6; +} + +/* (5) Set circle colors according to action type */ +svg > circle.svg_start{ fill: #2cde8b; } +svg > circle.svg_stop{ fill: #3a3a3a; } +svg > circle.svg_lock{ fill: #e04343; } +svg > circle.svg_unlock{ fill: #af1c1c; } +svg > circle.svg_signal{ fill: #3258d8; } +svg > circle.svg_unsignal{ fill: #2041ab; } \ No newline at end of file diff --git a/public_html/css/min/container.css b/public_html/css/min/container.css index 35f5a2f..a1d2b74 100644 --- a/public_html/css/min/container.css +++ b/public_html/css/min/container.css @@ -695,6 +695,57 @@ article.check-table > div > span input[type='checkbox'] + label[for] { article.check-table > div > span input[type='checkbox']:checked + label[for] { background-image: url("/src/static/container/checkbox@checked@007dd8.svg"); } + +/* [4] Timeline SVG +=========================================================*/ +/* (1) svg circles -> set right transform-origin */ +svg > circle[class^=svg_] { + -webkit-transform-origin: 50% 50% 0; + transform-origin: 50% 50% 0; + transition: transform .2s ease-in-out; +} + +/* (2) Middle circles -> scale+ on hover */ +svg > circle[class^=svg_]:not(.op_svg):hover { + -webkit-transform: scale(1.2); + transform: scale(1.2); +} + +/* (3) Avoid icons inside middle circles to block :hover */ +svg > circle[class^=svg_]:not(.op_svg) + image { + -webkit-pionter-events: none; + pointer-events: none; +} + +/* (4) Make around circles a bit transparent */ +svg > circle.op_svg { + opacity: .6; +} + +/* (5) Set circle colors according to action type */ +svg > circle.svg_start { + fill: #2cde8b; +} + +svg > circle.svg_stop { + fill: #3a3a3a; +} + +svg > circle.svg_lock { + fill: #e04343; +} + +svg > circle.svg_unlock { + fill: #af1c1c; +} + +svg > circle.svg_signal { + fill: #3258d8; +} + +svg > circle.svg_unsignal { + fill: #2041ab; +} /*# sourceMappingURL= container.css.map */ \ No newline at end of file diff --git a/public_html/src/static/timeline/lock.svg b/public_html/src/static/timeline/lock.svg new file mode 100644 index 0000000..2701307 --- /dev/null +++ b/public_html/src/static/timeline/lock.svg @@ -0,0 +1,51 @@ + +image/svg+xml \ No newline at end of file diff --git a/public_html/src/static/timeline/signal.svg b/public_html/src/static/timeline/signal.svg new file mode 100644 index 0000000..470ea21 --- /dev/null +++ b/public_html/src/static/timeline/signal.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/public_html/src/static/timeline/start.svg b/public_html/src/static/timeline/start.svg new file mode 100644 index 0000000..2792263 --- /dev/null +++ b/public_html/src/static/timeline/start.svg @@ -0,0 +1,48 @@ + +image/svg+xml \ No newline at end of file diff --git a/public_html/src/static/timeline/stop.svg b/public_html/src/static/timeline/stop.svg new file mode 100644 index 0000000..cab968f --- /dev/null +++ b/public_html/src/static/timeline/stop.svg @@ -0,0 +1,49 @@ + +image/svg+xml \ No newline at end of file diff --git a/public_html/src/static/timeline/unlock.svg b/public_html/src/static/timeline/unlock.svg new file mode 100644 index 0000000..5ee68e8 --- /dev/null +++ b/public_html/src/static/timeline/unlock.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/public_html/src/static/timeline/unsignal.svg b/public_html/src/static/timeline/unsignal.svg new file mode 100644 index 0000000..5ee68e8 --- /dev/null +++ b/public_html/src/static/timeline/unsignal.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + + + + + + + + + + + +