Reworked advanced tools

This commit is contained in:
PMKuipers 2023-11-11 20:17:45 +01:00
parent a60c259408
commit c3278f687c
12 changed files with 406 additions and 210 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -115,23 +115,33 @@ export default {
advanced_warning: 'advanced_warning',
advanced_pick_scale: 'advanced_pick_scale',
advanced_course_manipulation_title: 'advanced_course_manipulation_title',
advanced_bulk_course_timing: 'advanced_bulk_course_timing',
advanced_bulk_course_timing_desc: 'advanced_bulk_course_timing_desc',
advanced_force_scale_title: 'advanced_force_scale_title',
advanced_force_scale_desc: 'advanced_force_scale_desc',
advanced_force_scale_button: 'advanced_force_scale_button',
advanced_disable_autoenddate_title: 'advanced_disable_autoenddate_title',
advanced_disable_autoenddate_desc: 'advanced_disable_autoenddate_desc',
advanced_disable_autoenddate_button: 'advanced_disable_autoenddate_button',
advanced_confirm_header: 'advanced_confirm_header',
advanced_force_scale_confirm: 'advanced_force_scale_confirm',
advanced_import: 'advanced_import',
advanced_backup_restore: 'advanced_backup_restore',
advanced_restore: 'advanced_restore',
advanced_backup: 'advanced_backup',
advanced_restore_pages: 'advanced_restore_pages',
advanced_restore_lines: 'advanced_restore_lines',
advanced_backup_plan: 'advanced_backup_plan',
advanced_backup_page: 'advanced_backup_page',
advanced_export: 'advanced_export',
advanced_export_csv: 'advanced_export_csv',
advanced_export_csv_plan: 'advanced_export_csv_plan',
advanced_export_csv_page: 'advanced_export_csv_page',
advanced_import_from_file: 'advanced_import_from_file',
advanced_purge: "advanced_purge",
advanced_purge_expl: "advanced_purge_expl",
advanced_purge_plan: "advanced_purge_plan",
advanced_purge_plan_expl: "advanced_purge_plan_expl",
advanced_purge_page: "advanced_purge_page",
advanced_purge_page_expl: "advanced_purge_page_expl",
advanced_cascade_cohortsync_title: "advanced_cascade_cohortsync_title",
advanced_cascade_cohortsync_desc: "advanced_cascade_cohortsync_desc",
advanced_cascade_cohortsync: "advanced_cascade_cohortsync",
currentpage: "currentpage",
},
studyplan_edit: {
studyplan_edit: 'studyplan_edit',
@ -243,6 +253,10 @@ export default {
type: Object,
default(){ return null;},
},
selectedpage: {
type: Object,
default(){ return null;},
}
},
data() {
@ -271,18 +285,6 @@ export default {
},
},
methods: {
disable_autoenddate(){
const self=this;
call([{
methodname: 'local_treestudyplan_disable_autoenddate',
args: {
studyplan_id: this.value.id,
}
}])[0].done(function(response){
self.$bvModal.msgBoxConfirm((response.success?self.text.success$core:self.text.error$core)
+ "\n" + response.msg);
}).fail(notification.exception);
},
force_scales_start(){
// set confirmation box
const self=this;
@ -305,20 +307,49 @@ export default {
}
});
},
export_plan(format){
export_page(format){
const self = this;
if(format == undefined || !["json","csv"].includes(format)){
format = "json";
}
call([{
methodname: 'local_treestudyplan_export_plan',
methodname: 'local_treestudyplan_export_page',
args: {
studyplan_id: this.value.id,
page_id: this.selectedpage.id,
format: format,
},
}])[0].done(function(response){
download(self.value.shortname+"."+format,response.content,response.format);
download(self.value.shortname+".page."+format,response.content,response.format);
}).fail(notification.exception);
},
export_plan(){
const self = this;
call([{
methodname: 'local_treestudyplan_export_plan',
args: {
studyplan_id: this.value.id,
format: "json",
},
}])[0].done(function(response){
download(self.value.shortname+".plan.json",response.content,response.format);
}).fail(notification.exception);
},
bulk_course_timing() {
const self = this;
call([{
methodname: 'local_treestudyplan_bulk_course_timing',
args: {
page_id: this.selectedpage.id,
},
}])[0].done(function(response){
if(response.success){
// Reloading the webpage saves trouble reloading the specific page updated.
location.reload();
} else {
this.$bvModal.msgBoxOk(response.msg, {title: "Could not set bulk course timing"} );
debug.error("Could not set bulk course timing: ",response.msg);
}
}).fail(notification.exception);
},
import_studylines(){
@ -326,6 +357,26 @@ export default {
upload((filename,content)=>{
call([{
methodname: 'local_treestudyplan_import_studylines',
args: {
page_id: this.selectedpage.id,
content: content,
format: "application/json",
},
}])[0].done(function(response){
if(response.success){
location.reload();
} else {
this.$bvModal.msgBoxOk(response.msg, {title: "Import failed"} );
debug.error("Import failed: ",response.msg);
}
}).fail(notification.exception);
}, "application/json");
},
import_pages(){
//const self = this;
upload((filename,content)=>{
call([{
methodname: 'local_treestudyplan_import_pages',
args: {
studyplan_id: this.value.id,
content: content,
@ -335,13 +386,13 @@ export default {
if(response.success){
location.reload();
} else {
this.$bvModal.msgBoxOk(response.msg, {title: "Import failed"} );
debug.error("Import failed: ",response.msg);
}
}).fail(notification.exception);
}, "application/json");
},
purge_studyline(){
purge_studyplan(){
call([{
methodname: 'local_treestudyplan_delete_studyplan',
args: {
@ -352,11 +403,29 @@ export default {
if(response.success){
location.reload();
} else {
this.$bvModal.msgBoxOk(response.msg, {title: "Could not delete plan "} );
debug.error("Could not delete plan: ",response.msg);
}
}).fail(notification.exception);
},
purge_studyplanpage(){
if (this.selectedpage) {
call([{
methodname: 'local_treestudyplan_delete_studyplanpage',
args: {
id: this.selectedpage.id,
force: true,
},
}])[0].done(function(response){
if(response.success){
location.reload();
} else {
this.$bvModal.msgBoxOk(response.msg, {title: "Could not delete page"} );
debug.error("Could not delete page: ",response.msg);
}
}).fail(notification.exception);
}
},
cascade_cohortsync(){
const self = this;
call([{
@ -388,98 +457,99 @@ export default {
:title="text.advanced_tools_heading"
ok-only
@hide="modal_close"
body-class="p-0"
>
<b-card no-body>
<b-tabs card>
<b-tab :title="text.advanced_warning_title" active>
{{ text.advanced_warning}}
</b-tab>
<b-tab :title="text.advanced_course_manipulation_title" >
<b-container>
<b-row><b-col cols="*">
<h3>{{ text.advanced_cascade_cohortsync_title}}</h3>
{{ text.advanced_cascade_cohortsync_desc}}
</b-col></b-row>
<b-row><b-col cols="*">
<b-button
<p>{{ text.advanced_cascade_cohortsync_desc}}</p>
<p class="mt-2"><b-button
variant="info"
@click="cascade_cohortsync"
>{{ text.advanced_cascade_cohortsync}}</b-button>
</b-col></b-row>
<b-row class="mt-3"><b-col cols="*">
>{{ text.advanced_cascade_cohortsync}}</b-button></p>
<h3>{{ text.advanced_bulk_course_timing}}</h3>
<p>{{ text.advanced_bulk_course_timing_desc}}</p>
<p>{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
<p class="mt-2"><b-button
variant="info"
@click="bulk_course_timing"
>{{ text.advanced_bulk_course_timing}}</b-button></p>
<template v-if="['bistate','tristate'].includes(value.aggregation)">
<h3>{{ text.advanced_force_scale_title}}</h3>
{{ text.advanced_force_scale_desc}}
</b-col></b-row>
<b-row>
<b-col>
<b-form-select v-model="force_scales.selected_scale"
<p class="mt-2"><b-form-select v-model="force_scales.selected_scale"
:options="scales" text-field="name" value-field="id"
></b-form-select>
</b-col>
<b-col cols="4">
<b-button
variant="danger"
:disabled="force_scales.selected_scale == null"
@click="force_scales_start"
>{{ text.advanced_force_scale_button}}</b-button>
</b-col>
</b-row>
<b-row class="mt-3"><b-col cols="*">
</p>
<p class="mt-2">
<ul class='t-advanced-scrollable' v-if="force_scales.result.length > 0">
<li v-for="c in force_scales.result">
<span class='t-advanced-coursename'>{{c.course.fullname}}</span>
<ul v-if="c.grades.length > 0">
<li v-for='g in c.grades'>
<span class='t-advanced-gradename'><span v-html="g.name"></span></span>
<li v-for='g in c.grades'
><span class='t-advanced-gradename'><span v-html="g.name"></span></span>
<span v-if="g.changed == 'converted'" class='t-advanced-status changed'
>{{text.advanced_converted}}</span
><span v-else-if="g.changed == 'skipped'" class='t-advanced-status skipped'
>{{text.advanced_skipped}}</span
>
<span v-else class='t-advanced-status skipped'
><span v-else class='t-advanced-status skipped'
>{{text.advanced_error}}</span
>
</li>
></li>
</ul>
</li>
</ul>
</b-col></b-row>
<b-row><b-col cols="*">
<h3>{{ text.advanced_disable_autoenddate_title}}</h3>
{{ text.advanced_disable_autoenddate_desc}}
</b-col></b-row>
<b-row><b-col cols="*">
<b-button
variant="danger"
@click="disable_autoenddate"
>{{ text.advanced_disable_autoenddate_button}}</b-button>
</b-col></b-row>
</b-container>
</p>
</template>
</b-tab>
<b-tab :title='text.advanced_export'>
<b-button
<b-tab :title='text.advanced_backup_restore'>
<h3>{{ text.advanced_backup }}</h3>
<p><b-button
variant="primary"
@click="export_plan"
>{{ text.advanced_export}}</b-button>
<b-button
variant="danger"
@click="import_studylines"
>{{ text.advanced_import}}</b-button>
<b-button
@click="export_page('json')"
>{{ text.advanced_backup_page }}</b-button>
{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
<p><b-button
variant="primary"
@click="export_plan('csv')"
>{{ text.advanced_export_csv}}</b-button>
</b-tab>
<b-tab :title='text.advanced_purge'>
<p>{{text.advanced_purge_expl}}</p>
@click="export_plan('json')"
>{{ text.advanced_backup_plan }}</b-button></p>
<h3>{{ text.advanced_restore }}</h3>
<p><b-button
variant="danger"
@click="purge_studyline"
>{{ text.advanced_purge}}</b-button></p>
@click="import_studylines"
>{{ text.advanced_restore_lines}}</b-button></p>
<p><b-button
variant="danger"
@click="import_pages"
>{{ text.advanced_restore_pages }}</b-button></p>
<h3>{{ text.advanced_export }}</h3>
<p><b-button
variant="primary"
@click="export_page('csv')"
>{{ text.advanced_export_csv_page }}</b-button>
{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
</b-tab>
<b-tab :title='text.advanced_purge'>
<p>{{text.advanced_purge_page_expl}}</p>
<p>{{text.currentpage}} <i>{{selectedpage.fullname}}</i></p>
<p><b-button
variant="danger"
@click="purge_studyplanpage"
>{{ text.advanced_purge_page}}</b-button></p>
<p>{{text.advanced_purge_plan_expl}}</p>
<p><b-button
variant="danger"
@click="purge_studyplan"
>{{ text.advanced_purge_plan}}</b-button></p>
</b-tab>
</b-tabs>
</b-card>
</b-modal>
</span>
`
@ -1182,7 +1252,7 @@ export default {
},
mounted() {
if(this.value.pages[0].studylines.length == 0){
// start in editmode if studylines are empty
// start in editmode if studylines on first page are empty
this.edit.studyline.editmode = true;
}
this.$root.$emit('redrawLines');
@ -1472,7 +1542,7 @@ export default {
</div>
<div class="controlbox-group">
<span class='control editable'>
<t-studyplan-advanced v-model="value"></t-studyplan-advanced>
<t-studyplan-advanced v-model="value" :selectedpage="selectedpage"></t-studyplan-advanced>
</span>
<span class='control editable'>
<t-studyplan-associate
@ -2635,12 +2705,7 @@ export default {
// Listener for reposition events
// When an item in the list is repositioned, all lines need to be redrawn
onRePositioned(){
if(this.value.connections && this.value.connections.out){
for(let i in this.value.connections.out){
let conn = this.value.connections.out[i];
this.redrawLine(conn);
}
}
this.redrawLines();
},
// When an item is disPositioned - (temporarily) removed from the list,
// all connections need to be deleted.

View File

@ -139,6 +139,13 @@ class studyitem {
return $this->r->type;
}
/**
* Return period span
*/
public function span() : string {
return $this->r->span;
}
/**
* Return id of linked course (only relevant on COURSE types) or 0 if none
*/

View File

@ -699,7 +699,7 @@ class studyplan {
public static function export_structure() : \external_description {
return new \external_single_structure([
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
"content" => new \external_value(PARAM_TEXT, 'exported studyplan content'),
"content" => new \external_value(PARAM_RAW, 'exported studyplan content'),
], 'Exported studyplan');
}

View File

@ -479,7 +479,7 @@ class studyplanpage {
public static function export_structure() : \external_description {
return new \external_single_structure([
"format" => new \external_value(PARAM_TEXT, 'format of studyplan export'),
"content" => new \external_value(PARAM_TEXT, 'exported studyplan content'),
"content" => new \external_value(PARAM_RAW, 'exported studyplan content'),
], 'Exported studyplan');
}

View File

@ -1097,60 +1097,6 @@ class studyplanservice extends \external_api {
}
/****************************
* *
* disable_autoenddate *
* *
****************************/
/**
* Parameter description for webservice function disable_autoenddate
*/
public static function disable_autoenddate_parameters() : \external_function_parameters {
return new \external_function_parameters( [
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan'),
] );
}
/**
* Return value description for webservice function disable_autoenddate
*/
public static function disable_autoenddate_returns() : \external_description {
return success::structure();
}
/**
* Disable automatic end date for all courses in a study plan
* @param int $studyplanid Id of the studyplan
* @return array Success/fail model
*/
public static function disable_autoenddate($studyplanid) {
global $DB;
// Validate permissions.
webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::find_by_id($studyplanid)->context());
// Find studyline id's.
$studylineids = $DB->get_fieldset_select(studyline::TABLE, "id", "studyplan_id = :plan_id", ['plan_id' => $studyplanid]);
foreach ($studylineids as $studylineid) {
// Find id's of studyitems of type course.
$records = $DB->get_records(studyitem::TABLE, ['line_id' => $studylineid]);
foreach ($records as $itemr) {
$studyitem = new studyitem($itemr->id);
if ($studyitem->valid() && $studyitem->type() == studyitem::COURSE) {
$record = $DB->get_record("course_format_options",
["courseid" => $studyitem->courseid(), "name" => "automaticenddate"]);
if ($record && $record->value) {
$record->value = false;
$DB->update_record("course_format_options", $record);
}
}
}
}
return success::success()->model();
}
/****************************
* *
* duplicate studyplan *
@ -1225,12 +1171,7 @@ class studyplanservice extends \external_api {
webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::find_by_id($studyplanid)->context());
$plan = studyplan::find_by_id($studyplanid);
if ($format == "csv") {
// FIXME: Make sure this webservice function gets called for the page instead of the studyplan.
return $plan->pages()[0]->export_page_csv();
} else {
return $plan->export_plan();
}
} catch (\webservice_access_exception $x) {
return [ "format" => "", "content" => ""];
}
@ -1239,34 +1180,41 @@ class studyplanservice extends \external_api {
/**
* Parameter description for webservice function export_studylines
*/
public static function export_studylines_parameters() : \external_function_parameters {
public static function export_page_parameters() : \external_function_parameters {
return new \external_function_parameters( [
"studyplan_id" => new \external_value(PARAM_INT, 'id of plan to export '),
"page_id" => new \external_value(PARAM_INT, 'id of plan to export '),
"format" => new \external_value(PARAM_TEXT, 'export format', VALUE_OPTIONAL),
] );
}
/**
* Return value description for webservice function export_studylines
*/
public static function export_studylines_returns() : \external_description {
return studyplan::export_structure();
public static function export_page_returns() : \external_description {
return studyplanpage::export_structure();
}
/**
* Export studylines for a studyplan
* @param mixed $studyplanid Id of the studyplan to export the studylines for
* @param string $format Export format [csv, json (default)]
* @return array
*/
public static function export_studylines($studyplanid) {
public static function export_page($pageid,$format="json") {
try {
webservicehelper::require_capabilities(self::CAP_EDIT, studyplan::find_by_id($studyplanid)->context());
$plan = studyplan::find_by_id($studyplanid);
// FIXME: Make sure this gets called for the page instead of the studyplan.
return $plan->pages()[0]->export_studylines();
$page = studyplanpage::find_by_id($pageid);
webservicehelper::require_capabilities(self::CAP_EDIT, $page->studyplan()->context());
if ($format == "csv") {
return $page->export_page_csv();
} else {
return $page->export_page();
}
} catch (\webservice_access_exception $x) {
return [ "format" => "", "content" => ""];
}
}
/****************************
* *
* import studyplan *
@ -1278,7 +1226,7 @@ class studyplanservice extends \external_api {
*/
public static function import_plan_parameters() : \external_function_parameters {
return new \external_function_parameters( [
"content" => new \external_value(PARAM_TEXT, 'import file content'),
"content" => new \external_value(PARAM_RAW, 'import file content'),
"format" => new \external_value(PARAM_TEXT, 'import format'),
"context_id" => new \external_value(PARAM_INT, 'context of the study plan', VALUE_DEFAULT),
] );
@ -1312,13 +1260,50 @@ class studyplanservice extends \external_api {
}
}
/**
* Parameter description for webservice function import_studylines
*/
public static function import_pages_parameters() : \external_function_parameters {
return new \external_function_parameters( [
"studyplan_id" => new \external_value(PARAM_INT, 'id of studyplan to import to '),
"content" => new \external_value(PARAM_RAW, 'import file content'),
"format" => new \external_value(PARAM_TEXT, 'import format'),
] );
}
/**
* Return value description for webservice function import_studylines
*/
public static function import_pages_returns() : \external_description {
return success::structure();
}
/**
* Import studylines into existing studtplan
* @param int $studyplanid ID of studyplan to import to
* @param string $content Content of file
* @param string $format Format of file
* @return array Success/fail model
*/
public static function import_pages($studyplanid, $content, $format = "application/json") {
try {
$plan = studyplan::find_by_id($studyplanid);
// Validate import context.
webservicehelper::require_capabilities(self::CAP_EDIT, $plan->context());
$result = $plan->import_pages($content, $format);
return ($result ? success::success() : success::fail())->model();
} catch (\webservice_access_exception $x) {
return success::fail("Access denied")->model();
}
}
/**
* Parameter description for webservice function import_studylines
*/
public static function import_studylines_parameters() : \external_function_parameters {
return new \external_function_parameters( [
"studyplan_id" => new \external_value(PARAM_INT, 'id of plan to export '),
"content" => new \external_value(PARAM_TEXT, 'import file content'),
"page_id" => new \external_value(PARAM_INT, 'id of studyplan page to import to '),
"content" => new \external_value(PARAM_RAW, 'import file content'),
"format" => new \external_value(PARAM_TEXT, 'import format'),
] );
}
@ -1337,15 +1322,13 @@ class studyplanservice extends \external_api {
* @param string $format Format of file
* @return array Success/fail model
*/
public static function import_studylines($studyplanid, $content, $format = "application/json") {
public static function import_studylines($page_id, $content, $format = "application/json") {
try {
$plan = studyplan::find_by_id($studyplanid);
$page = studyplanpage::find_by_id($page_id);
// Validate import context.
webservicehelper::require_capabilities(self::CAP_EDIT, $plan->context());
webservicehelper::require_capabilities(self::CAP_EDIT, $page->studyplan()->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);
$result = $page->import_studylines($content, $format);
return ($result ? success::success() : success::fail())->model();
} catch (\webservice_access_exception $x) {
return success::fail("Access denied")->model();
@ -1636,4 +1619,107 @@ class studyplanservice extends \external_api {
}
/************************
* *
* bulk_course_timing *
* *
************************/
/**
* Parameter description for webservice function delete_studyplan
*/
public static function bulk_course_timing_parameters() : \external_function_parameters {
return new \external_function_parameters( [
"page_id" => new \external_value(PARAM_INT, 'id of studyplanpage'),
] );
}
/**
* Return value description for webservice function delete_studyplan
*/
public static function bulk_course_timing_returns() : \external_description {
return success::structure();
}
/**
* Delete a studyplan
* @param mixed $id Id of the studyplan
* @param bool $force Force deletion, even though studyplan is not empty
* @return array Succes/fail model
*/
public static function bulk_course_timing($pageid) {
$page = studyplanpage::find_by_id($pageid);
// Validate if the requesting user has the right to edit the plan in it's current context.
webservicehelper::require_capabilities(self::CAP_EDIT, $page->studyplan()->context());
$result = true;
$message = [];
$periods = period::find_for_page($page);
$studylines = studyline::find_page_children($page);
foreach ($studylines as $line) {
$studyitems = studyitem::find_studyline_children($line);
foreach ($studyitems as $item) {
if ($item->type() == studyitem::COURSE) {
if ( $item->slot() <= $page->periods() ) {
$period = $periods[$item->slot()];
try {
self::course_period_timing($period->id(),$item->courseid(),$item->span());
} catch (\webservice_access_exception $x) {
$result &= false;
$course = \get_course($item->courseid());
$message[] = "Course {$course->shortname}: {$x->debuginfo}";
} catch (\Exception $x) {
$result &= false;
$course = \get_course($item->courseid());
$xclass = \get_class($x);
$message[] = "Course {$course->shortname}: {$xclass} {$x->getMessage()}";
}
}
}
}
}
return (new success($result,implode("<p>\n",$message)))->model();
}
/************************
* *
* delete_studyplanpage *
* *
************************/
/**
* Parameter description for webservice function delete_studyplan
*/
public static function delete_studyplanpage_parameters() : \external_function_parameters {
return new \external_function_parameters( [
"id" => new \external_value(PARAM_INT, 'id of studyplanpage'),
"force" => new \external_value(PARAM_BOOL, 'force deletion', VALUE_DEFAULT),
] );
}
/**
* Return value description for webservice function delete_studyplan
*/
public static function delete_studyplanpage_returns() : \external_description {
return success::structure();
}
/**
* Delete a studyplan
* @param mixed $id Id of the studyplan
* @param bool $force Force deletion, even though studyplan is not empty
* @return array Succes/fail model
*/
public static function delete_studyplanpage($id, $force = false) {
$o = studyplanpage::find_by_id($id);
$p = $o->studyplan();
// Validate if the requesting user has the right to edit the plan in it's current context.
webservicehelper::require_capabilities(self::CAP_EDIT, $p->context());
return $o->delete(!!$force)->model();
}
}

View File

@ -74,7 +74,7 @@ class success {
public static function structure() : \external_description {
return new \external_single_structure([
"success" => new \external_value(PARAM_BOOL, 'operation completed succesfully'),
"msg" => new \external_value(PARAM_TEXT, 'message'),
"msg" => new \external_value(PARAM_RAW, 'message'),
"data" => new \external_value(PARAM_RAW, 'message'),
]);
}

View File

@ -137,6 +137,16 @@ $functions = [
'loginrequired' => true,
],
'local_treestudyplan_delete_studyplanpage' => [ // Web service function name.
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
'methodname' => 'delete_studyplanpage', // External function name.
'description' => 'Delete studyplan page',
'type' => 'write', // Database rights of the web service function (read, write).
'ajax' => true,
'capabilities' => 'local/treestudyplan:editstudyplan',
'loginrequired' => true,
],
'local_treestudyplan_delete_studyline' => [ // Web service function name.
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
'methodname' => 'delete_studyline', // External function name.
@ -412,15 +422,6 @@ $functions = [
'capabilities' => 'local/treestudyplan:editstudyplan',
'loginrequired' => true,
],
'local_treestudyplan_disable_autoenddate' => [ // Web service function name.
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
'methodname' => 'disable_autoenddate', // External function name.
'description' => 'Disable automatic end dates on courses in the study plan',
'type' => 'write', // Database rights of the web service function (read, write).
'ajax' => true,
'capabilities' => 'local/treestudyplan:forcescales',
'loginrequired' => true,
],
'local_treestudyplan_force_studyplan_scale' => [ // Web service function name.
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
'methodname' => 'force_studyplan_scale', // External function name.
@ -457,10 +458,10 @@ $functions = [
'capabilities' => 'local/treestudyplan:editstudyplan',
'loginrequired' => true,
],
'local_treestudyplan_export_studylines' => [ // Web service function name.
'local_treestudyplan_export_page' => [ // Web service function name.
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
'methodname' => 'export_studylines', // External function name.
'description' => 'Export study plan',
'methodname' => 'export_page', // External function name.
'description' => 'Export studyplan page',
'type' => 'read', // Database rights of the web service function (read, write).
'ajax' => true,
'capabilities' => 'local/treestudyplan:editstudyplan',
@ -475,6 +476,15 @@ $functions = [
'capabilities' => 'local/treestudyplan:editstudyplan',
'loginrequired' => true,
],
'local_treestudyplan_import_pages' => [ // Web service function name.
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
'methodname' => 'import_pages', // External function name.
'description' => 'Import study plan pages',
'type' => 'write', // Database rights of the web service function (read, write).
'ajax' => true,
'capabilities' => 'local/treestudyplan:editstudyplan',
'loginrequired' => true,
],
'local_treestudyplan_import_studylines' => [ // Web service function name.
'classname' => '\local_treestudyplan\studyplanservice', // Class containing the external function.
'methodname' => 'import_studylines', // External function name.
@ -609,4 +619,13 @@ $functions = [
'ajax' => true,
'loginrequired' => true,
],
'local_treestudyplan_bulk_course_timing' => [ // Web service function name.
'classname' => '\local_treestudyplan\utilityservice', // Class containing the external function.
'methodname' => 'bulk_course_timing', // External function name.
'description' => 'Change course start/end dates to match that of the studyplan period',
'type' => 'write', // Database rights of the web service function (read, write).
'capabilities' => 'local/treestudyplan:editstudyplan',
'ajax' => true,
'loginrequired' => true,
],
];

View File

@ -303,23 +303,33 @@ $string["advanced_force_scale_button"] = 'Apply';
$string["advanced_confirm_header"] = 'Are you sure';
$string["advanced_force_scale_confirm"] = 'Are you sure you want to set all associated gradables to this scale?';
$string["advanced_import_export"] = 'Backup and restore';
$string["advanced_import"] = 'Restore studylines from backup';
$string["advanced_export"] = 'Backup study plan';
$string["advanced_export_csv"] = 'Export as CSV';
$string["advanced_import_from_file"] = "Open from file";
$string["advanced_backup_restore"] = 'Backup and restore';
$string["advanced_restore"] = 'Restore from file';
$string["advanced_backup"] = 'Backup to file';
$string["advanced_restore_pages"] = 'Import pages from a studyplan backup';
$string["advanced_restore_lines"] = 'Import content from a studyplan page backup';
$string["advanced_backup_plan"] = 'Backup studyplan';
$string["advanced_backup_page"] = 'Backup active studyplan page ';
$string["advanced_export"] = 'Export to file';
$string["advanced_export_csv_page"] = 'Export current page as CSV';
$string["advanced_export_csv_plan"] = 'Export studyplan CSV';
$string["advanced_import_from_file"] = "Restore studyplan from file";
$string["advanced_purge"] = "Delete";
$string["advanced_purge_expl"] = "Delete the entire study plan. This is not recoverable";
$string["advanced_purge_plan"] = "Delete entire study plan";
$string["advanced_purge_plan_expl"] = "Delete the entire study plan. This is not recoverable";
$string["advanced_purge_page"] = "Delete active page";
$string["advanced_purge_page_expl"] = "Delete the currently active study plan page. This is not recoverable";
$string["currentpage"] = "Currently active page:";
$string["advanced_bulk_course_timing"] = 'Sync course timing to periods';
$string["advanced_bulk_course_timing_desc"] = 'Synchronize the start and end date of all courses in the currently active studyplan page to periods in which they are placed.';
$string["advanced_cascade_cohortsync_title"] = "Cascade cohort sync";
$string["advanced_cascade_cohortsync_desc"] = "Add cohort sync enrolment to each course in this study plan for all cohorts linked to this study plan";
$string["advanced_cascade_cohortsync"] = "Cascade cohort sync";
$string["advanced_course_manipulation_title"] = 'Course manipulation';
$string["advanced_disable_autoenddate_title"] = 'Disable automatic end date';
$string["advanced_disable_autoenddate_desc"] = 'Disable the default on automatic end date function weekly topics have set in all courses in the study plan';
$string["advanced_disable_autoenddate_button"] = 'Disable';
$string["myreport_teachermode"] = 'Study plans I am teaching';
$string["aggregation_overall_all"] = "Complete all of the following to complete this course";

View File

@ -301,23 +301,32 @@ $string["advanced_force_scale_button"] = 'Toepassen';
$string["advanced_confirm_header"] = 'Weet je het zeker?';
$string["advanced_force_scale_confirm"] = 'Weet je zeker dat je de beoordeling van alle gekoppelde activiteiten wilt omzetten?';
$string["advanced_import_export"] = 'Backup and terugzetten';
$string["advanced_import"] = 'Studieplan invullan vanuit backup';
$string["advanced_export"] = 'Backup downloaden';
$string["advanced_export_csv"] = 'Export als CSV';
$string["advanced_backup_restore"] = 'Backup and import';
$string["advanced_restore"] = 'Laden vanuit bestand';
$string["advanced_backup"] = 'Backup naar bestand';
$string["advanced_restore_pages"] = 'Importeer tabbladen uit de backup van een studieplan';
$string["advanced_restore_lines"] = 'Importeer inhoud uit de backup van een tabblad';
$string["advanced_backup_plan"] = 'Backup studieplan';
$string["advanced_backup_page"] = 'Backup actieve tabblad ';
$string["advanced_export"] = 'Exporteer naar bestand';
$string["advanced_export_csv_page"] = 'Exporteer actieve tabblad naar CSV';
$string["advanced_export_csv_plan"] = 'Exporteer studeeplan naar CSV';
$string["advanced_import_from_file"] = "Vanuit bestand";
$string["advanced_purge"] = "Verwijderen";
$string["advanced_purge_expl"] = "Dit hele studieplan permanent verwijderen.";
$string["advanced_purge_plan"] = "Studieplan verwijderen";
$string["advanced_purge_plan_expl"] = "Dit hele studieplan permanent verwijderen.";
$string["advanced_purge_page"] = "Tabblad verwijderen";
$string["advanced_purge_page_expl"] = "Het actieve tabblad permanent verwijderen.";
$string["currentpage"] = "Actief tabblad:";
$string["advanced_bulk_course_timing"] = 'Stel start- en einddatum in';
$string["advanced_bulk_course_timing_desc"] = 'Stel de start- en einddatum van alle cursussen in het actieve tabblas in op die van de perioden waarin ze geplaatst zijn';
$string["advanced_cascade_cohortsync_title"] = "Site-groep synchronisatie doorzetten";
$string["advanced_cascade_cohortsync_desc"] = "Voeg een site-group synchronisatie aanmelding toe aan alle cursussen in dit studieplan, voor alle gekoppelde site-groepen";
$string["advanced_cascade_cohortsync"] = "Site-groep sync doorzetten";
$string["advanced_course_manipulation_title"] = 'Cursussen aanpassen';
$string["advanced_disable_autoenddate_title"] = 'Automatische einddatum uitschakelen';
$string["advanced_disable_autoenddate_desc"] = 'Schakel de optie automatische einddatum uit in alle cursussen in dit studieplan';
$string["advanced_disable_autoenddate_button"] = 'Uitschakelen';
$string["myreport_teachermode"] = 'Studieplannen waar ik les aan geef';
$string["aggregation_overall_all"] = "Je voltooit de module door alles van het volgende";

View File

@ -22,7 +22,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
$plugin->version = 2023102401; // YYYYMMDDHH (year, month, day, iteration).
$plugin->version = 2023111001; // YYYYMMDDHH (year, month, day, iteration).
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
$plugin->release = "1.1.0-b";