SettingsModal.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <template>
  2. <BaseModal :show="stateStore.showingSettings" @close="close">
  3. <h1 class="text-3xl font-bold leading-6 text-gray-900 dark:text-white">
  4. Einstellungen
  5. </h1>
  6. <h2 class="mt-5 text-lg font-bold">Klassen PDF Version</h2>
  7. <div>
  8. <select ref="classVersionSelect" v-model="selectedClassVersion">
  9. <option
  10. v-for="ver in semesterVersions"
  11. :key="ver.key.join('/')"
  12. :value="ver.key"
  13. :disabled="ver.disabled"
  14. >
  15. {{ ver.title }}
  16. </option>
  17. </select>
  18. </div>
  19. <h2 class="mt-5 text-lg font-bold">Studenthub</h2>
  20. <div>
  21. <ul class="text-gray-600 dark:text-gray-400 list-decimal ml-5 md:ml-0">
  22. <li>
  23. Um die Studenthub-Daten zu verwenden, musst du dich zuerst einloggen
  24. <span class="italic"
  25. >(auch wenn der Modulteppich für dich noch nicht funktioniert)</span
  26. >:
  27. <span
  28. class="external-link"
  29. @click="openURLInNewWindow('https://studenthub.technik.fhnw.ch/')"
  30. >Login
  31. <font-awesome-icon icon="fa-solid fa-arrow-up-right-from-square"
  32. /></span>
  33. </li>
  34. <li>
  35. Danach kann die Ausgabe der APIs jeweils in das textfeld darunter
  36. kopiert werden.
  37. </li>
  38. </ul>
  39. <div
  40. class="block my-2"
  41. :class="[studenthubStore.hasSomeStudenthubData ? '' : 'text-gray-200']"
  42. >
  43. <span class="font-bold">Bereits bestandene Module ausblenden: </span>
  44. <input
  45. v-model="hideCompletedClasses"
  46. type="checkbox"
  47. class="inline w-auto ml-2"
  48. :disabled="!studenthubStore.hasSomeStudenthubData"
  49. />
  50. </div>
  51. <div class="mb-1">
  52. <span class="font-bold mr-2">Student JSON:</span>
  53. <span
  54. class="external-link"
  55. @click="
  56. openURLInNewWindow(
  57. 'https://studenthub.technik.fhnw.ch/api/studenthub/student',
  58. )
  59. "
  60. >API öffnen
  61. <font-awesome-icon icon="fa-solid fa-arrow-up-right-from-square"
  62. /></span>
  63. </div>
  64. <textarea
  65. :onchange="studenthubStudentChanged"
  66. :class="[
  67. errors.studenthubStudentParseError ? 'border border-red-500' : '',
  68. ]"
  69. class="font-mono w-full h-32 dark:bg-gray-900 bg-gray-100 p-1 text-xs"
  70. :value="
  71. studenthubStore.student ? JSON.stringify(studenthubStore.student) : ''
  72. "
  73. />
  74. </div>
  75. <div class="mt-2">
  76. <div class="mb-1">
  77. <span class="font-bold mr-2">Anmeldungen JSON:</span>
  78. <span
  79. class="external-link"
  80. @click="
  81. openURLInNewWindow(
  82. 'https://studenthub.technik.fhnw.ch/api/studenthub/anmeldungen',
  83. )
  84. "
  85. >API öffnen
  86. <font-awesome-icon icon="fa-solid fa-arrow-up-right-from-square"
  87. /></span>
  88. </div>
  89. <textarea
  90. :onchange="studenthubApplicationsChanged"
  91. :class="[
  92. errors.studenthubApplicationsParseError
  93. ? 'border border-red-500'
  94. : '',
  95. ]"
  96. class="font-mono w-full h-32 dark:bg-gray-900 bg-gray-100 p-1 text-xs"
  97. :value="
  98. studenthubStore.applications
  99. ? JSON.stringify(studenthubStore.applications)
  100. : ''
  101. "
  102. />
  103. </div>
  104. </BaseModal>
  105. </template>
  106. <script lang="ts">
  107. import { openURLInNewWindow } from "../../helpers";
  108. import { useClassesStore } from "../../stores/classes";
  109. import { useClassVersionStore } from "../../stores/ClassVersion";
  110. import { useConfigStore } from "../../stores/config";
  111. import { usePlanningStore } from "../../stores/planning";
  112. import { useStateStore } from "../../stores/state";
  113. import { useStudenthubStore } from "../../stores/studenthub";
  114. import BaseModal from "./BaseModal.vue";
  115. type SemesterVersionEntry = {
  116. disabled: boolean;
  117. title: string;
  118. key: [string, string];
  119. };
  120. export default {
  121. name: "SettingsModal",
  122. components: { BaseModal },
  123. setup() {
  124. const studenthubStore = useStudenthubStore();
  125. const stateStore = useStateStore();
  126. const classVersionStore = useClassVersionStore();
  127. const configStore = useConfigStore();
  128. const classesStore = useClassesStore();
  129. const planningStore = usePlanningStore();
  130. return {
  131. studenthubStore,
  132. stateStore,
  133. classVersionStore,
  134. configStore,
  135. classesStore,
  136. planningStore,
  137. openURLInNewWindow,
  138. };
  139. },
  140. data() {
  141. return {
  142. errors: {
  143. studenthubApplicationsParseError: false,
  144. studenthubStudentParseError: false,
  145. },
  146. };
  147. },
  148. computed: {
  149. hideCompletedClasses: {
  150. get(): boolean {
  151. return this.stateStore.hideCompletedClasses;
  152. },
  153. set(value: boolean) {
  154. this.stateStore.updateHideCompletedClasses(value);
  155. },
  156. },
  157. selectedClassVersion: {
  158. get(): [string, string] {
  159. const selected = this.classVersionStore;
  160. return [selected.semester ?? "", selected.version ?? ""];
  161. },
  162. set(value: [string, string]) {
  163. if (this.planningStore.chosen.length > 0) {
  164. const isSure = confirm(
  165. "Es ist keine gute Idee die Version des Stundenplans zu ändern, währendem dieser Module eingetragen hat.\n\n" +
  166. "Mache einen neuen, leeren Plan oder nimm in kauf, dass deine geplanten Module verschwinden.\n\n" +
  167. "Willst du trotzdem fortfahren?",
  168. );
  169. if (!isSure) {
  170. if (this.$refs.classVersionSelect)
  171. // @ts-expect-error The value prop exists here, no worries :)
  172. this.$refs.classVersionSelect.value = this.selectedClassVersion;
  173. return;
  174. }
  175. }
  176. const semester = value[0];
  177. const version = value[1];
  178. useClassVersionStore().useSemesterVersion(semester, version);
  179. this.planningStore.saveChosen();
  180. this.classVersionStore.useSemesterVersion(semester, version);
  181. },
  182. },
  183. semesterVersions(): SemesterVersionEntry[] {
  184. const out = [] as SemesterVersionEntry[];
  185. this.classVersionStore.semesterVersions.forEach((sem) => {
  186. out.push({ disabled: true, title: sem.semester, key: ["", ""] });
  187. sem.versions.forEach((version) =>
  188. out.push({
  189. disabled: false,
  190. title: `(${sem.semester}) ${version}`,
  191. key: [sem.semester, version],
  192. }),
  193. );
  194. });
  195. return out;
  196. },
  197. },
  198. methods: {
  199. close() {
  200. this.stateStore.showingSettings = false;
  201. },
  202. studenthubApplicationsChanged(event: Event) {
  203. const raw = (event.target as HTMLInputElement).value as string;
  204. this.errors.studenthubApplicationsParseError = false;
  205. if (raw.length == 0) {
  206. this.studenthubStore.setApplicationsData(null);
  207. return;
  208. }
  209. let parsed;
  210. try {
  211. parsed = JSON.parse(raw);
  212. } catch (e) {
  213. this.studenthubStore.setApplicationsData(null);
  214. this.errors.studenthubApplicationsParseError = true;
  215. console.error(e);
  216. return;
  217. }
  218. if (parsed === undefined) {
  219. this.studenthubStore.setApplicationsData(null);
  220. this.errors.studenthubApplicationsParseError = true;
  221. return;
  222. }
  223. this.studenthubStore.setApplicationsData(parsed);
  224. },
  225. studenthubStudentChanged(event: Event) {
  226. const raw = (event.target as HTMLInputElement).value as string;
  227. this.errors.studenthubStudentParseError = false;
  228. if (raw.length == 0) {
  229. this.studenthubStore.setStudentData(null);
  230. return;
  231. }
  232. let parsed;
  233. try {
  234. parsed = JSON.parse(raw);
  235. } catch (e) {
  236. this.studenthubStore.setStudentData(null);
  237. this.errors.studenthubStudentParseError = true;
  238. console.error(e);
  239. return;
  240. }
  241. if (parsed === undefined) {
  242. this.studenthubStore.setStudentData(null);
  243. this.errors.studenthubStudentParseError = true;
  244. return;
  245. }
  246. this.studenthubStore.setStudentData(parsed);
  247. },
  248. },
  249. };
  250. </script>