Fixed layout of item labels

This commit is contained in:
PMKuipers 2024-06-01 14:00:32 +02:00
parent 742f9ef772
commit 8b5cad01f8
12 changed files with 125 additions and 35 deletions

View File

@ -1,3 +1,3 @@
define("local_treestudyplan/util/fittext-vue",["exports","./css-calc","./fitty","./textfit"],(function(_exports,_cssCalc,_fitty,_textfit){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_fitty=(obj=_fitty)&&obj.__esModule?obj:{default:obj};var _default={install(Vue){Vue.component("fittext",{props:{maxsize:{type:String,default:"512px"},minsize:{type:String,default:"10px"},vertical:Boolean,singleline:Boolean,dynamic:Boolean},data:()=>({resizeObserver:null,mutationObserver:null}),computed:{rootStyle(){return this.vertical?"height: 100%;":"width: 100%;"}},methods:{},mounted(){(0,_fitty.default)(this.$refs.text,{minSize:(0,_cssCalc.calc)(this.minsize),maxSize:(0,_cssCalc.calc)(this.maxsize),vertical:this.vertical,multiline:!this.singleline})},unmounted(){this.mutationObserver&&this.mutationObserver.disconnect(),this.resizeObserver&&this.resizeObserver.disconnect()},template:"\n <div class='q-fittext' ref='container' :style=\"rootStyle\">\n <span :style=\"'display:block; white-space:'+ ((singleline)?'nowrap':'normal')+';'\" class='q-fittext-text' ref='text'><slot></slot>\n </span\n ></div>\n "})}};return _exports.default=_default,_exports.default})); define("local_treestudyplan/util/fittext-vue",["exports","./css-calc","./fitty","./textfit"],(function(_exports,_cssCalc,_fitty,_textfit){var obj;Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_fitty=(obj=_fitty)&&obj.__esModule?obj:{default:obj};var _default={install(Vue){Vue.component("fittext",{props:{maxsize:{type:String,default:"512px"},minsize:{type:String,default:"10px"},vertical:Boolean,singleline:Boolean,dynamic:Boolean},data:()=>({resizeObserver:null,mutationObserver:null}),computed:{rootStyle(){return this.vertical?"height: 100%;":"width: 100%;"}},methods:{},mounted(){(0,_fitty.default)(this.$refs.text,{minSize:(0,_cssCalc.calc)(this.minsize),maxSize:(0,_cssCalc.calc)(this.maxsize),vertical:this.vertical,multiline:!this.singleline})},unmounted(){this.mutationObserver&&this.mutationObserver.disconnect(),this.resizeObserver&&this.resizeObserver.disconnect()},template:"\n <div class='q-fittext' ref='container' :style=\"rootStyle + ';min-height:0;min-width:0;'\">\n <span :style=\"'display:block; white-space:'+ ((singleline)?'nowrap':'normal')+';' + rootStyle\" class='q-fittext-text' ref='text'><slot></slot>\n </span\n ></div>\n "})}};return _exports.default=_default,_exports.default}));
//# sourceMappingURL=fittext-vue.min.js.map //# sourceMappingURL=fittext-vue.min.js.map

View File

