ClassRow.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <template>
  2. <tr
  3. class="row"
  4. :class="[rowStyling]"
  5. >
  6. <td @click="showModuleInformation">
  7. <span class="class-name">{{ cls.name }}</span>
  8. </td>
  9. <td @click="showModuleInformation">
  10. <span> {{ cls.executionTime }}</span>
  11. </td>
  12. <td @click="showModuleInformation">
  13. <span>{{ cls.class }}</span>
  14. </td>
  15. <td
  16. class="hidden md:table-cell"
  17. @click="showModuleInformation"
  18. >
  19. <span
  20. v-for="teacher in cls.teachers"
  21. :key="teacher"
  22. class="block"
  23. >{{
  24. teacher
  25. }}</span>
  26. </td>
  27. <td
  28. class="hidden md:table-cell"
  29. @click="showModuleInformation"
  30. >
  31. <span
  32. v-for="room in cls.rooms"
  33. :key="room"
  34. class="block"
  35. >{{
  36. room
  37. }}</span>
  38. </td>
  39. <td @click="showModuleInformation">
  40. <TeachingTypeIcon :teaching-type="cls.teaching_type" />
  41. </td>
  42. <td
  43. class="hidden xl:table-cell"
  44. @click="showModuleInformation"
  45. >
  46. <span>{{ cls.module?.hasMSP === true ? "Ja" : "" }}</span>
  47. </td>
  48. <td class="cursor-default">
  49. <button
  50. :title="addRemoveClassTitle(cls.module, classChosen)"
  51. class="action-button"
  52. :disabled="cls.module?.hasCompleted || cls.module?.maxAttemptsReached"
  53. @click="toggleClassState"
  54. >
  55. <font-awesome-icon
  56. v-if="addable"
  57. icon="fa-solid fa-plus"
  58. />
  59. <font-awesome-icon
  60. v-else
  61. icon="fa-solid fa-minus"
  62. />
  63. </button>
  64. <a
  65. title="Klassen PDF in einem neuem Tab öffnen"
  66. target="_blank"
  67. :href="classesPDFLink(cls)"
  68. >
  69. <button
  70. class="action-button"
  71. title="Klassen PDF in einem neuem Tab öffnen"
  72. >
  73. <!-- I just gave up styling the link... -->
  74. <font-awesome-icon icon="fa-solid fa-file-pdf" />
  75. </button>
  76. </a>
  77. </td>
  78. </tr>
  79. </template>
  80. <script lang="ts">
  81. import { usePlanningStore } from "../../stores/planning";
  82. import {
  83. classesPDFLink,
  84. dayMap,
  85. toTime,
  86. addRemoveClassTitle,
  87. rowStyling,
  88. } from "../../helpers";
  89. import { ClassSelectorColumn, TeachingType } from "../../types";
  90. import { PropType } from "vue";
  91. import { useStudenthubStore } from "../../stores/studenthub";
  92. import { useStateStore } from "../../stores/state";
  93. import TeachingTypeIcon from "./TeachingTypeIcon.vue";
  94. import { TaughtClass } from "../../api/types/semesters/versions/class";
  95. export default {
  96. name: "ClassRow",
  97. components: { TeachingTypeIcon },
  98. props: {
  99. cls: {
  100. required: true,
  101. type: Object as PropType<TaughtClass>,
  102. },
  103. applyRowClass: {
  104. required: false,
  105. type: Boolean,
  106. default: true,
  107. },
  108. },
  109. setup() {
  110. const planningStore = usePlanningStore();
  111. const studenthubStore = useStudenthubStore();
  112. const stateStore = useStateStore();
  113. return {
  114. planningStore,
  115. studenthubStore,
  116. stateStore,
  117. toTime,
  118. classesPDFLink,
  119. addRemoveClassTitle,
  120. dayMap,
  121. ClassSelectorColumn,
  122. TeachingType,
  123. };
  124. },
  125. data() {
  126. return {
  127. currentPageIdx: 0,
  128. inspectingClass: null as TaughtClass | null,
  129. };
  130. },
  131. computed: {
  132. classChosen(): boolean {
  133. return this.planningStore.isModuleChosen(this.cls);
  134. },
  135. addable(): boolean {
  136. return !this.classChosen || (this.cls.module?.hasCompleted ?? false);
  137. },
  138. rowStyling(): string {
  139. return rowStyling(this.cls.module);
  140. },
  141. },
  142. methods: {
  143. showModuleInformation() {
  144. this.stateStore.inspectingClass = this.cls;
  145. },
  146. toggleClassState() {
  147. if (this.classChosen) this.planningStore.remove(this.cls);
  148. else this.planningStore.add(this.cls);
  149. },
  150. },
  151. };
  152. </script>
  153. <style scoped>
  154. .row {
  155. @apply border-b
  156. cursor-pointer
  157. dark:border-gray-500
  158. hover:bg-slate-200
  159. dark:hover:bg-gray-700
  160. transition-all
  161. duration-100;
  162. }
  163. .module-table .row td {
  164. @apply border-x border-gray-300 dark:border-gray-500 h-11;
  165. }
  166. .action-button {
  167. @apply rounded-lg
  168. aspect-square
  169. inline-block
  170. w-6
  171. text-xs
  172. md:w-8
  173. md:text-base
  174. hover:bg-gray-300
  175. active:bg-gray-300
  176. dark:hover:bg-gray-500
  177. dark:active:bg-gray-600
  178. mx-0.5
  179. transition-all
  180. duration-200
  181. disabled:hover:bg-inherit
  182. disabled:text-gray-300
  183. disabled:dark:text-gray-500;
  184. }
  185. </style>