Browse Source

refactor: webhook ui improvements

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/2068/head
Pranav C 2 years ago
parent
commit
eec922f1a9
  1. 67
      packages/nc-gui/components/global/NcSlider.vue
  2. 11
      packages/nc-gui/components/project/auditTab/Audit.vue
  3. 5
      packages/nc-gui/components/project/spreadsheet/components/MoreActions.vue
  4. 18
      packages/nc-gui/components/project/spreadsheet/components/SpreadsheetNavDrawer.vue
  5. 174
      packages/nc-gui/components/project/tableTabs/webhook/WebhookEditor.vue
  6. 134
      packages/nc-gui/components/project/tableTabs/webhook/WebhookList.vue
  7. 64
      packages/nc-gui/components/project/tableTabs/webhook/WebhookSlider.vue
  8. 11
      packages/nc-gui/helpers/index.js

67
packages/nc-gui/components/global/NcSlider.vue

@ -0,0 +1,67 @@
<template>
<div class="nc-container" :class="{active:modal}" @click="modal=false">
<div class="nc-content elevation-3 pa-4" @click.stop>
<slot />
</div>
</div>
</template>
<script>
export default {
name: 'NcSlider',
props: {
value: Boolean
},
computed: {
modal: {
get() {
return this.value
},
set(v) {
this.$emit('input', v)
}
}
},
mounted() {
(document.querySelector('[data-app]') || this.$root.$el).append(this.$el)
},
destroyed() {
this.$el.parentNode && this.$el.parentNode.removeChild(this.$el)
}
}
</script>
<style scoped lang="scss">
.nc-container {
position: fixed;
pointer-events: none;
width: 100vw;
height: 100vh;
z-index: 9999;
right: 0;
top: 0;
.nc-content {
background-color: var(--v-backgroundColorDefault-base);
height: 100%;
width: max(50%, 700px);
position: absolute;
bottom: 0;
top: 0;
right: min(-50%, -700px);
transition: .3s right;
}
&.active {
pointer-events: all;
& > .nc-content {
right: 0
}
}
}
</style>

11
packages/nc-gui/components/project/auditTab/Audit.vue

@ -81,12 +81,7 @@
</template>
<script>
import dayjs from 'dayjs'
const relativeTime = require('dayjs/plugin/relativeTime')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
dayjs.extend(relativeTime)
import { calculateDiff } from '~/helpers'
export default {
name: 'Audit',
@ -116,9 +111,7 @@ export default {
this.audits = list
this.count = pageInfo.totalRows
},
calculateDiff(date) {
return dayjs.utc(date).fromNow()
}
calculateDiff
}
}
</script>

5
packages/nc-gui/components/project/spreadsheet/components/MoreActions.vue