@ -1 +1 @@
{"version":3,"file":"fittext-vue.min.js","sources":["../../src/util/fittext-vue.js"],"sourcesContent":["/*eslint no-unused-vars: warn */\n/*eslint max-len: [\"error\", { \"code\": 160 }] */\n/*eslint-disable no-trailing-spaces */\n/*eslint-env es6*/\n\nimport {calc} from \"./css-calc\";\nimport fitty from \"./fitty\";\nimport {textFit} from \"./textfit\";\n\nexport default {\n install(Vue/*,options*/){\n Vue.component('fittext',{\n props: {\n maxsize: {\n type: String,\n default: \"512px\",\n },\n minsize: {\n type: String,\n default: \"10px\",\n },\n vertical: Boolean,\n singleline: Boolean,\n dynamic: Boolean,\n },\n data() {\n return {\n resizeObserver: null,\n mutationObserver: null,\n };\n },\n computed: {\n rootStyle() {\n if (this.vertical) {\n return `height: 100%;`;\n } else {\n return `width: 100%;`;\n }\n }\n },\n methods: {\n },\n mounted() {\n const self = this;\n // If the content could change after initial presentation,\n // Use the fitty method. It is slightly worse on multiline horizontal text,\n // but better supports content that can change later on.\n fitty(self.$refs.text,\n {\n minSize: calc(self.minsize),\n maxSize: calc(self.maxsize),\n vertical: self.vertical,\n multiline: !self.singleline,\n });\n },\n unmounted() {\n if(this.mutationObserver) {\n this.mutationObserver.disconnect();\n }\n if(this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n },\n template: `\n <div class='q-fittext' ref='container' :style=\"rootStyle\">\n <span :style=\"'display:block; white-space:'+ ((singleline)?'nowrap':'normal')+';'\" class='q-fittext-text' ref='text'><slot></slot>\n </span\n ></div>\n `,\n });\n },\n};"],"names":["install","Vue","component","props","maxsize","type","String","default","minsize","vertical","Boolean","singleline","dynamic","data","resizeObserver","mutationObserver","computed","rootStyle","this","methods","mounted","$refs","text","minSize","maxSize","multiline","unmounted","disconnect","template"],"mappings":"qSASe,CACXA,QAAQC,KACJA,IAAIC,UAAU,UAAU,CACxBC,MAAO,CACHC,QAAS,CACLC,KAAMC,OACNC,QAAS,SAEbC,QAAS,CACLH,KAAMC,OACNC,QAAS,QAEbE,SAAUC,QACVC,WAAYD,QACZE,QAASF,SAEbG,KAAI,KACO,CACHC,eAAgB,KAChBC,iBAAkB,OAG1BC,SAAU,CACNC,mBACQC,KAAKT,SACG,gBAEA,iBAIpBU,QAAS,GAETC,6BACiBF,KAIFG,MAAMC,KACb,CACAC,SAAS,iBANAL,KAMUV,SACnBgB,SAAS,iBAPAN,KAOUd,SACnBK,SARSS,KAQMT,SACfgB,WATSP,KASQP,cAGzBe,YACOR,KAAKH,uBACCA,iBAAiBY,aAEvBT,KAAKJ,qBACCA,eAAea,cAG5BC,SAAW"} {"version":3,"file":"fittext-vue.min.js","sources":["../../src/util/fittext-vue.js"],"sourcesContent":["/*eslint no-unused-vars: warn */\n/*eslint max-len: [\"error\", { \"code\": 160 }] */\n/*eslint-disable no-trailing-spaces */\n/*eslint-env es6*/\n\nimport {calc} from \"./css-calc\";\nimport fitty from \"./fitty\";\nimport {textFit} from \"./textfit\";\n\nexport default {\n install(Vue/*,options*/){\n Vue.component('fittext',{\n props: {\n maxsize: {\n type: String,\n default: \"512px\",\n },\n minsize: {\n type: String,\n default: \"10px\",\n },\n vertical: Boolean,\n singleline: Boolean,\n dynamic: Boolean,\n },\n data() {\n return {\n resizeObserver: null,\n mutationObserver: null,\n };\n },\n computed: {\n rootStyle() {\n if (this.vertical) {\n return `height: 100%;`;\n } else {\n return `width: 100%;`;\n }\n }\n },\n methods: {\n },\n mounted() {\n const self = this;\n // If the content could change after initial presentation,\n // Use the fitty method. It is slightly worse on multiline horizontal text,\n // but better supports content that can change later on.\n fitty(self.$refs.text,\n {\n minSize: calc(self.minsize),\n maxSize: calc(self.maxsize),\n vertical: self.vertical,\n multiline: !self.singleline,\n });\n },\n unmounted() {\n if(this.mutationObserver) {\n this.mutationObserver.disconnect();\n }\n if(this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n },\n template: `\n <div class='q-fittext' ref='container' :style=\"rootStyle + ';min-height:0;min-width:0;'\">\n <span :style=\"'display:block; white-space:'+ ((singleline)?'nowrap':'normal')+';' + rootStyle\" class='q-fittext-text' ref='text'><slot></slot>\n </span\n ></div>\n `,\n });\n },\n};"],"names":["install","Vue","component","props","maxsize","type","String","default","minsize","vertical","Boolean","singleline","dynamic","data","resizeObserver","mutationObserver","computed","rootStyle","this","methods","mounted","$refs","text","minSize","maxSize","multiline","unmounted","disconnect","template"],"mappings":"qSASe,CACXA,QAAQC,KACJA,IAAIC,UAAU,UAAU,CACxBC,MAAO,CACHC,QAAS,CACLC,KAAMC,OACNC,QAAS,SAEbC,QAAS,CACLH,KAAMC,OACNC,QAAS,QAEbE,SAAUC,QACVC,WAAYD,QACZE,QAASF,SAEbG,KAAI,KACO,CACHC,eAAgB,KAChBC,iBAAkB,OAG1BC,SAAU,CACNC,mBACQC,KAAKT,SACG,gBAEA,iBAIpBU,QAAS,GAETC,6BACiBF,KAIFG,MAAMC,KACb,CACAC,SAAS,iBANAL,KAMUV,SACnBgB,SAAS,iBAPAN,KAOUd,SACnBK,SARSS,KAQMT,SACfgB,WATSP,KASQP,cAGzBe,YACOR,KAAKH,uBACCA,iBAAiBY,aAEvBT,KAAKJ,qBACCA,eAAea,cAG5BC,SAAW"}

