mirror of
https://github.com/nocodb/nocodb.git
synced 2026-05-05 05:47:12 +00:00
@@ -0,0 +1,524 @@
|
||||
<template>
|
||||
<v-form v-if="hook" ref="form" v-model="valid" class="mx-auto" lazy-validation>
|
||||
<v-card-title>
|
||||
Webhook / {{ hook.id ? hook.title : 'New' }}
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
outlined
|
||||
tooltip="Save"
|
||||
small
|
||||
:disabled="loading || !valid || !hook.event"
|
||||
@click.prevent="$refs.webhookTest.testWebhook()"
|
||||
>
|
||||
Test webhook
|
||||
</v-btn>
|
||||
<v-btn
|
||||
outlined
|
||||
tooltip="Save"
|
||||
color="primary"
|
||||
small
|
||||
:disabled="loading || !valid || !hook.event"
|
||||
@click.prevent="saveHooks"
|
||||
>
|
||||
<v-icon small left>
|
||||
save
|
||||
</v-icon>
|
||||
<!-- Save -->
|
||||
{{ $t("general.save") }}
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="hook.title"
|
||||
class="caption"
|
||||
outlined
|
||||
dense
|
||||
:label="$t('general.title')"
|
||||
required
|
||||
:rules="[(v) => !!v || `${$t('general.required')}`]"
|
||||
/>
|
||||
|
||||
<webhook-event
|
||||
:event.sync="hook.event"
|
||||
:operation.sync="hook.operation"
|
||||
/>
|
||||
|
||||
<v-card class="mb-8">
|
||||
<v-card-text>
|
||||
<v-checkbox
|
||||
v-model="hook.condition"
|
||||
dense
|
||||
hide-details
|
||||
class="mt-1"
|
||||
label="On Condition"
|
||||
@change="checkConditionAvail"
|
||||
/>
|
||||
|
||||
<column-filter
|
||||
v-if="hook.condition"
|
||||
:key="key"
|
||||
ref="filter"
|
||||
v-model="filters"
|
||||
:meta="meta"
|
||||
:field-list="fieldList"
|
||||
dense
|
||||
style="max-width: 100%"
|
||||
:hook-id="hook.id"
|
||||
web-hook
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
|
||||
<v-select
|
||||
v-model="hook.notification.type"
|
||||
outlined
|
||||
dense
|
||||
:label="$t('general.notification')"
|
||||
required
|
||||
:items="notificationList"
|
||||
:rules="[(v) => !!v || `${$t('general.required')}`]"
|
||||
class="caption"
|
||||
:prepend-inner-icon="notificationIcon[hook.notification.type]"
|
||||
@change="onNotTypeChange"
|
||||
>
|
||||
<template #item="{ item }">
|
||||
<v-list-item-icon>
|
||||
<v-icon small>
|
||||
{{ notificationIcon[item] }}
|
||||
</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-title>
|
||||
{{ item }}
|
||||
</v-list-item-title>
|
||||
</template>
|
||||
</v-select>
|
||||
|
||||
<template v-if="hook.notification.type === 'URL'">
|
||||
<http-webhook v-model="notification" />
|
||||
</template>
|
||||
|
||||
<template v-if="hook.notification.type === 'Slack'">
|
||||
<v-combobox
|
||||
v-if="slackChannels"
|
||||
v-model="notification.channels"
|
||||
:rules="[(v) => !!v || `${$t('general.required')}`]"
|
||||
:items="slackChannels"
|
||||
item-text="channel"
|
||||
label="Select Slack channels"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
class="caption"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="hook.notification.type === 'Microsoft Teams'">
|
||||
<v-combobox
|
||||
v-if="teamsChannels"
|
||||
v-model="notification.channels"
|
||||
:rules="[(v) => !!v || `${$t('general.required')}`]"
|
||||
:items="teamsChannels"
|
||||
item-text="channel"
|
||||
label="Select Teams channels"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
class="caption"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="hook.notification.type === 'Discord'">
|
||||
<v-combobox
|
||||
v-if="discordChannels"
|
||||
v-model="notification.channels"
|
||||
:rules="[(v) => !!v || `${$t('general.required')}`]"
|
||||
:items="discordChannels"
|
||||
item-text="channel"
|
||||
label="Select Discord channels"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
class="caption"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="hook.notification.type === 'Mattermost'">
|
||||
<v-combobox
|
||||
v-if="mattermostChannels"
|
||||
v-model="notification.channels"
|
||||
:rules="[(v) => !!v || `${$t('general.required')}`]"
|
||||
:items="mattermostChannels"
|
||||
item-text="channel"
|
||||
label="Select Mattermost channels"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
class="caption"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-if="inputs[hook.notification.type] && notification">
|
||||
<template v-for="input in inputs[hook.notification.type]">
|
||||
<v-textarea
|
||||
v-if="input.type === 'LongText'"
|
||||
:key="input.key"
|
||||
v-model="notification[input.key]"
|
||||
class="caption"
|
||||
dense
|
||||
outlined
|
||||
:label="input.label"
|
||||
:rules="[
|
||||
(v) =>
|
||||
!input.required || !!v || `${$t('general.required')}`,
|
||||
]"
|
||||
/>
|
||||
<v-text-field
|
||||
v-else
|
||||
:key="input.key"
|
||||
v-model="notification[input.key]"
|
||||
class="caption"
|
||||
dense
|
||||
outlined
|
||||
:label="input.label"
|
||||
:rules="[
|
||||
(v) =>
|
||||
!input.required || !!v || `${$t('general.required')}`,
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text>
|
||||
<span class="caption grey--text">
|
||||
<em>Available context variables are
|
||||
<strong>data and user</strong></em>
|
||||
<v-tooltip top>
|
||||
<template #activator="{ on }">
|
||||
<v-icon
|
||||
small
|
||||
color="grey"
|
||||
class="ml-2"
|
||||
v-on="on"
|
||||
>mdi-information</v-icon>
|
||||
</template>
|
||||
<span class="caption">
|
||||
<strong>data</strong> : Row data <br>
|
||||
<strong>user</strong> : User information<br>
|
||||
</span>
|
||||
</v-tooltip>
|
||||
<br>
|
||||
<a
|
||||
href="https://docs.nocodb.com/developer-resources/webhooks/"
|
||||
>
|
||||
<!--Document Reference-->
|
||||
{{ $t("labels.docReference") }}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<webhooks-test
|
||||
ref="webhookTest"
|
||||
class="mt-3"
|
||||
:model-id="meta.id"
|
||||
hide-test-btn
|
||||
:hook="{
|
||||
...hook,
|
||||
filters,
|
||||
notification: {
|
||||
...hook.notification,
|
||||
payload: notification,
|
||||
},
|
||||
}"
|
||||
/>
|
||||
</v-card-text>
|
||||
</v-form>
|
||||
<span v-else />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WebhooksTest from '~/components/project/tableTabs/webhook/webhooksTest'
|
||||
import WebhookEvent from '~/components/project/tableTabs/webhook/webhookEvent'
|
||||
import HttpWebhook from '~/components/project/tableTabs/webhook/httpWebhook'
|
||||
export default {
|
||||
name: 'WebhookEditor',
|
||||
components: { HttpWebhook, WebhookEvent, WebhooksTest },
|
||||
props: {
|
||||
meta: Object
|
||||
},
|
||||
data: () => ({
|
||||
hook: {
|
||||
notification: {
|
||||
}
|
||||
},
|
||||
valid: false,
|
||||
apps: {},
|
||||
slackChannels: null,
|
||||
teamsChannels: null,
|
||||
discordChannels: null,
|
||||
mattermostChannels: null,
|
||||
enableCondition: false,
|
||||
notificationList: [
|
||||
'URL',
|
||||
'Email',
|
||||
'Slack',
|
||||
'Microsoft Teams',
|
||||
'Discord',
|
||||
'Mattermost',
|
||||
'Twilio',
|
||||
'Whatsapp Twilio'
|
||||
],
|
||||
filters: [],
|
||||
notificationIcon: {
|
||||
URL: 'mdi-link',
|
||||
Email: 'mdi-email',
|
||||
Slack: 'mdi-slack',
|
||||
'Microsoft Teams': 'mdi-microsoft-teams',
|
||||
Discord: 'mdi-discord',
|
||||
Mattermost: 'mdi-chat',
|
||||
'Whatsapp Twilio': 'mdi-whatsapp',
|
||||
Twilio: 'mdi-cellphone-message'
|
||||
},
|
||||
inputs: {
|
||||
Email: [
|
||||
{
|
||||
key: 'to',
|
||||
label: 'To Address',
|
||||
placeholder: 'To Address',
|
||||
type: 'SingleLineText',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'subject',
|
||||
label: 'Subject',
|
||||
placeholder: 'Subject',
|
||||
type: 'SingleLineText',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'body',
|
||||
label: 'Body',
|
||||
placeholder: 'Body',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
Slack: [
|
||||
{
|
||||
key: 'body',
|
||||
label: 'Body',
|
||||
placeholder: 'Body',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
'Microsoft Teams': [
|
||||
{
|
||||
key: 'body',
|
||||
label: 'Body',
|
||||
placeholder: 'Body',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
Discord: [
|
||||
{
|
||||
key: 'body',
|
||||
label: 'Body',
|
||||
placeholder: 'Body',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
Mattermost: [
|
||||
{
|
||||
key: 'body',
|
||||
label: 'Body',
|
||||
placeholder: 'Body',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
Twilio: [
|
||||
{
|
||||
key: 'body',
|
||||
label: 'Body',
|
||||
placeholder: 'Body',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'to',
|
||||
label: 'Comma separated Mobile #',
|
||||
placeholder: 'Comma separated Mobile #',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
'Whatsapp Twilio': [
|
||||
{
|
||||
key: 'body',
|
||||
label: 'Body',
|
||||
placeholder: 'Body',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
key: 'to',
|
||||
label: 'Comma separated Mobile #',
|
||||
placeholder: 'Comma separated Mobile #',
|
||||
type: 'LongText',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
}),
|
||||
created() {
|
||||
this.loadPluginList()
|
||||
},
|
||||
methods: {
|
||||
async loadPluginList() {
|
||||
try {
|
||||
// const plugins = await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'xcPluginList'])
|
||||
const plugins = (await this.$api.plugin.list()).list
|
||||
// plugins.push(...plugins.splice(0, 3))
|
||||
this.apps = plugins.reduce((o, p) => {
|
||||
p.tags = p.tags ? p.tags.split(',') : []
|
||||
p.parsedInput = p.input && JSON.parse(p.input)
|
||||
o[p.title] = p
|
||||
return o
|
||||
}, {})
|
||||
} catch (e) {}
|
||||
},
|
||||
addNewHook() {
|
||||
this.onEventChange()
|
||||
this.$refs.form.resetValidation()
|
||||
},
|
||||
async onNotTypeChange() {
|
||||
this.notification = {}
|
||||
if (this.hook.notification.type === 'Slack') {
|
||||
this.slackChannels =
|
||||
(this.apps && this.apps.Slack && this.apps.Slack.parsedInput) || []
|
||||
}
|
||||
if (this.hook.notification.type === 'Microsoft Teams') {
|
||||
this.teamsChannels =
|
||||
(this.apps &&
|
||||
this.apps['Microsoft Teams'] &&
|
||||
this.apps['Microsoft Teams'].parsedInput) ||
|
||||
[]
|
||||
}
|
||||
if (this.hook.notification.type === 'Discord') {
|
||||
this.discordChannels =
|
||||
(this.apps && this.apps.Discord && this.apps.Discord.parsedInput) ||
|
||||
[]
|
||||
}
|
||||
if (this.hook.notification.type === 'Mattermost') {
|
||||
this.mattermostChannels =
|
||||
(this.apps &&
|
||||
this.apps.Mattermost &&
|
||||
this.apps.Mattermost.parsedInput) ||
|
||||
[]
|
||||
}
|
||||
this.$nextTick(() => this.$refs.form.validate())
|
||||
},
|
||||
async onEventChange() {
|
||||
this.key++
|
||||
if (!this.hooks || !this.hooks.length) {
|
||||
return
|
||||
}
|
||||
const { notification: { payload, type } = {}, ...hook } =
|
||||
this.hooks[this.selectedHook] || {}
|
||||
|
||||
this.hook = {
|
||||
...hook,
|
||||
notification: {
|
||||
type
|
||||
}
|
||||
}
|
||||
// this.enableCondition = !!(this.hook && this.hook.condition && Object.keys(this.hook.condition).length)
|
||||
await this.onNotTypeChange()
|
||||
this.notification = payload
|
||||
if (this.hook.notification.type === 'Slack') {
|
||||
this.notification.webhook_url =
|
||||
this.notification.webhook_url &&
|
||||
this.notification.webhook_url.map(v =>
|
||||
this.slackChannels.find(s => v.webhook_url === s.webhook_url)
|
||||
)
|
||||
}
|
||||
if (this.hook.notification.type === 'Microsoft Teams') {
|
||||
this.notification.webhook_url =
|
||||
this.notification.webhook_url &&
|
||||
this.notification.webhook_url.map(v =>
|
||||
this.teamsChannels.find(s => v.webhook_url === s.webhook_url)
|
||||
)
|
||||
}
|
||||
if (this.hook.notification.type === 'Discord') {
|
||||
this.notification.webhook_url =
|
||||
this.notification.webhook_url &&
|
||||
this.notification.webhook_url.map(v =>
|
||||
this.discordChannels.find(s => v.webhook_url === s.webhook_url)
|
||||
)
|
||||
}
|
||||
if (this.hook.notification.type === 'Mattermost') {
|
||||
this.notification.webhook_url =
|
||||
this.notification.webhook_url &&
|
||||
this.notification.webhook_url.map(v =>
|
||||
this.mattermostChannels.find(s => v.webhook_url === s.webhook_url)
|
||||
)
|
||||
}
|
||||
if (this.hook.notification.type === 'URL') {
|
||||
//
|
||||
}
|
||||
},
|
||||
async saveHooks() {
|
||||
if (!this.$refs.form.validate() || !this.valid || !this.hook.event) {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
try {
|
||||
let res
|
||||
if (this.hook.id) {
|
||||
res = await this.$api.dbTableWebhook.update(this.hook.id, {
|
||||
...this.hook,
|
||||
notification: {
|
||||
...this.hook.notification,
|
||||
payload: this.notification
|
||||
}
|
||||
})
|
||||
} else {
|
||||
res = await this.$api.dbTableWebhook.create(this.meta.id, {
|
||||
...this.hook,
|
||||
notification: {
|
||||
...this.hook.notification,
|
||||
payload: this.notification
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!this.hook.id && res) {
|
||||
this.hook.id = res.id
|
||||
}
|
||||
if (this.$refs.filter) {
|
||||
await this.$refs.filter.applyChanges(false, {
|
||||
hookId: this.hook.id
|
||||
})
|
||||
}
|
||||
|
||||
this.$toast
|
||||
.success('Webhook details updated successfully')
|
||||
.goAway(3000)
|
||||
} catch (e) {
|
||||
this.$toast.error(e.message).goAway(3000)
|
||||
}
|
||||
this.loading = false
|
||||
|
||||
this.$e('a:webhook:add', {
|
||||
operation: this.hook.operation,
|
||||
condition: this.hook.condition,
|
||||
notification: this.hook.notification.type
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<v-select
|
||||
v-model="hookEvent"
|
||||
class="caption"
|
||||
outlined
|
||||
dense
|
||||
label="Event"
|
||||
required
|
||||
:items="eventList"
|
||||
:item-text="v => v.text.join(' ')"
|
||||
:item-value="v => v.value.join(' ')"
|
||||
:rules="[v => !!v || 'Event Required']"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'WebhookEvent',
|
||||
props: ['operation', 'event'],
|
||||
data: () => ({
|
||||
eventList: [
|
||||
// {text: ["Before", "Insert"], value: ['before', 'insert']},
|
||||
{ text: ['After', 'Insert'], value: ['after', 'insert'] },
|
||||
// {text: ["Before", "Update"], value: ['before', 'update']},
|
||||
{ text: ['After', 'Update'], value: ['after', 'update'] },
|
||||
// {text: ["Before", "Delete"], value: ['before', 'delete']},
|
||||
{ text: ['After', 'Delete'], value: ['after', 'delete'] }
|
||||
]
|
||||
}),
|
||||
computed: {
|
||||
hookEvent: {
|
||||
get() {
|
||||
return `${this.event} ${this.operation}`
|
||||
},
|
||||
set(v) {
|
||||
const [event, operation] = v.split(' ')
|
||||
this.$emit('update:event', event)
|
||||
this.$emit('update:operation', operation)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-card-title>
|
||||
Webhook
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
outlined
|
||||
tooltip="Save"
|
||||
small
|
||||
>
|
||||
Create webhook
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<div v-if="hooks" class="pa-4">
|
||||
<v-card v-for="hook in hooks" v-ripple class="elevation-0 backgroundColor">
|
||||
<div class="pa-4 ">
|
||||
<h4 class="nc-text">
|
||||
{{ hook.title }}
|
||||
</h4>
|
||||
<div class="d-flex">
|
||||
<!--Title-->
|
||||
<span class="caption textColor1--text">{{ $t("general.event") }} : {{ hook.event }} {{ hook.operation }}</span>
|
||||
<v-spacer />
|
||||
<!--Notify Via-->
|
||||
<span class="caption textColor1--text">{{ $t("labels.notifyVia") }} : {{ hook.notification && hook.notification.type }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</div>
|
||||
|
||||
<!-- <v-simple-table dense>
|
||||
<template #default>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<!–Title–>
|
||||
{{ $t("general.title") }}
|
||||
</th>
|
||||
<th>
|
||||
<!–Event–>
|
||||
{{ $t("general.event") }}
|
||||
</th>
|
||||
<th>
|
||||
<!–Condition–>
|
||||
{{ $t("general.condition") }}
|
||||
</th>
|
||||
<th>
|
||||
<!–Notify Via–>
|
||||
{{ $t("labels.notifyVia") }}
|
||||
</th>
|
||||
<th>
|
||||
<!–Action–>
|
||||
{{ $t("labels.action") }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<template v-if="hooks && hooks.length">
|
||||
<tr v-for="(item, i) in hooks" :key="i">
|
||||
<td>{{ item.title }}</td>
|
||||
<td>{{ item.event }} {{ item.operation }}</td>
|
||||
<td>
|
||||
<v-icon v-if="item.condition" color="success" small>
|
||||
mdi-check-bold
|
||||
</v-icon>
|
||||
</td>
|
||||
<td>
|
||||
{{ item.notification && item.notification.type }}
|
||||
</td>
|
||||
<td>
|
||||
<x-icon
|
||||
small
|
||||
color="error"
|
||||
@click.stop="deleteHook(item, i)"
|
||||
>
|
||||
mdi-delete
|
||||
</x-icon>
|
||||
<!– <x-icon small :color="loading || !valid || !hook.event ? 'grey' : 'primary'"
|
||||
@click.stop="(!loading && valid && hook.event) && saveHooks()">save
|
||||
</x-icon>–>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
<tr>
|
||||
<td colspan="6" class="text-center py-5">
|
||||
<!–:tooltip="$t('tooltip.saveChanges')"–>
|
||||
<x-btn
|
||||
v-ge="['hooks', 'add new']"
|
||||
outlined
|
||||
color="primary"
|
||||
small
|
||||
@click.prevent="$emit('add')"
|
||||
>
|
||||
<v-icon small left>
|
||||
mdi-plus
|
||||
</v-icon>
|
||||
<!–Add New Webhook–>
|
||||
{{ $t("activity.addWebhook") }}
|
||||
</x-btn>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</template>
|
||||
</v-simple-table>-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'WebhookList',
|
||||
props: { meta: Object },
|
||||
data: () => ({
|
||||
hooks: null, loading: false
|
||||
}),
|
||||
mounted() {
|
||||
this.loadHooksList()
|
||||
},
|
||||
methods: {
|
||||
async loadHooksList() {
|
||||
this.key++
|
||||
this.loading = true
|
||||
|
||||
const hooks = await this.$api.dbTableWebhook.list(this.meta.id)
|
||||
|
||||
this.hooks = hooks.list.map((h) => {
|
||||
h.notification = h.notification && JSON.parse(h.notification)
|
||||
return h
|
||||
})
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<v-dialog v-model="webhookModal" width="min(700px,90%)" overlay-opacity=".9">
|
||||
<v-card
|
||||
v-if="webhookModal"
|
||||
width="100%"
|
||||
min-height="350px"
|
||||
class="pa-4"
|
||||
>
|
||||
<webhook-editor v-if="editOrAdd" :meta="meta" />
|
||||
<webhook-list v-else :meta="meta" @edit="editOrAdd=true" @add="editOrAdd=true" />
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import WebhookList from '~/components/project/tableTabs/webhook/webhookList'
|
||||
import WebhookEditor from '~/components/project/tableTabs/webhook/webhookEditor'
|
||||
export default {
|
||||
name: 'WebhookModal',
|
||||
components: { WebhookEditor, WebhookList },
|
||||
props: {
|
||||
meta: Object,
|
||||
value: Boolean
|
||||
},
|
||||
data: () => ({
|
||||
editOrAdd: false,
|
||||
activePage: 'role'
|
||||
}),
|
||||
computed: {
|
||||
webhookModal: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(v) {
|
||||
this.$emit('input', v)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<div>
|
||||
<h5 @click="isVisible=!isVisible">
|
||||
Sample payload <v-icon x-small>
|
||||
mdi-chevron-{{ isVisible? 'up' : 'down' }}
|
||||
</v-icon>
|
||||
</h5>
|
||||
<div :class="{active:isVisible}" class="nc-sample-data">
|
||||
<monaco-json-object-editor v-model="sampleData" read-only style="min-height: 300px" class="caption mb-2 " />
|
||||
</div>
|
||||
<v-btn v-if="!hideTestBtn" small @click="testWebhook">
|
||||
Test webhook
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MonacoJsonObjectEditor from '~/components/monaco/MonacoJsonObjectEditor'
|
||||
export default {
|
||||
name: 'WebhooksTest',
|
||||
components: { MonacoJsonObjectEditor },
|
||||
props: {
|
||||
modelId: String,
|
||||
hook: Object,
|
||||
hideTestBtn: Boolean
|
||||
},
|
||||
data: () => ({
|
||||
sampleData: null,
|
||||
isVisible: false
|
||||
}),
|
||||
watch: {
|
||||
async 'hook.operation'() {
|
||||
await this.loadSampleData()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadSampleData()
|
||||
},
|
||||
methods: {
|
||||
async loadSampleData() {
|
||||
this.sampleData = {
|
||||
data: (await this.$api.dbTableWebhook.samplePayloadGet(this.modelId, this.hook.operation)),
|
||||
user: this.$store.state.users.user
|
||||
}
|
||||
},
|
||||
async testWebhook() {
|
||||
try {
|
||||
await this.$api.dbTableWebhook.test(this.modelId, {
|
||||
hook: this.hook,
|
||||
payload: this.sampleData
|
||||
})
|
||||
|
||||
this.$toast.success('Webhook tested successfully').goAway(3000)
|
||||
} catch (e) {
|
||||
const msg = await this._extractSdkResponseErrorMsg(e)
|
||||
this.$toast.error(msg).goAway(3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/*tr.selected{*/
|
||||
/* background: #8ceaf6;*/
|
||||
/*}*/
|
||||
|
||||
/deep/ label {
|
||||
font-size: 0.75rem !important
|
||||
}
|
||||
|
||||
.nc-sample-data{
|
||||
overflow-y: hidden;
|
||||
height:0;
|
||||
transition: .3s height;
|
||||
}
|
||||
.nc-sample-data.active{
|
||||
height:300px
|
||||
}
|
||||
</style>
|
||||
<!--
|
||||
/**
|
||||
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
|
||||
*
|
||||
* @author Naveen MR <oof1lab@gmail.com>
|
||||
* @author Pranav C Balan <pranavxc@gmail.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
-->
|
||||
Reference in New Issue
Block a user