sessionInfo.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <template>
  2. <div>
  3. <q-skeleton v-if="classroom.loading"
  4. type="text"
  5. width="200px" />
  6. <breadcrumbs v-else
  7. style="margin-top: 29px; margin-bottom: 19px;" />
  8. <div class="flex justify-end">
  9. <q-btn flat
  10. color="grey"
  11. @click="$router.go(-1)">
  12. بازگشت
  13. >
  14. </q-btn>
  15. </div>
  16. <entity-show v-if="mounted"
  17. v-model:value="sessionInfoInputs"
  18. title="جزییات جلسه"
  19. :api="api"
  20. :show-expand-button="false"
  21. :show-edit-button="false"
  22. :show-index-button="false"
  23. :show-reload-button="false"
  24. :before-load-input-data="beforeLoadInputData">
  25. <template #before-form-builder>
  26. <div class="session-title-and-time-row">
  27. <div class="item">
  28. <div class="icon">
  29. <svg xmlns="http://www.w3.org/2000/svg"
  30. width="18.165"
  31. height="19.91"
  32. viewBox="0 0 18.165 19.91">
  33. <g id="Document"
  34. transform="translate(0)">
  35. <path id="Combined_Shape"
  36. data-name="Combined Shape"
  37. d="M0,14.553v-9.2A4.973,4.973,0,0,1,5.215,0l7.693,0a5.025,5.025,0,0,1,5.257,5.357v9.2a4.973,4.973,0,0,1-5.215,5.354l-7.693,0A5.025,5.025,0,0,1,0,14.553ZM5.22,1.5A3.494,3.494,0,0,0,1.5,5.357v9.2A3.5,3.5,0,0,0,5.256,18.41l7.689,0a3.494,3.494,0,0,0,3.721-3.854v-9.2A3.5,3.5,0,0,0,12.909,1.5ZM5.5,14.973a.75.75,0,1,1,0-1.5h7.22a.75.75,0,1,1,0,1.5Zm0-4.186a.75.75,0,1,1,0-1.5h7.22a.75.75,0,0,1,0,1.5Zm0-4.177a.75.75,0,0,1,0-1.5H8.251a.75.75,0,0,1,0,1.5Z"
  38. transform="translate(0 0)"
  39. fill="#aaa095" />
  40. </g>
  41. </svg>
  42. </div>
  43. <div class="title">
  44. {{ title }}
  45. </div>
  46. </div>
  47. <div class="item">
  48. <div class="icon">
  49. <svg id="Calendar"
  50. xmlns="http://www.w3.org/2000/svg"
  51. width="19.5"
  52. height="21.5"
  53. viewBox="0 0 19.5 21.5">
  54. <path id="Combined_Shape"
  55. data-name="Combined Shape"
  56. d="M5.521,21.5C2.115,21.5,0,19.4,0,16.023V6.973A5,5,0,0,1,4.965,1.6V.75a.75.75,0,0,1,1.5,0v.83h6.578V.75a.75.75,0,0,1,1.5,0V1.6a5.382,5.382,0,0,1,3.532,1.46A5.379,5.379,0,0,1,19.5,6.976V16.1c0,3.332-2.116,5.4-5.522,5.4ZM1.5,16.023C1.5,18.588,2.928,20,5.521,20h8.458C16.572,20,18,18.615,18,16.1V8.9H1.5ZM18,7.4V6.973a3.862,3.862,0,0,0-.987-2.855A3.867,3.867,0,0,0,14.543,3.1v.938a.75.75,0,1,1-1.5,0V3.08H6.466v.961a.75.75,0,0,1-1.5,0V3.1A3.486,3.486,0,0,0,1.5,6.973V7.4Zm-4.553,8.542a.746.746,0,0,1,.745-.75H14.2a.75.75,0,1,1-.754.75Zm-4.437,0a.746.746,0,0,1,.745-.75h.009a.75.75,0,1,1-.754.75Zm-4.448,0a.747.747,0,0,1,.746-.75h.009a.75.75,0,1,1-.755.75Zm8.885-3.886a.747.747,0,0,1,.745-.751H14.2a.75.75,0,1,1-.754.751Zm-4.437,0a.747.747,0,0,1,.745-.751h.009a.75.75,0,1,1-.754.751Zm-4.448,0a.747.747,0,0,1,.746-.751h.009a.75.75,0,1,1-.755.751Z"
  57. transform="translate(0 0)"
  58. fill="#aaa095" />
  59. </svg>
  60. </div>
  61. <div class="title">
  62. شروع:
  63. {{ startingTime }}
  64. </div>
  65. </div>
  66. <div class="item">
  67. <div class="icon">
  68. <svg id="Calendar"
  69. xmlns="http://www.w3.org/2000/svg"
  70. width="19.5"
  71. height="21.5"
  72. viewBox="0 0 19.5 21.5">
  73. <path id="Combined_Shape"
  74. data-name="Combined Shape"
  75. d="M5.521,21.5C2.115,21.5,0,19.4,0,16.023V6.973A5,5,0,0,1,4.965,1.6V.75a.75.75,0,0,1,1.5,0v.83h6.578V.75a.75.75,0,0,1,1.5,0V1.6a5.382,5.382,0,0,1,3.532,1.46A5.379,5.379,0,0,1,19.5,6.976V16.1c0,3.332-2.116,5.4-5.522,5.4ZM1.5,16.023C1.5,18.588,2.928,20,5.521,20h8.458C16.572,20,18,18.615,18,16.1V8.9H1.5ZM18,7.4V6.973a3.862,3.862,0,0,0-.987-2.855A3.867,3.867,0,0,0,14.543,3.1v.938a.75.75,0,1,1-1.5,0V3.08H6.466v.961a.75.75,0,0,1-1.5,0V3.1A3.486,3.486,0,0,0,1.5,6.973V7.4Zm-4.553,8.542a.746.746,0,0,1,.745-.75H14.2a.75.75,0,1,1-.754.75Zm-4.437,0a.746.746,0,0,1,.745-.75h.009a.75.75,0,1,1-.754.75Zm-4.448,0a.747.747,0,0,1,.746-.75h.009a.75.75,0,1,1-.755.75Zm8.885-3.886a.747.747,0,0,1,.745-.751H14.2a.75.75,0,1,1-.754.751Zm-4.437,0a.747.747,0,0,1,.745-.751h.009a.75.75,0,1,1-.754.751Zm-4.448,0a.747.747,0,0,1,.746-.751h.009a.75.75,0,1,1-.755.751Z"
  76. transform="translate(0 0)"
  77. fill="#aaa095" />
  78. </svg>
  79. </div>
  80. <div class="title">
  81. پایان:
  82. {{ endingTime }}
  83. </div>
  84. </div>
  85. </div>
  86. </template>
  87. <template #after-form-builder>
  88. <q-inner-loading :showing="submitAttendanceStatusLoading || submitAssignmentLoading">
  89. <q-spinner-ball color="primary"
  90. size="50px" />
  91. </q-inner-loading>
  92. <template v-if="session.assignment_description">
  93. <q-separator class="q-my-lg" />
  94. <entity-create v-if="submitAttendanceStatusMounted && (!currentUserAttendanceSheet || currentUserAttendanceSheet.assignment_status === null)"
  95. ref="entityCreateSubmitAssignment"
  96. v-model:value="submitAssignmentInputs"
  97. :api="submitAssignmentApi"
  98. :default-layout="false"
  99. :show-expand-button="false"
  100. :show-edit-button="false"
  101. :show-index-button="false"
  102. :show-reload-button="false" />
  103. <entity-show v-if="submitAttendanceStatusMounted && currentUserAttendanceSheet && currentUserAttendanceSheet.assignment_status !== null"
  104. v-model:value="sessionAssignmentInfoInputs"
  105. title="پاسخ کاربر"
  106. :loaded-data="currentUserAttendanceSheet"
  107. :default-layout="false"
  108. :show-expand-button="false"
  109. :show-edit-button="false"
  110. :show-index-button="false"
  111. :show-reload-button="false" />
  112. </template>
  113. <q-separator class="q-my-lg" />
  114. <entity-create v-if="mounted"
  115. ref="entityCreateSubmitAttendanceStatus"
  116. v-model:value="submitAttendanceStatusInputs"
  117. :api="submitAttendanceStatusApi"
  118. :default-layout="false"
  119. :show-expand-button="false"
  120. :show-edit-button="false"
  121. :show-index-button="false"
  122. :show-reload-button="false" />
  123. </template>
  124. </entity-show>
  125. </div>
  126. </template>
  127. <script>
  128. import { shallowRef } from 'vue'
  129. import { Session } from 'src/models/Session.js'
  130. import ShamsiDate from 'src/assets/ShamsiDate.js'
  131. import { APIGateway } from 'src/api/APIGateway.js'
  132. import { Classroom } from 'src/models/Classroom.js'
  133. import { EntityShow, EntityCreate } from 'quasar-crud'
  134. import BtnControl from 'src/components/Control/btn.vue'
  135. import { FormBuilderAssist } from 'quasar-form-builder'
  136. import Breadcrumbs from 'src/components/Widgets/Breadcrumbs/Breadcrumbs.vue'
  137. import { SessionAttendanceSheets } from 'src/models/SessionAttendanceSheets.js'
  138. const BtnControlComp = shallowRef(BtnControl)
  139. export default {
  140. name: 'UserPanel.Profile.SessionInfo',
  141. components: {
  142. EntityShow,
  143. EntityCreate,
  144. Breadcrumbs
  145. },
  146. data () {
  147. const sessionId = parseInt(this.$route.params.id)
  148. return {
  149. classroom: new Classroom(),
  150. session: new Session(),
  151. mounted: false,
  152. api: APIGateway.session.APIAdresses.sessionAndCurrentUserAttendanceSheet(sessionId),
  153. sessionInfoInputs: [
  154. { type: 'inputEditor', name: 'description', responseKey: 'description', label: 'توضیحات', col: 'col-md-12' },
  155. { type: 'separator', name: 'space', size: '1px', col: 'col-md-12' },
  156. { type: 'inputEditor', name: 'syllabus', responseKey: 'syllabus', label: 'مقرری جلسه', col: 'col-md-12' },
  157. { type: 'separator', name: 'space', size: '1px', col: 'col-md-12' },
  158. { type: 'inputEditor', name: 'assignment_description', responseKey: 'assignment_description', label: 'تکلیف جلسه', col: 'col-md-12' },
  159. { type: 'hidden', name: 'title', responseKey: 'title', label: 'نام جلسه', col: 'col-md-1' },
  160. { type: 'hidden', name: 'beginning_time', responseKey: 'beginning_time', label: 'زمان شروع جلسه', col: 'col-md-1' },
  161. { type: 'hidden', name: 'ending_time', responseKey: 'ending_time', label: 'زمان پایان جلسه', col: 'col-md-1' },
  162. { type: 'hidden', name: 'id', responseKey: 'id', label: 'id', col: 'col-md-1' }
  163. ],
  164. submitAttendanceStatusLoading: false,
  165. submitAttendanceStatusInputsReadPart: {
  166. type: 'formBuilder',
  167. name: 'is_read_part',
  168. value: [
  169. { type: 'separator', name: 'space', label: 'مطالعه', className: 'custom-separator', col: 'col-12' },
  170. { type: 'checkbox', name: 'is_read_part1', responseKey: 'is_read_part1', value: false, label: 'نیمه اول را مطالعه کردم', col: 'col-md-12' },
  171. { type: 'checkbox', name: 'is_read_part2', responseKey: 'is_read_part2', value: false, label: 'نیمه دوم را مطالعه کردم', col: 'col-md-12' }
  172. ],
  173. col: 'col-md-4 col-12'
  174. },
  175. submitAttendanceStatusInputsPresentListenPart: {
  176. type: 'formBuilder',
  177. name: 'is_present_listen_part',
  178. value: [
  179. { type: 'separator', name: 'space', label: 'حضور', className: 'custom-separator', col: 'col-12' },
  180. { type: 'checkbox', name: 'is_present_listen_part1', responseKey: 'is_present_listen_part1', value: false, label: 'در نیمه اول حضور داشته‌ام', col: 'col-md-12' },
  181. { type: 'checkbox', name: 'is_present_listen_part2', responseKey: 'is_present_listen_part2', value: false, label: 'در نیمه دوم حضور داشته‌ام', col: 'col-md-12' }
  182. ],
  183. col: 'col-md-4 col-12'
  184. },
  185. submitAttendanceStatusAction: { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'ثبت حضور و غیاب', placeholder: ' ', customClass: 'flex justify-end', atClick: this.submitAttendanceStatus, col: 'col-12' },
  186. submitAttendanceStatusInputs: [
  187. { type: 'hidden', name: 'session', responseKey: 'session', value: sessionId }
  188. ],
  189. submitAttendanceStatusApi: APIGateway.sessionAttendanceSheets.APIAdresses.submitAttendanceStatus,
  190. submitAttendanceStatusMounted: false,
  191. submitAssignmentLoading: false,
  192. submitAssignmentInputs: [
  193. { type: 'InputEditor', name: 'answer_text', responseKey: 'answer_text', label: 'پاسخ به تکلیف', placeholder: ' ', col: 'col-md-12 col-12' },
  194. { type: 'file', name: 'answer_attachment', responseKey: 'answer_attachment', label: 'انتخاب فایل ضمیمه', placeholder: ' ', col: 'col-md-3 col-12' },
  195. { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'ارسال تکلیف', customClass: 'flex justify-end', atClick: this.submitAssignment, col: 'col-md-9 col-12' },
  196. { type: 'hidden', name: 'session', responseKey: 'session', value: sessionId }
  197. ],
  198. submitAssignmentApi: APIGateway.sessionAttendanceSheets.APIAdresses.submitAssignment,
  199. sessionAssignmentInfoInputs: [
  200. { type: 'InputEditor', name: 'answer_text', responseKey: 'answer_text', label: 'پاسخ کاربر', placeholder: ' ', col: 'col-md-12 col-12' },
  201. { type: 'file', name: 'answer_attachment', responseKey: 'answer_attachment', label: 'فایل ضمیمه', placeholder: ' ', col: 'col-md-3 col-12' },
  202. { type: 'select', name: 'assignment_status', responseKey: 'assignment_status', label: 'وضعیت تکلیف', placeholder: ' ', options: (new SessionAttendanceSheets()).assignment_statusEnums, col: 'col-md-3 col-12' },
  203. { type: 'dateTime', name: 'creation_time', responseKey: 'creation_time', label: 'زمان ارسال تکلیف', placeholder: ' ', col: 'col-md-6 col-12' }
  204. ]
  205. }
  206. },
  207. computed: {
  208. title () {
  209. return this.getSessionInfoInputValue('title')
  210. },
  211. endingTime () {
  212. const data = this.getSessionInfoInputValue('ending_time')
  213. if (!data) {
  214. return '-'
  215. }
  216. return ShamsiDate.getDateTime(data)
  217. },
  218. startingTime () {
  219. const data = this.getSessionInfoInputValue('beginning_time')
  220. if (!data) {
  221. return '-'
  222. }
  223. return ShamsiDate.getDateTime(data)
  224. },
  225. currentUserAttendanceSheet () {
  226. if (!this.session?.session_attendance_sheets || this.session.session_attendance_sheets.length === 0) {
  227. return null
  228. }
  229. return this.session.session_attendance_sheets[0]
  230. }
  231. },
  232. mounted() {
  233. this.mounted = true
  234. },
  235. methods: {
  236. updateAttendanceInputs (isDefinedSyllabus, classroomHoldingType) {
  237. this.updateAttendancePresentInputs(classroomHoldingType)
  238. this.updateAttendanceReadInputs(isDefinedSyllabus)
  239. this.updateAttendanceActionBtn(isDefinedSyllabus, classroomHoldingType)
  240. },
  241. updateAttendanceReadInputs (isDefinedSyllabus) {
  242. if (isDefinedSyllabus) {
  243. this.submitAttendanceStatusInputs.unshift(this.submitAttendanceStatusInputsReadPart)
  244. } else {
  245. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_read_part1', value: null })
  246. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_read_part2', value: null })
  247. }
  248. },
  249. updateAttendancePresentInputs (classroomHoldingType) {
  250. if (classroomHoldingType === 'OFFLINE') {
  251. this.submitAttendanceStatusInputs.unshift(this.submitAttendanceStatusInputsPresentListenPart)
  252. FormBuilderAssist.setAttributeByName(this.submitAttendanceStatusInputs, 'is_present_listen_part1', 'label', 'در نیمه اول استماع داشته‌ام')
  253. FormBuilderAssist.setAttributeByName(this.submitAttendanceStatusInputs, 'is_present_listen_part2', 'label', 'در نیمه دوم استماع داشته‌ام')
  254. } else {
  255. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_present_listen_part1', value: null })
  256. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_present_listen_part2', value: null })
  257. }
  258. },
  259. updateAttendanceActionBtn (isDefinedSyllabus, classroomHoldingType) {
  260. if (isDefinedSyllabus || classroomHoldingType === 'OFFLINE') {
  261. this.submitAttendanceStatusInputs.push(this.submitAttendanceStatusAction)
  262. }
  263. },
  264. submitAttendanceStatus () {
  265. this.submitAttendanceStatusLoading = true
  266. this.$refs.entityCreateSubmitAttendanceStatus.createEntity(false)
  267. .then(() => {
  268. this.submitAttendanceStatusLoading = false
  269. })
  270. .catch(() => {
  271. this.submitAttendanceStatusLoading = false
  272. })
  273. },
  274. submitAssignment () {
  275. this.submitAssignmentLoading = true
  276. this.$refs.entityCreateSubmitAssignment.createEntity(false)
  277. .then(() => {
  278. this.submitAssignmentLoading = false
  279. })
  280. .catch(() => {
  281. this.submitAssignmentLoading = false
  282. })
  283. },
  284. updateBreadcrumbs () {
  285. this.$store.commit('AppLayout/updateBreadcrumbs', {
  286. visible: true,
  287. loading: false,
  288. path: [
  289. {
  290. label: 'دوره های من',
  291. to: { name: 'UserPanel.Profile.AllClassrooms' }
  292. },
  293. {
  294. label: this.classroom.title,
  295. to: { name: 'UserPanel.Profile.ClassroomInfo', params: { id: this.classroom.id } }
  296. },
  297. {
  298. label: 'جزییات جلسه',
  299. to: { name: 'UserPanel.Profile.SessionInfo', params: { id: this.$route.params.id } }
  300. }
  301. ]
  302. })
  303. },
  304. getSessionInfoInputValue (name) {
  305. const target = FormBuilderAssist.getInputsByName(this.sessionInfoInputs, name)
  306. if (!target) {
  307. return null
  308. }
  309. return target.value
  310. },
  311. beforeLoadInputData (data) {
  312. this.session = new Session(data)
  313. this.classroom.loading = true
  314. this.submitAttendanceStatusMounted = true
  315. this.getClassInfo(this.session.classroom)
  316. },
  317. getClassInfo (classroomId) {
  318. this.classroom.loading = true
  319. APIGateway.classroom.get(classroomId)
  320. .then(classroom => {
  321. this.classroom = new Classroom(classroom)
  322. this.updateBreadcrumbs()
  323. this.classroom.loading = false
  324. this.updateAttendanceInputs(this.session.is_defined_syllabus, this.classroom.holding_type)
  325. })
  326. .catch(() => {
  327. this.classroom.loading = false
  328. })
  329. }
  330. }
  331. }
  332. </script>
  333. <style lang="scss">
  334. .entity-show {
  335. .session-title-and-time-row {
  336. background-color: #FCF9F4;
  337. margin: -16px;
  338. width: calc( 100% + 32px );
  339. max-width: calc( 100% + 32px );
  340. display: flex;
  341. flex-flow: row;
  342. justify-content: flex-start;
  343. align-items: center;
  344. padding: 16px;
  345. border-bottom: solid 1px #DFE1EC;
  346. margin-bottom: 24px;
  347. .item {
  348. display: flex;
  349. flex-flow: row;
  350. justify-content: flex-start;
  351. width: 25%;
  352. align-items: center;
  353. .icon {
  354. padding-right: 11px;
  355. }
  356. .title {
  357. padding-right: 11px;
  358. }
  359. }
  360. }
  361. }
  362. </style>