Browse Source

wip: improved webhook gui

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/1917/head
Pranav C 2 years ago
parent
commit
9303fd8a4c
  1. 129
      packages/nc-gui/components/monaco/MonacoHandlebarEditor.js
  2. 3
      packages/nc-gui/components/monaco/index.js
  3. 34
      packages/nc-gui/components/project/tableTabs/webhook/httpWebhook.vue
  4. 42
      packages/nc-gui/components/project/tableTabs/webhook/webhookEditor.vue
  5. 80
      packages/nc-gui/components/project/tableTabs/webhook/webhookList.vue
  6. 13
      packages/nc-gui/components/project/tableTabs/webhook/webhookModal.vue

129
packages/nc-gui/components/monaco/MonacoHandlebarEditor.js

@ -0,0 +1,129 @@
/* eslint-disable */
// import assign from "nano-assign";
// import sqlAutoCompletions from "./sqlAutoCompletions";
// import {ext} from "vee-validate/dist/rules.esm";
export default {
name: "MonacoHandlebarEditor",
props: {
value: {
default: "",
type: String
},
theme: {
type: String,
default: "vs-dark"
},
},
model: {
event: "change"
},
watch: {
value(newVal) {
if (newVal !== this.editor.getValue()) {
if (typeof newVal === 'object') {
this.editor.setValue(JSON.stringify(newVal, 0, 2));
} else {
this.editor.setValue(newVal);
}
}
}
},
mounted() {
this.$nextTick(() => {
if (this.amdRequire) {
this.amdRequire(["vs/editor/editor.main"], () => {
this.initMonaco(window.monaco);
});
} else {
// ESM format so it can't be resolved by commonjs `require` in eslint
// eslint-disable import/no-unresolved
const monaco = require("monaco-editor");
// monaco.editor.defineTheme('monokai', require('./Cobalt.json'))
// monaco.editor.setTheme('monokai')
this.monaco = monaco;
// this.completionItemProvider = monaco.languages.registerCompletionItemProvider("sql", {
// async provideCompletionItems(model, position) {
// // console.log(sqlAutoCompletions(monaco).actions[0])
// console.log(model === vm.editor,model,vm.editor)
// return model === vm.editor.getModel() ? {suggestions: await vm.getLiveSuggestionsList(model, position)} : {};
// }
// });
this.initMonaco(monaco);
}
});
},
unmounted() {
},
beforeDestroy() {
this.editor && this.editor.dispose();
},
methods: {
initMonaco(monaco) {
const typescriptCode = this.value;
const model = monaco.editor.createModel(typescriptCode);
this.editor = monaco.editor.create(this.$el, {
model: model,
theme: this.theme
});
this.editor.onDidChangeModelContent(event => {
const value = this.editor.getValue();
if (this.value !== value) {
this.$emit("change", value, event);
}
});
},
getMonaco() {
return this.editor;
},
getMonacoModule() {
return this.monaco;
},
},
render(h) {
return h("div");
},
created() {
},
destroyed() {
}
};
/**
* @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/>.
*
*/

3
packages/nc-gui/components/monaco/index.js

@ -1,10 +1,11 @@
import MonacoEditor from './MonacoEditor'
import MonacoJsonEditor from './MonacoJsonEditor'
import MonacoSingleLineEditor from './MonacoSingleLineEditor'
import MonacoHandlebarEditor from './MonacoHandlebarEditor'
export default MonacoEditor
export { MonacoJsonEditor, MonacoSingleLineEditor }
export { MonacoJsonEditor, MonacoSingleLineEditor, MonacoHandlebarEditor }
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.component(MonacoEditor.name, MonacoEditor)

34
packages/nc-gui/components/project/tableTabs/webhook/httpWebhook.vue

