浏览代码

fixed #183

ali 3 年之前
父节点
当前提交
f55abe74e3

+ 24 - 0
src/components/Widgets/Classroom/AdminClassroomShow/AdminClassroomShow.vue

@@ -30,6 +30,12 @@
              label="آزمون" />
       <q-tab name="members"
              label="اندیشه جویان" />
+      <q-tab name="teams"
+             label="گروه" />
+      <q-tab name="graders"
+             label="مصححین" />
+      <q-tab name="leaders"
+             label="سرگروه ها" />
       <q-tab name="activity_sheet"
              label="فعالیت کلاسی" />
       <q-tab name="live_streaming_url"
@@ -61,6 +67,18 @@
                    class="q-pa-none">
         <members-list :classroom-id="$route.params.id" />
       </q-tab-panel>
+      <q-tab-panel name="teams"
+                   class="q-pa-none">
+        <team-list :classroom-id="$route.params.id" />
+      </q-tab-panel>
+      <q-tab-panel name="graders"
+                   class="q-pa-none">
+        <grader-list :classroom-id="$route.params.id" />
+      </q-tab-panel>
+      <q-tab-panel name="leaders"
+                   class="q-pa-none">
+        <leader-list :classroom-id="$route.params.id" />
+      </q-tab-panel>
       <q-tab-panel name="activity_sheet"
                    class="q-pa-none">
         <activity-sheet-list :classroom-id="$route.params.id" />
@@ -74,6 +92,9 @@
 
 <script>
 import { Classroom } from 'src/models/Classroom.js'
+import TeamList from './components/TeamList.vue'
+import LeaderList from './components/LeaderList.vue'
+import GraderList from './components/GraderList.vue'
 import SessionList from './components/SessionList.vue'
 import ProjectList from './components/ProjectList.vue'
 import MembersList from './components/MembersList.vue'
