Skip to content

Commit 2c631e7

Browse files
author
Suhas Hariharan
authored
Merge pull request #267 from sas-fossdev/weighting7
added category weighting with hypothetical exemption and assignment
2 parents 8a00b83 + fc354a0 commit 2c631e7

File tree

6 files changed

+682
-0
lines changed

6 files changed

+682
-0
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
<!--
2+
- @copyright Copyright (c) 2020 Advay Ratan <[email protected]>
3+
-
4+
- @copyright Copyright (c) 2021 Suhas Hariharan <[email protected]>
5+
-
6+
- @author Advay Ratan <[email protected]>
7+
-
8+
- @license GNU AGPL version 3 only
9+
-
10+
- SAS Powerschool Enhancement Suite - A browser extension to improve the experience of SAS Powerschool.
11+
-
12+
- This program is free software: you can redistribute it and/or modify
13+
- it under the terms of the GNU Affero General Public License as
14+
- published by the Free Software Foundation, version 3.
15+
-
16+
- This program is distributed in the hope that it will be useful,
17+
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
- GNU Affero General Public License for more details.
20+
-
21+
- You should have received a copy of the GNU Affero General Public License
22+
- along with this program. If not, see <https://www.gnu.org/licenses/>.
23+
-->
24+
25+
<template>
26+
<div id="saspes-categories">
27+
<h3>Category Weighting</h3>
28+
<p>Enter the decimal weighting of each category (from your course syllabus) and use the exemptions / add assignment on the table above to add multiple hypothetical grades. This is a beta feature. For the old view please use the "add single assignment" option.</p>
29+
<table
30+
border="0"
31+
cellpadding="0"
32+
cellspacing="0"
33+
align="center"
34+
style="width: 40%;"
35+
>
36+
<col>
37+
<col style="width: 20%;">
38+
<tbody>
39+
<tr>
40+
<th>Category</th>
41+
<th>Weighting %</th>
42+
</tr>
43+
<tr
44+
v-for="(category, index) in renderWeights"
45+
:key="index"
46+
:bgcolor="(index % 2 == 0) ? '#edf3fe' : '#fff'"
47+
>
48+
<td v-if="category.newc">
49+
<input v-model="category.category" @change="changeCategory(index, category.category)">
50+
<button @click="delCategory(index)">Delete</button>
51+
</td>
52+
<td v-else v-html="category.category" />
53+
<td>
54+
<input
55+
v-model.number="category.weighting"
56+
type="number"
57+
style="width: 85%;"
58+
step="0.1"
59+
>
60+
</td>
61+
</tr>
62+
</tbody>
63+
</table>
64+
<button style="margin-left: 1.6%" @click="addCategory();">
65+
Add Category
66+
</button>
67+
<label v-if="categorySum != 100">Category weightings do not sum to 100%</label>
68+
<button
69+
v-else
70+
@click="saveCategoryWeightingLocal();"
71+
>
72+
Save Weighting
73+
</button>
74+
<h2 v-if="categorySum==100">{{ hypo.grade }} ({{ hypo.fp }})</h2>
75+
<br><br>
76+
<p>Note: Since teachers can adjust the weighting of each assignment as well, this number is not necessarily accurate. In addition, early in the year some categories(i.e the exam category) may contain no grades and the percentages would need to be adjusted accordingly.</p>
77+
</div>
78+
</template>
79+
<script>
80+
import { getSavedCategoryWeighting, saveCategoryWeighting, fpToGrade } from '../helpers';
81+
export default {
82+
name: 'CategoryWeighting',
83+
props: {
84+
categories: {
85+
type: Array,
86+
required: true,
87+
},
88+
gradetable: {
89+
type: Object,
90+
required: true,
91+
},
92+
},
93+
data () {
94+
return {
95+
renderWeights: [],
96+
newCategories: 0,
97+
};
98+
},
99+
computed: {
100+
categorySum () {
101+
if (this.renderWeights.length === 0) return 0;
102+
let sum = 0;
103+
const cm = this.getCategoryMap();
104+
for (const [key, val] of Object.entries(cm)) {
105+
if (val.weighting === "") {
106+
sum += 0;
107+
} else {
108+
sum += val.weighting;
109+
}
110+
}
111+
return Math.round(sum * 100) / 100;
112+
},
113+
hypo () {
114+
if (this.renderWeights.length === 0) return { grade: "F", fp: 0 };
115+
const percent = this.gradetable.calculateGrades(this.getCategoryMap());
116+
return {
117+
grade: fpToGrade(percent),
118+
fp: percent.toFixed(2),
119+
};
120+
},
121+
},
122+
created () {
123+
this.getCatmap();
124+
},
125+
methods: {
126+
async getCatmap () {
127+
let catmap = await getSavedCategoryWeighting();
128+
if (catmap === false) {
129+
catmap = {};
130+
this.categories.sort();
131+
this.categories.forEach((e, i) => {
132+
catmap[e] = { weighting: 0, category: e };
133+
});
134+
}
135+
for (var cat in catmap) {
136+
this.renderWeights.push(catmap[cat]);
137+
}
138+
},
139+
saveCategoryWeightingLocal () {
140+
saveCategoryWeighting(this.getCategoryMap());
141+
},
142+
addCategory () {
143+
this.newCategories++;
144+
const nc = "Category " + this.newCategories;
145+
this.categories.push(nc);
146+
this.renderWeights.push({ weighting: 0, category: nc, newc: true });
147+
},
148+
getCategoryMap () {
149+
const catmap = {};
150+
this.renderWeights.forEach((e, i) => {
151+
catmap[e.category] = e;
152+
});
153+
return catmap;
154+
},
155+
delCategory (i) {
156+
this.gradetable.delCategory(i);
157+
this.renderWeights.splice(i, 1);
158+
this.categories.splice(i, 1);
159+
},
160+
changeCategory (c, nc) {
161+
this.gradetable.changeCategory(this.categories[c], nc);
162+
this.categories[c] = nc;
163+
},
164+
},
165+
};
166+
</script>
167+
<style lang="less" scoped>
168+
#saspes-categories {
169+
border: 1px solid #CCCCCC;
170+
border-radius: 4px;
171+
margin: 10px 20px;
172+
padding: 0;
173+
& h3 {
174+
font-size: 110%;
175+
margin: 0 10px 10px 10px;
176+
padding: 0;
177+
border-top-right-radius: 3px;
178+
border-top-left-radius: 3px;
179+
}
180+
& select {
181+
margin: 0 auto 0 auto;
182+
border-radius: 5px 5px 5px 5px;
183+
}
184+
& label {
185+
vertical-align: initial;
186+
padding-left: 20px;
187+
}
188+
& input {
189+
border-radius: 5px 5px 5px 5px;
190+
padding: 5px;
191+
}
192+
}
193+
</style>

