| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| <template> |
| <div class="form-layout"> |
| <div v-if="(resource || payloadUrl)"> |
| <a-divider /> |
| <a-collapse |
| v-model:activeKey="collapseKey"> |
| <a-collapse-panel |
| :showArrow="isResponseNotEmpty" |
| key="1" |
| :collapsible="(resource || payloadUrl) ? 'enabled' : 'disabled'"> |
| <template #header> |
| <a-row style="width: 100%;"> |
| <a-col :span="22"> |
| <tooltip-label :title="$t('label.status')" v-if="isNotShowStatus"/> |
| <status class="status" :text="response.success ? 'success' : 'error'" displayText v-else/> |
| </a-col> |
| <a-col :span="2"> |
| <div v-if="showActions"> |
| <a-spin :spinning="loading" size="small" v-if="loading" /> |
| <div v-else> |
| <a-button |
| type="primary" |
| size="small" |
| @click.stop="testWebhookDelivery"> |
| <render-icon icon="reload-outlined" /> |
| <div class="ant-btn__progress-overlay" :style="computedOverlayStyle"></div> |
| </a-button> |
| </div> |
| </div> |
| </a-col> |
| </a-row> |
| </template> |
| <div v-if="isResponseNotEmpty"> |
| <a-row> |
| <a-col :span="8"> |
| <div class="response-detail-item" v-if="('success' in response)"> |
| <div class="response-detail-item__label"><strong>{{ $t('label.success') }}</strong></div> |
| <div class="response-detail-item__details"> |
| <status class="status" :text="response.success ? 'success' : 'error'"/> |
| </div> |
| </div> |
| </a-col> |
| <a-col :span="8"> |
| <div class="response-detail-item" v-if="response.startdate && response.enddate"> |
| <div class="response-detail-item__label"><strong>{{ $t('label.duration') }}</strong></div> |
| <div class="response-detail-item__details"> |
| {{ responseDuration }} |
| </div> |
| </div> |
| </a-col> |
| <a-col :span="8"> |
| <div class="response-detail-item" v-if="response.managementserverid"> |
| <div class="response-detail-item__label"><strong>{{ $t('label.managementserverid') }}</strong></div> |
| <div class="response-detail-item__details"> |
| {{ response.managementservername }} |
| </div> |
| </div> |
| </a-col> |
| </a-row> |
| <a-alert |
| :type="response.success ? 'success' : 'error'" |
| :showIcon="true" |
| :message="$t('label.response')" |
| :description="response.response ? response.response : 'Empty response'" /> |
| </div> |
| </a-collapse-panel> |
| </a-collapse> |
| <a-divider /> |
| </div> |
| </div> |
| </template> |
| |
| <script> |
| import { postAPI } from '@/api' |
| import TooltipLabel from '@/components/widgets/TooltipLabel' |
| import Status from '@/components/widgets/Status' |
| |
| export default { |
| name: 'TestWebhookDeliveryView', |
| components: { |
| TooltipLabel, |
| Status |
| }, |
| props: { |
| resource: { |
| type: Object |
| }, |
| payload: { |
| type: String |
| }, |
| payloadUrl: { |
| type: String |
| }, |
| sslVerification: { |
| type: Boolean, |
| default: false |
| }, |
| secretKey: { |
| type: String |
| }, |
| showActions: { |
| type: Boolean, |
| default: false |
| } |
| }, |
| data () { |
| return { |
| response: {}, |
| collapseKey: undefined, |
| loading: false, |
| testDeliveryInterval: null, |
| testDeliveryIntervalCouter: 0 |
| } |
| }, |
| beforeCreate () { |
| this.timedDeliveryWait = 4000 |
| }, |
| beforeUnmount () { |
| this.resetTestDeliveryInterval() |
| }, |
| computed: { |
| isResponseNotEmpty () { |
| return this.response && Object.keys(this.response).length > 0 |
| }, |
| isNotShowStatus () { |
| return !this.isResponseNotEmpty || |
| this.collapseKey === '1' || |
| (Array.isArray(this.collapseKey) && |
| this.collapseKey.length > 0 && |
| this.collapseKey[0] === '1') |
| }, |
| responseDuration () { |
| if (!this.response.startdate || !this.response.enddate) { |
| return '' |
| } |
| var duration = Date.parse(this.response.enddate) - Date.parse(this.response.startdate) |
| return (duration > 0 ? duration / 1000.0 : 0) + '' |
| }, |
| computedOverlayStyle () { |
| var opacity = this.testDeliveryIntervalCouter <= 10.0 ? 0 : 0.3 |
| var width = this.testDeliveryIntervalCouter |
| return 'opacity: ' + opacity + '; width: ' + width + '%;' |
| } |
| }, |
| methods: { |
| validateUrl (url) { |
| const urlPattern = /^(http|https):\/\/[^ "]+$/ |
| urlPattern.test(url) |
| }, |
| resetTestDeliveryInterval () { |
| if (this.testDeliveryInterval) { |
| clearInterval(this.testDeliveryInterval) |
| } |
| this.testDeliveryIntervalCouter = 0 |
| }, |
| testWebhookDelivery () { |
| this.resetTestDeliveryInterval() |
| this.response = {} |
| this.loading = true |
| this.$emit('change-loading', this.loading) |
| var params = {} |
| if (this.resource) { |
| params.webhookid = this.resource.id |
| } |
| if (this.payload) { |
| params.payload = this.payload |
| } |
| if (this.payloadUrl) { |
| params.payloadUrl = this.payloadUrl |
| } |
| if (this.sslVerification) { |
| params.payload = this.sslVerification |
| } |
| if (this.secretKey) { |
| params.secretKey = this.secretKey |
| } |
| postAPI('executeWebhookDelivery', params).then(response => { |
| this.response = response.executewebhookdeliveryresponse.webhookdelivery |
| this.$emit('update-success', response.success) |
| }).catch(error => { |
| this.$notifyError(error) |
| }).finally(() => { |
| this.loading = false |
| this.$emit('change-loading', this.loading) |
| }) |
| }, |
| getNormalizedPayloadUrl () { |
| if (!this.payloadUrl || this.payloadUrl === '' || this.validateUrl(this.payloadUrl)) { |
| return this.payloadUrl |
| } |
| return 'http://' + this.payloadUrl |
| }, |
| executeTestWebhookDeliveryOrReset () { |
| const url = this.getNormalizedPayloadUrl() |
| if (url) { |
| this.testWebhookDelivery() |
| return |
| } |
| this.resetTestDeliveryInterval() |
| }, |
| timedTestWebhookDelivery () { |
| const url = this.getNormalizedPayloadUrl() |
| this.resetTestDeliveryInterval() |
| this.testDeliveryInterval = setInterval(() => { |
| if (!url) { |
| this.resetTestDeliveryInterval() |
| return |
| } |
| this.testDeliveryIntervalCouter = this.testDeliveryIntervalCouter + 1 |
| if (this.testDeliveryIntervalCouter >= 100) { |
| this.executeTestWebhookDeliveryOrReset() |
| } |
| }, this.timedDeliveryWait / 100) |
| } |
| } |
| } |
| </script> |
| |
| <style scoped lang="scss"> |
| .response-detail-item { |
| margin-bottom: 20px; |
| word-break: break-all; |
| |
| &__details { |
| display: flex; |
| align-items: center; |
| |
| &--start { |
| align-items: flex-start; |
| |
| i { |
| margin-top: 4px; |
| } |
| |
| } |
| |
| } |
| |
| .anticon { |
| margin-right: 10px; |
| } |
| |
| &__label { |
| margin-bottom: 5px; |
| font-weight: bold; |
| } |
| } |
| |
| .ant-btn .ant-btn__progress-overlay { |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| z-index: 5; |
| opacity: 0.3; |
| transition: all 0s ease; |
| position: absolute; |
| left: 0; |
| top: 0; |
| background-color: #666; |
| } |
| </style> |