|
| 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> |
0 commit comments