Skip to content

Commit

Permalink
Force notification use JSON stringify and reject can add reason (#27)
Browse files Browse the repository at this point in the history
Co-authored-by: wangqiang <[email protected]>
  • Loading branch information
dispensable and wangqiang authored Jul 22, 2020
1 parent 8bb8dbf commit 23b2f80
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 32 deletions.
2 changes: 1 addition & 1 deletion frontend/src/components/HHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</a-menu-item>
<a-sub-menu :style="{ float: 'right' }">
<span slot="title">
<span>{{ user.display_name }}</span>
<span :style="{margin: '10px'}">{{ user.display_name }}</span>
<a-avatar shape="square" icon="user"
:src="user.avatar"
/>
Expand Down
52 changes: 36 additions & 16 deletions frontend/src/components/HTicketDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
<template slot="description">
<span v-if="!ticketInfo.is_approved">
by {{ticketInfo.confirmed_by}}<br/>
at {{UTCtoLcocalTime(ticketInfo.confirmed_at)}}
at {{UTCtoLcocalTime(ticketInfo.confirmed_at)}} <br/>
{{ ticketInfo.reason>150 ? ticketInfo.reason.slice(0, 150) + '...' : ticketInfo.reason }}
</span>
</template>
</a-step>
Expand Down Expand Up @@ -78,7 +79,10 @@
</a-card>
<a-row :style="{ marginTop: '16px' }">
<a-button-group v-show="showActionButtons">
<a-button @click="onReject">Reject</a-button>
<a-modal v-model="rejectModalVisible" title="Reject reason" ok-text="confirm" cancel-text="cancel" @ok="onReject" @cancel="hideRejectModal">
<a-input placeholder="Reject reason" v-model="rejectReason" maxLength:=128 />
</a-modal>
<a-button @click="showRejectModal">Reject</a-button>
<a-button @click="onApprove" type="primary">Approve</a-button>
</a-button-group>
<a-button v-show="showResultButton" :style="{ marginLeft: '16px' }" @click="toggleResult">{{resultButtonText}}</a-button>
Expand Down Expand Up @@ -110,6 +114,7 @@ export default {
params_in_modal: [],
resultButtonText: 'Show results',
resultVisible: false,
rejectModalVisible: false,
statusToStepStatus: {
'created': {'status': 'finish', 'stepKey': 0},
'approved': {'status': 'finish', 'stepKey': 2},
Expand All @@ -122,7 +127,8 @@ export default {
'success': {'status': 'finish', 'stepKey': 5},
'failed': {'status': 'error', 'stepKey': 4},
'unknown': {'status': 'process', 'stepKey': 4}
}
},
rejectReason: null,
}
},
computed: {
Expand Down Expand Up @@ -195,15 +201,6 @@ export default {
handleTicketList (response) {
this.table_data = response.data.data.tickets
},
onConfirm (record, status, actionUrl) {
HRequest.post(actionUrl).then(
(response) => {
if (response.status === 200) {
this.$message.success(response.data)
} else this.$message.warning(response.data)
}
)
},
UTCtoLcocalTime,
toggleResult () {
this.resultVisible = !this.resultVisible
Expand All @@ -216,20 +213,43 @@ export default {
resetResult () {
this.resultVisible = false
},
errorAsNotification (title, rawMsg) {
const msg = rawMsg.length > 300 ? rawMsg.slice(0, 300) + '... ' : rawMsg
this.$notification.title = rawMsg
this.$notification.open({
message: title,
description: msg,
duration: 0
})
},
showRejectModal () {
this.rejectModalVisible = true
},
hideRejectModal () {
this.rejectModalVisible = false
},
onReject () {
HRequest.post(this.ticketInfo.reject_url).then(() => {
HRequest.post(this.ticketInfo.reject_url, {"reason": this.rejectReason}).then(() => {
this.$message.loading('Action in progress..', 2.5)
this.loadTickets()
this.$message.info('Ticket rejected.')
this.hideRejectModal()
}).catch((error) => {
this.$message.error('Ticket reject failed: ' + error.response.data.message)
this.errorAsNotification(
"Ticket reject failed",
error.response.data.data.description
)
})
},
onApprove () {
HRequest.post(this.ticketInfo.approve_url).then(() => {
this.loadTickets()
this.$message.info('Ticket approved.')
}).catch((error) => {
this.$message.error('Ticket approved failed: ' + error.response.data.message)
}).catch((error) => {
this.errorAsNotification(
"Ticket approve failed",
error.response.data.data.description
)
})
}
},
Expand Down
42 changes: 32 additions & 10 deletions frontend/src/components/HTicketList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
</span>
<span slot="action" slot-scope="text, record">
<span v-if="record.is_approved === undefined">
<a-modal v-model="rejectModalVisible" title="Reject reason" ok-text="confirm" cancel-text="cancel" @ok="onConfirm(record, 'rejected', record.reject_url)" @cancel="hideRejectModal">
<a-input placeholder="Reject reason" v-model="rejectReason" maxLength:=128 />
</a-modal>
<a-popconfirm
title="Sure to approve?"
@confirm="() => onConfirm(record, 'approved', record.approve_url)"
Expand All @@ -41,14 +44,14 @@
<a-divider type="vertical" />
<a-popconfirm
title="Sure to reject?"
@confirm="() => onConfirm(record, 'rejected', record.reject_url)"
@confirm="() => showRejectModal()"
>
<a :href="record.reject_url">reject</a>
</a-popconfirm>
<a-divider type="vertical" />
</span>

<a :href="record.api_url">detail</a>
<a :href="record.url">detail</a>
</span>
</a-table>
<a-modal
Expand Down Expand Up @@ -96,7 +99,9 @@ export default {
pagination: {
pageSize: 1
},
params_in_modal: []
params_in_modal: [],
rejectModalVisible: false,
rejectReason: null,
}
},
computed: {
Expand Down Expand Up @@ -190,6 +195,12 @@ export default {
}
},
methods: {
showRejectModal () {
this.rejectModalVisible = true
},
hideRejectModal () {
this.rejectModalVisible = false
},
showDrawer () {
this.param_detail_visible = true
},
Expand Down Expand Up @@ -256,13 +267,24 @@ export default {
this.loadTickets(queryParams)
},
onConfirm (record, status, actionUrl) {
HRequest.post(actionUrl).then(
(response) => {
if (response.status === 200) {
this.$message.success(response.data)
} else this.$message.warning(response.data)
}
)
var postData = {}
if (status === "rejected") {
postData = {"reason": this.rejectReason}
}
this.$message.loading('Action in progress..', 2.5)
HRequest.post(actionUrl, postData).then(() => {
this.$message.info('Ticket ' + status)
this.hideRejectModal()
}).catch((error) => {
const rawMsg = error.response.data.data.description
const msg = rawMsg.length > 300 ? rawMsg.slice(0, 300) + '... ' : rawMsg
this.$notification.title = rawMsg
this.$notification.open({
message: "Ticket " + status + " failed",
description: msg + "\norigin url: " + actionUrl,
duration: 0
})
})
}
},
mounted () {
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/utils/HRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ HRequest.interceptors.response.use((response) => {
}
} else if (error.response.status === 403) {
// 403, insufficient privillege, Redirect to login page
vm.$message.warning('Insufficient privilege!' + error.response.status + ':' + error.response.data)
vm.$message.warning('Insufficient privilege!' + error.response.status + ':' + JSON.stringify(error.response.data))
if (vm.$route.name !== 'Login') {
vm.$router.push({name: 'Login', query: {next: currentPath}})
}
} else if (error.response.status >= 500) {
vm.$message.error('Internal error, please contact webadmin' + error.response.status + ':' + error.response.data)
vm.$message.error('Internal error, please contact webadmin' + error.response.status + ':' + JSON.stringify(error.response.data))
} else {
// > 500 internal error, notify only
// > 404 notify only
vm.$message.warning('Request failed: ' + error.response.status + ':' + error.response.data)
const rawMsg = JSON.stringify(error.response.data)
const msg = rawMsg.length > 150 ? rawMsg.slice(0, 150) + '...' : rawMsg
vm.$message.warning('Request failed: ' + error.response.status + ':' + msg)
}
return Promise.reject(error)
})
Expand Down
9 changes: 7 additions & 2 deletions helpdesk/views/api/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ async def ticket_op(request):
if not execution:
raise ApiError(ApiErrors.unknown_exception, description=msg)
elif op == 'reject':
data = await request.json()
if "reason" in data:
ticket.reason = data["reason"]
ret, msg = ticket.reject(by_user=request.user.name)
if not ret:
raise ApiError(ApiErrors.unrepeatable_operation, description=msg)
Expand Down Expand Up @@ -183,7 +186,7 @@ async def mark_ticket(request):
try:
data = await request.json()
assert 'execution_status' in data, "mark body fields error"
ticket.annotate(execution_status=data["execution_status"])
ticket.annotate(execution_status=data["execution_status"], final_exec_status=True)
logger.debug(f"tocket annotaion: {ticket.annotation}")
# add notification to ticket mark action
await ticket.notify(TicketPhase.MARK)
Expand Down Expand Up @@ -278,9 +281,11 @@ async def ticket_result(request):
# update ticket status by result
if not output_execution_id:
annotation_execution_status = ticket.annotation.get('execution_status')
final_exec_status = ticket.annotation.get('final_exec_status')
try:
exec_status = execution.get('status')
if exec_status and annotation_execution_status != exec_status:
if exec_status and annotation_execution_status != exec_status \
and not final_exec_status:
ticket.annotate(execution_status=exec_status)
await ticket.save()
except AttributeError as e:
Expand Down

0 comments on commit 23b2f80

Please sign in to comment.