From 0a994d82bb1177cf916d3adffdaefe9a38561ef9 Mon Sep 17 00:00:00 2001 From: PMKuipers Date: Thu, 3 Aug 2023 18:44:57 +0200 Subject: [PATCH] Current period highlight --- amd/src/report-viewer-components.js | 18 ++++- amd/src/studyplan-editor-components.js | 32 +++++++-- amd/src/treestudyplan-components.js | 14 +++- classes/studyplan.php | 14 ++-- classes/studyplanservice.php | 15 ++-- css/devstyles.css | 97 +++++++++++++++++++++++++- 6 files changed, 164 insertions(+), 26 deletions(-) diff --git a/amd/src/report-viewer-components.js b/amd/src/report-viewer-components.js index 679e384..c1da739 100644 --- a/amd/src/report-viewer-components.js +++ b/amd/src/report-viewer-components.js @@ -322,6 +322,7 @@ export default { :line="line" :plan="value" :page="page" + :period="page.perioddesc[index-1]" :guestmode='guestmode' :teachermode='teachermode' :layer="layeridx-1" @@ -446,6 +447,10 @@ export default { teachermode: { type: Boolean, default: false, + }, + period: { + type: Object, + default(){ return null;}, } }, mounted() { @@ -469,6 +474,17 @@ export default { } return null; }, + current(){ + if( this.period && this.period.startdate && this.period.enddate){ + const now = new Date(); + const pstart = new Date(this.period.startdate); + const pend = new Date(this.period.enddate); + return (now >= pstart && now < pend); + } + else { + return false; + } + } }, data() { return { @@ -478,7 +494,7 @@ export default { }, template: ` -
0){ @@ -596,6 +601,7 @@ export default { this.editdata.aggregation_config = JSON.stringify(this.aggregation_parsed[this.editdata.aggregation]); } objCopy(args,this.editdata,STUDYPLAN_EDITOR_FIELDS); + objCopy(args,this.editdata,STUDYPLAN_EDITOR_PAGE_FIELDS); call([{ methodname: method, @@ -609,7 +615,7 @@ export default { shortname: '', description: '', context_id: 1, - slots : 4, + periods : 4, startdate: (new Date()).getFullYear() + '-08-01', enddate: ((new Date()).getFullYear()+1) + '-08-01', aggregation: 'bistate', @@ -685,7 +691,7 @@ export default { {{ text.studyplan_slots}} - + @@ -1859,6 +1865,17 @@ export default { }, courseHoverDummy(){ return {course: this.hover.component}; + }, + current(){ + if( this.period && this.period.startdate && this.period.enddate){ + const now = new Date(); + const pstart = new Date(this.period.startdate); + const pend = new Date(this.period.enddate); + return (now >= pstart && now < pend); + } + else { + return false; + } } }, data() { @@ -2041,7 +2058,8 @@ export default { } }, template: ` -
= pstart && now < pend); + } + else { + return false; + } } + }, data() { return { }; }, template: ` -

{{ value.shortname }} null ]; foreach($addable as $f){ if(array_key_exists($f,$fields)){ @@ -192,15 +192,13 @@ class studyplan { // Add a single page and copy the names.This keeps the data sane until the upgrade to // real page management is done // TODO: Remove this when proper page management is implemented - $pageaddable = ['name','shortname','description','slots','startdate','enddate']; + $pageaddable = ['name','shortname','description','periods','startdate','enddate']; $pageinfo = ['studyplan_id' => $id]; foreach($pageaddable as $f){ if(array_key_exists($f,$fields)){ if($f == "name"){ $pageinfo["fullname"] = $fields[$f]; - } else if ($f == "slots") { - $pageinfo["periods"] = $fields[$f]; - }else { + } else { $pageinfo[$f] = $fields[$f]; } } @@ -214,7 +212,7 @@ class studyplan { public function edit($fields){ global $DB; - $editable = ['name','shortname','description','context_id','slots','startdate','enddate','aggregation','aggregation_config']; + $editable = ['name','shortname','description','context_id','periods','startdate','enddate','aggregation','aggregation_config']; $info = ['id' => $this->id,]; foreach($editable as $f){ if(array_key_exists($f,$fields)){ @@ -237,14 +235,12 @@ class studyplan { if(count($this->pages()) == 1){ // update the info to the page as well $page = $this->pages()[0]; - $pageeditable = ['name','shortname','description','slots','startdate','enddate']; + $pageeditable = ['name','shortname','description','periods','startdate','enddate']; $pageinfo = []; foreach($pageeditable as $f){ if(array_key_exists($f,$fields)){ if($f == "name"){ $pageinfo["fullname"] = $fields[$f]; - } else if ($f == "slots") { - $pageinfo["periods"] = $fields[$f]; }else { $pageinfo[$f] = $fields[$f]; } diff --git a/classes/studyplanservice.php b/classes/studyplanservice.php index e42b431..afb5665 100644 --- a/classes/studyplanservice.php +++ b/classes/studyplanservice.php @@ -120,7 +120,7 @@ class studyplanservice extends \external_api "name" => new \external_value(PARAM_TEXT, 'name of studyplan'), "shortname"=> new \external_value(PARAM_TEXT, 'shortname of studyplan'), "description"=> new \external_value(PARAM_TEXT, 'description of studyplan'), - "slots" => new \external_value(PARAM_INT, 'number of slots in studyplan'), + "periods" => new \external_value(PARAM_INT, 'number of periods in studyplan'), "startdate" => new \external_value(PARAM_TEXT, 'start date of studyplan'), "enddate" => new \external_value(PARAM_TEXT, 'end date of studyplan'), "aggregation" => new \external_value(PARAM_TEXT, 'selected aggregator',VALUE_DEFAULT), @@ -134,7 +134,7 @@ class studyplanservice extends \external_api return studyplan::simple_structure(); } - public static function add_studyplan($name, $shortname,$description, $slots, $startdate, $enddate, $aggregation="bistate", $aggregation_config='',$context_id=0) + public static function add_studyplan($name, $shortname,$description, $periods, $startdate, $enddate, $aggregation="bistate", $aggregation_config='',$context_id=0) { // Check if we have the proper rights for the requested context $context = webservicehelper::find_context($context_id); @@ -144,7 +144,7 @@ class studyplanservice extends \external_api 'name' => $name, 'shortname' => $shortname, 'description' => $description, - 'slots' => $slots, + 'periods' => $periods, 'startdate' => $startdate, 'enddate' => empty($enddate)?null:$enddate, 'aggregation' => $aggregation, @@ -167,7 +167,7 @@ class studyplanservice extends \external_api "name" => new \external_value(PARAM_TEXT, 'name of studyplan'), "shortname"=> new \external_value(PARAM_TEXT, 'shortname of studyplan'), "description"=> new \external_value(PARAM_TEXT, 'description of studyplan'), - "slots" => new \external_value(PARAM_INT, 'number of slots in studyplan'), + "periods" => new \external_value(PARAM_INT, 'number of periods in studyplan'), "startdate" => new \external_value(PARAM_TEXT, 'start date of studyplan'), "enddate" => new \external_value(PARAM_TEXT, 'end date of studyplan'), "aggregation" => new \external_value(PARAM_TEXT, 'selected aggregator',VALUE_DEFAULT), @@ -181,7 +181,7 @@ class studyplanservice extends \external_api return studyplan::simple_structure(); } - public static function edit_studyplan($id, $name, $shortname, $description, $slots, $startdate, $enddate, $aggregation="bistate", $aggregation_config='',$context_id=0) + public static function edit_studyplan($id, $name, $shortname, $description, $periods, $startdate, $enddate, $aggregation="bistate", $aggregation_config='',$context_id=0) { // Validate access in the intended context $context = webservicehelper::find_context($context_id); @@ -194,7 +194,7 @@ class studyplanservice extends \external_api 'name' => $name, 'shortname' => $shortname, 'description' => $description, - 'slots' => $slots, + 'periods' => $periods, 'startdate' => $startdate, 'enddate' => $enddate, 'aggregation' => $aggregation, @@ -1053,6 +1053,7 @@ class studyplanservice extends \external_api webservicehelper::require_capabilities(self::CAP_EDIT,$plan->context()); // FIXME: Make sure this gets called for the page instead of the studyplan + // Once proper page management is implemented $result = $plan->pages()[0]->import_studylines($content,$format); return ($result?success::success():success::fail())->model(); } @@ -1102,7 +1103,7 @@ class studyplanservice extends \external_api if (file_exists($modmoodleform)) { require_once($modmoodleform); } else { - print_error('noformdesc'); + throw new \moodle_exception('noformdesc', 'error'); } $mformclassname = 'mod_'.$module->name.'_mod_form'; diff --git a/css/devstyles.css b/css/devstyles.css index 6dd25c8..7103ecf 100644 --- a/css/devstyles.css +++ b/css/devstyles.css @@ -1,4 +1,10 @@ /* stylelint-disable length-zero-no-unit, color-hex-case, color-hex-length, no-eol-whitespace, unit-blacklist, block-no-empty */ +html { /* not :root, so we can override these colors in the :root field if needed */ + --less-light: color-mix(in srgb, var(--light) 80%, #ccc); + --highlight: var(--info); + --highlight-mix: 10%; +} + .t-toolbox-preface { margin: 10px; @@ -263,6 +269,85 @@ ul.t-competency-list li { margin-left: 10px; } +.t-studyline-slot.gradable.current.odd, +.r-studyline-slot.gradable.current.odd { + --hlcol: color-mix(in srgb, var(--less-light) , var(--highlight) var(--highlight-mix)); + background-color: var(--hlcol); + position: relative; +} + +.t-studyline-slot.gradable.current.odd:before, +.r-studyline-slot.gradable.current.odd:before { + --hlcol: color-mix(in srgb, var(--less-light) , var(--highlight) var(--highlight-mix)); + box-shadow: -20px 0 10px -7px var(--hlcol) inset; + content: " "; + height: 100%; + left: -20px; + position: absolute; + top: 0; + width: 20px; +} + +.t-studyline-slot.gradable.current.odd:after, +.r-studyline-slot.gradable.current.odd:after { + --hlcol: color-mix(in srgb, var(--less-light) , var(--highlight) var(--highlight-mix)); + box-shadow: 20px 0 10px -7px var(--hlcol) inset; + content: " "; + height: 100%; + right: -20px; + position: absolute; + top: 0; + width: 20px; +} + +.s-studyline-header-period.current { + --hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix)); + box-shadow: 0 0 10px 10px var(--hlcol); + background-color: var(--hlcol); + margin-top: 16px; + border-top-left-radius: 16px; + border-top-right-radius: 16px; +} + +.s-studyline-header-heading { + margin-top: 16px; +} + +.t-studyline-slot.gradable.current.even, +.r-studyline-slot.gradable.current.even { + --hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix)); + background-color: var(--hlcol); + position: relative; +} + +.t-studyline-slot.gradable.current.even:before, +.r-studyline-slot.gradable.current.even:before { + --hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix)); + box-shadow: -20px 0 10px -7px var(--hlcol) inset; + content: " "; + height: 100%; + left: -20px; + position: absolute; + top: 0; + width: 20px; +} + +.simpleline { + z-index: 20; +} + +.t-studyline-slot.gradable.current.even:after, +.r-studyline-slot.gradable.current.even:after { + --hlcol: color-mix(in srgb, var(--white) , var(--highlight) var(--highlight-mix)); + box-shadow: 20px 0 10px -7px var(--hlcol) inset; + content: " "; + height: 100%; + right: -20px; + position: absolute; + top: 0; + width: 20px; +} + .t-slot-drop { min-height: 32px; height: 100%; @@ -564,7 +649,15 @@ a.t-item-course-config { .r-studyline-heading.odd, .t-studyline-slot.odd, .r-studyline-slot.odd { - background-color: #f0f0f0; + background-color: var(--less-light); +} + +.t-studyline-drag:nth-child(even) .t-studyline div, +.t-studyline-heading.even, +.r-studyline-heading.even, +.t-studyline-slot.even, +.r-studyline-slot.even { + background-color: var(--white); } .t-studyline-drag:first-child, @@ -585,6 +678,7 @@ a.t-item-course-config { .s-studyline-header-period { text-align: center; + padding-top: 5px; } .s-studyline-header-period p { margin-bottom: 0; @@ -603,6 +697,7 @@ a.t-item-course-config { } + .t-studyline-slot.rightmost, .r-studyline-slot.rightmost { border-right-style: solid;