@ -23,6 +23,9 @@
class="req-tabs"
height="24"
>
<v-tab v-ge="['api-client','body']" class="caption">
<span class="text-capitalize">Body</span>
</v-tab>
<v-tab v-ge="['api-client','params']" class="caption">
<span class="text-capitalize"> Params&nbsp;<b
v-if="paramsCount"
@ -37,12 +40,19 @@
headersCount
}})</b></span>
</v-tab>
<v-tab v-ge="['api-client','body']" class="caption">
<span class="text-capitalize">Body</span>
</v-tab>
<v-tab v-ge="['api-client','auth']" class="caption">
<span class="text-capitalize">Auth</span>
</v-tab>
<v-tab-item>
<monaco-handlebar-editor
v-model="api.body"
style="height: 250px"
class="editor card text-left"
theme="vs-dark"
lang="json"
:options="{validate:true,documentFormattingEdits:true,foldingRanges:true}"
/>
</v-tab-item>
<v-tab-item>
<params
v-model="api.parameters"
@ -55,23 +65,13 @@
:env.sync="selectedEnv"
/>
</v-tab-item>
<v-tab-item>
<monaco-json-editor
v-model="api.body"
style="height: 250px"
class="editor card text-left"
theme="vs-dark"
lang="json"
:options="{validate:true,documentFormattingEdits:true,foldingRanges:true}"
/>
</v-tab-item>
<v-tab-item>
<monaco-json-editor
<monaco-handlebar-editor
v-model="api.auth"
style="height: 250px"
class="editor card text-left"
theme="vs-dark"
lang="json"
:options="{validate:true,documentFormattingEdits:true,foldingRanges:true}"
/>
<span class="caption grey--text">For more about auth option refer <a href="https://github.com/axios/axios#request-config" target="_blank">axios docs</a>.</span>
@ -84,7 +84,7 @@
import params from '../../../apiClient/params'
import headers from '../../../apiClient/headers'
import { MonacoJsonEditor } from '../../../monaco/index'
import { MonacoHandlebarEditor } from '../../../monaco/index'
export default {
tab: 0,
@ -92,7 +92,7 @@ export default {
components: {
params,
headers,
MonacoJsonEditor
MonacoHandlebarEditor
},
props: {
value: Object

42
packages/nc-gui/components/project/tableTabs/webhook/webhookEditor.vue

@ -1,7 +1,17 @@
<template>
<v-form v-if="hook" ref="form" v-model="valid" class="mx-auto" lazy-validation>
<v-form v-if="hook" ref="form" v-model="valid" class="mx-4" lazy-validation>
<v-card-title>
Webhook / {{ hook.id ? hook.title : 'New' }}
<a class="pointer mr-1" @click="$emit('backToList')">
<v-icon>mdi-arrow-left-bold</v-icon>
</a>
<v-spacer />
{{ meta.title }} : {{ hook.title || 'Webhook' }}
<v-spacer />
<div style="width: 24px;height: 24px" />
</v-card-title>
<div class="mx-4 d-flex m-2">
<v-spacer />
<v-btn
outlined
@ -26,7 +36,8 @@
<!-- Save -->
{{ $t("general.save") }}
</v-btn>
</v-card-title>
</div>
<v-card-text>
<v-text-field
v-model="hook.title"
@ -43,7 +54,7 @@
:operation.sync="hook.operation"
/>
<v-card class="mb-8">
<v-card class="mb-8 nc-filter-wrapper">
<v-card-text>
<v-checkbox
v-model="hook.condition"
@ -51,7 +62,6 @@
hide-details
class="mt-1"
label="On Condition"
@change="checkConditionAvail"
/>
<column-filter
@ -236,15 +246,17 @@
import WebhooksTest from '~/components/project/tableTabs/webhook/webhooksTest'
import WebhookEvent from '~/components/project/tableTabs/webhook/webhookEvent'
import HttpWebhook from '~/components/project/tableTabs/webhook/httpWebhook'
import ColumnFilter from '~/components/project/spreadsheet/components/columnFilter'
export default {
name: 'WebhookEditor',
components: { HttpWebhook, WebhookEvent, WebhooksTest },
components: { ColumnFilter, HttpWebhook, WebhookEvent, WebhooksTest },
props: {
meta: Object
},
data: () => ({
hook: {
notification: {
type: 'URL'
}
},
valid: false,
@ -416,15 +428,14 @@ export default {
this.apps.Mattermost.parsedInput) ||
[]
}
if (this.hook.notification.type === 'URL') {
this.notification = this.notification || {}
this.$set(this.notification, 'body', '{{ json data }}')
}
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] || {}
const { notification: { payload, type } = {}, ...hook } = this.hook
this.hook = {
...hook,
@ -464,7 +475,8 @@ export default {
)
}
if (this.hook.notification.type === 'URL') {
//
this.notification = this.notification || {}
this.$set(this.notification, 'body', this.notification.body || '{{ json data }}')
}
},
async saveHooks() {
@ -520,5 +532,7 @@ export default {
</script>
<style scoped>
/deep/ .nc-filter-wrapper label {
font-size: 0.75rem !important;
}
</style>

80
packages/nc-gui/components/project/tableTabs/webhook/webhookList.vue

@ -1,33 +1,47 @@
<template>
<div>
<v-card-title>
Webhook
Webhooks
<v-spacer />
<v-btn
outlined
tooltip="Save"
small
@click.prevent="$emit('add')"
>
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 v-if="hooks " class="pa-4">
<template v-if=" hooks.length">
<v-card v-for="(hook,i) in hooks" :key="hook.id" class="elevation-0 backgroundColor nc-hook" @click="$emit('edit', hook)">
<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>
</div>
</v-card>
<v-icon class="nc-hook-delete-icon" small @click.stop="deleteHook(hook,i)">
mdi-delete-outline
</v-icon>
</v-card>
</template>
<div v-else class="pa-4 backgroundColor caption textColor--text text--lighten-3">
Webhooks list is empty, create new webhook by clicking 'Create webhook' button.
</div>
</div>
<!-- <v-simple-table dense>
@ -130,11 +144,43 @@ export default {
return h
})
this.loading = false
},
async deleteHook(item, i) {
try {
if (item.id) {
await this.$api.dbTableWebhook.delete(item.id)
this.hooks.splice(i, 1)
} else {
this.hooks.splice(i, 1)
}
this.$toast.success('Hook deleted successfully').goAway(3000)
if (!this.hooks.length) {
this.hook = null
}
} catch (e) {
this.$toast.error(e.message).goAway(3000)
}
this.$e('a:webhook:delete')
}
}
}
</script>
<style scoped>
<style scoped lang="scss">
.nc-hook {
position: relative;
.nc-hook-delete-icon {
position: absolute;
opacity: 0;
transition: .3s opacity;
right: 16px;
top: 16px
}
&:hover .nc-hook-delete-icon {
opacity: 1;
}
}
</style>

13
packages/nc-gui/components/project/tableTabs/webhook/webhookModal.vue

@ -6,8 +6,8 @@
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" />
<webhook-editor v-if="editOrAdd" ref="editor" :meta="meta" @backToList="editOrAdd = false" />
<webhook-list v-else :meta="meta" @edit="editHook" @add="editOrAdd = true" />
</v-card>
</v-dialog>
</template>
@ -36,6 +36,15 @@ export default {
this.$emit('input', v)
}
}
},
methods: {
editHook(hook) {
this.editOrAdd = true
this.$nextTick(() => {
this.$refs.editor.hook = { ...hook }
this.$refs.editor.onEventChange()
})
}
}
}
</script>

Loading…
Cancel
Save