classroomInfo.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  1. <template>
  2. <breadcrumbs style="margin-top: 29px; margin-bottom: 19px;" />
  3. <div class="flex justify-end">
  4. <q-btn flat
  5. color="grey"
  6. @click="$router.go(-1)">
  7. بازگشت
  8. >
  9. </q-btn>
  10. </div>
  11. <q-card>
  12. <q-tabs v-model="tab"
  13. dense
  14. class="text-grey"
  15. active-color="primary"
  16. indicator-color="primary"
  17. align="justify"
  18. narrow-indicator>
  19. <q-tab name="classroomInfo"
  20. label="اطلاعات دوره آموزشی" />
  21. <q-tab v-if="canShowOtherTabsOfClassroom"
  22. name="educations"
  23. label="جدول آموزشی" />
  24. <q-tab v-if="canShowOtherTabsOfClassroom"
  25. name="team"
  26. label="گروه" />
  27. <q-tab v-if="canShowOtherTabsOfClassroom"
  28. name="tests"
  29. label="آزمون" />
  30. <q-tab v-if="canShowOtherTabsOfClassroom"
  31. name="projects"
  32. label="پروژه" />
  33. <q-tab v-if="canShowOtherTabsOfClassroom && classroom.live_streaming_url"
  34. name="live_streaming_url"
  35. label="بخش آنلاین" />
  36. </q-tabs>
  37. <q-separator />
  38. <q-tab-panels v-model="tab"
  39. animated>
  40. <q-tab-panel name="classroomInfo">
  41. <div v-if="mounted && classroom.current_user_register_info.transcript_sheet_info.status"
  42. :class="getTranscriptSheetStatusClass()"
  43. class="q-pa-md q-mb-md">
  44. <div class="row q-col-gutter-md">
  45. <div class="col-md-6 col-12">
  46. نمره حضور و غیاب: {{ classroom.current_user_register_info.transcript_sheet_info.attendance_score }}
  47. <br>
  48. نمره آزمون: {{ classroom.current_user_register_info.transcript_sheet_info.highest_test_score }}
  49. <br>
  50. نمره نهایی: {{ classroom.current_user_register_info.transcript_sheet_info.final_score }}
  51. </div>
  52. <div class="col-md-6 col-12">
  53. وضعیت نهایی: {{ getTranscriptSheetStatus(classroom.current_user_register_info.transcript_sheet_info) }}
  54. <br>
  55. <q-badge :color="classroom.current_user_register_info.transcript_sheet_info.is_sent_by_post ? 'green' : 'red'"
  56. outline>
  57. <template v-if="classroom.current_user_register_info.transcript_sheet_info.is_sent_by_post">
  58. ارسال شده با پست
  59. </template>
  60. <template v-else>
  61. پست نشده است
  62. </template>
  63. </q-badge>
  64. <br>
  65. <a v-if="classroom.current_user_register_info.transcript_sheet_info.certification"
  66. :href="classroom.current_user_register_info.transcript_sheet_info.certification"
  67. target="_blank">
  68. <q-btn outline
  69. color="primary">
  70. دانلود مدرک
  71. </q-btn>
  72. </a>
  73. </div>
  74. </div>
  75. </div>
  76. <show-classroom-info v-if="mounted"
  77. :options="{ profileMode: true }"
  78. @onloadn="onloadnClassroom" />
  79. </q-tab-panel>
  80. <q-tab-panel name="educations"
  81. class="q-pa-none">
  82. <entity-index v-if="mounted"
  83. ref="entityIndex"
  84. v-model:value="sessionsInputs"
  85. title="لیست جلسات"
  86. :api="sessionsApi"
  87. :table="sessionsTable"
  88. :table-keys="sessionsTableKeys"
  89. :table-grid-size="$q.screen.lt.sm"
  90. :show-expand-button="false"
  91. :show-reload-button="false"
  92. :show-search-button="false">
  93. <template #entity-index-table-cell="{inputData}">
  94. <template v-if="inputData.col.name === 'number'">
  95. {{ inputData.rowNumber }}
  96. </template>
  97. <template v-else-if="inputData.col.name === 'action'">
  98. <q-btn size="md"
  99. color="primary"
  100. label="جزییات"
  101. :to="{name: 'UserPanel.Profile.SessionInfo', params: {id: inputData.props.row.id}}" />
  102. </template>
  103. <template v-else>
  104. {{ inputData.col.value }}
  105. </template>
  106. </template>
  107. <template #entity-index-table-item-cell="{inputData}">
  108. <entity-index-grid-item :input-data="inputData">
  109. <template #col="{col, row}">
  110. <template v-if="col.name === 'number'">
  111. {{ inputData.rowNumber }}
  112. </template>
  113. <template v-else-if="col.name === 'action'">
  114. <q-btn size="md"
  115. color="primary"
  116. label="جزییات"
  117. :to="{name: 'UserPanel.Profile.SessionInfo', params: {id: row.id}}" />
  118. </template>
  119. </template>
  120. </entity-index-grid-item>
  121. </template>
  122. </entity-index>
  123. </q-tab-panel>
  124. <q-tab-panel name="team"
  125. class="q-pa-none">
  126. <entity-index v-if="mounted"
  127. ref="teamsList"
  128. v-model:value="teamsListInputs"
  129. title="لیست گروه ها"
  130. :api="teamsListApi"
  131. :table="teamsListTable"
  132. :table-keys="teamsListTableKeys"
  133. :show-search-button="false"
  134. :show-reload-button="false"
  135. :show-expand-button="false">
  136. <template v-slot:entity-index-table-cell="{inputData}">
  137. <template v-if="inputData.col.name === 'number'">
  138. {{ inputData.rowNumber }}
  139. </template>
  140. <template v-else-if="inputData.col.name === 'action'">
  141. <div class="action-column-entity-index">
  142. <q-btn size="md"
  143. outline
  144. color="primary"
  145. label="مشاهده اعضا"
  146. class="q-mr-md"
  147. @click="showTeamMembers(inputData.props.row)" />
  148. <q-btn size="md"
  149. color="primary"
  150. :flat="inputData.props.row.join_status !== 'ENABLED'"
  151. :disable="inputData.props.row.join_status !== 'ENABLED'"
  152. :label="getTeamJoinStatusLabel(inputData.props.row)"
  153. class="q-mr-md"
  154. :loading="joinTeamLoading"
  155. @click="joinTeam(inputData.props.row)" />
  156. </div>
  157. </template>
  158. <template v-else>
  159. {{ inputData.col.value }}
  160. </template>
  161. </template>
  162. </entity-index>
  163. <q-skeleton v-else
  164. type="rect"
  165. height="200px" />
  166. <q-dialog v-model="teamInfoDialog"
  167. class="team-info-dialog">
  168. <q-card class="team-info-dialog-card">
  169. <q-card-section class="team-info-dialog-title-section flex justify-between">
  170. <div>
  171. جزییات -
  172. {{ selectedTeam.title }}
  173. </div>
  174. <q-btn v-close-popup
  175. icon="close"
  176. flat
  177. round
  178. dense />
  179. </q-card-section>
  180. <q-separator />
  181. <q-card-section class="team-info-dialog-form-section">
  182. <div class="team-description q-mb-lg">
  183. <div class="q-mb-md">
  184. توضیحات:
  185. </div>
  186. <div v-html="selectedTeam.description" />
  187. </div>
  188. <div v-if="selectedTeam.leader_info"
  189. class="team-description q-mb-lg">
  190. <div class="q-mb-md">
  191. سرگروه:
  192. </div>
  193. <div class="row">
  194. <div class="col-md-3 col-12">
  195. {{ selectedTeam.leader_info.firstname }}
  196. {{ selectedTeam.leader_info.lastname }}
  197. </div>
  198. <div class="col-md-9 col-12">
  199. <span class="q-mr-sm">
  200. شماره تماس:
  201. </span>
  202. {{ selectedTeam.leader_info.mobile_number }}
  203. </div>
  204. </div>
  205. </div>
  206. </q-card-section>
  207. <q-separator />
  208. <div class="quasar-crud-index-table">
  209. <div class="full-width flex justify-between items-center q-pa-md">
  210. <div class="text-h6">اعضا</div>
  211. <q-btn size="md"
  212. color="primary"
  213. :flat="selectedTeam.join_status !== 'ENABLED'"
  214. :disable="selectedTeam.join_status !== 'ENABLED'"
  215. :label="getTeamJoinStatusLabel(selectedTeam)"
  216. class="q-mr-md"
  217. :loading="joinTeamLoading"
  218. @click="joinTeam(selectedTeam)" />
  219. </div>
  220. <q-table title="اعضا"
  221. hide-pagination
  222. :pagination="{
  223. rowsPerPage:0
  224. }"
  225. :rows="selectedTeamMemberRows"
  226. :columns="selectedTeamMemberColumns"
  227. row-key="name">
  228. <template #body-cell-number="props">
  229. <q-td>
  230. {{ props.rowIndex + 1 }}
  231. </q-td>
  232. </template>
  233. </q-table>
  234. </div>
  235. </q-card>
  236. </q-dialog>
  237. </q-tab-panel>
  238. <q-tab-panel name="tests"
  239. class="q-pa-none">
  240. <entity-index v-if="mounted"
  241. ref="entityIndex"
  242. v-model:value="testListInputs"
  243. title="آزمون ها"
  244. :api="testListApi"
  245. :table="testListTable"
  246. :table-keys="testListTableKeys"
  247. :table-grid-size="$q.screen.lt.sm"
  248. :show-expand-button="false"
  249. :show-reload-button="false"
  250. :show-search-button="false">
  251. <template #entity-index-table-cell="{inputData}">
  252. <template v-if="inputData.col.name === 'number'">
  253. {{ inputData.rowNumber }}
  254. </template>
  255. <template v-else-if="inputData.col.name === 'action'">
  256. <q-btn v-if="inputData.props.row.is_enabled_attending"
  257. size="md"
  258. color="primary"
  259. label="شرکت در آزمون"
  260. :to="{name: 'UserPanel.Test.AnswerBook.Confirmation', params: {test_id: inputData.props.row.test, answer_book_id: inputData.props.row.id}}" />
  261. <q-btn v-if="inputData.props.row.is_enabled_continuing"
  262. size="md"
  263. color="primary"
  264. label="ادامه آزمون"
  265. @click="showParticipateTypeDialog(inputData.props.row.test, inputData.props.row.id)" />
  266. <q-btn v-if="inputData.props.row.is_enabled_objecting"
  267. size="md"
  268. color="primary"
  269. label="ثبت اعتراض"
  270. :to="{name: 'UserPanel.Test.AnswerBook.Show', params: {test_id: inputData.props.row.test, answer_book_id: inputData.props.row.id}, query: { send_objection: 1}}" />
  271. <q-btn v-if="inputData.props.row.is_enabled_viewing"
  272. size="md"
  273. color="primary"
  274. label="مشاهده"
  275. :to="{name: 'UserPanel.Test.AnswerBook.Show', params: {test_id: inputData.props.row.test, answer_book_id: inputData.props.row.id}}" />
  276. </template>
  277. <template v-else>
  278. {{ inputData.col.value }}
  279. </template>
  280. </template>
  281. <template #entity-index-table-item-cell="{inputData}">
  282. <entity-index-grid-item :input-data="inputData">
  283. <template #col="{col, row}">
  284. <template v-if="col.name === 'number'">
  285. {{ inputData.rowNumber }}
  286. </template>
  287. <template v-else-if="col.name === 'action'">
  288. <q-btn v-if="row.is_enabled_attending"
  289. size="md"
  290. color="primary"
  291. label="شرکت در آزمون"
  292. :to="{name: 'UserPanel.Test.AnswerBook.Confirmation', params: {test_id: row.test, answer_book_id: row.id}}" />
  293. <q-btn v-if="row.is_enabled_continuing"
  294. size="md"
  295. color="primary"
  296. label="ادامه آزمون"
  297. @click="showParticipateTypeDialog(row.test, row.id)" />
  298. <q-btn v-if="row.is_enabled_objecting"
  299. size="md"
  300. color="primary"
  301. label="ثبت اعتراض"
  302. :to="{name: 'UserPanel.Test.AnswerBook.Show', params: {test_id: row.test, answer_book_id: row.id}, query: { send_objection: 1}}" />
  303. <q-btn v-if="row.is_enabled_viewing"
  304. size="md"
  305. color="primary"
  306. label="مشاهده"
  307. :to="{name: 'UserPanel.Test.AnswerBook.Show', params: {test_id: row.test, answer_book_id: row.id}}" />
  308. </template>
  309. </template>
  310. </entity-index-grid-item>
  311. </template>
  312. </entity-index>
  313. <q-skeleton v-else
  314. type="rect"
  315. height="200px" />
  316. <q-dialog v-model="participateTypeDialog">
  317. <q-card>
  318. <q-card-actions>
  319. نحوه پاسخ به آزمون
  320. </q-card-actions>
  321. <q-separator />
  322. <q-card-actions>
  323. <div>
  324. اندیشه جوی عزیز لطفا نحوه پاسخ به سوالات آزمون را مشخص کنید
  325. </div>
  326. <div>
  327. <q-radio v-model="participateType"
  328. val="UserPanel.Test.AnswerBook.Participate.AllQuestions"
  329. label="مایلم پاسخ سوالات را به صورت یک فایل جامع بارگذاری کنم" />
  330. <q-radio v-model="participateType"
  331. val="UserPanel.Test.AnswerBook.Participate.SingleQuestion"
  332. label="مایلم پاسخ سوالات را به صورت جداگانه ذیل همان سوال وارد کنم" />
  333. </div>
  334. </q-card-actions>
  335. <q-card-actions>
  336. <q-btn v-close-popup
  337. outline
  338. label="انصراف از آزمون"
  339. color="red" />
  340. <q-btn :disable="!participateType"
  341. label="تایید و شروع آزمون"
  342. color="primary"
  343. @click="startTest" />
  344. </q-card-actions>
  345. </q-card>
  346. </q-dialog>
  347. </q-tab-panel>
  348. <q-tab-panel name="projects"
  349. class="q-pa-none">
  350. <entity-index v-if="mounted"
  351. ref="projectList"
  352. v-model:value="projectListInputs"
  353. title="لیست پروژه ها"
  354. :api="projectListApi"
  355. :table="projectListTable"
  356. :table-keys="projectListTableKeys"
  357. :show-search-button="false"
  358. :show-reload-button="false"
  359. :show-expand-button="false">
  360. <template v-slot:entity-index-table-cell="{inputData}">
  361. <template v-if="inputData.col.name === 'number'">
  362. {{ inputData.rowNumber }}
  363. </template>
  364. <template v-else-if="inputData.col.name === 'actions'">
  365. <div class="action-column-entity-index">
  366. <q-btn size="md"
  367. color="primary"
  368. label="جزییات"
  369. :to="{name: 'UserPanel.Profile.Classroom.Project.Show', params: {classroom_id: $route.params.id, project_id: inputData.props.row.id}}"
  370. class="q-mr-md" />
  371. </div>
  372. </template>
  373. <template v-else>
  374. {{ inputData.col.value }}
  375. </template>
  376. </template>
  377. </entity-index>
  378. <q-skeleton v-else
  379. type="rect"
  380. height="200px" />
  381. </q-tab-panel>
  382. <q-tab-panel v-if="classroom.live_streaming_url"
  383. name="live_streaming_url">
  384. <q-btn class="full-width q-mb-lg"
  385. color="primary"
  386. @click="goToLiveStreamUrl">
  387. رفتن به کلاس
  388. </q-btn>
  389. <q-banner>
  390. <div class="q-mb-md">
  391. نام کاربری اسکای روم:
  392. {{ user.national_code }}
  393. </div>
  394. <div>
  395. کلمه عبور اسکای روم:
  396. 1234
  397. </div>
  398. </q-banner>
  399. <iframe :src="classroom.live_streaming_url"
  400. title="W3Schools Free Online Web Tutorials"
  401. style="height: 80vh"
  402. class="full-width" />
  403. </q-tab-panel>
  404. </q-tab-panels>
  405. </q-card>
  406. </template>
  407. <script>
  408. import { EntityIndex } from 'quasar-crud'
  409. import { Team } from 'src/models/Team.js'
  410. import { Test } from 'src/models/Test.js'
  411. import Enums from 'src/assets/Enums/Enums.js'
  412. import { mixinAuth } from 'src/mixin/Mixins.js'
  413. import ShamsiDate from 'src/assets/ShamsiDate.js'
  414. import { APIGateway } from 'src/api/APIGateway.js'
  415. import { Classroom } from 'src/models/Classroom.js'
  416. import { AnswerBook } from 'src/models/AnswerBook.js'
  417. import { FormBuilderAssist } from 'quasar-form-builder'
  418. import EntityIndexGridItem from 'src/components/EntityIndexGridItem.vue'
  419. import { Registration, RegistrationList } from 'src/models/Registration.js'
  420. import Breadcrumbs from 'src/components/Widgets/Breadcrumbs/Breadcrumbs.vue'
  421. import { ProjectAttendanceSheets } from 'src/models/ProjectAttendanceSheets.js'
  422. import { SessionAttendanceSheets } from 'src/models/SessionAttendanceSheets.js'
  423. import ShowClassroomInfo from 'src/components/Widgets/Other/ShowClassroomInfo/ShowClassroomInfo.vue'
  424. import { TranscriptSheet } from 'src/models/TranscriptSheet'
  425. export default {
  426. name: 'UserPanel.Profile.ClassroomInfo',
  427. components: {
  428. EntityIndex,
  429. Breadcrumbs,
  430. ShowClassroomInfo,
  431. EntityIndexGridItem
  432. },
  433. mixins: [mixinAuth],
  434. data () {
  435. const classroomId = this.$route.params.id
  436. // const userId = this.$store.getters['Auth/user'].id
  437. return {
  438. mounted: false,
  439. teamInfoDialog: false,
  440. selectedTeam: null,
  441. selectedTest: {
  442. testId: null,
  443. answerBookId: null
  444. },
  445. participateTypeDialog: false,
  446. participateType: null,
  447. tab: 'classroomInfo',
  448. inputs: [],
  449. sessionsInputs: [
  450. { type: 'hidden', name: 'classroom', value: classroomId }
  451. ],
  452. api: APIGateway.classroom.get(classroomId),
  453. sessionsApi: APIGateway.session.APIAdresses.attendanceSheets,
  454. classroom: new Classroom(),
  455. table: {
  456. columns: [
  457. {
  458. name: 'number',
  459. required: true,
  460. label: 'شماره',
  461. align: 'left',
  462. field: () => ''
  463. },
  464. {
  465. name: 'id',
  466. required: true,
  467. label: 'شناسه',
  468. align: 'left',
  469. field: row => row.id
  470. },
  471. {
  472. name: 'title',
  473. required: true,
  474. label: 'عنوان',
  475. align: 'left',
  476. field: row => row.title
  477. },
  478. {
  479. name: 'beginning_time',
  480. required: true,
  481. label: 'زمان شروع',
  482. align: 'left',
  483. field: row => row.beginning_time ? ShamsiDate.getDateTime(row.beginning_time) : '-'
  484. },
  485. {
  486. name: 'ending_time',
  487. required: true,
  488. label: 'زمان پایان',
  489. align: 'left',
  490. field: row => row.ending_time ? ShamsiDate.getDateTime(row.ending_time) : '-'
  491. },
  492. {
  493. name: 'action',
  494. required: true,
  495. label: 'جزییات',
  496. align: 'left',
  497. field: ''
  498. }
  499. ]
  500. },
  501. selectedTeamMemberColumns: [
  502. {
  503. name: 'number',
  504. required: true,
  505. label: 'شماره',
  506. align: 'left',
  507. field: () => ''
  508. },
  509. {
  510. name: 'title',
  511. required: true,
  512. label: 'نام',
  513. align: 'left',
  514. field: row => row.registration_info.owner_info.firstname
  515. },
  516. {
  517. name: 'title',
  518. required: true,
  519. label: 'نام خانوادگی',
  520. align: 'left',
  521. field: row => row.registration_info.owner_info.lastname
  522. },
  523. {
  524. name: 'title',
  525. required: true,
  526. label: 'دانشگاه',
  527. align: 'left',
  528. field: row => row.registration_info.owner_info.last_academy_name
  529. }
  530. ],
  531. sessionsTable: {
  532. columns: [
  533. {
  534. name: 'number',
  535. required: true,
  536. label: 'شماره',
  537. align: 'left',
  538. field: () => ''
  539. },
  540. {
  541. name: 'id',
  542. required: true,
  543. label: 'شناسه',
  544. align: 'left',
  545. field: row => row.id
  546. },
  547. {
  548. name: 'title',
  549. required: true,
  550. label: 'عنوان',
  551. align: 'left',
  552. field: row => row.title
  553. },
  554. {
  555. name: 'title',
  556. required: true,
  557. label: 'زمان شروع',
  558. align: 'left',
  559. field: row => row.beginning_time ? ShamsiDate.getDateTime(row.beginning_time) : '-'
  560. },
  561. {
  562. name: 'title',
  563. required: true,
  564. label: 'زمان پایان',
  565. align: 'left',
  566. field: row => row.ending_time ? ShamsiDate.getDateTime(row.ending_time) : '-'
  567. },
  568. {
  569. name: 'assignment_status',
  570. required: true,
  571. label: 'وضعیت تکلیف',
  572. align: 'left',
  573. field: row => (new SessionAttendanceSheets(this.getCurrentUserAttendanceSheet(row))).assignment_status_info.label
  574. },
  575. {
  576. name: 'attendance_status',
  577. required: true,
  578. label: 'وضعیت حضور و غیاب',
  579. align: 'left',
  580. field: row => (new SessionAttendanceSheets(this.getCurrentUserAttendanceSheet(row))).attendance_status_info.label
  581. },
  582. {
  583. name: 'action',
  584. required: true,
  585. label: 'جزییات',
  586. align: 'left',
  587. field: ''
  588. }
  589. ]
  590. },
  591. sessionsTableKeys: {
  592. data: 'results',
  593. total: 'count',
  594. currentPage: 'current',
  595. perPage: 'per_page',
  596. pageKey: 'page'
  597. },
  598. tableKeys: {
  599. data: 'results',
  600. total: 'count',
  601. currentPage: 'current',
  602. perPage: 'per_page',
  603. pageKey: 'page'
  604. },
  605. projectListInputs: [
  606. { type: 'hidden', name: 'classroom', value: classroomId }
  607. // { type: 'hidden', name: 'owner', value: userId }
  608. ],
  609. // projectListApi: APIGateway.projectAttendanceSheets.APIAdresses.base,
  610. projectListApi: APIGateway.project.APIAdresses.attendanceSheetsList,
  611. projectListTable: {
  612. columns: [
  613. {
  614. name: 'number',
  615. required: true,
  616. label: 'شماره',
  617. align: 'left',
  618. field: () => ''
  619. },
  620. {
  621. name: 'id',
  622. required: true,
  623. label: 'شناسه',
  624. align: 'left',
  625. field: row => row.id
  626. },
  627. {
  628. name: 'title',
  629. required: true,
  630. label: 'عنوان پروژه',
  631. align: 'left',
  632. field: row => row.title
  633. },
  634. {
  635. name: 'creation_time',
  636. required: true,
  637. label: 'زمان شروع',
  638. align: 'left',
  639. field: row => row?.beginning_doing_period ? ShamsiDate.getDateTime(row.beginning_doing_period) : '-'
  640. },
  641. {
  642. name: 'creation_time',
  643. required: true,
  644. label: 'زمان پایان',
  645. align: 'left',
  646. field: row => row?.ending_doing_period ? ShamsiDate.getDateTime(row.ending_doing_period) : '-'
  647. },
  648. {
  649. name: 'status',
  650. required: true,
  651. label: 'وضعیت',
  652. align: 'left',
  653. field: row => (new ProjectAttendanceSheets(this.getProjectAttendanceSheets(row))).answer_status_info.label
  654. },
  655. {
  656. name: 'actions',
  657. required: true,
  658. label: 'عملیات',
  659. align: 'left',
  660. field: ''
  661. }
  662. ]
  663. },
  664. projectListTableKeys: {
  665. data: 'results',
  666. total: 'count',
  667. currentPage: 'current',
  668. perPage: 'per_page',
  669. pageKey: 'page'
  670. },
  671. registrations: new RegistrationList(),
  672. classroomRegistration: new Registration(),
  673. joinTeamLoading: false,
  674. teamsListInputs: [
  675. { type: 'hidden', name: 'classroom', value: classroomId }
  676. ],
  677. teamsListApi: APIGateway.team.APIAdresses.classroomTeamsWithJoinStatus,
  678. teamsListTable: {
  679. columns: [
  680. {
  681. name: 'number',
  682. required: true,
  683. label: 'شماره',
  684. align: 'left',
  685. field: () => ''
  686. },
  687. {
  688. name: 'id',
  689. required: true,
  690. label: 'شناسه',
  691. align: 'left',
  692. field: row => row.id
  693. },
  694. {
  695. name: 'title',
  696. required: true,
  697. label: 'عنوان گروه',
  698. align: 'left',
  699. field: row => row.title
  700. },
  701. {
  702. name: 'leader_info',
  703. required: true,
  704. label: 'سرگروه',
  705. align: 'left',
  706. field: row => row.leader_info ? row.leader_info?.firstname + ' ' + row.leader_info?.lastname : '-'
  707. },
  708. {
  709. name: 'used_capacity',
  710. required: true,
  711. label: 'ظرفیت استفاده شده',
  712. align: 'left',
  713. field: row => row.used_capacity
  714. },
  715. {
  716. name: 'capacity',
  717. required: true,
  718. label: 'ظرفیت',
  719. align: 'left',
  720. field: row => row.capacity
  721. },
  722. {
  723. name: 'action',
  724. required: true,
  725. label: ' ',
  726. align: 'left',
  727. field: ''
  728. }
  729. ]
  730. },
  731. teamsListTableKeys: {
  732. data: 'results',
  733. total: 'count',
  734. currentPage: 'current',
  735. perPage: 'per_page',
  736. pageKey: 'page'
  737. },
  738. testListInputs: [
  739. { type: 'hidden', name: 'test__classroom', value: classroomId },
  740. { type: 'hidden', name: 'owner', value: null }
  741. ],
  742. testListApi: APIGateway.answerBook.APIAdresses.base,
  743. testListTable: {
  744. columns: [
  745. {
  746. name: 'number',
  747. required: true,
  748. label: 'شماره',
  749. align: 'left',
  750. field: () => ''
  751. },
  752. {
  753. name: 'id',
  754. required: true,
  755. label: 'شناسه',
  756. align: 'left',
  757. field: row => row.id
  758. },
  759. {
  760. name: 'id',
  761. required: true,
  762. label: 'شناسه آزمون',
  763. align: 'left',
  764. field: row => row.test_info.id
  765. },
  766. {
  767. name: 'title',
  768. required: true,
  769. label: 'عنوان آزمون',
  770. align: 'left',
  771. field: row => row.test_info?.title
  772. },
  773. {
  774. name: 'start_time',
  775. required: true,
  776. label: 'زمان شروع',
  777. align: 'left',
  778. field: row => row.test_info?.start_time ? ShamsiDate.getDateTime(row.test_info.start_time) : '-'
  779. },
  780. {
  781. name: 'end_time',
  782. required: true,
  783. label: 'زمان پایان',
  784. align: 'left',
  785. field: row => row.test_info?.end_time ? ShamsiDate.getDateTime(row.test_info.end_time) : '-'
  786. },
  787. {
  788. name: 'duration_deadline',
  789. required: true,
  790. label: 'مدت آزمون(دقیقه)',
  791. align: 'left',
  792. field: row => row.test_info.duration_deadline
  793. },
  794. {
  795. name: 'test_questions.length',
  796. required: true,
  797. label: 'تعداد سوالات',
  798. align: 'left',
  799. field: row => row.test_info?.test_questions_length
  800. },
  801. {
  802. name: 'grade',
  803. required: true,
  804. label: 'نمره نهایی',
  805. align: 'left',
  806. field: row => (row.status === 'GRADED' || row.status === 'OBJECTED' || row.status === 'FINALIZED') ? row.total_score : ''
  807. },
  808. {
  809. name: 'test_info_status',
  810. required: true,
  811. label: 'وضعیت آزمون',
  812. align: 'left',
  813. field: row => (new Test(row.test_info)).status_info.label
  814. },
  815. {
  816. name: 'result_status',
  817. required: true,
  818. label: 'وضعیت تصحیح',
  819. align: 'left',
  820. field: row => (new AnswerBook(row)).status_info.label
  821. },
  822. {
  823. name: 'action',
  824. required: true,
  825. label: 'عملیات',
  826. align: 'left',
  827. field: ''
  828. }
  829. ]
  830. },
  831. testListTableKeys: {
  832. data: 'results',
  833. total: 'count',
  834. currentPage: 'current',
  835. perPage: 'per_page',
  836. pageKey: 'page'
  837. }
  838. }
  839. },
  840. computed: {
  841. classroomId () {
  842. return this.$route.params.id
  843. },
  844. canShowOtherTabsOfClassroom () {
  845. return !this.classroomRegistration.loading && (this.classroomRegistration.status === 'REGISTERED' || this.classroomRegistration.status === 'ENROLLED')
  846. },
  847. selectedCategoryId () {
  848. return FormBuilderAssist.getInputsByName(this.inputs, 'category')?.value
  849. },
  850. selectedTeamMemberRows () {
  851. if (!this.selectedTeam) {
  852. return []
  853. }
  854. return this.selectedTeam.team_registrations_info
  855. }
  856. },
  857. watch: {
  858. selectedCategoryId () {
  859. this.setInputValue('unit', null)
  860. this.getUnits(this.selectedCategoryId)
  861. }
  862. },
  863. mounted () {
  864. this.$store.commit('Test/updateAnswerBook', null)
  865. this.getRegistrationInfo()
  866. this.mounted = true
  867. FormBuilderAssist.setAttributeByName(this.testListInputs, 'owner', 'value', this.user.id)
  868. },
  869. methods: {
  870. showParticipateTypeDialog (testId, answerBookId) {
  871. this.$store.commit('Test/updateAnswerBook', null)
  872. this.selectedTest.testId = testId
  873. this.selectedTest.answerBookId = answerBookId
  874. this.participateTypeDialog = true
  875. },
  876. startTest () {
  877. this.$store.commit('Test/updateAnswerBook', null)
  878. this.$router.push({ name: this.participateType, params: { test_id: this.selectedTest.testId, answer_book_id: this.selectedTest.answerBookId, question_number: 1 } })
  879. },
  880. getTeamJoinStatusLabel (team) {
  881. if (team.join_status === 'ENABLED') {
  882. return 'عضو شوید'
  883. }
  884. return (new Team(team)).join_status_info.label
  885. },
  886. joinTeam (team) {
  887. this.joinTeamLoading = true
  888. APIGateway.team.register(team.id)
  889. .then(() => {
  890. this.joinTeamLoading = false
  891. this.$refs.teamsList.search()
  892. })
  893. .then(() => {
  894. this.teamInfoDialog = false
  895. this.joinTeamLoading = false
  896. this.$refs.teamsList.search()
  897. })
  898. },
  899. showTeamMembers (team) {
  900. this.selectedTeam = team
  901. this.teamInfoDialog = true
  902. },
  903. getRegistrationInfo () {
  904. this.registrations.loading = true
  905. this.classroomRegistration.loading = true
  906. APIGateway.registration.index({ classroom: this.$route.params.id })
  907. .then(({ list }) => {
  908. this.registrations = new RegistrationList(list)
  909. if (this.registrations.list.length > 0) {
  910. this.classroomRegistration = this.registrations.list[0]
  911. }
  912. this.registrations.loading = false
  913. this.classroomRegistration.loading = false
  914. })
  915. .catch(() => {
  916. this.registrations.loading = false
  917. this.classroomRegistration.loading = false
  918. })
  919. },
  920. getCurrentUserAttendanceSheet (session) {
  921. if (!session?.session_attendance_sheets || session.session_attendance_sheets.length === 0) {
  922. return null
  923. }
  924. return session.session_attendance_sheets[0]
  925. },
  926. getProjectAttendanceSheets (project) {
  927. if (!project?.project_attendance_sheets || project.project_attendance_sheets.length === 0) {
  928. return null
  929. }
  930. return project.project_attendance_sheets[0]
  931. },
  932. goToLiveStreamUrl () {
  933. window.open(this.classroom.live_streaming_url, '_blank')
  934. },
  935. onloadnClassroom (classroom) {
  936. this.classroom = new Classroom(classroom)
  937. this.$store.commit('AppLayout/updateBreadcrumbs', {
  938. visible: true,
  939. loading: false,
  940. path: [
  941. {
  942. label: 'دوره های من',
  943. to: { name: 'UserPanel.Profile.AllClassrooms' }
  944. },
  945. {
  946. label: this.classroom.title,
  947. to: { name: 'UserPanel.Profile.ClassroomInfo', params: { id: this.classroom.id } }
  948. }
  949. ]
  950. })
  951. },
  952. search () {
  953. this.$refs.entityIndex.search()
  954. },
  955. getClassroomHoldingTypeTitle (type) {
  956. const target = Enums.classroomHoldingTypes.find(item => item.value === type)
  957. if (!target) {
  958. return '-'
  959. }
  960. return target.label
  961. },
  962. getClassroomStatusTitle (type) {
  963. const target = Enums.classroomStatuses.find(item => item.value === type)
  964. if (!target) {
  965. return '-'
  966. }
  967. return target.label
  968. },
  969. getInvoiceStatusTitle (type) {
  970. const target = Enums.invoiceStatus.find(item => item.value === type)
  971. if (!target) {
  972. return '-'
  973. }
  974. return target.label
  975. },
  976. loadInputDataOptions () {
  977. this.getCategories()
  978. this.getUnits()
  979. },
  980. setInputValue (name, value) {
  981. const inputIndex = this.inputs.findIndex(input => input.name === name)
  982. this.inputs[inputIndex].value = value
  983. },
  984. getSelectOptions (result, value, label) {
  985. return result.map(item => {
  986. return {
  987. value: item[value],
  988. label: item[label]
  989. }
  990. })
  991. },
  992. loadSelectOptions (name, value) {
  993. const inputIndex = this.inputs.findIndex(input => input.name === name)
  994. this.inputs[inputIndex].options = value
  995. },
  996. getTranscriptSheetStatus (transcriptSheet) {
  997. return new TranscriptSheet(transcriptSheet).status_info.label
  998. },
  999. getTranscriptSheetStatusClass () {
  1000. let cls = ''
  1001. if (this.classroom.current_user_register_info?.transcript_sheet_info?.status === 'CLEAN_PASSED') {
  1002. cls = 'bg-green-2'
  1003. } else if (this.classroom.current_user_register_info?.transcript_sheet_info?.status === 'CONDITIONAL_PASSED') {
  1004. cls = 'bg-yellow-2'
  1005. } else if (this.classroom.current_user_register_info?.transcript_sheet_info?.status === 'FAILED') {
  1006. cls = 'bg-red-2'
  1007. } else if (this.classroom.current_user_register_info?.transcript_sheet_info?.status === 'FAILED_DUE_TO_PRE_CONDITIONAL') {
  1008. cls = 'bg-red-2'
  1009. }
  1010. return cls
  1011. }
  1012. }
  1013. }
  1014. </script>
  1015. <style lang="scss">
  1016. .team-info-dialog {
  1017. .q-dialog__inner--minimized > div {
  1018. width: 900px;
  1019. max-width: 90vw;
  1020. }
  1021. }
  1022. </style>