View File

@ -62,8 +62,8 @@ export default {
} }
}, },
template: ` template: `
<div class='q-fittext' ref='container' :style="rootStyle"> <div class='q-fittext' ref='container' :style="rootStyle + ';min-height:0;min-width:0;'">
<span :style="'display:block; white-space:'+ ((singleline)?'nowrap':'normal')+';'" class='q-fittext-text' ref='text'><slot></slot> <span :style="'display:block; white-space:'+ ((singleline)?'nowrap':'normal')+';' + rootStyle" class='q-fittext-text' ref='text'><slot></slot>
</span </span
></div> ></div>
`, `,

View File

@ -117,12 +117,24 @@ class period {
$pend = $pstart + $ptime; $pend = $pstart + $ptime;
} }
// Continue period numbers if so configured
if (get_config("local_treestudyplan","continueperiodnumberingnewpage")) {
$offset = 0;
foreach (studyplanpage::find_studyplan_children($page->studyplan()) as $p) {
if ($p->id() != $page->id()) {
$offset += $p->periods();
}
}
$displaynr = $periodnr + $offset;
} else {
$displaynr = $periodnr;
}
// And create the period. // And create the period.
$period = self::add([ $period = self::add([
'page_id' => $page->id(), 'page_id' => $page->id(),
'period' => $periodnr, 'period' => $periodnr,
'fullname' => \get_string("period_default_fullname", "local_treestudyplan", $periodnr), 'fullname' => \get_string("period_default_fullname", "local_treestudyplan", $displaynr),
'shortname' => \get_string("period_default_shortname", "local_treestudyplan", $periodnr), 'shortname' => \get_string("period_default_shortname", "local_treestudyplan", $displaynr),
'startdate' => date("Y-m-d", $pstart), 'startdate' => date("Y-m-d", $pstart),
'enddate' => date("Y-m-d", $pend), 'enddate' => date("Y-m-d", $pend),
]); ]);

View File