@@ -85,6 +106,9 @@ import Breadcrumbs from 'src/components/Widgets/Breadcrumbs/Breadcrumbs.vue'
 export default {
   name: 'Admin.Classroom.Show',
   components: {
+    TeamList,
+    LeaderList,
+    GraderList,
     SessionList,
     ProjectList,
     MembersList,

+ 270 - 0
src/components/Widgets/Classroom/AdminClassroomShow/components/GraderList.vue

@@ -0,0 +1,270 @@
+<template>
+  <entity-index v-if="mounted"
+                ref="graderList"
+                v-model:value="graderListInputs"
+                title="لیست مصححین"
+                :api="graderListApi"
+                :table="graderListTable"
+                :table-keys="graderListTableKeys"
+                :show-search-button="false"
+                :show-reload-button="false"
+                :show-expand-button="false">
+    <template #toolbar>
+      <form-builder ref="formBuilder"
+                    v-model:value="addGraderInputs"
+                    :loading="addNewGraderLoading" />
+    </template>
+    <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+      <template v-if="inputData.col.name === 'number'">
+        {{ inputData.rowNumber }}
+      </template>
+      <template v-else-if="inputData.col.name === 'actions'">
+        <div class="action-column-entity-index">
+          <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
+        </div>
+      </template>
+      <template v-else-if="inputData.col.name === 'members'">
+        <div class="action-column-entity-index">
+          <q-btn size="md"
+                 color="primary"
+                 outline
+                 label="بررسی پروژه"
+                 :to="{name: 'Admin.Classroom.Grader.Members', params: {classroom_id: $route.params.id, project_id: inputData.props.row.id}}"
+                 class="q-mr-md" />
+        </div>
+      </template>
+      <template v-else>
+        {{ inputData.col.value }}
+      </template>
+    </template>
+  </entity-index>
+  <q-skeleton v-else
+              type="rect"
+              height="200px" />
+</template>
+
+<script>
+import { shallowRef } from 'vue'
+import { EntityIndex } from 'quasar-crud'
+import { APIGateway } from 'src/api/APIGateway.js'
+import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
+import { FormBuilder, inputMixin } from 'quasar-form-builder'
+import EntityInput from 'quasar-crud/src/components/Entity/Attachment/EntityInput.vue'
+
+const EntityInputComp = shallowRef(EntityInput)
+
+export default {
+  name: 'GraderList',
+  components: {
+    DeleteBtn,
+    EntityIndex,
+    FormBuilder
+  },
+  mixins: [inputMixin],
+  props: {
+    classroomId: {
+      type: Number,
+      default: null
+    }
+  },
+  data () {
+    const classroomId = this.classroomId
+    return {
+      mounted: false,
+      addNewGraderLoading: false,
+
+      addGraderInputs: [
+        {
+          type: EntityInputComp,
+          name: 'graders',
+          selectionMode: 'multiple',
+          popUpButtonConfig: {
+            label: 'اختصاص مصحح جدید',
+            outline: true,
+            buttonColor: 'deep-purple',
+            buttonTextColor: 'white',
+            buttonBadgeColor: 'pink'
+          },
+          dialogConfirmButtonConfig: {
+            label: 'تایید',
+            buttonColor: 'deep-purple',
+            buttonTextColor: 'white',
+            buttonBadgeColor: 'pink'
+          },
+
+          apiAddress: APIGateway.user.APIAdresses.base,
+          tableTitle: 'لیست کل مصححین',
+          showTableItemsRouteName: 'Admin.BlockManagement.Show',
+          tableKeys: {
+            data: 'results',
+            total: 'count',
+            currentPage: 'current',
+            perPage: 'per_page',
+            pageKey: 'page'
+          },
+          table: {
+            columns: [
+              {
+                name: 'id',
+                required: true,
+                label: 'شناسه',
+                align: 'left',
+                field: row => row.id
+              },
+              {
+                name: 'fullname',
+                required: true,
+                label: 'نام و نام خانوادگی',
+                align: 'left',
+                field: row => row.firstname + ' ' + row.lastname
+              },
+              {
+                name: 'national_code',
+                required: true,
+                label: 'کد ملی',
+                align: 'left',
+                field: row => row.national_code
+              },
+              {
+                name: 'mobile_number',
+                required: true,
+                label: 'شماره همراه',
+                align: 'left',
+                field: row => row.mobile_number
+              }
+            ]
+          },
+          inputs: [
+            { type: 'input', name: 'id', value: null, label: 'شناسه', placeholder: ' ', col: 'col-md-4 col-12' },
+            { type: 'input', name: 'national_code', value: null, label: 'کد ملی', placeholder: ' ', col: 'col-md-4 col-12' },
+            { type: 'input', name: 'mobile_number', value: null, label: 'شماره همراه', placeholder: ' ', col: 'col-md-4 col-12' },
+            { type: 'input', name: 'email', value: null, label: 'ایمیل', placeholder: ' ', col: 'col-md-3 col-12' },
+            { type: 'input', name: 'firstname', value: null, label: 'نام', placeholder: ' ', col: 'col-md-3 col-12' },
+            { type: 'input', name: 'lastname', value: null, label: 'نام خانوادگی', placeholder: ' ', col: 'col-md-3 col-12' },
+            { type: 'hidden', name: 'role', value: 'team_grader' },
+            { type: 'hidden', name: 'classroom_graders__classroom__ne', value: classroomId }
+          ],
+          itemIndicatorKey: row => row.firstname + ' ' + row.lastname,
+          // itemIndicatorKey: 'firstname',
+          itemIdentifyKey: 'id',
+          onConfirmed: this.onConfirmedSelected,
+
+          value: [],
+          selected: [],
+          col: 'col-md-12 col-12'
+        }
+      ],
+
+      graderListInputs: [
+        { type: 'hidden', name: 'classroom', value: classroomId }
+      ],
+      graderListApi: APIGateway.classroomGrader.APIAdresses.base,
+      graderListTable: {
+        columns: [
+          {
+            name: 'number',
+            required: true,
+            label: 'شماره',
+            align: 'left',
+            field: () => ''
+          },
+          {
+            name: 'id',
+            required: true,
+            label: 'شناسه',
+            align: 'left',
+            field: row => row.grader_info.id
+          },
+          {
+            name: 'title',
+            required: true,
+            label: 'جنسیت',
+            align: 'left',
+            field: row => (row.grader_info.gender === 1) ? 'مذکر' : ((row.grader_info.gender === 2) ? 'مونث' : '-')
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'نام و نام خانوادگی',
+            align: 'left',
+            field: row => row.grader_info.firstname + ' ' + row.grader_info.lastname
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'کدملی',
+            align: 'left',
+            field: row => row.grader_info.national_code
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'شماره تلفن',
+            align: 'left',
+            field: row => row.grader_info.mobile_number
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'دانشگاه',
+            align: 'left',
+            field: row => row.grader_info.last_academy_name
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'شهر',
+            align: 'left',
+            field: row => row.grader_info.living_city
+          },
+          {
+            name: 'actions',
+            required: true,
+            label: 'عملیات',
+            align: 'left',
+            field: ''
+          }
+        ]
+      },
+      graderListTableKeys: {
+        data: 'results',
+        total: 'count',
+        currentPage: 'current',
+        perPage: 'per_page',
+        pageKey: 'page'
+      }
+    }
+  },
+  computed: {
+    tableChosenValues: {
+      get () {
+        if (Array.isArray(this.tableSelectedValues)) {
+          return this.tableSelectedValues
+        }
+        return [this.tableSelectedValues]
+      },
+      set () {}
+    }
+  },
+  mounted () {
+    this.mounted = true
+  },
+  methods: {
+    onConfirmedSelected (data) {
+      const graders = data.map(item => item.id)
+      this.addNewGraderLoading = true
+      APIGateway.classroom.appendGraders({ classroomId: this.classroomId, graders })
+        .then(() => {
+          this.$refs.graderList.search()
+          this.addNewGraderLoading = false
+        })
+        .catch(() => {
+          this.addNewGraderLoading = false
+        })
+    },
+    getRemoveMessage (row) {
+      return 'آیا از حذف ' + row.grader_info.firstname + ' ' + row.grader_info.lastname + ' اطمینان دارید؟'
+    }
+  }
+}
+</script>

+ 270 - 0
src/components/Widgets/Classroom/AdminClassroomShow/components/LeaderList.vue

@@ -0,0 +1,270 @@
+<template>
+  <entity-index v-if="mounted"
+                ref="leaderList"
+                v-model:value="leaderListInputs"
+                title="لیست سرگروه ها"
+                :api="leaderListApi"
+                :table="leaderListTable"
+                :table-keys="leaderListTableKeys"
+                :show-search-button="false"
+                :show-reload-button="false"
+                :show-expand-button="false">
+    <template #toolbar>
+      <form-builder ref="formBuilder"
+                    v-model:value="addLeaderInputs"
+                    :loading="addNewLeaderLoading" />
+    </template>
+    <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+      <template v-if="inputData.col.name === 'number'">
+        {{ inputData.rowNumber }}
+      </template>
+      <template v-else-if="inputData.col.name === 'actions'">
+        <div class="action-column-entity-index">
+          <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
+        </div>
+      </template>
+      <template v-else-if="inputData.col.name === 'members'">
+        <div class="action-column-entity-index">
+          <q-btn size="md"
+                 color="primary"
+                 outline
+                 label="بررسی پروژه"
+                 :to="{name: 'Admin.Classroom.Leader.Members', params: {classroom_id: $route.params.id, project_id: inputData.props.row.id}}"
+                 class="q-mr-md" />
+        </div>
+      </template>
+      <template v-else>
+        {{ inputData.col.value }}
+      </template>
+    </template>
+  </entity-index>
+  <q-skeleton v-else
+              type="rect"
+              height="200px" />
+</template>
+
+<script>
+import { shallowRef } from 'vue'
+import { EntityIndex } from 'quasar-crud'
+import { APIGateway } from 'src/api/APIGateway.js'
+import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
+import { FormBuilder, inputMixin } from 'quasar-form-builder'
+import EntityInput from 'quasar-crud/src/components/Entity/Attachment/EntityInput.vue'
+
+const EntityInputComp = shallowRef(EntityInput)
+
+export default {
+  name: 'LeaderList',
+  components: {
+    DeleteBtn,
+    EntityIndex,
+    FormBuilder
+  },
+  mixins: [inputMixin],
+  props: {
+    classroomId: {
+      type: Number,
+      default: null
+    }
+  },
+  data () {
+    const classroomId = this.classroomId
+    return {
+      mounted: false,
+      addNewLeaderLoading: false,
+
+      addLeaderInputs: [
+        {
+          type: EntityInputComp,
+          name: 'leaders',
+          selectionMode: 'multiple',
+          popUpButtonConfig: {
+            label: 'اختصاص سرگروه جدید',
+            outline: true,
+            buttonColor: 'deep-purple',
+            buttonTextColor: 'white',
+            buttonBadgeColor: 'pink'
+          },
+          dialogConfirmButtonConfig: {
+            label: 'تایید',
+            buttonColor: 'deep-purple',
+            buttonTextColor: 'white',
+            buttonBadgeColor: 'pink'
+          },
+
+          apiAddress: APIGateway.user.APIAdresses.base,
+          tableTitle: 'لیست کل سرگروه ها',
+          showTableItemsRouteName: 'Admin.BlockManagement.Show',
+          tableKeys: {
+            data: 'results',
+            total: 'count',
+            currentPage: 'current',
+            perPage: 'per_page',
+            pageKey: 'page'
+          },
+          table: {
+            columns: [
+              {
+                name: 'id',
+                required: true,
+                label: 'شناسه',
+                align: 'left',
+                field: row => row.id
+              },
+              {
+                name: 'fullname',
+                required: true,
+                label: 'نام و نام خانوادگی',
+                align: 'left',
+                field: row => row.firstname + ' ' + row.lastname
+              },
+              {
+                name: 'national_code',
+                required: true,
+                label: 'کد ملی',
+                align: 'left',
+                field: row => row.national_code
+              },
+              {
+                name: 'mobile_number',
+                required: true,
+                label: 'شماره همراه',
+                align: 'left',
+                field: row => row.mobile_number
+              }
+            ]
+          },
+          inputs: [
+            { type: 'input', name: 'id', value: null, label: 'شناسه', placeholder: ' ', col: 'col-md-4 col-12' },
+            { type: 'input', name: 'national_code', value: null, label: 'کد ملی', placeholder: ' ', col: 'col-md-4 col-12' },
+            { type: 'input', name: 'mobile_number', value: null, label: 'شماره همراه', placeholder: ' ', col: 'col-md-4 col-12' },
+            { type: 'input', name: 'email', value: null, label: 'ایمیل', placeholder: ' ', col: 'col-md-3 col-12' },
+            { type: 'input', name: 'firstname', value: null, label: 'نام', placeholder: ' ', col: 'col-md-3 col-12' },
+            { type: 'input', name: 'lastname', value: null, label: 'نام خانوادگی', placeholder: ' ', col: 'col-md-3 col-12' },
+            { type: 'hidden', name: 'role', value: 'team_leader' },
+            { type: 'hidden', name: 'classroom_leaders__classroom__ne', value: classroomId }
+          ],
+          itemIndicatorKey: row => row.firstname + ' ' + row.lastname,
+          // itemIndicatorKey: 'firstname',
+          itemIdentifyKey: 'id',
+          onConfirmed: this.onConfirmedSelected,
+
+          value: [],
+          selected: [],
+          col: 'col-md-12 col-12'
+        }
+      ],
+
+      leaderListInputs: [
+        { type: 'hidden', name: 'classroom', value: classroomId }
+      ],
+      leaderListApi: APIGateway.classroomLeaders.APIAdresses.base,
+      leaderListTable: {
+        columns: [
+          {
+            name: 'number',
+            required: true,
+            label: 'شماره',
+            align: 'left',
+            field: () => ''
+          },
+          {
+            name: 'id',
+            required: true,
+            label: 'شناسه',
+            align: 'left',
+            field: row => row.leader_info.id
+          },
+          {
+            name: 'title',
+            required: true,
+            label: 'جنسیت',
+            align: 'left',
+            field: row => (row.leader_info.gender === 1) ? 'مذکر' : ((row.leader_info.gender === 2) ? 'مونث' : '-')
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'نام و نام خانوادگی',
+            align: 'left',
+            field: row => row.leader_info.firstname + ' ' + row.leader_info.lastname
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'کدملی',
+            align: 'left',
+            field: row => row.leader_info.national_code
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'شماره تلفن',
+            align: 'left',
+            field: row => row.leader_info.mobile_number
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'دانشگاه',
+            align: 'left',
+            field: row => row.leader_info.last_academy_name
+          },
+          {
+            name: 'creation_time',
+            required: true,
+            label: 'شهر',
+            align: 'left',
+            field: row => row.leader_info.living_city
+          },
+          {
+            name: 'actions',
+            required: true,
+            label: 'عملیات',
+            align: 'left',
+            field: ''
+          }
+        ]
+      },
+      leaderListTableKeys: {
+        data: 'results',
+        total: 'count',
+        currentPage: 'current',
+        perPage: 'per_page',
+        pageKey: 'page'
+      }
+    }
+  },
+  computed: {
+    tableChosenValues: {
+      get () {
+        if (Array.isArray(this.tableSelectedValues)) {
+          return this.tableSelectedValues
+        }
+        return [this.tableSelectedValues]
+      },
+      set () {}
+    }
+  },
+  mounted () {
+    this.mounted = true
+  },
+  methods: {
+    onConfirmedSelected (data) {
+      const leaders = data.map(item => item.id)
+      this.addNewLeaderLoading = true
+      APIGateway.classroom.appendLeaders({ classroomId: this.classroomId, leaders })
+        .then(() => {
+          this.$refs.leaderList.search()
+          this.addNewLeaderLoading = false
+        })
+        .catch(() => {
+          this.addNewLeaderLoading = false
+        })
+    },
+    getRemoveMessage (row) {
+      return 'آیا از حذف ' + row.leader_info.firstname + ' ' + row.leader_info.lastname + ' اطمینان دارید؟'
+    }
+  }
+}
+</script>

+ 156 - 0
src/components/Widgets/Classroom/AdminClassroomShow/components/TeamList.vue

@@ -0,0 +1,156 @@
+<template>
+  <entity-index v-if="mounted"
+                ref="teamsList"
+                v-model:value="teamsListInputs"
+                title="لیست گروه ها"
+                :api="teamsListApi"
+                :table="teamsListTable"
+                :table-keys="teamsListTableKeys"
+                :show-search-button="false"
+                :show-reload-button="false"
+                :show-expand-button="false">
+    <template #toolbar>
+      <q-btn color="primary"
+             outline
+             :loading="exportReportLoading"
+             :to="{name: 'Admin.Classroom.Team.Create', params: {classroom_id: classroomId}}">
+        ایجاد گروه جدید
+      </q-btn>
+    </template>
+    <template v-slot:entity-index-table-cell="{inputData, showConfirmRemoveDialog}">
+      <template v-if="inputData.col.name === 'number'">
+        {{ inputData.rowNumber }}
+      </template>
+      <template v-else-if="inputData.col.name === 'action'">
+        <div class="action-column-entity-index">
+          <q-btn size="md"
+                 color="primary"
+                 label="جزییات"
+                 :to="{name: 'Admin.Classroom.Team.Show', params: {classroom_id: classroomId, team_id:inputData.props.row.id}}"
+                 :loading="createInvoiceLoading"
+                 class="q-mr-md" />
+          <delete-btn @click="showConfirmRemoveDialog(inputData.props.row, 'id', getRemoveMessage(inputData.props.row))" />
+        </div>
+      </template>
+      <template v-else>
+        {{ inputData.col.value }}
+      </template>
+    </template>
+  </entity-index>
+  <q-skeleton v-else
+              type="rect"
+              height="200px" />
+</template>
+
+<script>
+import { EntityIndex } from 'quasar-crud'
+import { APIGateway } from 'src/api/APIGateway.js'
+import { Classroom } from 'src/models/Classroom.js'
+import { FormBuilderAssist } from 'quasar-form-builder'
+import DeleteBtn from 'src/components/Control/DeleteBtn.vue'
+
+export default {
+  name: 'MembersList',
+  components: {
+    DeleteBtn,
+    EntityIndex
+  },
+  props: {
+    classroomId: {
+      type: Number,
+      default: null
+    }
+  },
+  data () {
+    const classroomId = this.classroomId
+    return {
+      mounted: false,
+      createInvoiceLoading: false,
+      classroom: new Classroom(),
+
+      dropClassroomByAdminLoading: false,
+      exportReportLoading: false,
+      teamsListInputs: [
+        { type: 'hidden', name: 'classroom', value: classroomId }
+      ],
+      teamsListApi: APIGateway.team.APIAdresses.base,
+      teamsListTable: {
+        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: 'leader_info',
+            required: true,
+            label: 'سرگروه',
+            align: 'left',
+            field: row => row.leader_info?.firstname + ' ' + row.leader_info?.lastname
+          },
+          {
+            name: 'used_capacity',
+            required: true,
+            label: 'ظرفیت باقی مانده',
+            align: 'left',
+            field: row => row.used_capacity
+          },
+          {
+            name: 'capacity',
+            required: true,
+            label: 'ظرفیت',
+            align: 'left',
+            field: row => row.capacity
+          },
+          {
+            name: 'action',
+            required: true,
+            label: ' ',
+            align: 'left',
+            field: ''
+          }
+        ],
+        data: []
+      },
+      teamsListTableKeys: {
+        data: 'results',
+        total: 'count',
+        currentPage: 'current',
+        perPage: 'per_page',
+        pageKey: 'page'
+      }
+    }
+  },
+  mounted () {
+    this.setMembersListActionBtn()
+    this.mounted = true
+  },
+  methods: {
+    setMembersListActionBtn () {
+      FormBuilderAssist.setAttributeByName(this.teamsListInputs, 'btn', 'atClick', this.searchMembersList)
+    },
+    searchMembersList () {
+      this.$refs.teamsList.search()
+    },
+    getRemoveMessage (row) {
+      return 'آیا از حذف ' + row.title + ' اطمینان دارید؟'
+    }
+  }
+}
+</script>