sessionInfo.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. <entity-create v-if="submitAttendanceStatusMounted"
  93. ref="entityCreateSubmitAssignment"
  94. v-model:value="submitAssignmentInputs"
  95. :api="submitAssignmentApi"
  96. :default-layout="false"
  97. :show-expand-button="false"
  98. :show-edit-button="false"
  99. :show-index-button="false"
  100. :show-reload-button="false" />
  101. <q-separator class="q-my-lg" />
  102. <entity-create v-if="mounted"
  103. ref="entityCreateSubmitAttendanceStatus"
  104. v-model:value="submitAttendanceStatusInputs"
  105. :api="submitAttendanceStatusApi"
  106. :default-layout="false"
  107. :show-expand-button="false"
  108. :show-edit-button="false"
  109. :show-index-button="false"
  110. :show-reload-button="false" />
  111. </template>
  112. </entity-show>
  113. </div>
  114. </template>
  115. <script>
  116. import { shallowRef } from 'vue'
  117. import { Session } from 'src/models/Session.js'
  118. import ShamsiDate from 'src/assets/ShamsiDate.js'
  119. import { APIGateway } from 'src/api/APIGateway.js'
  120. import { Classroom } from 'src/models/Classroom.js'
  121. import { EntityShow, EntityCreate } from 'quasar-crud'
  122. import BtnControl from 'src/components/Control/btn.vue'
  123. import { FormBuilderAssist } from 'quasar-form-builder'
  124. import Breadcrumbs from 'src/components/Widgets/Breadcrumbs/Breadcrumbs.vue'
  125. const BtnControlComp = shallowRef(BtnControl)
  126. export default {
  127. name: 'UserPanel.Profile.SessionInfo',
  128. components: {
  129. EntityShow,
  130. EntityCreate,
  131. Breadcrumbs
  132. },
  133. data () {
  134. const sessionId = parseInt(this.$route.params.id)
  135. return {
  136. classroom: new Classroom(),
  137. session: new Session(),
  138. mounted: false,
  139. submitAttendanceStatusMounted: false,
  140. api: APIGateway.session.APIAdresses.byId(sessionId),
  141. sessionInfoInputs: [
  142. { type: 'inputEditor', name: 'description', responseKey: 'description', label: 'توضیحات', col: 'col-md-12' },
  143. { type: 'separator', name: 'space', size: '1px', col: 'col-md-12' },
  144. { type: 'inputEditor', name: 'syllabus', responseKey: 'syllabus', label: 'مقرری جلسه', col: 'col-md-12' },
  145. { type: 'separator', name: 'space', size: '1px', col: 'col-md-12' },
  146. { type: 'inputEditor', name: 'assignment_description', responseKey: 'assignment_description', label: 'تکلیف جلسه', col: 'col-md-12' },
  147. { type: 'hidden', name: 'title', responseKey: 'title', label: 'نام جلسه', col: 'col-md-1' },
  148. { type: 'hidden', name: 'beginning_time', responseKey: 'beginning_time', label: 'زمان شروع جلسه', col: 'col-md-1' },
  149. { type: 'hidden', name: 'ending_time', responseKey: 'ending_time', label: 'زمان پایان جلسه', col: 'col-md-1' },
  150. { type: 'hidden', name: 'id', responseKey: 'id', label: 'id', col: 'col-md-1' }
  151. ],
  152. submitAttendanceStatusLoading: false,
  153. submitAttendanceStatusInputsReadPart: {
  154. type: 'formBuilder',
  155. name: 'is_read_part',
  156. value: [
  157. { type: 'separator', name: 'space', label: 'مطالعه', className: 'custom-separator', col: 'col-12' },
  158. { type: 'checkbox', name: 'is_read_part1', responseKey: 'is_read_part1', value: false, label: 'نیمه اول را مطالعه کردم', col: 'col-md-12' },
  159. { type: 'checkbox', name: 'is_read_part2', responseKey: 'is_read_part2', value: false, label: 'نیمه دوم را مطالعه کردم', col: 'col-md-12' }
  160. ],
  161. col: 'col-md-4 col-12'
  162. },
  163. submitAttendanceStatusInputsPresentListenPart: {
  164. type: 'formBuilder',
  165. name: 'is_present_listen_part',
  166. value: [
  167. { type: 'separator', name: 'space', label: 'حضور', className: 'custom-separator', col: 'col-12' },
  168. { type: 'checkbox', name: 'is_present_listen_part1', responseKey: 'is_present_listen_part1', value: false, label: 'در نیمه اول حضور داشته‌ام', col: 'col-md-12' },
  169. { type: 'checkbox', name: 'is_present_listen_part2', responseKey: 'is_present_listen_part2', value: false, label: 'در نیمه دوم حضور داشته‌ام', col: 'col-md-12' }
  170. ],
  171. col: 'col-md-4 col-12'
  172. },
  173. submitAttendanceStatusAction: { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'ثبت حضور و غیاب', placeholder: ' ', customClass: 'flex justify-end', atClick: this.submitAttendanceStatus, col: 'col-12' },
  174. submitAttendanceStatusInputs: [
  175. { type: 'hidden', name: 'session', responseKey: 'session', value: sessionId }
  176. ],
  177. submitAttendanceStatusApi: APIGateway.sessionAttendanceSheets.APIAdresses.submitAttendanceStatus,
  178. submitAssignmentLoading: false,
  179. submitAssignmentInputs: [
  180. { type: 'InputEditor', name: 'answer_text', responseKey: 'answer_text', label: 'پاسخ به تکلیف', col: 'col-md-12 col-12' },
  181. { type: 'file', name: 'answer_attachment', responseKey: 'answer_attachment', label: 'انتخاب فایل ضمیمه', col: 'col-md-3 col-12' },
  182. { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'ارسال تکلیف', customClass: 'flex justify-end', atClick: this.submitAssignment, col: 'col-md-9 col-12' },
  183. { type: 'hidden', name: 'session', responseKey: 'session', value: sessionId }
  184. ],
  185. submitAssignmentApi: APIGateway.sessionAttendanceSheets.APIAdresses.submitAssignment
  186. }
  187. },
  188. computed: {
  189. title () {
  190. return this.getSessionInfoInputValue('title')
  191. },
  192. endingTime () {
  193. const data = this.getSessionInfoInputValue('ending_time')
  194. if (!data) {
  195. return '-'
  196. }
  197. return ShamsiDate.getDateTime(data)
  198. },
  199. startingTime () {
  200. const data = this.getSessionInfoInputValue('beginning_time')
  201. if (!data) {
  202. return '-'
  203. }
  204. return ShamsiDate.getDateTime(data)
  205. }
  206. },
  207. mounted() {
  208. this.mounted = true
  209. },
  210. methods: {
  211. updateAttendanceInputs (isDefinedSyllabus, classroomHoldingType) {
  212. this.updateAttendancePresentInputs(classroomHoldingType)
  213. this.updateAttendanceReadInputs(isDefinedSyllabus)
  214. this.updateAttendanceActionBtn(isDefinedSyllabus, classroomHoldingType)
  215. },
  216. updateAttendanceReadInputs (isDefinedSyllabus) {
  217. if (isDefinedSyllabus) {
  218. this.submitAttendanceStatusInputs.unshift(this.submitAttendanceStatusInputsReadPart)
  219. } else {
  220. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_read_part1', value: null })
  221. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_read_part2', value: null })
  222. }
  223. },
  224. updateAttendancePresentInputs (classroomHoldingType) {
  225. if (classroomHoldingType === 'OFFLINE') {
  226. this.submitAttendanceStatusInputs.unshift(this.submitAttendanceStatusInputsPresentListenPart)
  227. } else {
  228. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_present_listen_part1', value: null })
  229. this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_present_listen_part2', value: null })
  230. }
  231. },
  232. updateAttendanceActionBtn (isDefinedSyllabus, classroomHoldingType) {
  233. if (isDefinedSyllabus || classroomHoldingType === 'OFFLINE') {
  234. this.submitAttendanceStatusInputs.push(this.submitAttendanceStatusAction)
  235. }
  236. },
  237. submitAttendanceStatus () {
  238. this.submitAttendanceStatusLoading = true
  239. this.$refs.entityCreateSubmitAttendanceStatus.createEntity(false)
  240. .then(() => {
  241. this.submitAttendanceStatusLoading = false
  242. })
  243. .catch(() => {
  244. this.submitAttendanceStatusLoading = false
  245. })
  246. },
  247. submitAssignment () {
  248. this.submitAssignmentLoading = true
  249. this.$refs.entityCreateSubmitAssignment.createEntity(false)
  250. .then(() => {
  251. this.submitAssignmentLoading = false
  252. })
  253. .catch(() => {
  254. this.submitAssignmentLoading = false
  255. })
  256. },
  257. updateBreadcrumbs () {
  258. this.$store.commit('AppLayout/updateBreadcrumbs', {
  259. visible: true,
  260. loading: false,
  261. path: [
  262. {
  263. label: 'دوره های من',
  264. to: { name: 'UserPanel.Profile.AllClassrooms' }
  265. },
  266. {
  267. label: this.classroom.title,
  268. to: { name: 'UserPanel.Profile.ClassroomInfo', params: { id: this.classroom.id } }
  269. },
  270. {
  271. label: 'جزییات جلسه',
  272. to: { name: 'UserPanel.Profile.SessionInfo', params: { id: this.$route.params.id } }
  273. }
  274. ]
  275. })
  276. },
  277. getSessionInfoInputValue (name) {
  278. const target = FormBuilderAssist.getInputsByName(this.sessionInfoInputs, name)
  279. if (!target) {
  280. return null
  281. }
  282. return target.value
  283. },
  284. beforeLoadInputData (data) {
  285. this.session = new Session(data)
  286. this.classroom.loading = true
  287. this.getClassInfo(this.session.classroom)
  288. },
  289. getClassInfo (classroomId) {
  290. this.classroom.loading = true
  291. APIGateway.classroom.get(classroomId)
  292. .then(classroom => {
  293. this.classroom = new Classroom(classroom)
  294. this.updateBreadcrumbs()
  295. this.classroom.loading = false
  296. this.submitAttendanceStatusMounted = true
  297. this.updateAttendanceInputs(this.session.is_defined_syllabus, this.classroom.holding_type)
  298. })
  299. .catch(() => {
  300. this.classroom.loading = false
  301. })
  302. }
  303. }
  304. }
  305. </script>
  306. <style lang="scss">
  307. .entity-show {
  308. .session-title-and-time-row {
  309. background-color: #FCF9F4;
  310. margin: -16px;
  311. width: calc( 100% + 32px );
  312. max-width: calc( 100% + 32px );
  313. display: flex;
  314. flex-flow: row;
  315. justify-content: flex-start;
  316. align-items: center;
  317. padding: 16px;
  318. border-bottom: solid 1px #DFE1EC;
  319. margin-bottom: 24px;
  320. .item {
  321. display: flex;
  322. flex-flow: row;
  323. justify-content: flex-start;
  324. width: 25%;
  325. align-items: center;
  326. .icon {
  327. padding-right: 11px;
  328. }
  329. .title {
  330. padding-right: 11px;
  331. }
  332. }
  333. }
  334. }
  335. </style>