@ -801,8 +801,9 @@ class studyline {
* Duplicate this studyplan page * Duplicate this studyplan page
* @param studyplan $newstudyplan Studyplan to copy the line into * @param studyplan $newstudyplan Studyplan to copy the line into
* @param array $translation Mapping array of old item ids to new item ids for connection matching * @param array $translation Mapping array of old item ids to new item ids for connection matching
* @param bool $bare Set to true to skip copying contents
*/ */
public function duplicate($newpage, &$translation) : self { public function duplicate($newpage, &$translation,$bare = false) : self {
global $DB; global $DB;
// Clone the database fields. // Clone the database fields.
@ -814,14 +815,16 @@ class studyline {
$id = $DB->insert_record(self::TABLE, (array)$fields); $id = $DB->insert_record(self::TABLE, (array)$fields);
$new = self::find_by_id($id); $new = self::find_by_id($id);
// Next copy all the study items for this studyline. if (!$bare) {
// And record the original and copy id's in the $translation array. // Next copy all the study items for this studyline.
// So the calling function can connect the new studyitems as required. // And record the original and copy id's in the $translation array.
$children = studyitem::find_studyline_children($this); // So the calling function can connect the new studyitems as required.
$translation = []; $children = studyitem::find_studyline_children($this);
foreach ($children as $c) { $translation = [];
$newchild = $c->duplicate($new); foreach ($children as $c) {
$translation[$c->id()] = $newchild->id(); $newchild = $c->duplicate($new);
$translation[$c->id()] = $newchild->id();
}
} }
return $new; return $new;
} }

View File

@ -297,13 +297,39 @@ class studyplanpage {
$page = self::find_by_id($id); // Make sure the new page is immediately cached. $page = self::find_by_id($id); // Make sure the new page is immediately cached.
if (!$bare) { if (!$bare) {
// Add an empty study line
$lineinfo = ['page_id' => $id, if(get_config("local_treestudyplan","copystudylinesnewpage")) {
'name' => get_string("default_line_name","local_treestudyplan"), $templatepage = null;
'shortname' => get_string("default_line_shortname","local_treestudyplan"), $templatelines = [];
"color" => "#DDDDDD", // find the latest a page with lines in the plan
]; $pages = $plan->pages(true);
studyline::add($lineinfo); foreach ($pages as $p) {
if ($p->id() != $id) {
$lines = studyline::find_page_children($p);
if (count($lines) > 0) {
$templatepage = $p;
$templatelines = $lines;
}
}
}
if (isset($templatepage)) {
foreach ($templatelines as $l) {
$map = []; // Bare copy still requires passing an empty array.
$l->duplicate($page,$map,true); // Do bare copy, which does not include line content.
}
}
}
if(count(studyline::find_page_children($page)) == 0) {
// Add an empty study line if there are currently no study lines
$lineinfo = ['page_id' => $id,
'name' => get_string("default_line_name","local_treestudyplan"),
'shortname' => get_string("default_line_shortname","local_treestudyplan"),
"color" => "#DDDDDD",
];
studyline::add($lineinfo);
}
} }
return $page; return $page;

View File

@ -1890,25 +1890,33 @@ body.path-local-treestudyplan .editmode-switch-form > * {
height: 7rem; height: 7rem;
} }
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap { .path-local-treestudyplan .q-header .q-item-heading > .q-wrap {
display: grid; display: flex;
height: 10rem; height: 10rem;
white-space: nowrap; white-space: nowrap;
grid: auto/1em 1fr; flex-direction: column;
overflow: hidden; overflow: hidden;
gap: 2px;
}
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap > * {
min-height: 0;
} }
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-toggle { .path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-toggle {
width: 100%; width: 100%;
line-height: 100%; text-align: center;
} }
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-title { .path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-title {
flex: 1 0 0;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
overflow: hidden; overflow: hidden;
writing-mode: vertical-rl; writing-mode: vertical-rl;
text-orientation: sideways; text-orientation: sideways;
hyphens: auto; hyphens: auto;
padding-top: 2px;
width: 100%; width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 0.5rem;
} }
.path-local-treestudyplan .q-header .q-condition-heading { .path-local-treestudyplan .q-header .q-condition-heading {
text-align: left; text-align: left;

View File

@ -361,6 +361,10 @@ $string["setting_competency_thresh_completed"] = 'Threshold for good (%)';
$string["settingdesc_competency_thresh_completed"] = 'Minimum percentage of proficient competencies for result "Completed'; $string["settingdesc_competency_thresh_completed"] = 'Minimum percentage of proficient competencies for result "Completed';
$string["setting_competency_support_failed"] = 'Support "Failed" result'; $string["setting_competency_support_failed"] = 'Support "Failed" result';
$string["settingdesc_competency_support_failed"] = 'When the course end date has passed, mark course as "Failed" instead of "Progress"'; $string["settingdesc_competency_support_failed"] = 'When the course end date has passed, mark course as "Failed" instead of "Progress"';
$string["setting_copystudylinesnewpage"] = 'Copy study lines of last page to new page';
$string["settingdesc_copystudylinesnewpage"] = 'When creating a new page, fill it with an empty copy of the study lines from the last page.';
$string["setting_continueperiodnumberingnewpage"] = 'Continue periode numbering on new page';
$string["settingdesc_continueperiodnumberingnewpage"] = 'When creating a new page, the default name of the periods will continue the existing sequence (e.g. P5, P6, P7, P8) instead of starting a new sequence (P1, P2, P3, P4)';
$string["grade_include"] = 'Include'; $string["grade_include"] = 'Include';
$string["grade_require"] = 'Require'; $string["grade_require"] = 'Require';

View File

@ -364,6 +364,11 @@ $string["setting_competency_thresh_completed"] = 'Drempelwaarde voor voltooid (%
$string["settingdesc_competency_thresh_completed"] = 'Minimumpercentage behaalde competenties voor "Behaald"'; $string["settingdesc_competency_thresh_completed"] = 'Minimumpercentage behaalde competenties voor "Behaald"';
$string["setting_competency_support_failed"] = 'Onvoldoende ingeschakeld'; $string["setting_competency_support_failed"] = 'Onvoldoende ingeschakeld';
$string["settingdesc_competency_support_failed"] = 'Vink aan om "Onvoldoende" weer te kunnen geven als eind resultaat voor een cursus'; $string["settingdesc_competency_support_failed"] = 'Vink aan om "Onvoldoende" weer te kunnen geven als eind resultaat voor een cursus';
$string["setting_copystudylinesnewpage"] = 'Bestaande leerlijnen overnemen op nieuw tabblad';
$string["settingdesc_copystudylinesnewpage"] = 'Bij aanmaken van een nieuw tabblad wordt een lege kopie van de leerlijnen van het vorige bestaande tabblad overgenomen';
$string["setting_continueperiodnumberingnewpage"] = 'Perioden doornummeren op nieuw tabblad';
$string["settingdesc_continueperiodnumberingnewpage"] = 'Bij aanmaken van een nieuw tabblad, wordt de standaardnaam van perioden doorgenummerd (b.v. P5, P6, P7, P8) in plaats van herstart (P1, P2, P3, P4)';
$string["grade_include"] = 'Doel'; $string["grade_include"] = 'Doel';
$string["grade_require"] = 'Verplicht'; $string["grade_require"] = 'Verplicht';

View File

@ -32,6 +32,7 @@
border-right: 1px solid var(--border-color); border-right: 1px solid var(--border-color);
border-top: 1px solid var(--border-color); border-top: 1px solid var(--border-color);
padding: 0.5rem; padding: 0.5rem;
} }
.q-period-heading, .q-line-heading, .q-item-heading, .q-period-heading, .q-line-heading, .q-item-heading,
@ -75,18 +76,24 @@
height: 7rem; height: 7rem;
} }
.q-item-heading > .q-wrap{ .q-item-heading > .q-wrap{
display: grid; display: flex;
height: 10rem; height: 10rem;
white-space: nowrap; white-space: nowrap;
grid: auto / 1em 1fr; flex-direction: column;
overflow: hidden; overflow: hidden;
gap: 2px;
> * {
min-height: 0;
}
> .q-toggle { > .q-toggle {
width: 100%; width: 100%;
line-height: 100%; text-align: center;
} }
> .q-title { > .q-title {
flex: 1 0 0 ;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
overflow: hidden; overflow: hidden;
@ -94,8 +101,11 @@
text-orientation: sideways; text-orientation: sideways;
hyphens: auto; hyphens: auto;
padding-top: 2px;
width: 100%; width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 0.5rem;
} }
} }

