Skip to content

Commit

Permalink
Merge pull request #46 from bcgov/ofmcc-475-prompt-to-close-complete-…
Browse files Browse the repository at this point in the history
…request

Ofmcc 475 - Prompt to Close Complete request
  • Loading branch information
vietle-cgi authored Nov 27, 2023
2 parents d87856f + cafadcc commit 4dddaab
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 52 deletions.
92 changes: 92 additions & 0 deletions frontend/src/components/messages/CloseRequestBanner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<template>
<v-container>
<v-alert icon="mdi-information-slab-circle-outline" density="compact" prominent variant="outlined">
<v-row no-gutters>
<v-col cols="12" lg="8" xl="9">
<div class="text-body-1">Has this request been resolved?</div>
<div class="text-body-2">After 21 days of inactivity, this request will be closed automatically.</div>
</v-col>
<v-col cols="12" lg="4" xl="3" align="right">
<AppButton id="banner-close-request" @click="toggleConfirmDialog">Close request</AppButton>
</v-col>
</v-row>
</v-alert>
<AppDialog v-model="showConfirmDialog" title="Confirm" :isLoading="isLoading" persistent max-width="40%" @close="toggleConfirmDialog">
<template #content>
<div align="center" class="confirm-dialog-text">Are you sure you want to close this request?</div>
</template>
<template #button>
<v-row class="mt-2" justify="space-around">
<AppButton id="dialog-go-back" :primary="false" size="large" width="170px" @click="toggleConfirmDialog" :loading="isLoading">Go back</AppButton>
<AppButton id="dialog-close-request" size="large" width="170px" @click="closeAssistanceRequest" :loading="isLoading">Close request</AppButton>
</v-row>
</template>
</AppDialog>
</v-container>
</template>
<script>
import { mapActions } from 'pinia'
import AppButton from '@/components/ui/AppButton.vue'
import AppDialog from '@/components/ui/AppDialog.vue'
import { ASSISTANCE_REQUEST_STATUS_CODES, ASSISTANCE_REQUEST_STATE_CODES } from '@/utils/constants'
import { useMessagesStore } from '@/stores/messages'
import alertMixin from '@/mixins/alertMixin'
export default {
components: { AppButton, AppDialog },
mixins: [alertMixin],
props: {
assistanceRequestId: {
type: String,
required: true,
default: '',
},
},
data() {
return {
showConfirmDialog: false,
isLoading: false,
}
},
methods: {
...mapActions(useMessagesStore, ['updateAssistanceRequest', 'updateAssistanceRequestInStore']),
toggleConfirmDialog() {
this.showConfirmDialog = !this.showConfirmDialog
},
async closeAssistanceRequest() {
try {
this.isLoading = true
const payload = {
statusCode: ASSISTANCE_REQUEST_STATUS_CODES.CLOSED_COMPLETE,
stateCode: ASSISTANCE_REQUEST_STATE_CODES.INACTIVE,
}
await this.updateAssistanceRequest(this.assistanceRequestId, payload)
await this.updateAssistanceRequestInStore(this.assistanceRequestId)
this.setSuccessAlert('Request closed successfully')
} catch (error) {
this.setFailureAlert('Failed to close your request')
console.log(`Failed to close your request - ${error}`)
} finally {
this.toggleConfirmDialog()
this.isLoading = false
}
},
},
}
</script>
<style scoped>
.v-alert {
border-color: #003466;
background-color: #d4eaff;
}
:deep(.mdi-information-slab-circle-outline) {
color: #003466;
}
.confirm-dialog-text {
margin: 12px 0px;
font-size: 1.1em;
}
</style>
109 changes: 57 additions & 52 deletions frontend/src/components/messages/RequestConversations.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,19 @@
<span class="subject-header">Subject: {{ assistanceRequest.subject }}</span>
</v-col>
<v-col cols="2" class="d-flex flex-column align-start pb-0 pt-0">
<v-btn v-if="assistanceRequest.isRead"
@click="this.$emit('toggleMarkUnreadButtonInConversationThread')" class="btn-style">
<v-btn v-if="assistanceRequest.isRead" @click="this.$emit('toggleMarkUnreadButtonInConversationThread')" class="btn-style">
<v-icon class="icon" left>mdi-email-outline</v-icon>
<span class="btn-label">Mark unread</span>
</v-btn>
<v-tooltip v-if="showTooltip" content-class="tooltip"
:text="getReplyDisabledText()">
<v-tooltip v-if="showTooltip" content-class="tooltip" :text="getReplyDisabledText()">
<template v-slot:activator="{ props }">
<div v-bind="props" class="reply-disabled">
<v-icon left>mdi-reply</v-icon>
<span>Reply</span>
</div>
</template>
</v-tooltip>
<v-btn v-else-if="isReplyButtonEnabled" @click="toggleReplyRequestDialog"
class="btn-style pl-0 pr-15">
<v-btn v-else-if="isReplyButtonEnabled" @click="toggleReplyRequestDialog" class="btn-style pl-0 pr-15">
<v-icon class="icon" left>mdi-reply</v-icon>
<span class="btn-label">Reply</span>
</v-btn>
Expand All @@ -40,31 +37,37 @@
<v-col cols="auto" class="font-weight-bold pt-0 pb-0 pl-0">Topic:</v-col>
<v-col cols="3" class="pt-0 pb-0">{{ assistanceRequest.categoryName }}</v-col>
<v-col cols="auto" class="font-weight-bold pt-0 pb-0">Facility(s):</v-col>
<v-col class="pt-0 pb-0">{{ assistanceRequest.requestFacilities.map(facility =>
facility.facilityName).join(', ') }}</v-col>
<v-col class="pt-0 pb-0">{{ assistanceRequest.requestFacilities.map((facility) => facility.facilityName).join(', ') }}</v-col>
</v-row>
<v-row class="border-bottom">
<v-col class="d-flex justify-end pt-0 pb-0 pr-0 w-100 align-center"><span class="font-weight-bold">Sort
By:</span>
<v-row>
<v-col class="d-flex justify-end pt-0 pb-0 pr-0 w-100 align-center">
<span class="font-weight-bold">Sort By:</span>
<v-btn class="btn-style" @click="toggleSort()">
<span class="btn-label">{{ isSortedDesc ? 'Newest' : 'Oldest' }} first</span>
<v-icon v-if="isSortedDesc" class="icon">mdi-arrow-up</v-icon>
<v-icon v-else class="icon">mdi-arrow-down</v-icon>
</v-btn>
</v-col>
</v-row>
<v-row v-if="assistanceRequest">
<v-row v-if="showCloseRequestBanner">
<CloseRequestBanner :assistanceRequestId="assistanceRequestId" class="px-0" />
</v-row>
<v-row v-if="assistanceRequest" class="border-top">
<v-col cols="12" class="border-right pa-0">
<v-skeleton-loader :loading="loading" type="table-tbody">
<v-data-table-virtual :headers="headers" :items="assistanceRequestConversation" item-key="messageId"
class="data-table">
<template #headers>
</template>
<v-data-table-virtual :headers="headers" :items="assistanceRequestConversation" item-key="messageId" class="data-table">
<template #headers></template>
<template #item="{ item }">
<v-row class="border-bottom mr-0">
<v-col>
<div><span class="font-weight-bold">From:</span> {{ deriveFromDisplay(item) }}</div>
<div><span class="font-weight-bold">Sent:</span> {{ format.formatDate(item.sentDate) }}</div>
<div>
<span class="font-weight-bold">From:</span>
{{ deriveFromDisplay(item) }}
</div>
<div>
<span class="font-weight-bold">Sent:</span>
{{ format.formatDate(item.sentDate) }}
</div>
<div class="pt-1">{{ item.message }}</div>
</v-col>
</v-row>
Expand All @@ -73,34 +76,36 @@
</v-skeleton-loader>
</v-col>
</v-row>
<ReplyRequestDialog class="pa-0"
<ReplyRequestDialog
class="pa-0"
:assistanceRequestId="assistanceRequest.assistanceRequestId"
:referenceNumber="assistanceRequest.referenceNumber"
:show="showReplyRequestDialog"
@reply-success-event="replySuccessEvent"
@close="toggleReplyRequestDialog" />
</v-container>
</template>