@ -104,7 +104,8 @@
:parsed-csv="parsedCsv"
@import="importData"
/>
<webhook-modal v-if="webhookModal" v-model="webhookModal" :meta="meta" />
<!-- <webhook-modal v-if="webhookModal" v-model="webhookModal" :meta="meta" />-->
<webhook-slider v-model="webhookModal" :meta="meta" />
</div>
</template>
@ -117,10 +118,12 @@ import ColumnMappingModal from '~/components/project/spreadsheet/components/impo
import CSVTemplateAdapter from '~/components/import/templateParsers/CSVTemplateAdapter'
import { UITypes } from '~/components/project/spreadsheet/helpers/uiTypes'
import WebhookModal from '~/components/project/tableTabs/webhook/WebhookModal'
import WebhookSlider from '~/components/project/tableTabs/webhook/WebhookSlider'
export default {
name: 'ExportImport',
components: {
WebhookSlider,
WebhookModal,
ColumnMappingModal,
DropOrSelectFileModal

18
packages/nc-gui/components/project/spreadsheet/components/SpreadsheetNavDrawer.vue

@ -286,6 +286,20 @@
</v-btn>
<code-snippet v-model="codeSnippetModal" :query-params="queryParams" :meta="meta" :view="selectedView" />
</div>
<div>
<v-btn
v-t="['c:actions:webhook']"
color="primary"
outlined
class="caption d-100 mt-2"
@click="webhookSliderModal=true"
>
<v-icon small class="mr-2">
mdi-hook
</v-icon> Webhooks
</v-btn>
<webhook-slider v-model="webhookSliderModal" :meta="meta" />
</div>
<div
v-if="time - $store.state.settings.miniSponsorCard > 15 * 60 * 1000"
@ -524,10 +538,11 @@ import viewIcons from '~/helpers/viewIcons'
import { copyTextToClipboard } from '~/helpers/xutils'
import SponsorMini from '~/components/SponsorMini'
import CodeSnippet from '~/components/project/spreadsheet/components/CodeSnippet'
import WebhookSlider from '~/components/project/tableTabs/webhook/WebhookSlider'
export default {
name: 'SpreadsheetNavDrawer',
components: { CodeSnippet, SponsorMini, Extras, CreateViewDialog, draggable },
components: { WebhookSlider, CodeSnippet, SponsorMini, Extras, CreateViewDialog, draggable },
props: {
extraViewParams: Object,
showAdvanceOptions: Boolean,
@ -563,6 +578,7 @@ export default {
queryParams: Object
},
data: () => ({
webhookSliderModal: false,
codeSnippetModal: false,
drag: false,
dragOptions: {

174
packages/nc-gui/components/project/tableTabs/webhook/WebhookEditor.vue

@ -1,42 +1,41 @@
<template>
<v-form v-if="hook" ref="form" v-model="valid" class="mx-4" lazy-validation>
<v-card-title>
<a class="pointer mr-1" @click="$emit('backToList')">
<v-icon>mdi-arrow-left-bold</v-icon>
<div>
<a class="pointer mx-4" @click="$emit('backToList')">
<v-icon class="ml-n1">mdi-arrow-left-bold</v-icon>
</a>
<v-spacer />
</div>
<v-card-title>
{{ 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
tooltip="Save"
small
:disabled="loading || !valid || !hook.event"
@click.prevent="$refs.webhookTest.testWebhook()"
>
Test webhook
</v-btn>
<v-btn
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>
</div>
<div class="d-flex ">
<v-spacer />
<v-btn
outlined
tooltip="Save"
small
:disabled="loading || !valid || !hook.event"
@click.prevent="$refs.webhookTest.testWebhook()"
>
Test webhook
</v-btn>
<v-btn
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>
</div>
</v-card-title>
<v-divider class="my-4" />
<v-card-text>
<v-text-field
v-model="hook.title"
@ -47,61 +46,38 @@
required
:rules="[(v) => !!v || `${$t('general.required')}`]"
/>
<webhook-event
:event.sync="hook.event"
:operation.sync="hook.operation"
/>
<v-card class="mb-8 nc-filter-wrapper">
<v-card-text>
<v-checkbox
v-model="hook.condition"
dense
hide-details
class="mt-1"
label="On Condition"
<v-row>
<v-col>
<webhook-event
:event.sync="hook.event"
:operation.sync="hook.operation"
/>
<column-filter
v-if="hook.condition"
:key="key"
ref="filter"
v-model="filters"
:meta="meta"
:field-list="fieldList"
</v-col><v-col>
<v-select
v-model="hook.notification.type"
outlined
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>
: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>
</v-col>
</v-row>
<template v-if="hook.notification.type === 'URL'">
<http-webhook v-model="notification" />
</template>
@ -195,6 +171,32 @@
</template>
</v-card-text>
<v-card-text>
<v-card class=" nc-filter-wrapper ">
<v-card-text>
<v-checkbox
v-model="hook.condition"
dense
hide-details
class="mt-1"
label="On Condition"
/>
<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-card-text>
<v-card-text>
<span class="caption grey--text">
<em>Available context variables are

134
packages/nc-gui/components/project/tableTabs/webhook/WebhookList.vue

@ -1,7 +1,7 @@
<template>
<div>
<v-card-title>
Webhooks
<span class="text-capitalize mr-1">{{ meta.title }}</span> : Webhooks
<v-spacer />
<v-btn
tooltip="Save"
@ -12,116 +12,51 @@
</v-btn>
</v-card-title>
<div v-if="hooks " class="pa-4">
<v-divider />
<div v-if="hooks " class="pa-6">
<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>
<v-card v-for="(hook,i) in hooks" :key="hook.id" max-width="500px" class="mx-auto elevation-0 backgroundColor nc-hook mb-4" @click="$emit('edit', hook)">
<div class="d-flex">
<v-icon class="ml-4">
mdi-hook
</v-icon>
<div class="pa-4 flex-grow-1">
<div class="d-flex">
<h4 class="nc-text mb-2">
{{ hook.title }}
</h4>
<v-spacer />
<!--Notify Via-->
<span class="caption textColor1--text mt-1">{{
$t("labels.notifyVia")
}} : {{ hook.notification && hook.notification.type }}
</span>
</div>
<div class="d-flex">
<!--Title-->
<span class="caption textColor1--text text-uppercase"> {{ hook.event }} {{
hook.operation
}}</span>
</div>
</div>
<v-icon class="nc-hook-delete-icon" small @click.stop="deleteHook(hook,i)">
mdi-delete-outline
</v-icon>
</div>
<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>
<template #default>
<thead>
<tr>
<th>
&lt;!&ndash;Title&ndash;&gt;
{{ $t("general.title") }}
</th>
<th>
&lt;!&ndash;Event&ndash;&gt;
{{ $t("general.event") }}
</th>
<th>
&lt;!&ndash;Condition&ndash;&gt;
{{ $t("general.condition") }}
</th>
<th>
&lt;!&ndash;Notify Via&ndash;&gt;
{{ $t("labels.notifyVia") }}
</th>
<th>
&lt;!&ndash;Action&ndash;&gt;
{{ $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>
&lt;!&ndash; <x-icon small :color="loading || !valid || !hook.event ? 'grey' : 'primary'"
@click.stop="(!loading && valid && hook.event) && saveHooks()">save
</x-icon>&ndash;&gt;
</td>
</tr>
</template>
<tr>
<td colspan="6" class="text-center py-5">
&lt;!&ndash;:tooltip="$t('tooltip.saveChanges')"&ndash;&gt;
<x-btn
v-ge="['hooks', 'add new']"
outlined
color="primary"
small
@click.prevent="$emit('add')"
>
<v-icon small left>
mdi-plus
</v-icon>
&lt;!&ndash;Add New Webhook&ndash;&gt;
{{ $t("activity.addWebhook") }}
</x-btn>
</td>
</tr>
</tbody>
</template>
</v-simple-table>-->
</div>
</template>
<script>
import { calculateDiff } from '~/helpers'
export default {
name: 'WebhookList',
props: { meta: Object },
@ -132,6 +67,7 @@ export default {
this.loadHooksList()
},
methods: {
calculateDiff,
async loadHooksList() {
this.key++
this.loading = true
@ -175,7 +111,7 @@ export default {
opacity: 0;
transition: .3s opacity;
right: 16px;
top: 16px
bottom: 16px
}
&:hover .nc-hook-delete-icon {

64
packages/nc-gui/components/project/tableTabs/webhook/WebhookSlider.vue

@ -0,0 +1,64 @@
<template>
<nc-slider v-model="webhookSlider">
<v-card
v-if="webhookSlider"
width="100%"
min-height="350px"
class="pa-4 elevation-0"
>
<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>
</nc-slider>
</template>
<script>
import WebhookList from '~/components/project/tableTabs/webhook/WebhookList'
import WebhookEditor from '~/components/project/tableTabs/webhook/WebhookEditor'
import NcSlider from '~/components/global/NcSlider'
export default {
name: 'WebhookSlider',
components: { NcSlider, WebhookEditor, WebhookList },
props: {
meta: Object,
value: Boolean
},
data: () => ({
editOrAdd: false,
activePage: 'role'
}),
computed: {
webhookSlider: {
get() {
return this.value
},
set(v) {
this.$emit('input', v)
}
}
},
mounted() {
(document.querySelector('[data-app]') || this.$root.$el).append(this.$el)
},
destroyed() {
this.$el.parentNode && this.$el.parentNode.removeChild(this.$el)
},
methods: {
editHook(hook) {
this.editOrAdd = true
this.$nextTick(() => {
this.$refs.editor.hook = { ...hook }
this.$refs.editor.onEventChange()
})
}
}
}
</script>
<style scoped lang="scss">
::v-deep{
.nc-content{max-width: 600px !important}
}
</style>

11
packages/nc-gui/helpers/index.js

@ -1,3 +1,14 @@
import dayjs from 'dayjs'
const relativeTime = require('dayjs/plugin/relativeTime')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
dayjs.extend(relativeTime)
export function calculateDiff(date) {
return dayjs.utc(date).fromNow()
}
export const isEmail = v => /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i.test(v)
// ref : https://stackoverflow.com/a/5717133

Loading…
Cancel
Save