Просмотр исходного кода

نمایش تیکت اعتراض در انتهای پاسخ نامه

hgh 1 год назад
Родитель
Сommit
8d379b3ca0

+ 128 - 2
src/components/Widgets/Test/AdminAnswerBookShow/AdminAnswerBookShow.vue

@@ -4,11 +4,11 @@
     <q-card v-if="!answerBook.loading && answerBook.id">
       <q-card-section class="flex justify-between">
         <div>{{ answerBook.test_info.title }}</div>
-        <q-btn v-if="!answerBook.loading && answerBook.status === 'OBJECTED' && answerBook.ticket"
+        <q-btn v-if="!answerBook.loading && answerBook.ticket"
                outline
                color="primary"
                class="btn-need-installment"
-               :to="{name: 'Admin.Ticket.Show', params: {id: answerBook.ticket}}">
+               @click="scrollToObjectionBox">
           مشاهده اعتراض
         </q-btn>
       </q-card-section>
@@ -194,6 +194,59 @@
       کمی صبر کنید...
     </div>
   </div>
+  <q-card v-if="mounted && !answerBook.loading && answerBook.id && answerBook.ticket"
+          ref="objectionBox"
+          class="q-mt-md">
+    <q-card-section>
+      <div class="row justify-center">
+        <div class="full-width">
+          <q-skeleton v-if="entityLoading"
+                      type="rect"
+                      width="100%"
+                      height="200px" />
+          <template v-else>
+            {{ answerBook.ticket_info.body }}
+            <q-chat-message v-for="message in answerBook.ticket_info.replies_info.list"
+                            :key="message.id"
+                            :avatar="message.creator_info?.picture ? message.creator_info.picture : 'assets/images/web/sample-avatar.svg'"
+                            :name="message.creator_info?.firstname + ' ' + message.creator_info?.lastname"
+                            text-html
+                            :text="[message.body]"
+                            :sent="!isUserMessage(authenticatedUser, message)">
+              <template v-slot:stamp>
+                <div>
+                  {{ miladiToShamsi(message.creation_time) }}
+                </div>
+                <q-btn icon="clear"
+                       round
+                       color="red"
+                       flat
+                       size="xs"
+                       @click="removeMessage(message.id)" />
+                <q-icon v-if="isUserMessage(authenticatedUser, message)"
+                        :name="message.read ? 'done_all' : 'done'" />
+              </template>
+            </q-chat-message>
+            <div>
+              <q-input v-model="replyText"
+                       bottom-slots
+                       autogrow
+                       :loading="entityLoading">
+                <template v-slot:after>
+                  <q-btn round
+                         dense
+                         flat
+                         icon="send"
+                         :loading="entityLoading"
+                         @click="sendReply" />
+                </template>
+              </q-input>
+            </div>
+          </template>
+        </div>
+      </div>
+    </q-card-section>
+  </q-card>
 </template>
 
 <script>
@@ -202,6 +255,7 @@ import { APIGateway } from 'src/api/APIGateway.js'
 import { EntityShow, EntityEdit } from 'quasar-crud'
 import { AnswerBook } from 'src/models/AnswerBook.js'
 import { mixinWidget, mixinAuth } from 'src/mixin/Mixins.js'
