Bladeren bron

fixed #142

ali 3 jaren geleden
bovenliggende
commit
3ef19040e9

+ 1 - 0
src/api/models/Registration.js

@@ -8,6 +8,7 @@ export default class RegistrationAPI extends APIRepository {
     this.APIAdresses = {
       base: '/lma/registrations',
       exportReport: '/lma/registrations/export_report',
+      classroomDetail: (registrationId) => '/lma/registrations/' + registrationId + '/classroom_detail',
       byId: (id) => '/lma/registrations/' + id
     }
     this.CacheList = {

+ 1 - 0
src/api/models/Session.js

@@ -22,6 +22,7 @@ export default class SessionAPI extends APIRepository {
       request: this.APIAdresses.base,
       data: this.getNormalizedSendData({
         category: null, // Number
+        classroom: null, // Number
         per_page: 10, // Number
         page: 1 // Number
       }, data),

+ 1 - 1
src/api/models/SessionAttendanceSheets.js

@@ -8,7 +8,7 @@ export default class SessionAttendanceSheetsAPI extends APIRepository {
     this.APIAdresses = {
       base: '/lma/session_attendance_sheets',
       submitAssignment: '/lma/session_attendance_sheets/submit_assignment',
-      submitAssignmentStatus: '/lma/session_attendance_sheets/submit_attendance_status',
+      submitAttendanceStatus: '/lma/session_attendance_sheets/submit_attendance_status',
       byId: (id) => '/lma/project_attendance_sheets/' + id
     }
     this.CacheList = {

+ 14 - 8
src/components/Control/btn.vue

@@ -1,12 +1,14 @@
 <template>
-  <div v-if="placeholder && label"
-       class="outside-label" />
-  <q-btn :label="label"
-         :color="color"
-         :class="btnClass"
-         :disable="disable"
-         :loading="loading"
-         @click="onClick" />
+  <div :class="customClass">
+    <div v-if="placeholder && label"
+         class="outside-label" />
+    <q-btn :label="label"
+           :color="color"
+           :class="btnClass"
+           :disable="disable"
+           :loading="loading"
+           @click="onClick" />
+  </div>
 </template>
 
 <script>
@@ -41,6 +43,10 @@ export default {
       default: false,
       type: Boolean
     },
+    customClass: {
+      default: '',
+      type: String
+    },
     atClick: {
       type: Function,
       default: () => {}

+ 70 - 12
src/pages/User/Profile/classroomInfo.vue

@@ -43,11 +43,11 @@
                    class="q-pa-none">
         <entity-index v-if="mounted"
                       ref="entityIndex"
-                      v-model:value="inputs"
+                      v-model:value="sessionsInputs"
                       title="لیست جلسات"
-                      :api="api"
-                      :table="table"
-                      :table-keys="tableKeys"
+                      :api="sessionsApi"
+                      :table="sessionsTable"
+                      :table-keys="sessionsTableKeys"
                       :table-grid-size="$q.screen.lt.sm"
                       :show-expand-button="false"
                       :show-reload-button="false"
@@ -157,6 +157,7 @@ import { Classroom } from 'src/models/Classroom.js'
 import { FormBuilderAssist } from 'quasar-form-builder'
 import EntityIndexGridItem from 'src/components/EntityIndexGridItem.vue'
 import Breadcrumbs from 'src/components/Widgets/Breadcrumbs/Breadcrumbs.vue'
+import { ProjectAttendanceSheets } from 'src/models/ProjectAttendanceSheets.js'
 import ShowClassroomInfo from 'src/components/Widgets/Other/ShowClassroomInfo/ShowClassroomInfo.vue'
 
 export default {
@@ -175,7 +176,11 @@ export default {
       mounted: false,
       tab: 'classroomInfo',
       inputs: [],
+      sessionsInputs: [
+        { type: 'hidden', name: 'classroom', value: classroomId }
+      ],
       api: APIGateway.classroom.APIAdresses.byId(classroomId),
+      sessionsApi: APIGateway.session.APIAdresses.base,
       classroom: new Classroom(),
       table: {
         columns: [
@@ -223,8 +228,61 @@ export default {
           }
         ]
       },
+      sessionsTable: {
+        columns: [
+          {
+            name: 'number',
+            required: true,
+            label: 'شماره',
+            align: 'left',
+            field: () => ''
+          },
+          {
+            name: 'id',
+            required: true,
+            label: 'شناسه',
+            align: 'left',
+            field: row => row.id
+          },
+          {
+            name: 'title',
+            required: true,
+            label: 'عنوان',
+            align: 'left',
+            field: row => row.title
+          },
+          {
+            name: 'title',
+            required: true,
+            label: 'زمان شروع',
+            align: 'left',
+            field: row => row.beginning_time ? ShamsiDate.getDateTime(row.beginning_time) : '-'
+          },
+          {
+            name: 'title',
+            required: true,
+            label: 'زمان پایان',
+            align: 'left',
+            field: row => row.ending_time ? ShamsiDate.getDateTime(row.ending_time) : '-'
+          },
+          {
+            name: 'action',
+            required: true,
+            label: 'جزییات',
+            align: 'left',
+            field: ''
+          }
+        ]
+      },
+      sessionsTableKeys: {
+        data: 'results',
+        total: 'count',
+        currentPage: 'current',
+        perPage: 'per_page',
+        pageKey: 'page'
+      },
       tableKeys: {
-        data: 'sessions_info',
+        data: 'results',
         total: 'count',
         currentPage: 'current',
         perPage: 'per_page',
@@ -232,10 +290,10 @@ export default {
       },
 
       projectListInputs: [
-        { type: 'hidden', name: 'classroom', value: classroomId },
+        { type: 'hidden', name: 'project__classroom', value: classroomId },
         { type: 'hidden', name: 'owner', value: userId }
       ],
-      projectListApi: APIGateway.project.APIAdresses.base,
+      projectListApi: APIGateway.projectAttendanceSheets.APIAdresses.base,
       projectListTable: {
         columns: [
           {
@@ -250,35 +308,35 @@ export default {
             required: true,
             label: 'شناسه',
             align: 'left',
-            field: row => row.id
+            field: row => row.project_info.id
           },
           {
             name: 'title',
             required: true,
             label: 'عنوان پروژه',
             align: 'left',
-            field: row => row.title
+            field: row => row.project_info.title
           },
           {
             name: 'creation_time',
             required: true,
             label: 'زمان شروع',
             align: 'left',
-            field: row => row.beginning_doing_period ? ShamsiDate.getDateTime(row.beginning_doing_period) : '-'
+            field: row => row.project_info?.beginning_doing_period ? ShamsiDate.getDateTime(row.project_info.beginning_doing_period) : '-'
           },
           {
             name: 'creation_time',
             required: true,
             label: 'زمان پایان',
             align: 'left',
-            field: row => row.ending_doing_period ? ShamsiDate.getDateTime(row.ending_doing_period) : '-'
+            field: row => row.project_info?.ending_doing_period ? ShamsiDate.getDateTime(row.project_info.ending_doing_period) : '-'
           },
           {
             name: 'status',
             required: true,
             label: 'وضعیت',
             align: 'left',
-            field: '-'
+            field: row => (new ProjectAttendanceSheets(row)).is_answer_verified_info.label
           },
           {
             name: 'actions',

+ 1 - 1
src/pages/User/Profile/classrooms.vue

@@ -137,7 +137,7 @@ export default {
             required: true,
             label: 'شناسه',
             align: 'left',
-            field: row => row.id
+            field: row => row.classroom_info.id
           },
           {
             name: 'classroom_info.title',

+ 131 - 11
src/pages/User/Profile/sessionInfo.vue

@@ -14,7 +14,7 @@
       </q-btn>
     </div>
     <entity-show v-if="mounted"
-                 v-model:value="inputs"
+                 v-model:value="sessionInfoInputs"
                  title="جزییات جلسه"
                  :api="api"
                  :show-expand-button="false"
@@ -84,31 +84,64 @@
           </div>
         </div>
       </template>
+      <template #after-form-builder>
+        <q-inner-loading :showing="submitAttendanceStatusLoading || submitAssignmentLoading">
+          <q-spinner-ball color="primary"
+                          size="50px" />
+        </q-inner-loading>
+        <entity-create v-if="submitAttendanceStatusMounted"
+                       ref="entityCreateSubmitAssignment"
+                       v-model:value="submitAssignmentInputs"
+                       :api="submitAssignmentApi"
+                       :default-layout="false"
+                       :show-expand-button="false"
+                       :show-edit-button="false"
+                       :show-index-button="false"
+                       :show-reload-button="false" />
+        <q-separator class="q-my-lg" />
+        <entity-create v-if="mounted"
+                       ref="entityCreateSubmitAttendanceStatus"
+                       v-model:value="submitAttendanceStatusInputs"
+                       :api="submitAttendanceStatusApi"
+                       :default-layout="false"
+                       :show-expand-button="false"
+                       :show-edit-button="false"
+                       :show-index-button="false"
+                       :show-reload-button="false" />
+      </template>
     </entity-show>
   </div>
 </template>
 
 <script>
-import { EntityShow } from 'quasar-crud'
+import { shallowRef } from 'vue'
 import { Session } from 'src/models/Session.js'
 import ShamsiDate from 'src/assets/ShamsiDate.js'
 import { APIGateway } from 'src/api/APIGateway.js'
 import { Classroom } from 'src/models/Classroom.js'
+import { EntityShow, EntityCreate } from 'quasar-crud'
+import BtnControl from 'src/components/Control/btn.vue'
+import { FormBuilderAssist } from 'quasar-form-builder'
 import Breadcrumbs from 'src/components/Widgets/Breadcrumbs/Breadcrumbs.vue'
 
+const BtnControlComp = shallowRef(BtnControl)
+
 export default {
   name: 'UserPanel.Profile.SessionInfo',
   components: {
     EntityShow,
+    EntityCreate,
     Breadcrumbs
   },
   data () {
+    const sessionId = parseInt(this.$route.params.id)
     return {
       classroom: new Classroom(),
       session: new Session(),
       mounted: false,
-      api: null,
-      inputs: [
+      submitAttendanceStatusMounted: false,
+      api: APIGateway.session.APIAdresses.byId(sessionId),
+      sessionInfoInputs: [
         { type: 'inputEditor', name: 'description', responseKey: 'description', label: 'توضیحات', col: 'col-md-12' },
         { type: 'separator', name: 'space', size: '1px', col: 'col-md-12' },
         { type: 'inputEditor', name: 'syllabus', responseKey: 'syllabus', label: 'مقرری جلسه', col: 'col-md-12' },
@@ -119,15 +152,50 @@ export default {
         { type: 'hidden', name: 'beginning_time', responseKey: 'beginning_time', label: 'زمان شروع جلسه', col: 'col-md-1' },
         { type: 'hidden', name: 'ending_time', responseKey: 'ending_time', label: 'زمان پایان جلسه', col: 'col-md-1' },
         { type: 'hidden', name: 'id', responseKey: 'id', label: 'id', col: 'col-md-1' }
-      ]
+      ],
+      submitAttendanceStatusLoading: false,
+      submitAttendanceStatusInputsReadPart: {
+        type: 'formBuilder',
+        name: 'is_read_part',
+        value: [
+          { type: 'separator', name: 'space', label: 'مطالعه', className: 'custom-separator', col: 'col-12' },
+          { type: 'checkbox', name: 'is_read_part1', responseKey: 'is_read_part1', value: false, label: 'نیمه اول را مطالعه کردم', col: 'col-md-12' },
+          { type: 'checkbox', name: 'is_read_part2', responseKey: 'is_read_part2', value: false, label: 'نیمه دوم را مطالعه کردم', col: 'col-md-12' }
+        ],
+        col: 'col-md-4 col-12'
+      },
+      submitAttendanceStatusInputsPresentListenPart: {
+        type: 'formBuilder',
+        name: 'is_present_listen_part',
+        value: [
+          { type: 'separator', name: 'space', label: 'حضور', className: 'custom-separator', col: 'col-12' },
+          { type: 'checkbox', name: 'is_present_listen_part1', responseKey: 'is_present_listen_part1', value: false, label: 'در نیمه اول حضور داشته‌ام', col: 'col-md-12' },
+          { type: 'checkbox', name: 'is_present_listen_part2', responseKey: 'is_present_listen_part2', value: false, label: 'در نیمه دوم حضور داشته‌ام', col: 'col-md-12' }
+        ],
+        col: 'col-md-4 col-12'
+      },
+      submitAttendanceStatusAction: { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'ثبت حضور و غیاب', placeholder: ' ', customClass: 'flex justify-end', atClick: this.submitAttendanceStatus, col: 'col-12' },
+      submitAttendanceStatusInputs: [
+        { type: 'hidden', name: 'session', responseKey: 'session', value: sessionId }
+      ],
+      submitAttendanceStatusApi: APIGateway.sessionAttendanceSheets.APIAdresses.submitAttendanceStatus,
+
+      submitAssignmentLoading: false,
+      submitAssignmentInputs: [
+        { type: 'InputEditor', name: 'answer_text', responseKey: 'answer_text', label: 'پاسخ به تکلیف', col: 'col-md-12 col-12' },
+        { type: 'file', name: 'answer_attachment', responseKey: 'answer_attachment', label: 'انتخاب فایل ضمیمه', col: 'col-md-3 col-12' },
+        { type: BtnControlComp, name: 'btn', responseKey: 'btn', label: 'ارسال تکلیف', customClass: 'flex justify-end', atClick: this.submitAssignment, col: 'col-md-9 col-12' },
+        { type: 'hidden', name: 'session', responseKey: 'session', value: sessionId }
+      ],
+      submitAssignmentApi: APIGateway.sessionAttendanceSheets.APIAdresses.submitAssignment
     }
   },
   computed: {
     title () {
-      return this.getInputValue('title')
+      return this.getSessionInfoInputValue('title')
     },
     endingTime () {
-      const data = this.getInputValue('ending_time')
+      const data = this.getSessionInfoInputValue('ending_time')
       if (!data) {
         return '-'
       }
@@ -135,7 +203,7 @@ export default {
       return ShamsiDate.getDateTime(data)
     },
     startingTime () {
-      const data = this.getInputValue('beginning_time')
+      const data = this.getSessionInfoInputValue('beginning_time')
       if (!data) {
         return '-'
       }
@@ -144,10 +212,55 @@ export default {
     }
   },
   mounted() {
-    this.api = APIGateway.session.APIAdresses.byId(this.$route.params.id)
     this.mounted = true
   },
   methods: {
+    updateAttendanceInputs (isDefinedSyllabus, classroomHoldingType) {
+      this.updateAttendancePresentInputs(classroomHoldingType)
+      this.updateAttendanceReadInputs(isDefinedSyllabus)
+      this.updateAttendanceActionBtn(isDefinedSyllabus, classroomHoldingType)
+    },
+    updateAttendanceReadInputs (isDefinedSyllabus) {
+      if (isDefinedSyllabus) {
+        this.submitAttendanceStatusInputs.unshift(this.submitAttendanceStatusInputsReadPart)
+      } else {
+        this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_read_part1', value: null })
+        this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_read_part2', value: null })
+      }
+    },
+    updateAttendancePresentInputs (classroomHoldingType) {
+      if (classroomHoldingType === 'OFFLINE') {
+        this.submitAttendanceStatusInputs.unshift(this.submitAttendanceStatusInputsPresentListenPart)
+      } else {
+        this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_present_listen_part1', value: null })
+        this.submitAttendanceStatusInputs.unshift({ type: 'hidden', name: 'is_present_listen_part2', value: null })
+      }
+    },
+    updateAttendanceActionBtn (isDefinedSyllabus, classroomHoldingType) {
+      if (isDefinedSyllabus || classroomHoldingType === 'OFFLINE') {
+        this.submitAttendanceStatusInputs.push(this.submitAttendanceStatusAction)
+      }
+    },
+    submitAttendanceStatus () {
+      this.submitAttendanceStatusLoading = true
+      this.$refs.entityCreateSubmitAttendanceStatus.createEntity(false)
+        .then(() => {
+          this.submitAttendanceStatusLoading = false
+        })
+        .catch(() => {
+          this.submitAttendanceStatusLoading = false
+        })
+    },
+    submitAssignment () {
+      this.submitAssignmentLoading = true
+      this.$refs.entityCreateSubmitAssignment.createEntity(false)
+        .then(() => {
+          this.submitAssignmentLoading = false
+        })
+        .catch(() => {
+          this.submitAssignmentLoading = false
+        })
+    },
     updateBreadcrumbs () {
       this.$store.commit('AppLayout/updateBreadcrumbs', {
         visible: true,
@@ -168,8 +281,13 @@ export default {
         ]
       })
     },
-    getInputValue (name) {
-      return this.inputs.find(input => input.name === name).value
+    getSessionInfoInputValue (name) {
+      const target = FormBuilderAssist.getInputsByName(this.sessionInfoInputs, name)
+      if (!target) {
+        return null
+      }
+
+      return target.value
     },
     beforeLoadInputData (data) {
       this.session = new Session(data)
@@ -183,6 +301,8 @@ export default {
           this.classroom = new Classroom(classroom)
           this.updateBreadcrumbs()
           this.classroom.loading = false
+          this.submitAttendanceStatusMounted = true
+          this.updateAttendanceInputs(true, 'ONLINE')
         })
         .catch(() => {
           this.classroom.loading = false

+ 1 - 1
src/router/routes.js

@@ -252,7 +252,7 @@ const routes = [
                   middlewares: [HasOverdueInstalment]
                 }
               },
-              { name: 'UserPanel.Profile.Classroom.Project.Show', path: 'classroom/:classroom_id/project/:project_id', component: () => import('src/pages/User/Profile/projectInfo.vue'), breadcrumbs: { title: 'مشاهده اطلاعات دوره آموزشی' } },
+              { name: 'UserPanel.Profile.Classroom.Project.Show', path: 'classroom/:classroom_id/project/:project_id', component: () => import('src/pages/User/Profile/projectInfo.vue') },
               {
                 name: 'UserPanel.Profile.SessionInfo',
                 path: 'session/:id',