View File

@ -138,9 +138,23 @@ if ($hassiteconfig) {
$page->add(new admin_setting_configcheckbox('local_treestudyplan/toolboxleft', $page->add(new admin_setting_configcheckbox('local_treestudyplan/toolboxleft',
get_string('setting_toolboxleft', 'local_treestudyplan'), get_string('setting_toolboxleft', 'local_treestudyplan'),
get_string('settingdesc_toolboxleft', 'local_treestudyplan'), get_string('settingdesc_toolboxleft', 'local_treestudyplan'),
false, true,
)); ));
//get_config("local_treestudyplan","copystudylinesnewpage")
$page->add(new admin_setting_configcheckbox('local_treestudyplan/copystudylinesnewpage',
get_string('setting_copystudylinesnewpage', 'local_treestudyplan'),
get_string('settingdesc_copystudylinesnewpage', 'local_treestudyplan'),
false,
));
//get_config("local_treestudyplan","continueperiodnumberingnewpage")
$page->add(new admin_setting_configcheckbox('local_treestudyplan/continueperiodnumberingnewpage',
get_string('setting_continueperiodnumberingnewpage', 'local_treestudyplan'),
get_string('settingdesc_continueperiodnumberingnewpage', 'local_treestudyplan'),
false,
));
if (premium::enabled()) { if (premium::enabled()) {
//get_config("local_treestudyplan","enablecoach") //get_config("local_treestudyplan","enablecoach")
$page->add(new admin_setting_configcheckbox('local_treestudyplan/enablecoach', $page->add(new admin_setting_configcheckbox('local_treestudyplan/enablecoach',

View File

@ -1890,25 +1890,33 @@ body.path-local-treestudyplan .editmode-switch-form > * {
height: 7rem; height: 7rem;
} }
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap { .path-local-treestudyplan .q-header .q-item-heading > .q-wrap {
display: grid; display: flex;
height: 10rem; height: 10rem;
white-space: nowrap; white-space: nowrap;
grid: auto/1em 1fr; flex-direction: column;
overflow: hidden; overflow: hidden;
gap: 2px;
}
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap > * {
min-height: 0;
} }
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-toggle { .path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-toggle {
width: 100%; width: 100%;
line-height: 100%; text-align: center;
} }
.path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-title { .path-local-treestudyplan .q-header .q-item-heading > .q-wrap > .q-title {
flex: 1 0 0;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
overflow: hidden; overflow: hidden;
writing-mode: vertical-rl; writing-mode: vertical-rl;
text-orientation: sideways; text-orientation: sideways;
hyphens: auto; hyphens: auto;
padding-top: 2px;
width: 100%; width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 0.5rem;
} }
.path-local-treestudyplan .q-header .q-condition-heading { .path-local-treestudyplan .q-header .q-condition-heading {
text-align: left; text-align: left;