+import { User } from 'src/models/User.js'
 
 export default {
   name: 'AdminAnswerBookShow',
@@ -210,6 +264,9 @@ export default {
   data () {
     return {
       mounted: false,
+      replyText: null,
+      entityLoading: true,
+      authenticatedUser: new User(),
       graderDescriptionLoading: false,
       overallAnswerInput: [
         // { type: 'input', name: 'overall_answer_text', responseKey: 'overall_answer_text', label: 'متن پاسخ جامع', placeholder: ' ', inputType: 'textarea', col: 'col-12' },
@@ -240,10 +297,76 @@ export default {
     }
   },
   mounted () {
+    this.loadAuthData()
     this.getAnswerBook()
     this.mounted = true
   },
   methods: {
+    scrollToObjectionBox() {
+      this.$nextTick(() => {
+        if (this.$refs.objectionBox && this.$refs.objectionBox.$el) {
+          this.$refs.objectionBox.$el.scrollIntoView({ behavior: 'smooth', block: 'end' })
+        }
+      })
+    },
+    loadAuthData () {
+      this.authenticatedUser = this.$store.getters['Auth/user']
+    },
+    closeTicket () {
+      this.$q.dialog({
+        title: 'توجه',
+        message: 'آیا از بستن تیکت اطمینان دارید؟',
+        cancel: true,
+        persistent: true
+      }).onOk(() => {
+        this.entityLoading = true
+        APIGateway.ticket.close(this.$route.params.id)
+          .then(() => {
+            this.$refs.entityEdit.getData()
+          })
+          .catch(() => {
+            this.entityLoading = false
+          })
+      })
+    },
+    miladiToShamsi (miladi) {
+      return Assist.miladiToShamsi(miladi)
+    },
+    isUserMessage (authenticatedUser, message) {
+      return authenticatedUser.id === message.creator_info.id
+    },
+    removeMessage (replyMessageId) {
+      this.$q.dialog({
+        title: 'توجه',
+        message: 'آیا از حذف پیام اطمینان دارید؟',
+        cancel: true,
+        persistent: true
+      }).onOk(() => {
+        this.entityLoading = true
+        APIGateway.ticket.deleteReplyMessage(replyMessageId)
+          .then(() => {
+            this.getAnswerBook()
+          })
+          .catch(() => {
+            this.entityLoading = false
+          })
+      })
+    },
+    sendReply() {
+      this.entityLoading = true
+      const body = this.replyText.replace(/\n/g, '<br>\n')
+      APIGateway.ticket.reply({
+        id: this.answerBook.ticket,
+        body
+      })
+        .then(() => {
+          this.replyText = null
+          this.getAnswerBook()
+        })
+        .catch(() => {
+          this.getAnswerBook()
+        })
+    },
     sendObjection () {
       this.answerBook.loading = true
       this.$refs.objectionEntityEdit.editEntity(false)
@@ -304,13 +427,16 @@ export default {
     },
     getAnswerBook () {
       this.answerBook.loading = true
+      this.entityLoading = true
       APIGateway.answerBook.get(this.$route.params.answer_book_id)
         .then((answerBook) => {
           this.loadAnswerBook(answerBook)
           this.answerBook.loading = false
+          this.entityLoading = false
         })
         .catch(() => {
           this.answerBook.loading = false
+          this.entityLoading = false
         })
     },
     confirmScores () {

+ 2 - 2
src/components/Widgets/Test/TestShow/TestShow.vue

@@ -4,7 +4,7 @@
     <q-card v-if="!answerBook.loading && answerBook.id">
       <q-card-section class="flex justify-between">
         <div>{{ answerBook.test_info.title }}</div>
-        <q-btn v-if="!answerBook.loading && answerBook.status === 'OBJECTED' && answerBook.ticket"
+        <q-btn v-if="!answerBook.loading && answerBook.ticket"
                outline
                color="primary"
                class="btn-need-installment"
@@ -250,7 +250,7 @@ export default {
     scrollToObjectionBox() {
       this.$nextTick(() => {
         if (this.$refs.objectionBox && this.$refs.objectionBox.$el) {
-          this.$refs.objectionBox.$el.scrollIntoView({ behavior: 'smooth', block: 'start' })
+          this.$refs.objectionBox.$el.scrollIntoView({ behavior: 'smooth', block: 'end' })
         }
       })
     },

+ 4 - 0
src/models/AnswerBook.js

@@ -112,6 +112,10 @@ class AnswerBook extends Model {
             label: 'اعتراض شده',
             value: 'OBJECTED'
           },
+          {
+            label: 'پاسخ اعتراض',
+            value: 'OBJECTION_RESPONDED'
+          },
           {
             label: 'نهایی شده',
             value: 'FINALIZED'