src/js/components/GradeRow.vue

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<!--
2+
- @copyright Copyright (c) 2020 Advay Ratan <[email protected]>
3+
-
4+
- @author Advay Ratan <[email protected]>
5+
-
6+
- @license GNU AGPL version 3 only
7+
-
8+
- SAS Powerschool Enhancement Suite - A browser extension to improve the experience of SAS Powerschool.
9+
-
10+
- This program is free software: you can redistribute it and/or modify
11+
- it under the terms of the GNU Affero General Public License as
12+
- published by the Free Software Foundation, version 3.
13+
-
14+
- This program is distributed in the hope that it will be useful,
15+
- but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
- GNU Affero General Public License for more details.
18+
-
19+
- You should have received a copy of the GNU Affero General Public License
20+
- along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
-->
22+
23+
<template>
24+
<tr :bgcolor="(assignment.id % 2 == 0) ? '#edf3fe' : '#fff'">
25+
<td v-html="assignment.date" />
26+
<td
27+
v-if="!assignment.hypo"
28+
v-html="assignment.category"
29+
/>
30+
<td v-else>
31+
<select v-model="assignment.category">
32+
<option
33+
v-for="category in categories"
34+
:key="category"
35+
:value="category"
36+
>
37+
{{ category }}
38+
</option>
39+
</select>
40+
</td>
41+
<td v-html="assignment.name" />
42+
<td width="14">
43+
<img
44+
v-if="assignment.collected"
45+
src="/images/icon_check.gif"
46+
alt="Collected"
47+
>
48+
</td>
49+
<td width="14">
50+
<img
51+
v-if="assignment.late"
52+
src="/images/icon_late.gif"
53+
alt="Late"
54+
>
55+
</td>
56+
<td width="14">
57+
<img
58+
v-if="assignment.missing"
59+
src="/images/icon_missing.gif"
60+
alt="Missing"
61+
>
62+
</td>
63+
<td width="14">
64+
<img
65+
v-if="assignment.exempt"
66+
src="/images/icon_exempt.gif"
67+
alt="Exempt"
68+
>
69+
</td>
70+
<td width="19">
71+
<img
72+
v-if="assignment.excluded"
73+
src="/images/icon_excluded.gif"
74+
alt="Excluded"
75+
>
76+
</td>
77+
<td align="center">
78+
<span
79+
class="bold-underline"
80+
v-html="assignment.score"
81+
/>
82+
</td>
83+
<td align="center">
84+
&nbsp;
85+
</td>
86+
<td
87+
v-if="!assignment.hypo"
88+
align="center"
89+
v-html="assignment.grade"
90+
/>
91+
<td
92+
v-else
93+
align="center"
94+
>
95+
<select v-model="assignment.grade">
96+
<option
97+
v-for="grade in gradeOptions"
98+
:key="grade"
99+
:value="grade"
100+
>
101+
{{ grade }}
102+
</option>
103+
</select>
104+
</td>
105+
<td
106+
v-if="assignment.userExempt && categoryWeighting"
107+
align="center"
108+
>
109+
<input
110+
v-model="assignment.userExempt"
111+
type="checkbox"
112+
checked
113+
>
114+
</td>
115+
<td
116+
v-else-if="categoryWeighting"
117+
align="center"
118+
>
119+
<input
120+
v-model="assignment.userExempt"
121+
type="checkbox"
122+
>
123+
</td>
124+
</tr>
125+
</template>
126+
<script>
127+
import { avaliableGrades } from '../helpers';
128+
import ClassAssignment from '../models/ClassAssignment';
129+
export default {
130+
name: 'GradeRow',
131+
props: {
132+
assignment: {
133+
type: ClassAssignment,
134+
required: true,
135+
},
136+
categories: {
137+
type: Array,
138+
required: true,
139+
},
140+
categoryWeighting: {
141+
type: Boolean,
142+
required: true,
143+
},
144+
},
145+
data: () => ({
146+
gradeOptions: avaliableGrades,
147+
}),
148+
};
149+
</script>

0 commit comments

Comments
 (0)