Implemented progress option on studyplan card

This commit is contained in:
PMKuipers 2023-10-23 23:19:14 +02:00
parent c6882b916a
commit 1975952c8f
14 changed files with 454 additions and 128 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

@ -27,7 +27,8 @@ export default {
open: "open",
noenddate: "noenddate",
idnumber: "studyplan_idnumber",
description: "studyplan_description"
description: "studyplan_description",
completed: "completed",
}
});
// Create new eventbus for interaction between item components
@ -40,7 +41,7 @@ export default {
},
open: {
type: Boolean
}
},
},
data() {
return {
@ -72,6 +73,27 @@ export default {
else {
return this.text.noenddate;
}
},
width_completed() {
if(this.value.progress) {
return this.value.progress * 100;
} else {
return 0;
}
},
width_incomplete() {
if(this.value.progress) {
return (1-this.value.progress) * 100;
} else {
return 100;
}
},
percentage_complete() {
if(this.value.progress) {
return Math.round(this.value.progress * 100) + "%";
} else {
return "0%";
}
}
},
methods: {
@ -84,14 +106,37 @@ export default {
:class="'s-studyplan-card timing-' + timing"
>
<template #header></template>
<b-card-title>
<a v-if='open' href='#' @click.prevent='onOpenClick($event)'>{{value.name}}</a>
<template v-else>{{value.name}}</template>
<slot name='title'></slot>
</b-card-title>
<div class='s-studyplan-card-icon'><img :src='value.icon' style="width: 64px; height: 64px;"></div>
<div class='s-studyplan-card-idnumber' v-if='value.idnumber'><i>{{ text.idnumber}}:</i> {{ value.idnumber }}</div>
<div class='s-studyplan-card-content'>
<div class='s-studyplan-card-icon'><img :src='value.icon'></div>
<div class='s-studyplan-card-info'>
<div class='s-studyplan-card-titlebar'>
<b-card-title>
<a v-if='open' href='#' @click.prevent='onOpenClick($event)'>{{value.name}}</a>
<template v-else>{{value.name}}</template>
</b-card-title>
<div class='s-studyplan-card-titleslot'><slot name='title'></slot></div>
</div>
<div class='s-studyplan-card-idnumber' v-if='value.idnumber'>
{{ text.idnumber }}: {{ value.idnumber }}
</div>
<div class='s-studyplan-card-progress' v-if='value.progress !== undefined && value.progress !== null'>
<div class="s-studyplan-card-progressbar"
><span v-if="width_completed > 0"
:style="{width: width_completed+'%'}"
class='s-studyplan-card-progress-segment s-studyplan-card-progress-completed'
></span
><span :style="{width: width_incomplete+'%'}"
class='s-studyplan-card-progress-segment s-studyplan-card-progress-incomplete'
></span
></div>
<div class="s-studyplan-card-progresstext">
{{ percentage_complete}} {{ text.completed.toLowerCase() }}
</div>
</div>
</div>
</div>
<slot></slot>
<template #footer>
<span :class="'t-timing-'+timing" v-html="startdate + ' - '+ enddate"></span>

View File

@ -526,7 +526,7 @@ class studyitem {
* @param int $userid User id
* @return int completion:: constant
*/
private function completion($userid) : int {
public function completion($userid) : int {
global $DB;
if ($this->valid()) {

View File

@ -221,6 +221,7 @@ class studyplan {
"aggregation_config" => new \external_value(PARAM_TEXT, 'config string for aggregator'),
"aggregation_info" => aggregator::basic_structure(),
"pages" => new \external_multiple_structure(studyplanpage::simple_structure(), 'pages'),
"progress" => new \external_value(PARAM_FLOAT,"fraction of completed modules",VALUE_OPTIONAL),
], 'Basic studyplan info', $value);
}
@ -247,6 +248,8 @@ class studyplan {
'aggregation_config' => $this->aggregator->config_string(),
'aggregation_info' => $this->aggregator->basic_model(),
'pages' => $pages,
// Next line is for development debugging only.
"progress" => (\rand(0,100) / 100),
];
}
@ -623,6 +626,7 @@ class studyplan {
"description" => new \external_value(PARAM_RAW, 'description of studyplan'),
"descriptionformat" => new \external_value(PARAM_INT, 'description format'),
"icon" => new \external_value(PARAM_RAW,'icon for this plan'),
"progress" => new \external_value(PARAM_FLOAT,"fraction of completed modules"),
"idnumber" => new \external_value(PARAM_TEXT, 'idnumber of curriculum'),
"pages" => new \external_multiple_structure(studyplanpage::user_structure()),
"aggregation_info" => aggregator::basic_structure(),
@ -630,6 +634,21 @@ class studyplan {
}
/**
* Scan user progress (completed modules) over all pages for a specific user
* @param int $userid ID of user to check for
* @return float Fraction of completion
*/
private function scanuserprogress($userid) {
$progress = 0;
$pages = $this->pages();
foreach ($pages as $p) {
$progress += $p->scanuserprogress($userid);
}
// Now average it out over the amount of pages
$progress = $progress / count($pages);
}
/**
* Webservice model for user info
* @param int $userid ID of user to check specific info for
@ -645,6 +664,7 @@ class studyplan {
'descriptionformat' => $this->r->descriptionformat,
'icon' => $this->icon(),
'idnumber' => $this->r->idnumber,
'progress' => $this->scanuserprogress($userid),
'pages' => [],
'aggregation_info' => $this->aggregator->basic_model(),
];

View File

@ -335,6 +335,29 @@ class studyplanpage {
return $model;
}
/**
* Scan user progress (completed modules) over this page for a specific user
* @param int $userid ID of user to check for
* @return float Fraction of completion
*/
public function scanuserprogress($userid) {
$courses = 0;
$completed = 0;
foreach (studyline::find_page_children($this) as $line) {
$items = studyitem::find_studyline_children($line);
foreach ($items as $c) {
if (in_array($c->type(), studyline::COURSE_TYPES)) {
$courses += 1;
if($c->completion($userid) >= completion::COMPLETED){
$completed += 1;
}
}
}
}
return ($completed/$courses);
}
/**
* Find list of pages belonging to a specified study plan
* @param studyplan $plan Studyplan to search pages for

View File

@ -1178,45 +1178,6 @@
.features-treestudyplan .r-completion-bar-ungraded {
background-color: var(--warning);
}
.path-local-treestudyplan .card.s-studyplan-card,
.features-treestudyplan .card.s-studyplan-card {
min-width: 300px;
max-width: 500px;
margin-bottom: 1em;
}
.path-local-treestudyplan .card.s-studyplan-card.timing-past .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-past .card-header {
background-color: var(--past);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-present .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-present .card-header {
background-color: var(--present);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-future .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-future .card-header {
background-color: var(--future);
}
.path-local-treestudyplan .s-studyplan-card-title-buttons,
.features-treestudyplan .s-studyplan-card-title-buttons {
font-size: 16px;
float: right;
}
.path-local-treestudyplan .s-studyplan-card-title-buttons > *,
.features-treestudyplan .s-studyplan-card-title-buttons > * {
margin-left: 0.2em;
margin-right: 0.3em;
}
.path-local-treestudyplan .s-studyplan-card-buttons,
.features-treestudyplan .s-studyplan-card-buttons {
float: right;
display: flex;
align-items: center;
justify-content: right;
}
.path-local-treestudyplan .s-studyplan-card-buttons > *,
.features-treestudyplan .s-studyplan-card-buttons > * {
margin-left: 1em;
}
.path-local-treestudyplan .s-studyplan-associate-window .custom-select,
.features-treestudyplan .s-studyplan-associate-window .custom-select {
width: 100%;
@ -1334,6 +1295,121 @@
border-color: #aaa;
}
.path-local-treestudyplan .card.s-studyplan-card,
.features-treestudyplan .card.s-studyplan-card {
min-width: 300px;
max-width: 500px;
margin-bottom: 1em;
}
.path-local-treestudyplan .card.s-studyplan-card.timing-past .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-past .card-header {
background-color: var(--past);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-present .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-present .card-header {
background-color: var(--present);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-future .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-future .card-header {
background-color: var(--future);
}
.path-local-treestudyplan .s-studyplan-card-title-buttons,
.features-treestudyplan .s-studyplan-card-title-buttons {
font-size: 16px;
float: right;
}
.path-local-treestudyplan .s-studyplan-card-title-buttons > *,
.features-treestudyplan .s-studyplan-card-title-buttons > * {
margin-left: 0.2em;
margin-right: 0.3em;
}
.path-local-treestudyplan .s-studyplan-card-buttons,
.features-treestudyplan .s-studyplan-card-buttons {
float: right;
display: flex;
align-items: center;
justify-content: right;
}
.path-local-treestudyplan .s-studyplan-card-buttons > *,
.features-treestudyplan .s-studyplan-card-buttons > * {
margin-left: 1em;
}
.path-local-treestudyplan .s-studyplan-card-content,
.features-treestudyplan .s-studyplan-card-content {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
gap: 20px;
height: 100%;
}
.path-local-treestudyplan .s-studyplan-card-icon img,
.features-treestudyplan .s-studyplan-card-icon img {
width: 64px;
height: 64px;
}
.path-local-treestudyplan .s-studyplan-card-titlebar,
.features-treestudyplan .s-studyplan-card-titlebar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
gap: 5px;
}
.path-local-treestudyplan .s-studyplan-card-titlebuttons,
.features-treestudyplan .s-studyplan-card-titlebuttons {
margin-left: auto;
}
.path-local-treestudyplan .s-studyplan-card-info,
.features-treestudyplan .s-studyplan-card-info {
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.path-local-treestudyplan .s-studyplan-card-info > :last-child,
.features-treestudyplan .s-studyplan-card-info > :last-child {
margin-top: auto;
}
.path-local-treestudyplan .s-studyplan-card-progressbar,
.features-treestudyplan .s-studyplan-card-progressbar {
width: calc(100% - 2px);
height: 16px;
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment {
display: inline-block;
height: 10px;
border-top: solid;
border-bottom: solid;
border-color: var(--info);
border-width: 1px;
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:first-child,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
border-left: 1px solid var(--info);
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:last-child,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-right: 1px solid var(--info);
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-completed,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-completed {
background-color: var(--info);
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-incomplete,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-incomplete {
background-color: var(--light);
}
.path-local-treestudyplan .s-studyplan-card-progresstext,
.features-treestudyplan .s-studyplan-card-progresstext {
font-size: 80%;
color: var(--gray);
}
.path-local-treestudyplan .b-modal-justify-footer-between .modal-footer,
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
justify-content: space-between;

View File

@ -87,6 +87,9 @@ $string["setting_navigation_heading"] = 'Navigation';
$string["settingdesc_navigation_heading"] = 'Navigation menu configuration';
$string["setting_primary_nav_autofill"] = 'Automatically fill <i>custom menu items</i>';
$string["settingdesc_primary_nav_autofill"] = 'To show the studyplan links in the primary navigation menu (especially in moodle 4.x), lines have to be added to the setting <b>Appearance</b>&nbsp;-&nbsp;<b>Theme&nbsp;settings</b>&nbsp;-&nbsp;<b>Custom&nbsp;menu&nbsp;items</b>.<br>Disable this feature here if you do not want this, e.g. if your theme (up to moodle 3.11) uses flat navigation.';
$string["setting_defaulticon"] = 'Default studyplan image';
$string["settingdesc_defaulticon"] = 'Configure default image to show for a study plans if no specific image is set';
$string["settingspage_csync"] = 'Synchronize linked cohorts and users to courses';
$string["setting_csync_heading"] = 'Automatically create a cohort sync in all courses linked to a study plan for all cohorts linked to a study plan';
@ -103,15 +106,18 @@ $string["setting_csync_remember_manual_csync_field"] = 'Remember existing cohort
$string["settingdesc_csync_remember_manual_csync_field"] = 'Mark cohort syncs that were manually created earlier, so they won\'t be removed during autosync if cohorts are removed from the studyplan';
$string["setting_csync_users_field"] = 'Enroll linked users';
$string["settingdesc_csync_users_field"] = 'Also enrol all users that are explicitly linked to a study plan in that study plan\'s courses.';
$string["autocohortsync_name"] = 'Study plan automatic cohort sync cascading';
$string["refreshteacherlist_name"] = "Refresh teacher's study plan list";
$string["studyplan_add"] = 'Add study plan';
$string["studyplan_edit"] = 'Edit study plan';
$string["studyplan_remove"] = 'Remove study plan';
$string["studyplan_confirm_remove"] = 'Are you sure you want to remove study plan {$a}?';
$string["studyplan_name"] = 'Full name';
$string["studyplan_name_ph"] = '';
$string["studyplan_icon"] = "Image for this studyplan";
$string["studyplan_context"] = 'Category';
$string["studyplan_shortname"] = 'Short name';
$string["studyplan_shortname_ph"] = '';

View File

@ -82,6 +82,8 @@ $string["setting_navigation_heading"] = 'Navigatie';
$string["settingdesc_navigation_heading"] = 'Instellingen voor navigatie';
$string["setting_primary_nav_autofill"] = '<i>Aangepast menu items</i> automatisch aanvullen';
$string["settingdesc_primary_nav_autofill"] = 'Om in het primaire navigatiemenu de studieplan links te tonen (vooral in Moodle 4.x), moeten regels worden toegevoegd in <b>Uiterlijk</b>&nbsp;-&nbsp;<b>Thema&nbsp;instellingen</b>&nbsp;<b>Aangepast&nbsp;menu&nbsp;items</b><br>Zet deze functie hier uit als dat niet gewenst is, b.v. als je Moodle (3.11 of lager) thema flat navigation gebruikt.';
$string["setting_defaulticon"] = 'Standaard afbeelding foor studieplan';
$string["settingdesc_defaulticon"] = 'Stel standaard afbeelding in om weer te geven als een studieplan geen eigen afbeelding heeft ingesteld';
$string["setting_display_heading"] = 'Weergave';
$string["settingdesc_display_heading"] = 'Configuratie voor de weergave van de studieplannen';
@ -112,6 +114,7 @@ $string["studyplan_remove"] = 'Studieplan verwijderen';
$string["studyplan_confirm_remove"] = 'Weet je zeker dat je studieplan {$a} wilt verwijderen?';
$string["studyplan_name"] = 'Volledige Naam';
$string["studyplan_name_ph"] = '';
$string["studyplan_icon"] = "Afbeelding for this studyplan";
$string["studyplan_context"] = 'Categorie';
$string["studyplan_shortname"] = 'Korte naam';
$string["studyplan_shortname_ph"] = '';

View File

@ -1011,43 +1011,6 @@
background-color: var(--warning);
}
.card.s-studyplan-card {
min-width: 300px;
max-width: 500px;
margin-bottom: 1em;
}
.card.s-studyplan-card.timing-past .card-header {
background-color: var(--past);
}
.card.s-studyplan-card.timing-present .card-header {
background-color: var(--present);
}
.card.s-studyplan-card.timing-future .card-header {
background-color: var(--future);
}
.s-studyplan-card-title-buttons {
font-size: 16px /*12pt*/;
float: right;
}
.s-studyplan-card-title-buttons > * {
margin-left: 0.2em;
margin-right: 0.3em;
}
.s-studyplan-card-buttons {
float: right;
display: flex;
align-items: center;
justify-content: right;
}
.s-studyplan-card-buttons > * {
margin-left: 1em;
}
.s-studyplan-associate-window .custom-select {
width: 100%;
max-width: 100%;

113
scss/studyplancard.scss Normal file
View File

@ -0,0 +1,113 @@
.path-local-treestudyplan, .features-treestudyplan {
.card.s-studyplan-card {
min-width: 300px;
max-width: 500px;
margin-bottom: 1em;
}
.card.s-studyplan-card.timing-past .card-header {
background-color: var(--past);
}
.card.s-studyplan-card.timing-present .card-header {
background-color: var(--present);
}
.card.s-studyplan-card.timing-future .card-header {
background-color: var(--future);
}
.s-studyplan-card-title-buttons {
font-size: 16px /*12pt*/;
float: right;
}
.s-studyplan-card-title-buttons > * {
margin-left: 0.2em;
margin-right: 0.3em;
}
.s-studyplan-card-buttons {
float: right;
display: flex;
align-items: center;
justify-content: right;
}
.s-studyplan-card-buttons > * {
margin-left: 1em;
}
.s-studyplan-card-content {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
gap: 20px;
height: 100%;
}
.s-studyplan-card-icon {
img {
width: 64px;
height: 64px;
}
}
.s-studyplan-card-titlebar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
gap: 5px;
}
.s-studyplan-card-titlebuttons {
margin-left: auto;
}
.s-studyplan-card-info {
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
> :last-child {
margin-top: auto;
}
}
.s-studyplan-card-progressbar {
width: calc(100% - 2px);
height: 16px;
.s-studyplan-card-progress-segment {
display: inline-block;
height: 10px;
border-top: solid;
border-bottom: solid;
border-color: var(--info);
border-width: 1px;
&:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
border-left: 1px solid var(--info);
}
&:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-right: 1px solid var(--info);
}
}
.s-studyplan-card-progress-completed {
background-color: var(--info);
}
.s-studyplan-card-progress-incomplete {
background-color: var(--light);
}
}
.s-studyplan-card-progresstext {
font-size: 80%;
color: var(--gray);
}
}

View File

@ -2,4 +2,5 @@
@import "generic.scss";
@import "invitemanager.scss";
@import "studyplan.scss";
@import "studyplancard.scss";
@import "bootstraptweaking.scss";

View File

@ -57,7 +57,7 @@ if ($hassiteconfig) {
// Default image for study plans
$page->add(new admin_setting_configstoredfile('local_treestudyplan/defaulticon',
get_string('setting_defaulticon', 'local_treestudyplan'),
get_string('setting_defaulticon_desc', 'local_treestudyplan'),
get_string('settingdesc_defaulticon', 'local_treestudyplan'),
'defaulticon', 0,
[
'maxfiles' => 1,

View File

@ -1178,45 +1178,6 @@
.features-treestudyplan .r-completion-bar-ungraded {
background-color: var(--warning);
}
.path-local-treestudyplan .card.s-studyplan-card,
.features-treestudyplan .card.s-studyplan-card {
min-width: 300px;
max-width: 500px;
margin-bottom: 1em;
}
.path-local-treestudyplan .card.s-studyplan-card.timing-past .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-past .card-header {
background-color: var(--past);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-present .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-present .card-header {
background-color: var(--present);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-future .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-future .card-header {
background-color: var(--future);
}
.path-local-treestudyplan .s-studyplan-card-title-buttons,
.features-treestudyplan .s-studyplan-card-title-buttons {
font-size: 16px;
float: right;
}
.path-local-treestudyplan .s-studyplan-card-title-buttons > *,
.features-treestudyplan .s-studyplan-card-title-buttons > * {
margin-left: 0.2em;
margin-right: 0.3em;
}
.path-local-treestudyplan .s-studyplan-card-buttons,
.features-treestudyplan .s-studyplan-card-buttons {
float: right;
display: flex;
align-items: center;
justify-content: right;
}
.path-local-treestudyplan .s-studyplan-card-buttons > *,
.features-treestudyplan .s-studyplan-card-buttons > * {
margin-left: 1em;
}
.path-local-treestudyplan .s-studyplan-associate-window .custom-select,
.features-treestudyplan .s-studyplan-associate-window .custom-select {
width: 100%;
@ -1334,6 +1295,121 @@
border-color: #aaa;
}
.path-local-treestudyplan .card.s-studyplan-card,
.features-treestudyplan .card.s-studyplan-card {
min-width: 300px;
max-width: 500px;
margin-bottom: 1em;
}
.path-local-treestudyplan .card.s-studyplan-card.timing-past .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-past .card-header {
background-color: var(--past);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-present .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-present .card-header {
background-color: var(--present);
}
.path-local-treestudyplan .card.s-studyplan-card.timing-future .card-header,
.features-treestudyplan .card.s-studyplan-card.timing-future .card-header {
background-color: var(--future);
}
.path-local-treestudyplan .s-studyplan-card-title-buttons,
.features-treestudyplan .s-studyplan-card-title-buttons {
font-size: 16px;
float: right;
}
.path-local-treestudyplan .s-studyplan-card-title-buttons > *,
.features-treestudyplan .s-studyplan-card-title-buttons > * {
margin-left: 0.2em;
margin-right: 0.3em;
}
.path-local-treestudyplan .s-studyplan-card-buttons,
.features-treestudyplan .s-studyplan-card-buttons {
float: right;
display: flex;
align-items: center;
justify-content: right;
}
.path-local-treestudyplan .s-studyplan-card-buttons > *,
.features-treestudyplan .s-studyplan-card-buttons > * {
margin-left: 1em;
}
.path-local-treestudyplan .s-studyplan-card-content,
.features-treestudyplan .s-studyplan-card-content {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
gap: 20px;
height: 100%;
}
.path-local-treestudyplan .s-studyplan-card-icon img,
.features-treestudyplan .s-studyplan-card-icon img {
width: 64px;
height: 64px;
}
.path-local-treestudyplan .s-studyplan-card-titlebar,
.features-treestudyplan .s-studyplan-card-titlebar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
gap: 5px;
}
.path-local-treestudyplan .s-studyplan-card-titlebuttons,
.features-treestudyplan .s-studyplan-card-titlebuttons {
margin-left: auto;
}
.path-local-treestudyplan .s-studyplan-card-info,
.features-treestudyplan .s-studyplan-card-info {
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
}
.path-local-treestudyplan .s-studyplan-card-info > :last-child,
.features-treestudyplan .s-studyplan-card-info > :last-child {
margin-top: auto;
}
.path-local-treestudyplan .s-studyplan-card-progressbar,
.features-treestudyplan .s-studyplan-card-progressbar {
width: calc(100% - 2px);
height: 16px;
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment {
display: inline-block;
height: 10px;
border-top: solid;
border-bottom: solid;
border-color: var(--info);
border-width: 1px;
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:first-child,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
border-left: 1px solid var(--info);
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:last-child,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-segment:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
border-right: 1px solid var(--info);
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-completed,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-completed {
background-color: var(--info);
}
.path-local-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-incomplete,
.features-treestudyplan .s-studyplan-card-progressbar .s-studyplan-card-progress-incomplete {
background-color: var(--light);
}
.path-local-treestudyplan .s-studyplan-card-progresstext,
.features-treestudyplan .s-studyplan-card-progresstext {
font-size: 80%;
color: var(--gray);
}
.path-local-treestudyplan .b-modal-justify-footer-between .modal-footer,
.features-treestudyplan .b-modal-justify-footer-between .modal-footer {
justify-content: space-between;