<script>
import { mapState, mapActions } from 'pinia'
import { useAuthStore } from '@/stores/auth'
import { useMessagesStore } from '@/stores/messages'
import ReplyRequestDialog from '@/components/messages/ReplyRequestDialog.vue'
import CloseRequestBanner from '@/components/messages/CloseRequestBanner.vue'
import alertMixin from '@/mixins/alertMixin'
import format from '@/utils/format'
import { ASSISTANCE_REQUEST_REPLY_DISABLED_TEXT, ASSISTANCE_REQUEST_STATUS_CODES, OFM_PROGRAM } from '@/utils/constants'
export default {
mixins: [alertMixin],
format: [format],
components: { ReplyRequestDialog },
components: { ReplyRequestDialog, CloseRequestBanner },
props: {
assistanceRequestId: {
type: String,
required: true,
default: ''
}
default: '',
},
},
emits: ['toggleMarkUnreadButtonInConversationThread'],
data() {
Expand All @@ -114,27 +119,29 @@ export default {
{
title: 'dateReceived',
key: 'dateReceived',
sortable: true
}
sortable: true,
},
],
}
},
computed: {
...mapState(useMessagesStore, ['assistanceRequests', 'assistanceRequestConversation']),
...mapState(useAuthStore, ['userInfo']),
showTooltip() {
return !this.isReplyButtonEnabled && !this.isStatusClosed;
return !this.isReplyButtonEnabled && !this.isStatusClosed
},
showCloseRequestBanner() {
const assistanceRequest = this.assistanceRequests.find((item) => item.assistanceRequestId === this.assistanceRequestId)
return assistanceRequest?.statusCode === ASSISTANCE_REQUEST_STATUS_CODES.READY_TO_RESOLVE
},
isReplyButtonEnabled() {
return this.assistanceRequest &&
(this.assistanceRequest.statusCode === ASSISTANCE_REQUEST_STATUS_CODES.WITH_PROVIDER ||
this.assistanceRequest.statusCode === ASSISTANCE_REQUEST_STATUS_CODES.READY_TO_RESOLVE);
const assistanceRequest = this.assistanceRequests.find((item) => item.assistanceRequestId === this.assistanceRequestId)
return [ASSISTANCE_REQUEST_STATUS_CODES.WITH_PROVIDER, ASSISTANCE_REQUEST_STATUS_CODES.READY_TO_RESOLVE].includes(assistanceRequest?.statusCode)
},
isStatusClosed() {
return this.assistanceRequest &&
(this.assistanceRequest.statusCode === ASSISTANCE_REQUEST_STATUS_CODES.CLOSED_COMPLETE ||
this.assistanceRequest.statusCode === ASSISTANCE_REQUEST_STATUS_CODES.CLOSED_CANCELLED);
}
const assistanceRequest = this.assistanceRequests.find((item) => item.assistanceRequestId === this.assistanceRequestId)
return [ASSISTANCE_REQUEST_STATUS_CODES.CLOSED_COMPLETE, ASSISTANCE_REQUEST_STATUS_CODES.CLOSED_CANCELLED].includes(assistanceRequest?.statusCode)
},
},
watch: {
// When assistanceRequestId changes, get the conversation for the new assistance request.
Expand All @@ -143,7 +150,7 @@ export default {
await this.getAssistanceRequestConversation(this.assistanceRequestId)
this.sortConversation()
this.loading = false
this.assistanceRequest = this.assistanceRequests.find(item => item.assistanceRequestId === newVal)
this.assistanceRequest = this.assistanceRequests.find((item) => item.assistanceRequestId === newVal)
},
},
methods: {
Expand All @@ -155,11 +162,11 @@ export default {
sortConversation() {
this.assistanceRequestConversation.sort((a, b) => {
if (this.isSortedDesc) {
return (a.sentDate < b.sentDate) ? 1 : -1;
return a.sentDate < b.sentDate ? 1 : -1
} else {
return (a.sentDate > b.sentDate) ? 1 : -1;
return a.sentDate > b.sentDate ? 1 : -1
}
});
})
},
/**
Expand All @@ -184,31 +191,30 @@ export default {
async replySuccessEvent(isSuccess) {
if (isSuccess) {
// Assistance request status has been updated as part of reply, get the latest from store.
this.assistanceRequest = this.assistanceRequests.find(item => item.assistanceRequestId === this.assistanceRequestId)
await this.getAssistanceRequestConversation(this.assistanceRequestId);
this.sortConversation();
this.setSuccessAlert('Reply sent successfully');
this.assistanceRequest = this.assistanceRequests.find((item) => item.assistanceRequestId === this.assistanceRequestId)
await this.getAssistanceRequestConversation(this.assistanceRequestId)
this.sortConversation()
this.setSuccessAlert('Reply sent successfully')
}
},
/**
* Returns the text to display in the tooltip for the reply button when it is disabled.
*/
getReplyDisabledText() {
return ASSISTANCE_REQUEST_REPLY_DISABLED_TEXT;
return ASSISTANCE_REQUEST_REPLY_DISABLED_TEXT
},
/**
* Returns the sent by value for the conversation depending on the source system.
*/
deriveFromDisplay(item) {
return (item.ofmSourceSystem) ? `${this.userInfo?.firstName} ${this.userInfo?.lastName}` : OFM_PROGRAM;
}
}
return item.ofmSourceSystem ? `${this.userInfo?.firstName} ${this.userInfo?.lastName}` : OFM_PROGRAM
},
},
}
</script>
<style scoped>
.data-table {
max-height: 635px;
Expand Down Expand Up @@ -247,18 +253,17 @@ export default {
text-decoration: underline;
}
.border-bottom {
padding: 0px;
border-bottom: 1px solid #E0E0E0;
.border-top {
padding-top: 12px;
border-top: 1px solid #e0e0e0;
}
.reply-disabled {
padding-right: 17px;
font-size: 14px;
font-weight: 400;
letter-spacing: 1.25px;
color: #C0C0C0;
color: #c0c0c0;
font-family: BCSans, veranda, arial, sans-serif;
}
</style>
1 change: 1 addition & 0 deletions frontend/src/stores/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const useMessagesStore = defineStore('messages', {
if (assistanceRequestIndex !== -1) {
this.assistanceRequests[assistanceRequestIndex] = assistanceRequest
}
sortAssistanceRequests(this.assistanceRequests)
},
async getAssistanceRequestConversation(assistanceRequestId) {
try {
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export const ASSISTANCE_REQUEST_STATUS_CODES = Object.freeze({
CLOSED_CANCELLED: 6,
})

export const ASSISTANCE_REQUEST_STATE_CODES = Object.freeze({
ACTIVE: 0,
INACTIVE: 1,
})

export const ASSISTANCE_REQUEST_REPLY_DISABLED_TEXT = 'Your request is still in the queue. If this is an urgent request, you can call the program at 1-888-338-6622 (Option 7).'

export const OFM_PROGRAM = 'OFM Program'

0 comments on commit 4dddaab

Please sign in to comment.